LoginSignup
4
0

More than 5 years have passed since last update.

PHPでNEMのアドレス有効性チェック

Last updated at Posted at 2018-04-07

PHP 5.3〜

ネットワーク種別は、単純に頭文字をチェックするんでもOK。

$ composer require christian-riesen/base32
$ composer require izayoi256/keccak
require_once __DIR__ . '/vendor/autoload.php';

use Base32\Base32;
use izayoi256\Keccak;

define('NETWORK_ID_MAINNET', 104);
define('NETWORK_ID_MIJINNET', 96);
define('NETWORK_ID_TESTNET', -104);

function is_valid_address($address, array $networkIds = array())
{
    if (!is_string($address)) {
        throw new \InvalidArgumentException('Address must be string.');
        // または
        // return false;
    }

    if (!is_array($networkIds) || $networkIds !== array_filter($networkIds, 'is_int')) {
        throw new \InvalidArgumentException('Network IDs must be an array of integer.');
    }

    $str = str_replace('-', '', $address);

    if (strlen($str) !== 40) {
        return false;
    }

    $decoded = bin2hex(Base32::decode($str));
    $hash = substr($decoded, 0, 42);
    // hex2bin()はPHP5.4以降のため、pack('H*', $var)を使用する。
    $bin = pack('H*', $hash);
    $checksum = substr(Keccak::hash($bin, 256), 0, 8);

    if (substr($decoded, 42) !== $checksum) {
        return false;
    }

    $networkValid = !count($networkIds);

    foreach ($networkIds as $networkId) {
        $hex = bin2hex(pack('c', $networkId));
        $networkValid = $networkValid || preg_match("/^{$hex}/", $decoded);
    }

    return $networkValid;
}

// アドレスの有効性をチェックする
is_valid_address('TCY3JIKAYRUPEFDAJUZX7TPOOV6M22E4YU6R42RI');
// TRUE

// アドレスの有効性と、ネットワーク種別をチェックする
is_valid_address('TCY3JIKAYRUPEFDAJUZX7TPOOV6M22E4YU6R42RI', array(NETWORK_ID_MAINNET));
// FALSE

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0