This commit is contained in:
2026-06-12 12:33:29 -04:00
parent e4bb07226f
commit 0355ae14de

View File

@@ -38,15 +38,32 @@ function cry01_get_balance($g1_pubkey) {
return cry01_decode_balance($result);
}
function cry01_twox128($data) {
// Substrate's "Twox128" storage prefix hash.
//
// This is NOT the same as PHP's hash('xxh128', ...) — that is a single
// 128-bit xxHash variant and produces a completely different result.
//
// Substrate's Twox128 is constructed as:
// reverse(xxh64(data, seed=0)) . reverse(xxh64(data, seed=1))
//
// Confirmed correct against the live Ğ1 chain: Twox128("Timestamp") .
// Twox128("Now") used as a storage key for Timestamp.Now (a plain
// StorageValue with no map/hasher) returned a non-null SCALE-encoded
// u64, confirming both the algorithm and byte order.
$h0 = strrev(hash('xxh64', $data, true, ['seed' => 0]));
$h1 = strrev(hash('xxh64', $data, true, ['seed' => 1]));
return $h0 . $h1;
}
function cry01_balance_storage_key($account_id_bytes) {
// Builds the Substrate storage key for System.Account(account_id_bytes).
//
// Storage key = xxh128("System") . xxh128("Account") . Blake2_128Concat(account_id_bytes)
// = xxh128("System") . xxh128("Account") . blake2b_128(account_id_bytes) . account_id_bytes
// Storage key = Twox128("System") . Twox128("Account") . Blake2_128Concat(account_id_bytes)
// = Twox128("System") . Twox128("Account") . blake2b_128(account_id_bytes) . account_id_bytes
//
// xxh128 is PHP's native hash('xxh128', ..., true) — confirmed correct
// against the published test vector (16c27099bd855aff3b3efe27980515ad
// for "php.watch").
// Twox128 is cry01_twox128() above — confirmed correct against the live
// Ğ1 chain via Timestamp.Now.
//
// blake2b_128 is the vendored deemru/Blake2b pure-PHP implementation,
// confirmed correct against RFC 7693 parameterized test vectors:
@@ -59,8 +76,8 @@ function cry01_balance_storage_key($account_id_bytes) {
return '0x';
}
$prefix_system = hash('xxh128', 'System', true);
$prefix_account = hash('xxh128', 'Account', true);
$prefix_system = cry01_twox128('System');
$prefix_account = cry01_twox128('Account');
$b2b128 = new Blake2b(16);
$key_hash = $b2b128->hash($account_id_bytes);
@@ -100,9 +117,8 @@ function cry01_decode_balance($rpc_result) {
return '0';
}
$hex = ltrim($hex, '0x');
if (substr($rpc_result['result'], 0, 2) === '0x') {
$hex = substr($rpc_result['result'], 2);
if (substr($hex, 0, 2) === '0x') {
$hex = substr($hex, 2);
}
$bytes = hex2bin($hex);