【问题标题】:How to validate an Ethereum address PHP / Laravel?如何验证以太坊地址 PHP / Laravel?
【发布时间】:2018-02-03 02:30:41
【问题描述】:

如何检查来自 Laravel 输入的以太坊地址在格式上是否有效?

【问题讨论】:

    标签: php laravel validation laravel-5 ethereum


    【解决方案1】:

    任何以 0x 开头,后跟 0-9、A-F、a-f(有效的十六进制字符)的 42 个字符的字符串都表示一个有效的以太坊地址。

    您可以找到有关小写和部分大写(用于添加校验和)以太坊地址格式here 的更多信息。

    【讨论】:

    • 感谢回复,我使用 go-ethereum JSON RPC API 概念,但没有任何函数来验证地址。
    • 是的,它比需要一个新的 api 调用更简单。您只需一行代码就可以做到这一点。例如使用 python re 模块: True if re.match("^(0x)?[0-9a-f]{40}$", address) else False
    【解决方案2】:

    这是一个 Laravel custom validation rule,用于根据 EIP 55 规范验证以太坊地址。具体如何工作,请浏览 cmets。

    <?php
    
    namespace App\Rules;
    
    use kornrunner\Keccak; // composer require greensea/keccak
    use Illuminate\Contracts\Validation\Rule;
    
    class ValidEthereumAddress implements Rule
    {
        /**
         * @var Keccak
         */
        protected $hasher;
    
        public function __construct(Keccak $hasher)
        {
            $this->keccak = $hasher;
        }
    
        public function passes($attribute, $value)
        {
            // See: https://github.com/ethereum/web3.js/blob/7935e5f/lib/utils/utils.js#L415
            if ($this->matchesPattern($value)) {
                return $this->isAllSameCaps($value) ?: $this->isValidChecksum($value);
            }
    
            return false;
        }
    
        public function message()
        {
            return 'The :attribute must be a valid Ethereum address.';
        }
    
        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);
            $hash = $this->keccak->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;
        }
    }
    

    依赖关系

    要验证校验和地址,我们需要一个 Keccac 实现,内置 hash() 函数不支持该实现。您需要 this pure PHP implementation 才能使上述规则生效。

    【讨论】:

    • 它无法正常工作。如果您检查此有效地址,那么它也会显示无效,即0x7614e80bE7E0C1e5aFce4E8e35627dEEc461d2bD
    • 这里的哈希算法有问题。以太坊使用 SHA3 的变体,具有不同的填充常数,称为 Keccak。我已经更新了答案。感谢@WebSpanner 指出这一点。
    • @DhavalBharadva,你确定它是有效的以太坊地址吗?
    猜你喜欢
    • 2022-06-18
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 2016-10-05
    • 2021-07-20
    • 2021-11-29
    • 2020-10-17
    相关资源
    最近更新 更多