-
Notifications
You must be signed in to change notification settings - Fork 12
/
namehash.py
52 lines (35 loc) · 1.13 KB
/
namehash.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import codecs
import functools
from sha3 import sha3_256
def is_bytes(value):
return isinstance(value, (bytes, bytearray))
def combine(f, g):
return lambda x: f(g(x))
def compose(*functions):
return functools.reduce(combine, functions, lambda x: x)
def sha3(value):
return sha3_256(value).digest()
# ensure we have the *correct* sha3 installed (keccak)
assert codecs.encode(sha3(b''), 'hex') == b'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' # noqa
def _sub_hash(value, label):
return sha3(value + sha3(label))
def namehash(name, encoding=None):
"""
Implementation of the namehash algorithm from EIP137.
"""
node = b'\x00' * 32
if name:
if encoding is None:
if is_bytes(name):
encoded_name = name
else:
encoded_name = codecs.encode(name, 'utf8')
else:
encoded_name = codecs.encode(name, encoding)
labels = encoded_name.split(b'.')
return compose(*(
functools.partial(_sub_hash, label=label)
for label
in labels
))(node)
return node