我正在使用PHP和curl与json与我的geth服务器进行交互.
除了一件事,我能够做我想要的一切:根据以太坊钱包格式检查用户的输入地址是否有效.
我看到了一个javascript函数here,但我主要使用PHP,我根本不是JS.
任何想法如何验证PHP中的以太坊地址?
解决方法:
这是针对EIP 55规范的以太坊地址验证的PHP实现.有关其工作原理的详细信息,请阅读评论.
<?php
use bb\Sha3\Sha3;
class EthereumValidator
{
public function isAddress(string $address): bool
{
// See: https://github.com/ethereum/web3.js/blob/7935e5f/lib/utils/utils.js#L415
if ($this->matchesPattern($address)) {
return $this->isAllSameCaps($address) ?: $this->isValidChecksum($address);
}
return false;
}
protected function matchesPattern(string $address): int
{
return preg_match('/^(0x)?[0-9a-f]{40}$/i', $address);
}
protected function isAllSameCaps(string $address): bool
{
return preg_match('/^(0x)?[0-9a-f]{40}$/', $address) || preg_match('/^(0x)?[0-9A-F]{40}$/', $address);
}
protected function isValidChecksum($address)
{
$address = str_replace('0x', '', $address);
// See: https://github.com/ethereum/web3.js/blob/b794007/lib/utils/sha3.js#L35
$hash = Sha3::hash(strtolower($address), 256);
// See: https://github.com/web3j/web3j/pull/134/files#diff-db8702981afff54d3de6a913f13b7be4R42
for ($i = 0; $i < 40; $i++ ) {
if (ctype_alpha($address{$i})) {
// Each uppercase letter should correlate with a first bit of 1 in the hash char with the same index,
// and each lowercase letter with a 0 bit.
$charInt = intval($hash{$i}, 16);
if ((ctype_upper($address{$i}) && $charInt <= 7) || (ctype_lower($address{$i}) && $charInt > 7)) {
return false;
}
}
}
return true;
}
}
依赖
要验证校验和地址,我们需要SHA3实现,内置hash()
功能尚不支持.您需要在this pure PHP implementation中获取上述规则才能生效.它没有在Packagist上注册,将repo注册为composer VCS repository.
还有一个PHP扩展实现我现在不想找到.