encoding.py (2691B)
1 # standard imports 2 import logging 3 4 # external imports 5 import coincurve 6 import sha3 7 from hexathon import ( 8 strip_0x, 9 uniform, 10 ) 11 12 logg = logging.getLogger(__name__) 13 14 15 def private_key_from_bytes(b): 16 return coincurve.PrivateKey(secret=b) 17 18 19 def public_key_bytes_to_address(pubk_bytes, result_format='hex'): 20 h = sha3.keccak_256() 21 logg.debug('public key bytes {}'.format(pubk_bytes.hex())) 22 h.update(pubk_bytes[1:]) 23 z = h.digest()[12:] 24 if result_format == 'hex': 25 return to_checksum_address(z[:20].hex()) 26 elif result_format == 'bytes': 27 return z[:20] 28 raise ValueError('invalid result format "{}"'.format(result_format)) 29 30 31 def public_key_to_address(pubk, result_format='hex'): 32 pubk_bytes = pubk.format(compressed=False) 33 return public_key_bytes_to_address(pubk_bytes, result_format='hex') 34 35 36 def private_key_to_address(pk, result_format='hex'): 37 pubk = coincurve.PublicKey.from_secret(pk.secret) 38 #logg.debug('secret {} '.format(pk.secret.hex())) 39 return public_key_to_address(pubk, result_format) 40 41 42 def private_key_to_public_key(pk, result_format='hex'): 43 pubk = coincurve.PublicKey.from_secret(pk.secret) 44 r = pubk.format(compressed=False) 45 if result_format=='hex': 46 r = r.hex() 47 return r 48 49 50 def is_address(address_hex): 51 try: 52 address_hex = strip_0x(address_hex, pad=False) 53 except ValueError: 54 return False 55 return len(address_hex) == 40 56 57 58 def is_checksum_address(address_hex): 59 hx = None 60 try: 61 hx = to_checksum(address_hex) 62 except ValueError: 63 return False 64 return hx == strip_0x(address_hex) 65 66 67 def to_checksum_address(address_hex): 68 address_hex = strip_0x(address_hex, pad=False) 69 if len(address_hex) != 40: 70 raise ValueError('Invalid address length') 71 address_hex = uniform(address_hex) 72 h = sha3.keccak_256() 73 h.update(address_hex.encode('utf-8')) 74 z = h.digest() 75 76 #checksum_address_hex = '0x' 77 checksum_address_hex = '' 78 79 for (i, c) in enumerate(address_hex): 80 if c in '1234567890': 81 checksum_address_hex += c 82 elif c in 'abcdef': 83 if z[int(i / 2)] & (0x80 >> ((i % 2) * 4)) > 1: 84 checksum_address_hex += c.upper() 85 else: 86 checksum_address_hex += c 87 88 return checksum_address_hex 89 90 to_checksum = to_checksum_address 91 92 ethereum_recid_modifier = 35 93 94 def chain_id_to_v(chain_id, signature): 95 v = signature[64] 96 return (chain_id * 2) + ethereum_recid_modifier + v 97 98 def chainv_to_v(chain_id, v): 99 return v - ethereum_recid_modifier - (chain_id * 2)