def test_block_parsing_and_serialization(self): tx_in = TxIn( prev_tx=b'\x00' * 32, prev_index=0xffffffff, script_sig=Script([b'muhhh coinz']), ) sk = create_sk(100) sec = sk.verifying_key.to_sec(compressed=False) tx_out = TxOut( amount=50 * 100_000_000, script_pubkey=p2pk_script(sec), ) coinbase = Tx( version=1, tx_ins=[tx_in], tx_outs=[tx_out], locktime=0, ) block = mine( Block(version=1, prev_block=genesis.hash(), merkle_root=merkle_root([coinbase.hash()]), timestamp=int(time.time()), bits=starting_bits, nonce=b'\x00\x00\x00\x00', txns=[coinbase])) assert Block.parse(BytesIO(block.serialize())).hash() == block.hash()
def spend_nonexistant_output(bitcoin_node): coinbase = prepare_coinbase(bob_sec) tx_in = TxIn( prev_tx=urandom(32), prev_index=0, script_sig=p2pk_script(bob_sec), ) tx_out = TxOut( amount=50 * 100_000_000, script_pubkey=p2pk_script(bob_sec), ) bad_spend = Tx( version=1, tx_ins=[tx_in], tx_outs=[tx_out], locktime=0, ) block = mine( Block( version=1, prev_block=bitcoin_node.headers[-1].hash(), merkle_root=merkle_root([coinbase.hash(), bad_spend.hash()]), # FIXME timestamp=int(time.time()), bits=starting_bits, nonce=b'\x00\x00\x00\x00', txns=[coinbase, bad_spend], )) valid = False hints = make_hints([ 'this transaction spends an output that does not exist', ]) # FIXME: check that utxo_set was updated return block, valid, hints
def bad_coinbase(bitcoin_node): # this scenario sucks b/c we test multiple things and it's unclear whether the latter # checks are even happening tx_in = TxIn( prev_tx=b'\x00' * 32, prev_index=0xffffffff, script_sig=p2pk_script(urandom(10)), ) tx_out = TxOut( amount=100 * 100_000_000, script_pubkey=p2pk_script(bob_sec), ) coinbase = Tx( version=1, tx_ins=[tx_in], tx_outs=[tx_out], locktime=0, ) block = mine( Block( version=1, prev_block=bitcoin_node.headers[-1].hash(), merkle_root=merkle_root([coinbase.hash()]), # FIXME timestamp=int(time.time()), bits=starting_bits, nonce=b'\x00\x00\x00\x00', txns=[coinbase])) valid = False hints = make_hints([ "Bad coinbase", ]) return block, valid, hints
def parse(cls, s): block = BlockHeader.parse(s) # FIXME # num_txns - varint num_txns = read_varint(s) # num_txns many transactions remain block.txns = [] for _ in range(num_txns): block.txns.append(Tx.parse(s)) return block
def first_valid_spend(bitcoin_node): coinbase = prepare_coinbase(bob_sec) assert len(list(bitcoin_node.utxo_set.keys())) == 1 outpoint = list(bitcoin_node.utxo_set.keys())[0] # FIXME utxo = bitcoin_node.utxo_set[outpoint] tx_in = TxIn( prev_tx=bytes.fromhex(outpoint[0]), prev_index=outpoint[1], ) tx_out = TxOut( amount=utxo.amount - 10, script_pubkey=p2pk_script(bob_sec), ) bad_spend = Tx( version=1, tx_ins=[tx_in], tx_outs=[tx_out], locktime=0, ) ### HACKS!!! ### for i in range(len(bad_spend.tx_ins)): bad_spend.sign_input(i, bob_sk, utxo.script_pubkey) ### /HACKS!!! ### block = mine( Block( version=1, prev_block=bitcoin_node.headers[-1].hash(), merkle_root=merkle_root([coinbase.hash(), bad_spend.hash()]), # FIXME timestamp=int(time.time()), bits=starting_bits, nonce=b'\x00\x00\x00\x00', txns=[coinbase, bad_spend], )) valid = True hints = make_hints([ 'did utxo set update?', ]) # FIXME: check that utxo_set was updated return block, valid, hints
def prepare_coinbase(sec): tx_in = TxIn( prev_tx=b'\x00' * 32, prev_index=0xffffffff, script_sig=p2pk_script(urandom(10)), ) tx_out = TxOut( amount=50 * 100_000_000, script_pubkey=p2pk_script(sec), ) return Tx( version=1, tx_ins=[tx_in], tx_outs=[tx_out], locktime=0, )