fix incomplete base58 move from a7d3ae4
[p2pool.git] / p2pool / bitcoin / data.py
1 from __future__ import division
2
3 import hashlib
4
5 from p2pool.util import bases, math, pack
6
7 def hash256(data):
8     return pack.IntType(256).unpack(hashlib.sha256(hashlib.sha256(data).digest()).digest())
9
10 def hash160(data):
11     return pack.IntType(160).unpack(hashlib.new('ripemd160', hashlib.sha256(data).digest()).digest())
12
13 class ChecksummedType(pack.Type):
14     def __init__(self, inner):
15         self.inner = inner
16     
17     def read(self, file):
18         obj, file = self.inner.read(file)
19         data = self.inner.pack(obj)
20         
21         checksum, file = pack.read(file, 4)
22         if checksum != hashlib.sha256(hashlib.sha256(data).digest()).digest()[:4]:
23             raise ValueError('invalid checksum')
24         
25         return obj, file
26     
27     def write(self, file, item):
28         data = self.inner.pack(item)
29         return (file, data), hashlib.sha256(hashlib.sha256(data).digest()).digest()[:4]
30
31 class FloatingInteger(object):
32     __slots__ = ['bits', '_target']
33     
34     @classmethod
35     def from_target_upper_bound(cls, target):
36         n = bases.natural_to_string(target)
37         if n and ord(n[0]) >= 128:
38             n = '\x00' + n
39         bits2 = (chr(len(n)) + (n + 3*chr(0))[:3])[::-1]
40         bits = pack.IntType(32).unpack(bits2)
41         return cls(bits)
42     
43     def __init__(self, bits, target=None):
44         self.bits = bits
45         self._target = None
46         if target is not None and self.target != target:
47             raise ValueError('target does not match')
48     
49     @property
50     def target(self):
51         res = self._target
52         if res is None:
53             res = self._target = math.shift_left(self.bits & 0x00ffffff, 8 * ((self.bits >> 24) - 3))
54         return res
55     
56     def __hash__(self):
57         return hash(self.bits)
58     
59     def __eq__(self, other):
60         return self.bits == other.bits
61     
62     def __ne__(self, other):
63         return not (self == other)
64     
65     def __cmp__(self, other):
66         assert False
67     
68     def __repr__(self):
69         return 'FloatingInteger(bits=%s, target=%s)' % (hex(self.bits), hex(self.target))
70
71 class FloatingIntegerType(pack.Type):
72     _inner = pack.IntType(32)
73     
74     def read(self, file):
75         bits, file = self._inner.read(file)
76         return FloatingInteger(bits), file
77     
78     def write(self, file, item):
79         return self._inner.write(file, item.bits)
80
81 address_type = pack.ComposedType([
82     ('services', pack.IntType(64)),
83     ('address', pack.IPV6AddressType()),
84     ('port', pack.IntType(16, 'big')),
85 ])
86
87 tx_type = pack.ComposedType([
88     ('version', pack.IntType(32)),
89     ('tx_ins', pack.ListType(pack.ComposedType([
90         ('previous_output', pack.PossiblyNoneType(dict(hash=0, index=2**32 - 1), pack.ComposedType([
91             ('hash', pack.IntType(256)),
92             ('index', pack.IntType(32)),
93         ]))),
94         ('script', pack.VarStrType()),
95         ('sequence', pack.PossiblyNoneType(2**32 - 1, pack.IntType(32))),
96     ]))),
97     ('tx_outs', pack.ListType(pack.ComposedType([
98         ('value', pack.IntType(64)),
99         ('script', pack.VarStrType()),
100     ]))),
101     ('lock_time', pack.IntType(32)),
102 ])
103
104 merkle_branch_type = pack.ListType(pack.IntType(256))
105
106 merkle_tx_type = pack.ComposedType([
107     ('tx', tx_type),
108     ('block_hash', pack.IntType(256)),
109     ('merkle_branch', merkle_branch_type),
110     ('index', pack.IntType(32)),
111 ])
112
113 block_header_type = pack.ComposedType([
114     ('version', pack.IntType(32)),
115     ('previous_block', pack.PossiblyNoneType(0, pack.IntType(256))),
116     ('merkle_root', pack.IntType(256)),
117     ('timestamp', pack.IntType(32)),
118     ('bits', FloatingIntegerType()),
119     ('nonce', pack.IntType(32)),
120 ])
121
122 block_type = pack.ComposedType([
123     ('header', block_header_type),
124     ('txs', pack.ListType(tx_type)),
125 ])
126
127 aux_pow_type = pack.ComposedType([
128     ('merkle_tx', merkle_tx_type),
129     ('merkle_branch', merkle_branch_type),
130     ('index', pack.IntType(32)),
131     ('parent_block_header', block_header_type),
132 ])
133
134
135 merkle_record_type = pack.ComposedType([
136     ('left', pack.IntType(256)),
137     ('right', pack.IntType(256)),
138 ])
139
140 def merkle_hash(hashes):
141     if not hashes:
142         return 0
143     hash_list = list(hashes)
144     while len(hash_list) > 1:
145         hash_list = [hash256(merkle_record_type.pack(dict(left=left, right=left if right is None else right)))
146             for left, right in zip(hash_list[::2], hash_list[1::2] + [None])]
147     return hash_list[0]
148
149 def calculate_merkle_branch(hashes, index):
150     # XXX optimize this
151     
152     hash_list = [(h, i == index, []) for i, h in enumerate(hashes)]
153     
154     while len(hash_list) > 1:
155         hash_list = [
156             (
157                 hash256(merkle_record_type.pack(dict(left=left, right=right))),
158                 left_f or right_f,
159                 (left_l if left_f else right_l) + [dict(side=1, hash=right) if left_f else dict(side=0, hash=left)],
160             )
161             for (left, left_f, left_l), (right, right_f, right_l) in
162                 zip(hash_list[::2], hash_list[1::2] + [hash_list[::2][-1]])
163         ]
164     
165     res = [x['hash'] for x in hash_list[0][2]]
166     
167     assert hash_list[0][1]
168     assert check_merkle_branch(hashes[index], index, res) == hash_list[0][0]
169     assert index == sum(k*2**i for i, k in enumerate([1-x['side'] for x in hash_list[0][2]]))
170     
171     return res
172
173 def check_merkle_branch(tip_hash, index, merkle_branch):
174     return reduce(lambda c, (i, h): hash256(merkle_record_type.pack(
175         dict(left=h, right=c) if 2**i & index else
176         dict(left=c, right=h)
177     )), enumerate(merkle_branch), tip_hash)
178
179 def target_to_average_attempts(target):
180     return 2**256//(target + 1)
181
182 def target_to_difficulty(target):
183     return (0xffff0000 * 2**(256-64) + 1)/(target + 1)
184
185 # tx
186
187 def tx_get_sigop_count(tx):
188     return sum(script.get_sigop_count(txin['script']) for txin in tx['tx_ins']) + sum(script.get_sigop_count(txout['script']) for txout in tx['tx_outs'])
189
190 # human addresses
191
192 base58_alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
193
194 def base58_encode(bindata):
195     bindata2 = bindata.lstrip(chr(0))
196     return base58_alphabet[0]*(len(bindata) - len(bindata2)) + bases.natural_to_string(bases.string_to_natural(bindata2), base58_alphabet)
197
198 def base58_decode(b58data):
199     b58data2 = b58data.lstrip(base58_alphabet[0])
200     return chr(0)*(len(b58data) - len(b58data2)) + bases.natural_to_string(bases.string_to_natural(b58data2, base58_alphabet))
201
202 human_address_type = ChecksummedType(pack.ComposedType([
203     ('version', pack.IntType(8)),
204     ('pubkey_hash', pack.IntType(160)),
205 ]))
206
207 def pubkey_hash_to_address(pubkey_hash, net):
208     return base58_encode(human_address_type.pack(dict(version=net.ADDRESS_VERSION, pubkey_hash=pubkey_hash)))
209
210 def pubkey_to_address(pubkey, net):
211     return pubkey_hash_to_address(hash160(pubkey), net)
212
213 def address_to_pubkey_hash(address, net):
214     x = human_address_type.unpack(base58_decode(address))
215     if x['version'] != net.ADDRESS_VERSION:
216         raise ValueError('address not for this net!')
217     return x['pubkey_hash']
218
219 # transactions
220
221 def pubkey_to_script2(pubkey):
222     return ('\x41' + pubkey) + '\xac'
223
224 def pubkey_hash_to_script2(pubkey_hash):
225     return '\x76\xa9' + ('\x14' + pack.IntType(160).pack(pubkey_hash)) + '\x88\xac'
226
227 def script2_to_address(script2, net):
228     try:
229         pubkey = script2[1:-1]
230         script2_test = pubkey_to_script2(pubkey)
231     except:
232         pass
233     else:
234         if script2_test == script2:
235             return pubkey_to_address(pubkey, net)
236     
237     try:
238         pubkey_hash = pack.IntType(160).unpack(script2[3:-2])
239         script2_test2 = pubkey_hash_to_script2(pubkey_hash)
240     except:
241         pass
242     else:
243         if script2_test2 == script2:
244             return pubkey_hash_to_address(pubkey_hash, net)
245
246 def script2_to_human(script2, net):
247     try:
248         pubkey = script2[1:-1]
249         script2_test = pubkey_to_script2(pubkey)
250     except:
251         pass
252     else:
253         if script2_test == script2:
254             return 'Pubkey. Address: %s' % (pubkey_to_address(pubkey, net),)
255     
256     try:
257         pubkey_hash = pack.IntType(160).unpack(script2[3:-2])
258         script2_test2 = pubkey_hash_to_script2(pubkey_hash)
259     except:
260         pass
261     else:
262         if script2_test2 == script2:
263             return 'Address. Address: %s' % (pubkey_hash_to_address(pubkey_hash, net),)
264     
265     return 'Unknown. Script: %s'  % (script2.encode('hex'),)