3

So I am trying to create the namehash() function in PHP for my own project and to also learn how to do it. But i am having issues.

This python function works as intended:

def namehash(name: str, encoding  = 'utf-8'):
if name == '':
    return b'\x00' * 32
else:
    label, _, remainder = name.partition('.')
    return sha3.keccak_256(namehash(remainder) + sha3.keccak_256(bytes(label, encoding = encoding)).digest()).digest()

namehash('') = 0x0000000000000000000000000000000000000000000000000000000000000000 namehash('eth') = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae

However this PHP function doesn not:

function namehash($_name){
    $node = '';
for($i = 0; $i < 32; $i++){
    $node .= '0';
}

if($_name){

    $labels = explode('.', $_name);
    for($i = count($labels) - 1; $i >= 0; $i--){

        $labelSha = Keccak::hash($labels[$i], 256);
        $node = Keccak::hash($node . $labelSha, 256);

    }

}

return '0x' . $node;

}

0x00000000000000000000000000000000 0xc850e024ab508b89ab4833ddd18f253ddd83897cb813469cc62f68d359c5f314

I assume something is not encoded properly, but I am having a hard time finding what. Can anyone show me what the issue is?

Andriy Lysak
  • 271
  • 1
  • 5

2 Answers2

1

The namehash for vitalik.eth is 0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835

For testing against.. you can generate namehashes (and other ENS related hashes) here. Disclaimer: EthTools.com is my site.

To generate a namehash in PHP using php-keccak your code would look like the following:

    //The base namehash for '' - 0000000000000000000000000000000000000000000000000000000000000000
    $baseNamehash = hex2bin("0000000000000000000000000000000000000000000000000000000000000000");
//The labelhash for 'eth' - 4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0
$ethLabelhash = hex2bin(\kornrunner\Keccak::hash("eth", 256));

//The namehash for 'eth' - 93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae
$ethNamehash = \kornrunner\Keccak::hash($baseNamehash . $ethLabelhash, 256); 

//The labelhash for vitalik - af2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc
$vitalikLabelhash = hex2bin(\kornrunner\Keccak::hash("vitalik", 256));

//The namehash for vitalik.eth - ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
$vitalikNamehash = \kornrunner\Keccak::hash(hex2bin($ethNamehash) . $vitalikLabelhash, 256);

The important bit is using hex2bin to convert a hexadecimal hash string to its binary form for utilisation by the php-keccak library. Note the lack of prepending 0x.

Thomas Clowes
  • 4,385
  • 2
  • 19
  • 43
0

It is better to use the built-in PHP functions as they are less prone to errors

Here the error could be in the input value of the $_name parameter or in the missing implementation of the Keccak hash function.

You can import sha3 library in PHP, and also add some checks to ensure there are no errors if you enter an empty input and $node value is 32 before returning it

AmariS1
  • 77
  • 9