简体   繁体   English

如何验证以太坊地址 PHP / Laravel?

[英]How to validate an Ethereum address PHP / Laravel?

How can I check if the Ethereum address from Laravel input is valid in terms of format?如何检查 Laravel 输入的以太坊地址格式是否有效?

Here's a Laravel custom validation rule for validating Ethereum addresses against the EIP 55 specification.这是一个 Laravel自定义验证规则,用于根据EIP 55规范验证以太坊地址。 For details of how it works, please go through the comments.具体如何操作,请通过评论go。

<?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;
    }
}

Dependencies依赖关系

To validate checksum addresses, we need a Keccac implementation in place which is not supported by the built-in hash() function. You need to require this pure PHP implementation for the above rule to work.为了验证校验和地址,我们需要一个Keccac实现,内置hash() function 不支持它。您需要这个纯 PHP 实现才能使上述规则起作用。

Any 42 character string starting with 0x, and following with 0-9, AF, af (valid hex characters) represent a valid Ethereum address.任何以 0x 开头,后跟 0-9、AF、af(有效的十六进制字符)的 42 个字符串代表一个有效的以太坊地址。

You can find more information about lowercase and partial uppercase (for adding checksum) Ethereum addresses format here .您可以在此处找到有关小写和部分大写(用于添加校验和)以太坊地址格式的更多信息。

As of Laravel 9, If you are using a request class for validation, add this to the validation rules: As of Laravel 9, 如果你使用请求 class 进行验证,在验证规则中添加:

/**
 * Get the validation rules that apply to the request.
 * 
 * @return array
 */
public function rules()
{
    return [
        'address' => 'regex:/^(0x)?(?i:[0-9a-f]){40}$/'
    ];
}

Notes:笔记:

  • Here, the input field name is address这里,输入的字段名称是address
  • I applied case insensitivity to only a part of the regular expression using the format (?i: ... )我使用格式(?i: ... )将不区分大小写仅应用于正则表达式的一部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM