def test_exercise_3_1(self): prev_tx = bytes.fromhex( 'eb581753a4dbd6befeaaaa28a6f4576698ba13a07c03da693a65bce11cf9887a') prev_index = 1 target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv' target_amount = 0.04 change_address = 'mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2' fee = 50000 secret = 8675309 private_key = PrivateKey(secret=secret) tx_ins = [] tx_ins.append(TxIn(prev_tx, prev_index)) tx_outs = [] h160 = decode_base58(target_address) script_pubkey = p2pkh_script(h160) target_satoshis = int(target_amount * 100000000) tx_outs.append(TxOut(target_satoshis, script_pubkey)) h160 = decode_base58(change_address) script_pubkey = p2pkh_script(h160) prev_amount = tx_ins[0].value(testnet=True) change_satoshis = prev_amount - target_satoshis - fee tx_outs.append(TxOut(change_satoshis, script_pubkey)) tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True) tx_obj.sign_input(0, private_key) if private_key.point.address(testnet=True) != change_address: raise RuntimeError( 'Private Key does not correspond to Change Address, check priv_key and change_address' ) if tx_ins[0].script_pubkey( testnet=True).instructions[2] != decode_base58(change_address): raise RuntimeError( 'Output is not something you can spend with this private key. Check that the prev_tx and prev_index are correct' ) if tx_obj.fee() > 0.05 * 100000000 or tx_obj.fee() <= 0: raise RuntimeError( 'Check that the change amount is reasonable. Fee is {}'.format( tx_obj.fee())) self.assertEqual( tx_obj.serialize().hex(), '01000000017a88f91ce1bc653a69da037ca013ba986657f4a628aaaafebed6dba4531758eb010000006a47304402204ce6e3877ed2e18d2165276cbdba241507ce72b44d8df640eb6cb4d415eaaea002207dffd162da35593d86188ce87a1cbc9d3a5b26391870f19bf1764ca05b315ad9012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff0200093d00000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac7077e401000000001976a914d52ad7ca9b3d096a38e752c2018e6fbc40cdf26f88ac00000000' )
def test_exercise_3_2(self): prev_tx_1 = bytes.fromhex( '89cbfe2eddaddf1eb11f5c4adf6adaa9bca4adc01b2a3d03f8dd36125c068af4') prev_index_1 = 0 prev_tx_2 = bytes.fromhex( '19069e1304d95f70e03311d9d58ee821e0978e83ecfc47a30af7cd10fca55cf4') prev_index_2 = 0 target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv' fee = 50000 secret = 61740721216174072121 private_key = PrivateKey(secret=secret) tx_ins = [] tx_ins.append(TxIn(prev_tx_1, prev_index_1)) tx_ins.append(TxIn(prev_tx_2, prev_index_2)) tx_outs = [] h160 = decode_base58(target_address) script_pubkey = p2pkh_script(h160) target_satoshis = tx_ins[0].value(True) + tx_ins[1].value(True) - fee tx_outs.append(TxOut(target_satoshis, script_pubkey)) tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True) tx_obj.sign_input(0, private_key) tx_obj.sign_input(1, private_key) if tx_ins[0].script_pubkey( testnet=True).instructions[2] != decode_base58( private_key.point.address(testnet=True)): raise RuntimeError( 'Output is not something you can spend with this private key. Check that the prev_tx and prev_index are correct' ) if tx_obj.fee() > 0.05 * 100000000 or tx_obj.fee() <= 0: raise RuntimeError( 'Check that the change amount is reasonable. Fee is {}'.format( tx_obj.fee())) self.assertEqual( tx_obj.serialize().hex(), '0100000002f48a065c1236ddf8033d2a1bc0ada4bca9da6adf4a5c1fb11edfaddd2efecb89000000006a47304402204b9ee431a2f5deaefb5282a34d7dcfdb47d55b1e3ce00cac4c6b6e6f0f0e8d58022062710e84786d2c6c89ddda5a149b45088b15230c6b825f0f21490f99bd74c81d012103f96f3a1efd31e1a8d7078118ee56bff7355d58907ce0f865f5f0b3dbe34e55befffffffff45ca5fc10cdf70aa347fcec838e97e021e88ed5d91133e0705fd904139e0619000000006a473044022073d7217b2d582e55978284c2628015a14e3490e835c76488eb29b63de15d17920220384e4b5282c911273efd4d98170e7092e10a729d142db17f4725c15364fa4ecc012103f96f3a1efd31e1a8d7078118ee56bff7355d58907ce0f865f5f0b3dbe34e55beffffffff01021f320a000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000' )
tx_ins=tx_ins, tx_outs=tx_outs, locktime=0, testnet=True) # now sign the 0th input with the private key using SIGHASH_ALL using sign_input tx_obj.sign_input(0, priv1, SIGHASH_ALL) # SANITY CHECK: change address corresponds to private key if priv1.point.address(testnet=True) != change_address: raise RuntimeError( 'Private Key does not correspond to Change Address, check priv_key and change_address' ) # SANITY CHECK: output's script_pubkey is the same one as your address if tx_ins[0].script_pubkey( testnet=True).elements[2] != decode_base58(change_address): raise RuntimeError( 'Output is not something you can spend with this private key. Check that the prev_tx and prev_index are correct' ) # SANITY CHECK: fee is reasonable if tx_obj.fee(testnet=True) > 0.05 * 100000000 or tx_obj.fee( testnet=True) <= 0: raise RuntimeError( 'Check that the change amount is reasonable. Fee is {}'.format( tx_obj.fee())) # serialize and hex() print(tx_obj.serialize().hex())