-
Notifications
You must be signed in to change notification settings - Fork 47
/
unspendable.py
92 lines (70 loc) · 2.16 KB
/
unspendable.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#! /usr/bin/env python3
import sys
import hashlib
import binascii
dhash = lambda x: hashlib.sha256(hashlib.sha256(x).digest()).digest()
b58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def base58_check_encode(b, version):
d = version + b
address = d + dhash(d)[:4]
# Convert big‐endian bytes to integer
n = int('0x0' + binascii.hexlify(address).decode('utf8'), 16)
# Divide that integer into base58
res = []
while n > 0:
n, r = divmod (n, 58)
res.append(b58_digits[r])
res = ''.join(res[::-1])
# Encode leading zeros as base58 zeros
czero = 0
pad = 0
for c in d:
if c == czero: pad += 1
else: break
return b58_digits[0] * pad + res
def base58_decode (s, version):
# Convert the string to an integer
n = 0
for c in s:
n *= 58
if c not in b58_digits:
raise Exception
digit = b58_digits.index(c)
n += digit
# Convert the integer to bytes
h = '%x' % n
if len(h) % 2:
h = '0' + h
res = binascii.unhexlify(h.encode('utf8'))
# Add padding back.
pad = 0
for c in s[:-1]:
if c == b58_digits[0]: pad += 1
else: break
k = version * pad + res
addrbyte, data, chk0 = k[0:1], k[1:-4], k[-4:]
return data
def generate (name, network):
# Pick network.
if network == 'testnet':
prefix_string = 'mv'
prefix_bytes = b'\x6f'
elif network == 'mainnet':
prefix_string = '1'
prefix_bytes = b'\x00'
else:
raise Exception('unknown network')
# Pad and prefix.
prefixed_name = prefix_string + name
padded_prefixed_name = prefixed_name.ljust(34, 'X')
# Decode, ignoring (bad) checksum.
decoded_address = base58_decode(padded_prefixed_name, prefix_bytes)
# Re-encode, calculating checksum.
address = base58_check_encode(decoded_address, prefix_bytes)
# Double-check.
assert base58_decode(address, prefix_bytes) == decoded_address
return address
if __name__ == '__main__':
name = sys.argv[1]
print('mainnet:', generate(name, 'mainnet'))
print('testnet:', generate(name, 'testnet'))