Dev Question: namehash vs solidity

Hi - I’m working on a dapp and am confused about nodes names and labels. Hope someone can set me straight.

I want to register the name bob.alice.eth in the alice.eth subdomain.

I use the eth-ens-namehash npm module to calculate a few nodes and labels:

alice.eth : 0x787192fc5378cc32aa956ddfdedbf26b24e8d78e40109add0eea2c1a012c3dec
bob : 0xb04218a8af305c01e75093737bf8fe1565c7346ab357ec8cb5bf836a65c3e5b8
bob.alice.eth : 0x740c03d323112b17841937a0e5f8dbe8d2df496a577f5c75ab1156dd8b1158c3

The alice.eth one matches online documentation so namehash seems to be working. Then I have an uber-simple ENS mock deployed in ganache-cli as follows:

contract ENSMock {
  event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
  event Subnode(bytes32 indexed node); // debug

  mapping(bytes32=>address) public owners;

  function owner(bytes32 _node) external view returns (address) {
    return owners[_node];
  }

  function setSubnodeOwner(bytes32 _node, bytes32 _label, address _owner)
  external {
    bytes32 subnode = keccak256( abi.encode(_node, _label) );
    emit Subnode( subnode ); // debug
    owners[subnode] = _owner;
    emit NewOwner(_node, _label, _owner);
  }
}

I am calling setSubnodeOwner from javascript as follows:

// node is namehash('alice.eth')
let node='0x787192fc5378cc32aa956ddfdedbf26b24e8d78e40109add0eea2c1a012c3dec'
// label is namehash('bob')
let label='0xb04218a8af305c01e75093737bf8fe1565c7346ab357ec8cb5bf836a65c3e5b8'
let addr='0x147b61187F3F16583AC77060cbc4f711AE6c9349'

con.methods.setSubnodeOwner(
  web3.utils.hexToBytes(node),
  web3.utils.hexToBytes(label),
  addr )

My code grabs the log and prints out the Subnode and NewOwner events as:

Subnode:
        node: 0xc1bbc2c2b0145d3d9e25bf3cf0dc632e066e703e7dde1432da97d51e941dd0f9

NewOwner:
	node: 0x787192fc5378cc32aa956ddfdedbf26b24e8d78e40109add0eea2c1a012c3dec
	label: 0xb04218a8af305c01e75093737bf8fe1565c7346ab357ec8cb5bf836a65c3e5b8
	owner: 0x147b61187F3F16583AC77060cbc4f711AE6c9349

The namehash algorithm says bob.alice.eth should have a node value of:

0x740c03d323112b17841937a0e5f8dbe8d2df496a577f5c75ab1156dd8b1158c3

but solidity calculates it as:

0xc1bbc2c2b0145d3d9e25bf3cf0dc632e066e703e7dde1432da97d51e941dd0f9

Why the difference?

I tried using abi.encodePacked() but results are similar.

The labelhash of ‘bob’ is 0x38e47a7b719dce63662aeaf43440326f551b8a7ee198cee35cb5d517f2d296a2 - it’s simply the keccak256() of the value.

Thanks! So namehash() for full names and keccak256() to create labels. This was driving me NUTS :slight_smile: