def test_serialize_inv_message(self): inv_message = InvMessage([Invitem(INV_TX, Uint256.from_hexstr("f6eea3dd4f6536350344a535e37a4178170bba18b871a424d696e196d4d3b555")), Invitem(INV_BLOCK, Uint256.from_hexstr("0000000040a24e14497879bdd67db948cf30edc5d0a5833e8cb2736582157b49"))]) serialized_msg = MessageSerializer(MAIN).serialize(inv_message) self.assertEquals(hexstr(serialized_msg), "f9beb4d9696e76000000000000000000490000008be920f5020100000055b5d3d496e196d624a471b818ba0b1778417ae335a544033536654fdda3eef602000000497b15826573b28c3e83a5d0c5ed30cf48b97dd6bd797849144ea24000000000") serialized_msg = MessageSerializer(TESTNET).serialize(inv_message) self.assertEquals(hexstr(serialized_msg), "fabfb5da696e76000000000000000000490000008be920f5020100000055b5d3d496e196d624a471b818ba0b1778417ae335a544033536654fdda3eef602000000497b15826573b28c3e83a5d0c5ed30cf48b97dd6bd797849144ea24000000000")
def test_serialize_getblocks_message(self): getblocks_msg = GetblocksMessage(BlockLocator(32200, [Uint256.from_hexstr("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")]), Uint256.zero()) serialized_msg = GetblocksMessageSerializer().serialize(getblocks_msg) self.assertEquals(hexstr(serialized_msg), "c87d0000016fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000000000000000000000000000000000000000000000000000000000")
def test_WalletFile_1(self): io = IoHandle.using_stringio() wallet = WalletFile.new(io) wallet.start_tx() wallet.outpoints[1]= OutpointIndex(12, Uint256.from_hexstr("2af4cc9ec3358354345c91694031a1fcdbe9a9064197521814e8a20fe018eb5f"), 3, OutpointIndex.PUBKEY_HASH, 4, PubKeyOutpoint(PublicKey.from_hexstr("022af4cc9ec3358354345c91691031a1fcdbe9a9064197521814e8a20fe018eb5f"), is_pubkey_hash=True)) wallet.end_tx() wallet.commit() wallet.start_tx() wallet.outpoints[1] = OutpointIndex(12, Uint256.from_hexstr("2af4cc9ec3358354345c91694031a1fcdbe9a9064197521814e8a20fe018eb5f"), 3, OutpointIndex.PUBKEY_HASH, 4, PubKeyOutpoint(PublicKey.from_hexstr("022af4cc9ec3358354345c91691031a1fcdbe9a9064197521814e8a20fe018eb5f"), is_pubkey_hash=True)) wallet.end_tx() wallet.commit() #with open(r"c:\local\tmp\wallet-test.wlt", "wb") as wlt: # wlt.write(io.iohandle.getvalue()) io.seek(0, SEEK_SET) wallet2 = WalletFile.load(io, len(io.iohandle.getvalue())) print wallet2.fileheader print wallet2.outpoints
def test_invitem_serialize(self): blockitem = Invitem(INV_BLOCK, Uint256.from_hexstr("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")) txitem = Invitem(INV_TX, Uint256.from_hexstr("84eb3cf3a391a0a0b70e05a3a54d8385f7dcb3809aaf274d392622205b27f288")) self.assertEquals(hexstr(InvitemSerializer().serialize(blockitem)), "0200000008b067b31dc139ee8e7a76a4f2cfcca477c4c06e1ef89f4ae308951907000000") self.assertEquals(hexstr(InvitemSerializer().serialize(txitem)), "0100000088f2275b202226394d27af9a80b3dcf785834da5a3050eb7a0a091a3f33ceb84")
def test_transaction_handle(self): with self.assertRaises(TransactionNotFound): self.database1.get_transaction_handle( Uint256.from_hexstr( "07c17eafb870acf0fece060b814ff71fd36a7df0f0a3a7e359c2c61b3b34c3e1" )) handle1 = self.database1.get_transaction_handle( Uint256.from_hexstr( "cebbc8d7d3550ca6df92eba4f41b93dc55f35b8199bb14dc3d0a95f9bd0e2dbd" )) assert isinstance(handle1.get_transaction(), Tx) self.assertEquals( str(handle1.get_block_hash()), "001f9c93fece90e2e1f729bb9c2b04ba59432592f8ebdc7d117146c74f7c833a") self.assertEquals(handle1.output_count(), 7) self.assertEquals(handle1.is_output_spent(0), False) self.assertEquals(handle1.is_output_spent(2), True) self.assertEquals( str(handle1.get_spending_transaction_hash(2)), "53bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667") handle1.mark_unspent(2) self.assertEquals(handle1.is_output_spent(2), False) handle1.mark_spent( 0, Uint256.from_hexstr( "13bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667" )) self.assertEquals(handle1.is_output_spent(2), False) self.assertEquals(handle1.is_output_spent(0), True) self.assertEquals( str(handle1.get_spending_transaction_hash(0)), "13bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667")
def test_sign_transaction(self): tx = Tx(version=1, in_list=[TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("d2a42ebcb98b598ddcb6d430ce9061dba76804a97f7c1413dd3faef744f909a8"),index=0), script=Script(instructions=[]), sequence=4294967295),TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("2be8e319be1d15c1ba54708bdd7969b638e7e6fa2154819136e363ea6d33664a"),index=1), script=Script(instructions=[]), sequence=4294967295)], out_list=[TxOut(value=3315075843, script=Script(instructions=[Instruction(OP_DUP),Instruction(OP_HASH160),Instruction(20, decodehexstr("297c5a2ee31a1ab721115722d83f8654ca21d5df")),Instruction(OP_EQUALVERIFY),Instruction(OP_CHECKSIG)])),TxOut(value=2971972133, script=Script(instructions=[Instruction(OP_DUP),Instruction(OP_HASH160),Instruction(20, decodehexstr("7d5feab86e31e8fc99d8e735d56226de9043e5fc")),Instruction(OP_EQUALVERIFY),Instruction(OP_CHECKSIG)])),TxOut(value=1046301823, script=Script(instructions=[Instruction(OP_DUP),Instruction(OP_HASH160),Instruction(20, decodehexstr("fd91232a2fa0c389fa0188efde26c8a6165f4c50")),Instruction(OP_EQUALVERIFY),Instruction(OP_CHECKSIG)]))], locktime=0) outscript0 = Script(instructions=[Instruction(33, decodehexstr("03409fe679bdff9e801692c999b86d0c47b62dc02cdd10591ee70ca8056cd05023")),Instruction(OP_CHECKSIG)]) outscript1 = Script(instructions=[Instruction(OP_DUP),Instruction(OP_HASH160),Instruction(20, decodehexstr("5fb7fdb3d1ab0f3fec90b38417cca8ab736b10c6")),Instruction(OP_EQUALVERIFY),Instruction(OP_CHECKSIG)]) # Sign TX_PUBKEY sign_transaction(tx, [TxOut(None, outscript0), TxOut(None, outscript1)], [decodehexstr("f006b27418527b1c400bbc434a3f22ee57c376bd4819cfe2a1162682788ae714"), decodehexstr("c693115901c2840badd1e404706a4866a90d3afa16a542c1a3d0de9aad0875fe")]) vm = TxValidationVM() valid, reason = vm.validate(tx, 0, outscript0, tx.in_list[0].script) if not valid: raise Exception(reason) valid, reason = vm.validate(tx, 1, outscript1, tx.in_list[1].script) if not valid: raise Exception(reason)
def test_deserialize_getdata_message(self): serialized_getdata = decodehexstr("030100000098a23359c17ca2678e2039c8ff9081b18c4913749c9a081ac3f62958f09fa4720100000055b5d3d496e196d624a471b818ba0b1778417ae335a544033536654fdda3eef602000000497b15826573b28c3e83a5d0c5ed30cf48b97dd6bd797849144ea24000000000") getdata_msg, _ = GetdataMessageSerializer().deserialize(serialized_getdata) expected_msg = GetdataMessage([Invitem(INV_TX, Uint256.from_hexstr("72a49ff05829f6c31a089a9c7413498cb18190ffc839208e67a27cc15933a298")), Invitem(INV_TX, Uint256.from_hexstr("f6eea3dd4f6536350344a535e37a4178170bba18b871a424d696e196d4d3b555")), Invitem(INV_BLOCK, Uint256.from_hexstr("0000000040a24e14497879bdd67db948cf30edc5d0a5833e8cb2736582157b49"))]) self.assertEquals(getdata_msg, expected_msg)
def test_blocklocator_deserialize(self): loc, cursor = BlockLocatorSerializer().deserialize( decodehexstr( "0100000005a329e1166037b2ea0cfbef5060c011c1cbbd37ad047a47b62d3dae020000000070bdb41302a622800ddfb2b3ebdd937fdca812ec8a7ab90ef250410700000000398052b24b2cc45ef953222e23880d25c3df95a913e72e9b015b34250000000066739a04b15f117929b581f6fe0ba2906bc4323829400f949086bb7d0000000008b067b31dc139ee8e7a76a4f2cfcca477c4c06e1ef89f4ae308951907000000" )) self.assertEquals( loc, BlockLocator( version=1, blockhashlist=[ Uint256.from_hexstr( "0000000002ae3d2db6477a04ad37bdcbc111c06050effb0ceab2376016e129a3" ), Uint256.from_hexstr( "00000000074150f20eb97a8aec12a8dc7f93ddebb3b2df0d8022a60213b4bd70" ), Uint256.from_hexstr( "0000000025345b019b2ee713a995dfc3250d88232e2253f95ec42c4bb2528039" ), Uint256.from_hexstr( "000000007dbb8690940f40293832c46b90a20bfef681b52979115fb1049a7366" ), Uint256.from_hexstr( "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008" ) ]))
def test_blocklocator_deserialize(self): loc, cursor = BlockLocatorSerializer().deserialize(decodehexstr("0100000005a329e1166037b2ea0cfbef5060c011c1cbbd37ad047a47b62d3dae020000000070bdb41302a622800ddfb2b3ebdd937fdca812ec8a7ab90ef250410700000000398052b24b2cc45ef953222e23880d25c3df95a913e72e9b015b34250000000066739a04b15f117929b581f6fe0ba2906bc4323829400f949086bb7d0000000008b067b31dc139ee8e7a76a4f2cfcca477c4c06e1ef89f4ae308951907000000")) self.assertEquals(loc, BlockLocator(version=1, blockhashlist=[Uint256.from_hexstr("0000000002ae3d2db6477a04ad37bdcbc111c06050effb0ceab2376016e129a3"), Uint256.from_hexstr("00000000074150f20eb97a8aec12a8dc7f93ddebb3b2df0d8022a60213b4bd70"), Uint256.from_hexstr("0000000025345b019b2ee713a995dfc3250d88232e2253f95ec42c4bb2528039"), Uint256.from_hexstr("000000007dbb8690940f40293832c46b90a20bfef681b52979115fb1049a7366"), Uint256.from_hexstr("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")]))
def test_blockheader_serialize(self): h = BlockHeader(version=1, hash_prev=Uint256.from_hexstr("1e4baab89f3a3251818c31bc87f6a33b4a5a88ef76673e2cc77ab2127b7afded"), #hash_prev hash_merkle=Uint256.from_hexstr("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"), #merkle time=1237006505, bits=486605799, nonce=2083236893) self.assertEquals(hexstr(BlockheaderSerializer().serialize(h)), "01000000edfd7a7b12b27ac72c3e6776ef885a4a3ba3f687bc318c8151323a9fb8aa4b1e3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4aa938bb49e703011d1dac2b7c")
def test_get_block_handle(self): with self.assertRaises(BlockNotFound): self.database1.get_block_handle(Uint256.from_hexstr("041f9c93fece90e2e1f729bb9c2b04ba59432592f8ebdc7d117146c74f7c833a")) handle1 = self.database1.get_block_handle(Uint256.from_hexstr("001f9c93fece90e2e1f729bb9c2b04ba59432592f8ebdc7d117146c74f7c833a")) self.assertEquals(handle1.get_height(), 4) self.assertEquals(handle1.get_hash(), Uint256.from_hexstr("001f9c93fece90e2e1f729bb9c2b04ba59432592f8ebdc7d117146c74f7c833a")) assert isinstance(handle1.get_block(), Block) assert isinstance(handle1.get_blockheader(), BlockHeader)
def test_contains_transaction(self): self.assertTrue( self.database1.contains_transaction( Uint256.from_hexstr( "a87f530f2174f6c12945831e731a6fc99f699f1539cf14f36357b66d267b75a8" ))) self.assertFalse( self.database1.contains_transaction( Uint256.from_hexstr( "07c17eafb870acf0fece060b814ff71fd36a7df0f0a3a7e359c2c61b3b34c3e1" )))
def test_next_in_mainchain(self): self.assertEquals( self.database1.get_next_in_mainchain( Uint256.from_hexstr( "003ee3cf880906caa5662f10d4b4fb1c86c1853230dee8a7b8a62f434c73da5f" )), Uint256.from_hexstr( "000cdbffc59b95168c34e5f1853075376308c05c53a1a53425d7f1ca9cab7073" )) self.assertIs( self.database1.get_next_in_mainchain( Uint256.from_hexstr( "002afdfc8ed8111fa00c98bb7b94c34e02a52c57ba971a5fd29935d68fa1060b" )), None)
def test_mine_genesis_block(self): """ Mine the unitnet GENESIS block """ time_source = MockTimeSource(time=1356446436) miner = BitcoinMiner() block, template = miner.mine_block(hash_prev=Uint256.from_hexstr("0000000000000000000000000000000000000000000000000000000000000000"), block_height=0, time_source=time_source, difficulty_bits=524287999, transactions=[], coinbase_txout_list=[TxOut(5000000000, Script([push_data_instruction(decodehexstr("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")),Instruction(OP_CHECKSIG)]))], coinbase_flags=["/P2SH/", "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"]) self.assertEquals(block.blockheader.nonce, 1260) self.assertEquals(block.blockheader.hash_merkle, Uint256.from_hexstr("cf7ac9a3b387cf5e9fc14e03e2a5bbfc16d1ba00d2af6c96869ab4da949bd240")) self.assertEquals(hash_block(block), Uint256.from_hexstr("003ee3cf880906caa5662f10d4b4fb1c86c1853230dee8a7b8a62f434c73da5f"))
def mine_block(hash_prev, block_height, time_source, difficulty_bits, transactions, coinbase_txout_list, coinbase_flags=["/P2SH/"], nonce_changer=default_nonce_changer): template = BlockheaderTemplate(hash_prev, block_height, coinbase_txout_list, transactions, time_source.get_time(), difficulty_bits, coinbase_flags=coinbase_flags) difficulty_target = uint256_difficulty(difficulty_bits) hash_found = False while not hash_found: hash = Uint256.from_bytestr(doublesha256( template.get_serialized())) if (hash <= difficulty_target): hash_found = True else: nonce_changer(template) return (template.get_block(), template)
def hash_tx(tx): if tx.hash: return tx.hash if not tx.rawdata: tx.rawdata = TX_SERIALIZE.serialize(tx) tx.hash = Uint256.from_bytestr(doublesha256(tx.rawdata)) return tx.hash
def hash_blockheader(blockheader): if blockheader.hash: return blockheader.hash if not blockheader.rawdata: blockheader.rawdata = BLOCK_SERIALIZE.serialize(blockheader) blockheader.hash = Uint256.from_bytestr(doublesha256(blockheader.rawdata)) return blockheader.hash
def test_txin_serialize(self): txin = TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("17c5cb687ba453ab65e12cdc0d8721c70ab4678665eb200c50cb9f1e3207090e"), index=0), script=Script([Instruction(72, decodehexstr("3045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c01")), Instruction(65, decodehexstr("04b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3e"))]), sequence=TxIn.NSEQUENCE_FINAL) self.assertEquals(hexstr(TxinSerializer().serialize(txin)), "0e0907321e9fcb500c20eb658667b40ac721870ddc2ce165ab53a47b68cbc517000000008b483045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c014104b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3effffffff")
def test_blockheader_serialize(self): h = BlockHeader( version=1, hash_prev=Uint256.from_hexstr( "1e4baab89f3a3251818c31bc87f6a33b4a5a88ef76673e2cc77ab2127b7afded" ), #hash_prev hash_merkle=Uint256.from_hexstr( "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b" ), #merkle time=1237006505, bits=486605799, nonce=2083236893) self.assertEquals( hexstr(BlockheaderSerializer().serialize(h)), "01000000edfd7a7b12b27ac72c3e6776ef885a4a3ba3f687bc318c8151323a9fb8aa4b1e3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4aa938bb49e703011d1dac2b7c" )
def get_next_work_required(self, blkprevhash, block): blkprev = self.database.get_block_handle(blkprevhash) # Difficulty changes only once every TARGET_INTERVAL blocks (except for testnet) if ((blkprev.get_height() + 1) % TARGET_INTERVAL): # Special rules for testnet after 15 Feb 2012 if ((self.database.runmode == TESTNET and (block.blockheader.time > 1329264000)) or (self.database.runmode == TESTNET3)): return self.get_testnet_work_required_15feb1012(blkprev, block) # Difficulty unchanged return (blkprev.get_blockheader().bits) # Locate the block 2 weeks ago blk2weekago = blkprev for i in range(TARGET_INTERVAL-1): blk2weekago = self.database.get_block_handle(blk2weekago.get_blockheader().hash_prev) header_block2weekago = blk2weekago.get_blockheader() header_blocknow = blkprev.get_blockheader() actual_timespan = header_blocknow.time - header_block2weekago.time # Limit adjustment step if actual_timespan < TARGET_TIMESPAN/4: actual_timespan = TARGET_TIMESPAN/4; if actual_timespan > TARGET_TIMESPAN*4: actual_timespan = TARGET_TIMESPAN*4; # Retarget new_target = Uint256.from_bignum(header_blocknow.target().get_bignum() * actual_timespan / TARGET_TIMESPAN) if new_target > PROOF_OF_WORK_LIMIT[self.database.runmode]: new_target = PROOF_OF_WORK_LIMIT[self.database.runmode] new_bits = compact_difficulty(new_target) self.log.info("Retarget: targetTimespan:%d actualTimespan:%d, %08x -> %08x " % (TARGET_TIMESPAN, actual_timespan, header_blocknow.bits, new_bits)) return (new_bits)
def get_next_in_mainchain(self, blockhash): if not self.indexdb.contains_block(blockhash): raise BlockNotFound(str(blockhash)) blockindex = self.indexdb.get_blockindex(blockhash) if (blockindex.hash_next == Uint256.zero()): return None return blockindex.hash_next
def _find_fork(self, altchainhash): hash = altchainhash while hash != Uint256.zero(): handle = self.get_block_handle(hash) if handle.is_mainchain(): return hash hash = handle.get_blockheader().hash_prev return handle.hash
def test_mine_block(self): """ Mine a block changing both nonce and extra_nonce""" def nonce_changer(template): if template.nonce >= 20: template.set_extra_nonce(template.extra_nonce + 1) template.set_nonce(0) else: template.set_nonce(template.nonce + 1) time_source = MockTimeSource(time=1356446436) miner = BitcoinMiner() block, template = miner.mine_block( hash_prev=Uint256.from_hexstr( "0000000000000000000000000000000000000000000000000000000000000000" ), block_height=0, time_source=time_source, difficulty_bits=524287999, transactions=[], coinbase_txout_list=[ TxOut( 5000000000, Script([ Instruction( OP_PUSHDATA, decodehexstr( "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f" )), Instruction(OP_CHECKSIG) ])) ], nonce_changer=nonce_changer) self.assertEquals(block.blockheader.nonce, 8) self.assertEquals(template.nonce, 8) self.assertEquals(template.extra_nonce, 14) self.assertEquals( block.blockheader.hash_merkle, Uint256.from_hexstr( "ca839450c8702d6768d1803bb6d99c6d059a56240933e5bf72cb2936f6c9e211" )) self.assertEquals( hash_block(block), Uint256.from_hexstr( "003c7a06c7efe128cb3bea692e1a485f7400f3670df7986c020083e9b10e295d" ))
def test_outpoint_serialize(self): self.assertEquals( hexstr(OutpointSerializer().serialize( Outpoint(hash=Uint256.from_hexstr( "17c5cb687ba453ab65e12cdc0d8721c70ab4678665eb200c50cb9f1e3207090e" ), index=0))), "0e0907321e9fcb500c20eb658667b40ac721870ddc2ce165ab53a47b68cbc51700000000" )
def test_deserialize_tx_message(self): # TX 1 from block 398 on testnet 3 serialized_tx_message = decodehexstr("010000000328ce10c7189026866bcfc1d06b278981ddf21ec0e364e28e294365b5c328cd43000000006c493046022100b918951cc55fbb285168004de7eab21e702e89dc43c167ba0fc1b09273e29cf5022100f95c24b6c740e2306a45bea1e7a0c8f2032c9d4da4d8d1cc6b5c4166d1fabfe50121033b2dd6fe53611ef3d112b7098a8999f48bf27c7bf94bd045439d87a9ec11fca3fffffffffc4f1ed498c5f31fe90b10389f12566a3350a5080db1dba1f01f8834e5813ca900000000484730440220161ee27efad282e8c984051418fcc2bca6854f3f5d4e24031b950bcd7853943a02202b5566c72aeaff2295db82c79d52d88dbe9450e01c6c951d5d0148c290f6cbbe01fffffffffc5eecfa90d46aeeda36bb1a2f2da61e4f9be81253033ae55625d00acb13ef35000000004a493046022100f7d996bc39ef00b217014ee3e7f8b49ed714fcce2fe970a2ada2b9a87a741c2d022100c55a6089c2b23ec87c5063513c6c8abfc14c913f8ab69cf4ebed6a58c220946901ffffffff0340f1f23a000000001976a914f069756ffd9d331119e5430268437aed14210afb88ac00f2052a0100000017a914290bba32a49315789a030bb40b0047f8fb90ff668700f2052a0100000017a9141d9ca71efa36d814424ea6ca1437e67287aebe348700000000") tx_message, _ = TxMessageSerializer().deserialize(serialized_tx_message) expected_message = TxMessage(Tx(version=1, in_list=[TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("43cd28c3b56543298ee264e3c01ef2dd8189276bd0c1cf6b86269018c710ce28"),index=0), script=Script(instructions=[Instruction(73, decodehexstr("3046022100b918951cc55fbb285168004de7eab21e702e89dc43c167ba0fc1b09273e29cf5022100f95c24b6c740e2306a45bea1e7a0c8f2032c9d4da4d8d1cc6b5c4166d1fabfe501")),Instruction(33, decodehexstr("033b2dd6fe53611ef3d112b7098a8999f48bf27c7bf94bd045439d87a9ec11fca3"))]), sequence=4294967295),TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("a93c81e534881ff0a1dbb10d08a550336a56129f38100be91ff3c598d41e4ffc"),index=0), script=Script(instructions=[Instruction(71, decodehexstr("30440220161ee27efad282e8c984051418fcc2bca6854f3f5d4e24031b950bcd7853943a02202b5566c72aeaff2295db82c79d52d88dbe9450e01c6c951d5d0148c290f6cbbe01"))]), sequence=4294967295),TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("35ef13cb0ad02556e53a035312e89b4f1ea62d2f1abb36daee6ad490faec5efc"),index=0), script=Script(instructions=[Instruction(73, decodehexstr("3046022100f7d996bc39ef00b217014ee3e7f8b49ed714fcce2fe970a2ada2b9a87a741c2d022100c55a6089c2b23ec87c5063513c6c8abfc14c913f8ab69cf4ebed6a58c220946901"))]), sequence=4294967295)], out_list=[TxOut(value=989000000, script=Script(instructions=[Instruction(OP_DUP),Instruction(OP_HASH160),Instruction(20, decodehexstr("f069756ffd9d331119e5430268437aed14210afb")),Instruction(OP_EQUALVERIFY),Instruction(OP_CHECKSIG)])),TxOut(value=5000000000, script=Script(instructions=[Instruction(OP_HASH160),Instruction(20, decodehexstr("290bba32a49315789a030bb40b0047f8fb90ff66")),Instruction(OP_EQUAL)])),TxOut(value=5000000000, script=Script(instructions=[Instruction(OP_HASH160),Instruction(20, decodehexstr("1d9ca71efa36d814424ea6ca1437e67287aebe34")),Instruction(OP_EQUAL)]))], locktime=0)) self.assertEquals(tx_message, expected_message)
def test_pop_append_block(self): self.assertTrue( self.database1.contains_transaction( Uint256.from_hexstr( "53bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667" ))) block = self.database1.pop_block() self.assertFalse( self.database1.contains_transaction( Uint256.from_hexstr( "53bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667" ))) self.database1.append_block(block) self.assertTrue( self.database1.contains_transaction( Uint256.from_hexstr( "53bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667" )))
def test_get_block_handle(self): with self.assertRaises(BlockNotFound): self.database1.get_block_handle( Uint256.from_hexstr( "041f9c93fece90e2e1f729bb9c2b04ba59432592f8ebdc7d117146c74f7c833a" )) handle1 = self.database1.get_block_handle( Uint256.from_hexstr( "001f9c93fece90e2e1f729bb9c2b04ba59432592f8ebdc7d117146c74f7c833a" )) self.assertEquals(handle1.get_height(), 4) self.assertEquals( handle1.get_hash(), Uint256.from_hexstr( "001f9c93fece90e2e1f729bb9c2b04ba59432592f8ebdc7d117146c74f7c833a" )) assert isinstance(handle1.get_block(), Block) assert isinstance(handle1.get_blockheader(), BlockHeader)
def test_transaction_handle(self): with self.assertRaises(TransactionNotFound): self.database1.get_transaction_handle(Uint256.from_hexstr("07c17eafb870acf0fece060b814ff71fd36a7df0f0a3a7e359c2c61b3b34c3e1")) handle1 = self.database1.get_transaction_handle(Uint256.from_hexstr("cebbc8d7d3550ca6df92eba4f41b93dc55f35b8199bb14dc3d0a95f9bd0e2dbd")) assert isinstance(handle1.get_transaction(), Tx) self.assertEquals(str(handle1.get_block_hash()), "001f9c93fece90e2e1f729bb9c2b04ba59432592f8ebdc7d117146c74f7c833a") self.assertEquals(handle1.output_count(), 7) self.assertEquals(handle1.is_output_spent(0), False) self.assertEquals(handle1.is_output_spent(2), True) self.assertEquals(str(handle1.get_spending_transaction_hash(2)), "53bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667") handle1.mark_unspent(2) self.assertEquals(handle1.is_output_spent(2), False) handle1.mark_spent(0, Uint256.from_hexstr("13bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667")) self.assertEquals(handle1.is_output_spent(2), False) self.assertEquals(handle1.is_output_spent(0), True) self.assertEquals(str(handle1.get_spending_transaction_hash(0)), "13bb1c14b4c6156d7352ee471fb7697736f4696accf5392e0f1830e38143f667")
def test_deserialize_inv_message(self): serialized_inv_message = decodehexstr( "f9beb4d9696e76000000000000000000490000008be920f5020100000055b5d3d496e196d624a471b818ba0b1778417ae335a544033536654fdda3eef602000000497b15826573b28c3e83a5d0c5ed30cf48b97dd6bd797849144ea24000000000" ) inv_message, _ = MessageSerializer(MAIN).deserialize( serialized_inv_message) expected_message = InvMessage([ Invitem( INV_TX, Uint256.from_hexstr( "f6eea3dd4f6536350344a535e37a4178170bba18b871a424d696e196d4d3b555" )), Invitem( INV_BLOCK, Uint256.from_hexstr( "0000000040a24e14497879bdd67db948cf30edc5d0a5833e8cb2736582157b49" )) ]) self.assertEquals(inv_message, expected_message)
def test_invitem_serialize(self): blockitem = Invitem( INV_BLOCK, Uint256.from_hexstr( "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008" )) txitem = Invitem( INV_TX, Uint256.from_hexstr( "84eb3cf3a391a0a0b70e05a3a54d8385f7dcb3809aaf274d392622205b27f288" )) self.assertEquals( hexstr(InvitemSerializer().serialize(blockitem)), "0200000008b067b31dc139ee8e7a76a4f2cfcca477c4c06e1ef89f4ae308951907000000" ) self.assertEquals( hexstr(InvitemSerializer().serialize(txitem)), "0100000088f2275b202226394d27af9a80b3dcf785834da5a3050eb7a0a091a3f33ceb84" )
def test_uint256_deserialize(self): uint256, _ = Uint256Serializer().deserialize( decodehexstr( "6a921ac1ae5e23610d07d2b2a9377fbc3c3bb233e900aa1a5bc40f5562a19d0d" )) self.assertEquals( uint256, Uint256.from_hexstr( "0d9da162550fc45b1aaa00e933b23b3cbc7f37a9b2d2070d61235eaec11a926a" ))
def check_proof_of_work(self, hash, block): target = block.blockheader.target() if (target <= Uint256.zero() or target > PROOF_OF_WORK_LIMIT[self.runmode]): raise Exception("proof of work: value out of range : %x" % (block.blockheader.bits)) if (hash > target): raise Exception( "proof of work: hash doesn't match target hash:%s, target:%s" % (hash, target))
def test_deserialize_block_message(self): #block 22 on testnet 3 serialized_block_msg= decodehexstr("0100000073379e3ff3dffd006e0090e52ac571a9a309490a23e64d15f8af291a0000000051f1c5b2b7c8f980e7715b4d3ce0180f99c44a16fc9c00ede2f5984b8d7cc22d16ed494dffff001d0082467f0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0f0416ed494d02fa00062f503253482fffffffff0100f2052a01000000232103b787920594cb47fbfccee915befae40ac2e2b295224460eee075ad0ada4c0c54ac00000000") block_msg, _ = BlockMessageSerializer().deserialize(serialized_block_msg) expected_block_msg = BlockMessage(Block(blockheader=BlockHeader(version=1, hash_prev=Uint256.from_hexstr("000000001a29aff8154de6230a4909a3a971c52ae590006e00fddff33f9e3773"), hash_merkle=Uint256.from_hexstr("2dc27c8d4b98f5e2ed009cfc164ac4990f18e03c4d5b71e780f9c8b7b2c5f151"), time=1296690454, bits=486604799, nonce=2135327232), transactions=[Tx(version=1, in_list=[TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("0000000000000000000000000000000000000000000000000000000000000000"),index=4294967295), script=Script(instructions=[Instruction(4, decodehexstr("16ed494d")),Instruction(2, decodehexstr("fa00")),Instruction(6, decodehexstr("2f503253482f"))]), sequence=4294967295)], out_list=[TxOut(value=5000000000, script=Script(instructions=[Instruction(33, decodehexstr("03b787920594cb47fbfccee915befae40ac2e2b295224460eee075ad0ada4c0c54")),Instruction(OP_CHECKSIG)]))], locktime=0)])) self.assertEquals(block_msg, expected_block_msg)
def get_median_time_past(self, hashprev): block_times = [] i = 0 while hashprev != Uint256.zero() and i < MEDIAN_TIME_SPAN: blk = self.database.get_block_handle(hashprev) blkheader = blk.get_blockheader() block_times.append(blkheader.time) hashprev = blkheader.hash_prev i += 1 return median(block_times)
def check_merkle_branch(txhash, merkle_branch, index_tx): """Return True if the merkle branch is valid for txhash and index_tx. Attributes: txhash(Uint256): Hash of a Transaction merkle_branch(list of Uint256): Merkle Branch index_tx(int): Index of the transaction in the block. """ hash = txhash.get_bytestr() index = index_tx otherside_branch, merkle_root = merkle_branch[:-1], merkle_branch[-1] for otherside in otherside_branch: if index & 1: hash = double_sha256_2_input(otherside.get_bytestr(), hash) else: hash = double_sha256_2_input(hash, otherside.get_bytestr()) index = index >> 1 print "u", Uint256.from_bytestr(hash) return (Uint256.from_bytestr(hash) == merkle_root)
def test_serialize_outpoint_index(self): outpoint = OutpointIndex(12, Uint256.from_hexstr("2af4cc9ec3358354345c91694031a1fcdbe9a9064197521814e8a20fe018eb5f"), 3, OutpointIndex.PUBKEY_HASH, 4, PubKeyOutpoint(PublicKey.from_hexstr("022af4cc9ec3358354345c91691031a1fcdbe9a9064197521814e8a20fe018eb5f"), is_pubkey_hash=True)) serialized = OutpointIndexSerializer.serialize(outpoint) self.assertEquals(hexstr(serialized), "0000000c2af4cc9ec3358354345c91694031a1fcdbe9a9064197521814e8a20fe018eb5f030200000004022af4cc9ec3358354345c91691031a1fcdbe9a9064197521814e8a20fe018eb5f")
def append_block(self, blockhash, block): file, blockpos = self.blockstore.saveblock(block) prevblock = self.get_block_handle(block.blockheader.hash_prev) idx = DbBlockIndex(self.version, Uint256.zero(), file, blockpos, prevblock.get_height()+1, block.blockheader) self.indexdb.set_blockindex(blockhash, idx) if prevblock.hash == self.get_mainchain(): prevblock.blockindex.hash_next = blockhash self.indexdb.set_blockindex(prevblock.hash, prevblock.blockindex) self.indexdb.set_hashbestchain(blockhash) self._index_transactions(blockhash, block) return DBBlockHandle(self.log, self.indexdb, self.blockstore, blockhash, block=block)
def test_tx_deserialize(self): tx, _ = TxSerializer().deserialize( decodehexstr( "01000000010e0907321e9fcb500c20eb658667b40ac721870ddc2ce165ab53a47b68cbc517000000008b483045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c014104b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3effffffff02802385d1050000001976a9144d8b17fbce571614be89df4bd872de892a47984488ac00f2052a010000001976a914fadad27c40adbe230f5e3c04d44a29297508483188ac00000000" )) tx_expected = Tx( version=1, in_list=[ TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr( "17c5cb687ba453ab65e12cdc0d8721c70ab4678665eb200c50cb9f1e3207090e" ), index=0), script=Script([ Instruction( 72, decodehexstr( "3045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c01" )), Instruction( 65, decodehexstr( "04b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3e" )) ]), sequence=TxIn.NSEQUENCE_FINAL) ], out_list=[ TxOut(value=24990000000, script=Script([ Instruction(OP_DUP), Instruction(OP_HASH160), Instruction( 20, decodehexstr( "4d8b17fbce571614be89df4bd872de892a479844")), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG) ])), TxOut(value=5000000000, script=Script([ Instruction(OP_DUP), Instruction(OP_HASH160), Instruction( 20, decodehexstr( "fadad27c40adbe230f5e3c04d44a292975084831")), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG) ])) ], locktime=0) self.assertEquals(tx, tx_expected)
def test_serialize_tx_message(self): # TX 1 from block 389 on testnet 3 tx_message = TxMessage(Tx(version=1, in_list=[TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("f519f238c54e20bb418bb4513ce75484546d198200a901be55152e12cfa82652"),index=1), script=Script(instructions=[Instruction(73, decodehexstr("3046022100b96e2fd2015bb3fe22c23c712c3ac4a8636d4a78df7d669babd64eaba314c236022100f402d7e3392d1770ce2be0c823eab0122bb83ee0bd65f5de54a1feb53e452eed01")),Instruction(65, decodehexstr("04c4bee5e6dbb5c1651437cb4386c1515c7776c64535077204c6f24f05a37d04a32bc78beb2193b53b104c9954c44b0ce168bc78efd5f1e1c7db9d6c21b3016599"))]), sequence=4294967295),TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("d748009c88abacfbd8d0dafb5552f0700a16f9a35ff41583988d9f70618c1971"),index=0), script=Script(instructions=[Instruction(72, decodehexstr("304502210092e96f4185fc1bb74b4d9c258219dc5ffc71afb43e73ec0e78bdd91bafbe386e022019fc5b3d9602005b61f5dc75e7bd4dde1c19a0700c0a7958503528014d39019101")),Instruction(33, decodehexstr("02274eae01d391bbec32d4b60e24d5d24f9cc23ca8da6708cf6c062381bfa71006"))]), sequence=4294967295)], out_list=[TxOut(value=5000000000, script=Script(instructions=[Instruction(OP_DUP),Instruction(OP_HASH160),Instruction(20, decodehexstr("dbf89509176a975e41d04cc0af24cfc8de4394a9")),Instruction(OP_EQUALVERIFY),Instruction(OP_CHECKSIG)]))], locktime=0)) serialized_msg = TxMessageSerializer().serialize(tx_message) self.assertEquals(hexstr(serialized_msg), "01000000025226a8cf122e1555be01a90082196d548454e73c51b48b41bb204ec538f219f5010000008c493046022100b96e2fd2015bb3fe22c23c712c3ac4a8636d4a78df7d669babd64eaba314c236022100f402d7e3392d1770ce2be0c823eab0122bb83ee0bd65f5de54a1feb53e452eed014104c4bee5e6dbb5c1651437cb4386c1515c7776c64535077204c6f24f05a37d04a32bc78beb2193b53b104c9954c44b0ce168bc78efd5f1e1c7db9d6c21b3016599ffffffff71198c61709f8d988315f45fa3f9160a70f05255fbdad0d8fbacab889c0048d7000000006b48304502210092e96f4185fc1bb74b4d9c258219dc5ffc71afb43e73ec0e78bdd91bafbe386e022019fc5b3d9602005b61f5dc75e7bd4dde1c19a0700c0a7958503528014d390191012102274eae01d391bbec32d4b60e24d5d24f9cc23ca8da6708cf6c062381bfa71006ffffffff0100f2052a010000001976a914dbf89509176a975e41d04cc0af24cfc8de4394a988ac00000000")
def test_mine_block(self): """ Mine a block changing both nonce and extra_nonce""" def nonce_changer(template): if template.nonce >= 20: template.set_extra_nonce(template.extra_nonce + 1) template.set_nonce(0) else: template.set_nonce(template.nonce + 1) time_source = MockTimeSource(time=1356446436) miner = BitcoinMiner() block, template = miner.mine_block(hash_prev=Uint256.from_hexstr("0000000000000000000000000000000000000000000000000000000000000000"), block_height=0, time_source=time_source, difficulty_bits=524287999, transactions=[], coinbase_txout_list=[TxOut(5000000000, Script([Instruction(OP_PUSHDATA, decodehexstr("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")),Instruction(OP_CHECKSIG)]))], nonce_changer=nonce_changer) self.assertEquals(block.blockheader.nonce, 8) self.assertEquals(template.nonce, 8) self.assertEquals(template.extra_nonce, 14) self.assertEquals(block.blockheader.hash_merkle, Uint256.from_hexstr("ca839450c8702d6768d1803bb6d99c6d059a56240933e5bf72cb2936f6c9e211")) self.assertEquals(hash_block(block), Uint256.from_hexstr("003c7a06c7efe128cb3bea692e1a485f7400f3670df7986c020083e9b10e295d"))
def test_mine_genesis_block(self): """ Mine the unitnet GENESIS block """ time_source = MockTimeSource(time=1356446436) miner = BitcoinMiner() block, template = miner.mine_block( hash_prev=Uint256.from_hexstr( "0000000000000000000000000000000000000000000000000000000000000000" ), block_height=0, time_source=time_source, difficulty_bits=524287999, transactions=[], coinbase_txout_list=[ TxOut( 5000000000, Script([ push_data_instruction( decodehexstr( "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f" )), Instruction(OP_CHECKSIG) ])) ], coinbase_flags=[ "/P2SH/", "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" ]) self.assertEquals(block.blockheader.nonce, 1260) self.assertEquals( block.blockheader.hash_merkle, Uint256.from_hexstr( "cf7ac9a3b387cf5e9fc14e03e2a5bbfc16d1ba00d2af6c96869ab4da949bd240" )) self.assertEquals( hash_block(block), Uint256.from_hexstr( "003ee3cf880906caa5662f10d4b4fb1c86c1853230dee8a7b8a62f434c73da5f" ))
def test_block_deserialize(self): blk, _ = BlockSerializer().deserialize(decodehexstr("01000000a3a71e679426f6cd46a27441ac5021a5bf75b2168b6e14811508ec0f000000006a921ac1ae5e23610d07d2b2a9377fbc3c3bb233e900aa1a5bc40f5562a19d0dafaa8d4d7ffa0f1cef18524c0201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07047ffa0f1c014effffffff018076242a010000004341049cc3cae30927c40598032044b9e9e25f4739b0d7ade62803f5e9cf075debc817e6d29f42c70d0a1beb1c904eaaa50ef885b011f9fbaa16ef288a7ad193e11567ac0000000001000000010e0907321e9fcb500c20eb658667b40ac721870ddc2ce165ab53a47b68cbc517000000008b483045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c014104b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3effffffff02802385d1050000001976a9144d8b17fbce571614be89df4bd872de892a47984488ac00f2052a010000001976a914fadad27c40adbe230f5e3c04d44a29297508483188ac00000000")) blockheader = BlockHeader(version=1, hash_prev=Uint256.from_hexstr("000000000fec081581146e8b16b275bfa52150ac4174a246cdf62694671ea7a3"), hash_merkle=Uint256.from_hexstr("0d9da162550fc45b1aaa00e933b23b3cbc7f37a9b2d2070d61235eaec11a926a"), time=1301129903, bits=470809215, nonce=1280448751) tx1 = Tx(version=1, in_list=[TxIn(previous_output=Outpoint.null(), script=Script([Instruction(4, decodehexstr("7ffa0f1c")), Instruction(1, decodehexstr("4e"))]), sequence=TxIn.NSEQUENCE_FINAL )], out_list=[TxOut(value=5002000000, script=Script([Instruction(65, decodehexstr("049cc3cae30927c40598032044b9e9e25f4739b0d7ade62803f5e9cf075debc817e6d29f42c70d0a1beb1c904eaaa50ef885b011f9fbaa16ef288a7ad193e11567")), Instruction(OP_CHECKSIG)]))], locktime=0) tx2 = Tx(version=1, in_list=[TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("17c5cb687ba453ab65e12cdc0d8721c70ab4678665eb200c50cb9f1e3207090e"), index=0), script=Script([Instruction(72, decodehexstr("3045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c01")), Instruction(65, decodehexstr("04b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3e"))]), sequence=TxIn.NSEQUENCE_FINAL )], out_list=[TxOut(value=24990000000, script=Script([Instruction(OP_DUP), Instruction(OP_HASH160), Instruction(20, decodehexstr("4d8b17fbce571614be89df4bd872de892a479844")), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG)])), TxOut(value=5000000000, script=Script([Instruction(OP_DUP), Instruction(OP_HASH160), Instruction(20, decodehexstr("fadad27c40adbe230f5e3c04d44a292975084831")), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG)]))], locktime=0) self.assertEquals(blk, Block(blockheader, [tx1, tx2]))
def test_WalletFile_1(self): io = IoHandle.using_stringio() wallet = WalletFile.new(io) wallet.start_tx() wallet.outpoints[1] = OutpointIndex( 12, Uint256.from_hexstr( "2af4cc9ec3358354345c91694031a1fcdbe9a9064197521814e8a20fe018eb5f" ), 3, OutpointIndex.PUBKEY_HASH, 4, PubKeyOutpoint(PublicKey.from_hexstr( "022af4cc9ec3358354345c91691031a1fcdbe9a9064197521814e8a20fe018eb5f" ), is_pubkey_hash=True)) wallet.end_tx() wallet.commit() wallet.start_tx() wallet.outpoints[1] = OutpointIndex( 12, Uint256.from_hexstr( "2af4cc9ec3358354345c91694031a1fcdbe9a9064197521814e8a20fe018eb5f" ), 3, OutpointIndex.PUBKEY_HASH, 4, PubKeyOutpoint(PublicKey.from_hexstr( "022af4cc9ec3358354345c91691031a1fcdbe9a9064197521814e8a20fe018eb5f" ), is_pubkey_hash=True)) wallet.end_tx() wallet.commit() #with open(r"c:\local\tmp\wallet-test.wlt", "wb") as wlt: # wlt.write(io.iohandle.getvalue()) io.seek(0, SEEK_SET) wallet2 = WalletFile.load(io, len(io.iohandle.getvalue())) print wallet2.fileheader print wallet2.outpoints
def test_serialize_outpoint_index(self): outpoint = OutpointIndex( 12, Uint256.from_hexstr( "2af4cc9ec3358354345c91694031a1fcdbe9a9064197521814e8a20fe018eb5f" ), 3, OutpointIndex.PUBKEY_HASH, 4, PubKeyOutpoint(PublicKey.from_hexstr( "022af4cc9ec3358354345c91691031a1fcdbe9a9064197521814e8a20fe018eb5f" ), is_pubkey_hash=True)) serialized = OutpointIndexSerializer.serialize(outpoint) self.assertEquals( hexstr(serialized), "0000000c2af4cc9ec3358354345c91694031a1fcdbe9a9064197521814e8a20fe018eb5f030200000004022af4cc9ec3358354345c91691031a1fcdbe9a9064197521814e8a20fe018eb5f" )
def retarget(time_2weekago, time_now, target_timespan, current_target, # compact format proof_of_work_limit): actual_timespan = time_now - time_2weekago # Limit adjustment step if actual_timespan < target_timespan/4: actual_timespan = target_timespan/4; if actual_timespan > target_timespan*4: actual_timespan = target_timespan*4; # Retarget new_target = Uint256.from_bignum(uint256_difficulty(current_target).get_bignum() * actual_timespan / target_timespan) if new_target > proof_of_work_limit: new_target = proof_of_work_limit return compact_difficulty(new_target)
def send_transaction(self, planned_tx, passphrases): try: self.wallet.unlock(passphrases) privkey_list = [] for outpoint, txout in planned_tx.selected_outputs: privkey_list.append( self.wallet.get_txout_private_key_secret(txout)) finally: self.wallet.lock() sign_transaction( planned_tx.tx, [txout for outpoint, txout in planned_tx.selected_outputs], privkey_list) txhash = hash_tx(planned_tx.tx) self.log.info( "Sending %f to %s (fee:%f), change address: %s, hash:%s" % (planned_tx.amount, str(planned_tx.address), planned_tx.fee, str(planned_tx.change_address), str(txhash))) #Initially, create an empty MerkleTx (the tx is not yet in a block) merkle_tx = MerkleTx(planned_tx.tx, Uint256.zero(), [], 4294967295) self.wallet.begin_updates() self.wallet.allocate_key(planned_tx.change_public_key, ischange=True) #Set the spend flags for the input transactions for outpoint, txout in planned_tx.selected_outputs: input_wallet_tx = self.wallet.get_transaction(outpoint.hash) input_wallet_tx.set_spent(outpoint.index) self.wallet.set_transaction(outpoint.hash, input_wallet_tx) #Add the wallet_tx (contains supporting transations) txtime = int(time.time()) wallet_tx = create_wallet_tx(self.blockchain, merkle_tx, txtime) self.wallet.add_transaction(txhash, wallet_tx) self.wallet.commit_updates() self.fire(self.EVT_NEW_TRANSACTION_ITEM, item=(planned_tx.tx, txhash, txtime, planned_tx.address, "", -planned_tx.amount, False)) self.compute_balances() # we could only compute delta here self.fire(self.EVT_PUBLISH_TRANSACTION, txhash=txhash, tx=planned_tx.tx) self.last_tx_publish[txhash] = txtime #update description of change address new_description = self.wallet.get_address_description( planned_tx.change_public_key) self.fire(self.EVT_NEW_ADDRESS_DESCRIPTION, public_key=planned_tx.change_public_key, description=new_description)
def test_merkletx_serialize(self): # This is tx 37 of block 429 on testnet3 merkle_tx = MerkleTx( Tx(version=1, in_list=[TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("88c844570a227fe89d82e4e20d41576b95df8aa790a799bf7114dbed83b788b0"),index=0), script=Script(instructions=[Instruction(72, decodehexstr("3045022100813a4dfdfda02946bf9fddc59ffd0b8d2feaa618518a3015fd5e65dd88a0d4480220137b25ea7531e103405bfe1617cb92f524e88c86e66a79c1e3c62558d019528201")),Instruction(33, decodehexstr("03cf163e38520a7b390305528eca2fa1c620f0da225a044017fd92b30067875dc8"))]), sequence=4294967295)], out_list=[TxOut(value=4899704976, script=Script(instructions=[Instruction(OP_DUP),Instruction(OP_HASH160),Instruction(20, decodehexstr("10170e3f7c3b0c93d2e07e90e307d3fb21811702")),Instruction(OP_EQUALVERIFY),Instruction(OP_CHECKSIG)])),TxOut(value=887733, script=Script(instructions=[Instruction(OP_HASH160),Instruction(20, decodehexstr("184cd0a38ac3b1357d07179553788375a9e8a3b8")),Instruction(OP_EQUAL)]))], locktime=0), blockhash=Uint256.from_hexstr("00000000e080223655db52d2c35a37f6aa17a3f2efefa6794fd9831374cff09f"), merkle_branch=[Uint256.from_hexstr("88c844570a227fe89d82e4e20d41576b95df8aa790a799bf7114dbed83b788b0"), Uint256.from_hexstr("225dd6a6857be59dbf2d72d4d5cca1325053dd66a9c3a35a16c51de04a1b0d03"), Uint256.from_hexstr("74f79002e7c2cbbf40581aa56d8037cb32844d34ae049629a757b6ff709a10fa"), Uint256.from_hexstr("02099d8b6bf46c3f87ccc922dec8c18a9dc420e17ebc672030145bd8ee33ab34"), Uint256.from_hexstr("15b202c47b1ad2638c4ea260611839be7cdf15e13e6de50861f41e46a5e9f8cf"), Uint256.from_hexstr("007e2166afda37ce696e971ac530a7cc22e183b37acf57c79cb0ee21a9de2179"), Uint256.from_hexstr("a7d06d9452a65fae2662ae63c9b450ba4ce22dfab76d22624a95d97d294421d4")], nindex=37) self.assertEquals(hexstr(MerkleTxSerializer().serialize(merkle_tx)), "0100000001b088b783eddb1471bf99a790a78adf956b57410de2e4829de87f220a5744c888000000006b483045022100813a4dfdfda02946bf9fddc59ffd0b8d2feaa618518a3015fd5e65dd88a0d4480220137b25ea7531e103405bfe1617cb92f524e88c86e66a79c1e3c62558d0195282012103cf163e38520a7b390305528eca2fa1c620f0da225a044017fd92b30067875dc8ffffffff0290900b24010000001976a91410170e3f7c3b0c93d2e07e90e307d3fb2181170288acb58b0d000000000017a914184cd0a38ac3b1357d07179553788375a9e8a3b887000000009ff0cf741383d94f79a6efeff2a317aaf6375ac3d252db55362280e00000000007b088b783eddb1471bf99a790a78adf956b57410de2e4829de87f220a5744c888030d1b4ae01dc5165aa3c3a966dd535032a1ccd5d4722dbf9de57b85a6d65d22fa109a70ffb657a7299604ae344d8432cb37806da51a5840bfcbc2e70290f77434ab33eed85b14302067bc7ee120c49d8ac1c8de22c9cc873f6cf46b8b9d0902cff8e9a5461ef46108e56d3ee115df7cbe39186160a24e8c63d21a7bc402b2157921dea921eeb09cc757cf7ab383e122cca730c51a976e69ce37daaf66217e00d42144297dd9954a62226db7fa2de24cba50b4c963ae6226ae5fa652946dd0a725000000")
def deserialize(data): length = struct.calcsize(">I32sBBI") if len(data) < length: raise Exception("size too small") index_data, outpoint_data = data[:length], data[length:] id, hash, index, type_value, masterkey_id = struct.unpack(">I32sBBI", index_data) if type_value not in OutpointIndexSerializer.OUTPOINT_TYPES: raise Exception("unknown outpoint type: %d" % (type_value)) oupoint_type = OutpointIndexSerializer.OUTPOINT_TYPES[type_value] if (oupoint_type == OutpointIndex.PUBKEY or oupoint_type == OutpointIndex.PUBKEY_HASH): outpoint = PubKeyOutpointSerializer.deserialize(outpoint_data, oupoint_type == OutpointIndex.PUBKEY_HASH) elif oupoint_type == OutpointIndex.MULTISIG: outpoint = MultiSigOutpointSerializer.serialize(outpoint_data) elif oupoint_type == OutpointIndex.SCRIPT_HASH: outpoint = ScriptHashOutpointSerializer.serialize(outpoint_data) return OutpointIndex(id, Uint256.from_bytestr_be(hash), index, oupoint_type, masterkey_id, outpoint)
def test_blockheader_template(self): """ Change nonce and extra_nonce in a blockheader_template """ template = BlockheaderTemplate( Uint256.from_hexstr( "0009d8ab497a46a0d6a2b9b302993bd26613b145695d986be50e0b6e68c5b524" ), 1, # version 2 blocks see BIP-34 [ TxOut( 5000000000, Script([ Instruction( OP_PUSHDATA, decodehexstr( "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f" )), Instruction(OP_CHECKSIG) ])) ], [], time=1356447036, bits=524287999, nonce=0, extra_nonce=0, coinbase_flags=["/P2SH/"]) self.assertEquals( hexstr(template.get_serialized()), "0200000024b5c5686e0b0ee56b985d6945b11366d23b9902b3b9a2d6a0467a49abd80900ad7af2ede803ff129e66775d56153a7a649721e524eecad69a437ecdc01e29343cbdd950ffff3f1f00000000" ) template.set_nonce(8) self.assertEquals( hexstr(template.get_serialized()), "0200000024b5c5686e0b0ee56b985d6945b11366d23b9902b3b9a2d6a0467a49abd80900ad7af2ede803ff129e66775d56153a7a649721e524eecad69a437ecdc01e29343cbdd950ffff3f1f08000000" ) template.set_nonce(492498294) self.assertEquals( hexstr(template.get_serialized()), "0200000024b5c5686e0b0ee56b985d6945b11366d23b9902b3b9a2d6a0467a49abd80900ad7af2ede803ff129e66775d56153a7a649721e524eecad69a437ecdc01e29343cbdd950ffff3f1f76ed5a1d" ) template.set_extra_nonce(2) template.set_nonce(0) self.assertEquals( hexstr(template.get_serialized()), "0200000024b5c5686e0b0ee56b985d6945b11366d23b9902b3b9a2d6a0467a49abd80900e1cc38b530e20307a310a57a6e2e22985ce2e292bfc73b28a723dd77f8e8f0ca3cbdd950ffff3f1f00000000" )
def get_merkle_branch(block, index_tx): """Get the merkle branch of a transaction. block: block that contains the transaction index_tx: index of the transaction in the block Return value: [list of Uint256] The first element is a hash of a transaction at the bottom of the merkle tree. The last element is the merkle root. The algorithm uses XOR 1, to select the opposite element at each level. """ merkle_branch = [] merkle_tree = get_merkle_tree(block) for level in merkle_tree: merkle_branch.append(Uint256.from_bytestr(level[min(index_tx^1, len(level)-1)])) index_tx = index_tx >> 1 return (merkle_branch)
def test_blockheader_template(self): """ Change nonce and extra_nonce in a blockheader_template """ template = BlockheaderTemplate(Uint256.from_hexstr("0009d8ab497a46a0d6a2b9b302993bd26613b145695d986be50e0b6e68c5b524"), 1, # version 2 blocks see BIP-34 [TxOut(5000000000, Script([Instruction(OP_PUSHDATA, decodehexstr("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")),Instruction(OP_CHECKSIG)]))], [], time=1356447036, bits=524287999, nonce=0, extra_nonce=0, coinbase_flags=["/P2SH/"]) self.assertEquals(hexstr(template.get_serialized()), "0200000024b5c5686e0b0ee56b985d6945b11366d23b9902b3b9a2d6a0467a49abd80900ad7af2ede803ff129e66775d56153a7a649721e524eecad69a437ecdc01e29343cbdd950ffff3f1f00000000") template.set_nonce(8) self.assertEquals(hexstr(template.get_serialized()), "0200000024b5c5686e0b0ee56b985d6945b11366d23b9902b3b9a2d6a0467a49abd80900ad7af2ede803ff129e66775d56153a7a649721e524eecad69a437ecdc01e29343cbdd950ffff3f1f08000000") template.set_nonce(492498294) self.assertEquals(hexstr(template.get_serialized()), "0200000024b5c5686e0b0ee56b985d6945b11366d23b9902b3b9a2d6a0467a49abd80900ad7af2ede803ff129e66775d56153a7a649721e524eecad69a437ecdc01e29343cbdd950ffff3f1f76ed5a1d") template.set_extra_nonce(2) template.set_nonce(0) self.assertEquals(hexstr(template.get_serialized()), "0200000024b5c5686e0b0ee56b985d6945b11366d23b9902b3b9a2d6a0467a49abd80900e1cc38b530e20307a310a57a6e2e22985ce2e292bfc73b28a723dd77f8e8f0ca3cbdd950ffff3f1f00000000")
def test_tx_serialize(self): tx = Tx(version=1, in_list=[TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr("17c5cb687ba453ab65e12cdc0d8721c70ab4678665eb200c50cb9f1e3207090e"), index=0), script=Script([Instruction(72, decodehexstr("3045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c01")), Instruction(65, decodehexstr("04b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3e"))]), sequence=TxIn.NSEQUENCE_FINAL )], out_list=[TxOut(value=24990000000, script=Script([Instruction(OP_DUP), Instruction(OP_HASH160), Instruction(20, decodehexstr("4d8b17fbce571614be89df4bd872de892a479844")), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG)])), TxOut(value=5000000000, script=Script([Instruction(OP_DUP), Instruction(OP_HASH160), Instruction(20, decodehexstr("fadad27c40adbe230f5e3c04d44a292975084831")), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG)]))], locktime=0) self.assertEquals(hexstr(TxSerializer().serialize(tx)), "01000000010e0907321e9fcb500c20eb658667b40ac721870ddc2ce165ab53a47b68cbc517000000008b483045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c014104b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3effffffff02802385d1050000001976a9144d8b17fbce571614be89df4bd872de892a47984488ac00f2052a010000001976a914fadad27c40adbe230f5e3c04d44a29297508483188ac00000000")