-
Notifications
You must be signed in to change notification settings - Fork 7
/
lightclient.py
99 lines (78 loc) · 3.09 KB
/
lightclient.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
93
94
95
96
97
98
99
import json
from hashlib import sha256
from binascii import unhexlify
with open("block0.json") as block0_file:
block0 = json.load(block0_file)
with open("block1.json") as block1_file:
block1 = json.load(block1_file)
# from bitcoinlib.blocks import Block
# b = Block(block1['hash'], block1['version'], block1['previousblockhash'],
# block1['merkleroot'], block1['time'], block1['bits'], block1['nonce'])
# print(b.target_hex)
# block header
# [version, previousblockhash, merkleroot, time, bits, nonce]
# [4, 32, 32, 4, 4, 4 ]
# [int, string, string, int, string, int]
# all little endian
ENDIANNESS = 'little'
def to_bytes(string, unhexlify=True):
if not string:
return b''
if unhexlify:
try:
if isinstance(string, bytes):
string = string.decode()
s = bytes.fromhex(string)
return s
except (TypeError, ValueError):
pass
if isinstance(string, bytes):
return string
else:
return bytes(string, 'utf8')
def double_sha256(string, as_hex=False):
if not as_hex:
return sha256(sha256(string).digest()).digest()
else:
return sha256(sha256(string).digest()).hexdigest()
def big_to_little_endian(s):
return bytes.fromhex(s)[::-1].hex()
def verifyBlock(block):
versionHex = big_to_little_endian(block['versionHex'])
previousBlockHashHex = big_to_little_endian(
block['previousblockhash']) if 'previousblockhash' in block else (0).to_bytes(32, ENDIANNESS).hex()
merkleRootHex = big_to_little_endian(block['merkleroot'])
timeHex = block['time'].to_bytes(4, ENDIANNESS).hex()
bitsHex = big_to_little_endian(block['bits'])
nonceB = block['nonce'].to_bytes(4, ENDIANNESS).hex()
header_hex = versionHex + previousBlockHashHex + \
merkleRootHex + timeHex + bitsHex + nonceB
print(len(header_hex), header_hex)
header_bin = unhexlify(header_hex)
hash = sha256(sha256(header_bin).digest()).digest()
print(hash[::-1].hex())
def header_to_cairo(block):
versionHex = big_to_little_endian(block['versionHex'])
previousBlockHashHex = big_to_little_endian(
block['previousblockhash']) if 'previousblockhash' in block else (0).to_bytes(32, ENDIANNESS).hex()
merkleRootHex = big_to_little_endian(block['merkleroot'])
timeHex = block['time'].to_bytes(4, ENDIANNESS).hex()
bitsHex = big_to_little_endian(block['bits'])
nonceB = block['nonce'].to_bytes(4, ENDIANNESS).hex()
header_hex = versionHex + previousBlockHashHex + \
merkleRootHex + timeHex + bitsHex + nonceB
header_bin = unhexlify(header_hex)
data = header_bin.hex()
# print(data)
# return [data[8*i:8*(i+1)] for i in range(160//8)]
tmp = [int(data[8*i:8*(i+1)], 16) for i in range(160//8)]
# for i,d in enumerate(tmp):
# print(f'data[{i}] = {d}')
return tmp
if __name__ == "__main__":
print(header_to_cairo(block0))
print(header_to_cairo(block1))
verifyBlock(block0)
print(block0['hash'])
verifyBlock(block1)
print(block1['hash'])