2
from pybtcengine import *
3
from CppBlockUtils import BlockHeader as CppBlockHeader
4
from CppBlockUtils import BlockHeaderRef as CppBlockHeaderRef
5
from CppBlockUtils import Tx as CppTx
6
from CppBlockUtils import TxIn as CppTxIn
7
from CppBlockUtils import TxOut as CppTxOut
8
from CppBlockUtils import BtcWallet as CppBtcWallet
10
from time import time, sleep
13
blkfile = open('/home/alan/.bitcoin/blk0001.dat','r')
15
genBlock = PyBlock().unserialize(blkfile.read(80 + 1 + 285))
18
print 'Genesis block header:'
19
genBlock.blockHeader.pprint()
20
print 'Genesis block tx:'
21
genBlock.blockData.txList[0].pprint()
24
satoshiPubKey = hex_to_binary('04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f')
26
################################################################################
27
def printHashEnds(theHash):
28
intList = [ord(c) for c in theHash]
29
print 'First 4 LE bytes: [%03d,%03d,%03d,%03d]' % tuple(intList[:4]),
30
print 'First 4 BE bytes: [%03d,%03d,%03d,%03d]' % tuple(intList[::-1][:4])
33
def printBlkInfo(blk, suffix):
34
print 'BLOCK (', suffix ,')'
35
print ' Head :', binary_to_hex(blk.blockHeader.getHash())
36
for i,tx in enumerate(blk.blockData.txList):
37
print ' Tx :', binary_to_hex(tx.getHash())
41
printHashEnds(blk.blockHeader.getHash())
42
for i,tx in enumerate(blk.blockData.txList):
44
printHashEnds(tx.getHash())
47
print ' RawHeader :', binary_to_hex(blk.blockHeader.getHash())
48
pprintHex(binary_to_hex(blk.blockHeader.serialize()), indent=' '*12, withAddr=False)
49
for i,tx in enumerate(blk.blockData.txList):
50
print ' RawTx :', binary_to_hex(tx.getHash())
51
print ' PrevOut: (%s,%d)' % (binary_to_hex(tx.inputs[0].outpoint.txOutHash), \
52
tx.inputs[0].outpoint.index)
53
pprintHex(binary_to_hex(tx.serialize()), indent=' '*12, withAddr=False)
57
################################################################################
58
def createPyBlock(prevBlkHeader, txlist):
60
print 'Creating block (%d tx): Computing nonce...' % len(txlist),
61
extraNonce = random.randrange(2**32)
62
txlist[0].inputs[0].binScript = int_to_binary(extraNonce, widthBytes=4)
65
# Instead of changing the txin script as a nonce, we slightly modify
67
newbh = CppBlockHeader()
68
while aGoodNonce == 0:
69
blk = PyBlock(prevBlkHeader, txlist)
70
newbh = CppBlockHeader()
71
newbh.unserialize_1_(blk.blockHeader.serialize())
72
tstamp = newbh.getTimestamp()
73
newbh.setTimestamp(tstamp+numTries)
74
aGoodNonce = newbh.findNonce()
77
blk.blockHeader.nonce = aGoodNonce
78
blk.blockHeader.timestamp = newbh.getTimestamp()
84
AddrA = PyBtcAddress().createFromPublicKey(satoshiPubKey)
85
AddrB = PyBtcAddress().createFromPrivateKey(hex_to_int('bb'*32))
86
AddrC = PyBtcAddress().createFromPrivateKey(hex_to_int('cc'*32))
87
AddrD = PyBtcAddress().createFromPrivateKey(hex_to_int('dd'*32))
88
print 'Addr A: %s' % AddrA.getAddrStr(), ' (Satoshi)'
89
for a,s in ([AddrB,'B'], [AddrC, 'C'], [AddrD, 'D']):
90
print 'Addr %s: %s (PrivKey:%s)' % ( s, a.getAddrStr(), binary_to_hex(a.privKey_serialize()))
92
btcValue = lambda btc: btc*(10**8)
96
Blk1_Tx0 = PyCreateAndSignTx( [COINBASE], [[AddrB, btcValue(50)]] )
97
Blk1 = createPyBlock(genBlock.blockHeader, [Blk1_Tx0] )
98
printBlkInfo(Blk1, '1')
102
Blk2_Tx0 = PyCreateAndSignTx( [COINBASE], [[AddrB, btcValue(50)]] )
103
Blk2_Tx1 = PyCreateAndSignTx( [[AddrB, Blk1.tx(0), 0]], [[AddrC, btcValue(10)], \
104
[AddrB, btcValue(40)]] )
105
Blk2 = createPyBlock(Blk1.blockHeader, [Blk2_Tx0, Blk2_Tx1] )
106
printBlkInfo(Blk2, '2')
110
Blk3_Tx0 = PyCreateAndSignTx( [COINBASE], [[AddrC, btcValue(50)]] ) # will be reversed
111
Blk3_Tx1 = PyCreateAndSignTx( [[AddrB, Blk2.tx(1), 1]], [[AddrD, btcValue(40)]] ) # will be in both chains
112
Blk3_Tx2 = PyCreateAndSignTx( [[AddrC, Blk2.tx(1), 0]], [[AddrD, btcValue(10)]] ) # will be reversed
113
Blk3 = createPyBlock(Blk2.blockHeader, [Blk3_Tx0, Blk3_Tx1, Blk3_Tx2] )
114
printBlkInfo(Blk3, '3')
118
Blk4_Tx0 = PyCreateAndSignTx( [COINBASE], [[AddrA, btcValue(50)]] )
119
Blk4_Tx1 = PyCreateAndSignTx( [[AddrB, Blk2.tx(0), 0]], [[AddrD, btcValue(50)]] ) # will be moved blk5A
120
Blk4 = createPyBlock(Blk3.blockHeader, [Blk4_Tx0, Blk4_Tx1] )
121
printBlkInfo(Blk4, '4')
125
Blk3A_Tx0 = PyCreateAndSignTx( [COINBASE], [[AddrD, btcValue(50)]] )
126
Blk3A_Tx1 = PyTx().unserialize(Blk3.tx(1).serialize())
127
Blk3A_Tx2 = PyCreateAndSignTx( [[AddrC, Blk2.tx(1), 0]], [[AddrB, btcValue(10)]] )
129
Blk3A = createPyBlock(Blk2.blockHeader, [Blk3A_Tx0, Blk3A_Tx1, Blk3A_Tx2] )
130
printBlkInfo(Blk3A, '3A')
134
Blk4A_Tx0 = PyCreateAndSignTx( [COINBASE], [[AddrA, btcValue(50)]] )
135
Blk4A = createPyBlock(Blk3A.blockHeader, [Blk4A_Tx0])
136
printBlkInfo(Blk4A, '4A')
139
Blk5A_Tx0 = PyCreateAndSignTx( [COINBASE], [[AddrA, btcValue(50)]] )
140
Blk5A_Tx1 = PyTx().unserialize(Blk4.tx(1).serialize())
141
Blk5A = createPyBlock(Blk4A.blockHeader, [Blk5A_Tx0, Blk5A_Tx1] )
142
printBlkInfo(Blk5A, '5A')
151
################################################################################
152
# Now serialize the block data into .dat files so we can feed them into a
153
# program that claims to handle reorgs
155
def writeBlkBin(fileHandle, blk):
156
fileHandle.write( hex_to_binary('f9beb4d9') )
157
fileHandle.write( int_to_binary(blk.getSize(), widthBytes=4) )
158
fileHandle.write( blk.serialize() )
160
def writeBlkPrettyHex(fileHandle, blk):
161
fileHandle.write( 'f9beb4d9' + '\n')
162
fileHandle.write( int_to_hex(blk.getSize(), widthBytes=4) + '\n');
163
fileHandle.write( prettyHex(binary_to_hex(blk.blockHeader.serialize()), \
164
indent=' '*6, withAddr=False) + '\n')
165
fileHandle.write( int_to_hex(blk.getNumTx()) + '\n')
166
for tx in blk.blockData.txList:
167
fileHandle.write( prettyHex(binary_to_hex(tx.serialize()), \
168
indent=' '*6, withAddr=False) + '\n')
169
fileHandle.write('\n')
172
rtfile = open('reorgTest/reorgTest.hex','w')
175
rtfile.write(prstr + '\n')
177
pr('\n\nWriting blocks to ReorgTest/ directory')
178
pr( 'File path: ' + 'reorgTest/blk_0_to_4.dat' )
179
blkFirstChain = open('reorgTest/blk_0_to_4.dat','wb')
180
for blk in [genBlock, Blk1, Blk2, Blk3, Blk4]:
181
writeBlkBin(blkFirstChain, blk)
182
writeBlkPrettyHex(rtfile, blk)
183
blkFirstChain.close()
185
for blk,suffix in [[Blk3A,'3A'], [Blk4A, '4A'], [Blk5A, '5A']]:
186
filename = 'reorgTest/blk_%s.dat' % suffix
187
pr( 'File path: ' + filename + '\n')
188
blkAlt = open(filename, 'wb')
190
writeBlkBin(blkAlt, blk)
191
writeBlkPrettyHex(rtfile, blk)