def test_siganyonecanpay_none_send(self): """ SIGHASH_NONE | SIGHASH_ANYONECANPAY:signs only the txin_index input """ tx = Transaction([self.txin1_siganyonecanpay_none], [self.txout1_siganyonecanpay_none], has_segwit=True) pk = self.sk.get_public_key().to_hex() sig_signone = self.sk.sign_segwit_input( tx, 0, self.p2pkh_redeem_script, self.txin1_siganyonecanpay_none_amount, SIGHASH_NONE | SIGHASH_ANYONECANPAY) tx.witnesses = [Script([sig_signone, pk])] tx.inputs.append(self.txin2_siganyonecanpay_none) tx.outputs.append(self.txout2_siganyonecanpay_none) sig = self.sk.sign_segwit_input(tx, 1, self.p2pkh_redeem_script, self.txin2_siganyonecanpay_none_amount, SIGHASH_ALL) tx.witnesses.append(Script([sig, pk])) self.assertEqual(tx.serialize(), self.test_siganyonecanpay_none_send_result)
def test_multiple_input_multiple_ouput(self): tx = Transaction( [self.txin1_multiple, self.txin2_multiple, self.txin3_multiple], [ self.output1_multiple, self.output2_multiple, self.output3_multiple ], has_segwit=True) sig1 = self.sk1.sign_input(tx, 0, self.p2pkh_addr.to_script_pub_key()) pk1 = self.sk1.get_public_key().to_hex() self.txin1_multiple.script_sig = Script([sig1, pk1]) tx.witnesses = [Script([])] sig_p2sh1 = self.sk1.sign_segwit_input(tx, 1, self.p2wsh_redeem_script, self.txin2_multiple_amount) sig_p2sh2 = self.sk2.sign_segwit_input(tx, 1, self.p2wsh_redeem_script, self.txin2_multiple_amount) pk2 = self.p2wsh_redeem_script.to_hex() tx.witnesses.append(Script(['OP_0', sig_p2sh1, sig_p2sh2, pk2])) sig3 = self.sk1.sign_segwit_input(tx, 2, self.p2pkh_addr.to_script_pub_key(), self.txin3_multiple_amount) pk3 = self.sk1.get_public_key().to_hex() tx.witnesses.append(Script([sig3, pk3])) #print(tx.serialize()) self.assertEqual(tx.serialize(), self.multiple_input_multiple_ouput_result)
def setUp(self): setup('testnet') self.txin = TxInput( "76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f", 0) self.from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') self.sk = PrivateKey( 'cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo') self.p2pk_sk = PrivateKey( 'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9') self.p2pk_redeem_script = Script( [self.p2pk_sk.get_public_key().to_hex(), 'OP_CHECKSIG']) self.txout = TxOutput(to_satoshis(0.09), self.p2pk_redeem_script.to_p2sh_script_pub_key()) self.create_p2sh_and_send_result = '02000000010f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b483045022100fd3a3fd4aeec5db0f3f9c5c5ef7f60f37920be7464a80edacbc3b6b9d0624173022031ce309330e60b19d39cec8c5597460c840adcdd66f7dbbf896eef3ec42b472f012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff01405489000000000017a9142910fc0b1b7ab6c9789c5a67c22c5bcde5b903908700000000' self.txin_spend = TxInput( '7db363d5a7fabb64ccce154e906588f1936f34481223ea8c1f2c935b0a0c945b', 0) # self.p2pk_sk , self.p2pk_redeem_script from above self.to_addr = self.from_addr self.txout2 = TxOutput(to_satoshis(0.08), self.to_addr.to_script_pub_key()) self.spend_p2sh_result = '02000000015b940c0a5b932c1f8cea231248346f93f18865904e15cecc64bbfaa7d563b37d000000006c47304402204984c2089bf55d5e24851520ea43c431b0d79f90d464359899f27fb40a11fbd302201cc2099bfdc18c3a412afb2ef1625abad8a2c6b6ae0bf35887b787269a6f2d4d01232103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708acffffffff0100127a00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac00000000' # P2SH(CSV+P2PKH) self.sk_csv_p2pkh = PrivateKey( 'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9') self.seq = Sequence(TYPE_RELATIVE_TIMELOCK, 200) self.txin_seq = TxInput( 'f557c623e55f0affc696b742630770df2342c4aac395e0ed470923247bc51b95', 0, sequence=self.seq.for_input_sequence()) self.another_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') self.spend_p2sh_csv_p2pkh_result = '0200000001951bc57b24230947ede095c3aac44223df70076342b796c6ff0a5fe523c657f5000000008a483045022100c123775e69ec27094f7940facb9ad769c09f48a7fc88250a2fce67bd92c9b4cf02204ebdbed84af46e584fe6db9a23c420b7370879e883b555e119465f84bf34d82f012103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af327081e02c800b27576a914c3f8e5b0f8455a2b02c29c4488a550278209b66988acc80000000100ab9041000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac00000000'
def test_signed_tx_1_input_2_outputs(self): tx = Transaction([self.txin], [self.txout, self.change_txout]) sig = self.sk.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160', self.from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG']) ) pk = self.sk.get_public_key().to_hex() self.txin.script_sig = Script([sig, pk]) self.assertEqual(tx.serialize(), self.core_tx_signed_result)
def main(): # always remember to setup the network setup('testnet') # # This script creates a P2SH address containing a P2PK script and sends # some funds to it # # create transaction input from tx id of UTXO (contained 0.1 tBTC) txin = TxInput( '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 0) # address we are spending from from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') # secret key of address that we are trying to spent sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo') # # create transaction output using P2SH scriptPubKey (locking script) # (the recipient will give us the final address but for now we create it # for demonstration purposes) # # secret key corresponding to the pubkey needed for the P2SH (P2PK) transaction p2pk_sk = PrivateKey( 'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9') p2pk_pk = p2pk_sk.get_public_key().to_hex() redeem_script = Script([p2pk_pk, 'OP_CHECKSIG']) txout = TxOutput(to_satoshis(0.09), redeem_script.to_p2sh_script_pub_key()) # no change address - the remaining 0.01 tBTC will go to miners) # create transaction from inputs/outputs -- default locktime is used tx = Transaction([txin], [txout]) # print raw transaction print("\nRaw unsigned transaction:\n" + tx.serialize()) # use the private key corresponding to the address that contains the # UTXO we are trying to spend to create the signature for the txin sig = sk.sign_input(tx, 0, from_addr.to_script_pub_key()) #print(sig) # get public key as hex pk = sk.get_public_key() pk = pk.to_hex() #print (pk) # set the scriptSig (unlocking script) txin.script_sig = Script([sig, pk]) signed_tx = tx.serialize() # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + signed_tx) print("\nTxId:", tx.get_txid())
def main(): # always remember to setup the network setup('testnet') # create transaction input from tx id of UTXO (contained 0.4 tBTC) txin = TxInput( 'fb48f4e23bf6ddf606714141ac78c3e921c8c0bebeb7c8abb2c799e9ff96ce6c', 0) # create transaction output using P2PKH scriptPubKey (locking script) addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') txout = TxOutput( to_satoshis(0.1), Script([ 'OP_DUP', 'OP_HASH160', addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ])) # create another output to get the change - remaining 0.01 is tx fees # note that this time we used to_script_pub_key() to create the P2PKH # script change_addr = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w') change_txout = TxOutput(to_satoshis(0.29), change_addr.to_script_pub_key()) #change_txout = TxOutput(to_satoshis(0.29), Script(['OP_DUP', 'OP_HASH160', # change_addr.to_hash160(), # 'OP_EQUALVERIFY', 'OP_CHECKSIG'])) # create transaction from inputs/outputs -- default locktime is used tx = Transaction([txin], [txout, change_txout]) # print raw transaction print("\nRaw unsigned transaction:\n" + tx.serialize()) # use the private key corresponding to the address that contains the # UTXO we are trying to spend to sign the input sk = PrivateKey('cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9') # note that we pass the scriptPubkey as one of the inputs of sign_input # because it is used to replace the scriptSig of the UTXO we are trying to # spend when creating the transaction digest from_addr = P2pkhAddress('myPAE9HwPeKHh8FjKwBNBaHnemApo3dw6e') sig = sk.sign_input( tx, 0, Script([ 'OP_DUP', 'OP_HASH160', from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ])) #print(sig) # get public key as hex pk = sk.get_public_key().to_hex() # set the scriptSig (unlocking script) txin.script_sig = Script([sig, pk]) signed_tx = tx.serialize() # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + signed_tx)
def test_signed_low_s_SIGNONE_tx_1_input_2_outputs(self): tx = Transaction([self.txin], [self.txout, self.change_low_s_txout]) sig = self.sk.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160', self.from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG']), SIGHASH_NONE) pk = self.sk.get_public_key().to_hex() self.txin.script_sig = Script([sig, pk]) # check correct raw tx self.assertEqual(tx.serialize(), self.core_tx_signed_low_s_SIGNONE_result) # check correct calculation of txid self.assertEqual(tx.get_txid(), self.core_tx_signed_low_s_SIGNONE_txid)
def main(): # always remember to setup the network setup('regtest') # create transaction input from tx id of UTXO (contained 0.4 tBTC) txin = TxInput( 'e2d08a63a540000222d6a92440436375d8b1bc89a2638dc5366833804287c83f', 1) # locking script expects 2 numbers that when added equal 5 (silly example) txout = TxOutput(to_satoshis(0.9), Script(['OP_ADD', 'OP_5', 'OP_EQUAL'])) # create another output to get the change - remaining 0.01 is tx fees # note that this time we used to_script_pub_key() to create the P2PKH # script change_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r') change_txout = TxOutput(to_satoshis(2), change_addr.to_script_pub_key()) # create transaction from inputs/outputs -- default locktime is used tx = Transaction([txin], [txout, change_txout]) # print raw transaction print("\nRaw unsigned transaction:\n" + tx.serialize()) # use the private key corresponding to the address that contains the # UTXO we are trying to spend to sign the input sk = PrivateKey('cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA') # note that we pass the scriptPubkey as one of the inputs of sign_input # because it is used to replace the scriptSig of the UTXO we are trying to # spend when creating the transaction digest from_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r') sig = sk.sign_input( tx, 0, Script([ 'OP_DUP', 'OP_HASH160', from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ])) #print(sig) # get public key as hex pk = sk.get_public_key() pk = pk.to_hex() #print (pk) # set the scriptSig (unlocking script) txin.script_sig = Script([sig, pk]) signed_tx = tx.serialize() # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + signed_tx)
def main(): # always remember to setup the network setup('testnet') # send 2 P2PKH inputs to 1 P2WPKH output # create transaction inputs from tx ids of UTXOs (contained 0.002 tBTC) txin = TxInput('eddfaa3d5a1c9a2a2961638aa4e28871b09ed9620f9077482248f368d46d8205', 1) txin2 = TxInput('cf4b2987c06b9dd2ba6770af31a4942a4ea3e7194c0d64e8699e9fda03f50551', 1) # create transaction output using P2WPKH scriptPubKey (locking script) addr = P2wpkhAddress('tltc1qedur7y052upuzd7wzh60d2f86szgpuspmml8ce') txout = TxOutput(to_satoshis(0.0019), addr.to_script_pub_key()) #txout = TxOutput(to_satoshis(0.0019), Script([0, addr.to_hash()]) ) # create transaction from inputs/outputs -- default locktime is used # note that this is not a segwit transaction since we don't spend segwit tx = Transaction([txin, txin2], [txout]) #, has_segwit=True) # print raw transaction print("\nRaw unsigned transaction:\n" + tx.serialize()) # use the private keys corresponding to the address that contains the # UTXOs we are trying to spend to sign the input sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo') sk2 = PrivateKey('cVf3kGh6552jU2rLaKwXTKq5APHPoZqCP4GQzQirWGHFoHQ9rEVt') # note that we pass the scriptPubkey as one of the inputs of sign_input # because it is used to replace the scriptSig of the UTXO we are trying to # spend when creating the transaction digest from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') sig = sk.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160', from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG']) ) from_addr2 = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w') sig2 = sk2.sign_input( tx, 1, from_addr2.to_script_pub_key() ) # get public key as hex pk = sk.get_public_key().to_hex() pk2 = sk2.get_public_key().to_hex() # set the scriptSig (unlocking script) txin.script_sig = Script([sig, pk]) txin2.script_sig = Script([sig2, pk2]) signed_tx = tx.serialize() # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + signed_tx)
def test_p2pkh_and_p2wpkh_to_p2pkh(self): tx = Transaction([self.txin_spend_p2pkh, self.txin_spend_p2wpkh], [self.txout3], has_segwit=True) # spend_p2pkh sig1 = self.sk.sign_input(tx, 0, self.p2pkh_addr.to_script_pub_key()) pk1 = self.sk.get_public_key().to_hex() self.txin_spend_p2pkh.script_sig = Script([sig1, pk1]) tx.witnesses = [Script([])] # spend_p2wpkh sig2 = self.sk.sign_segwit_input(tx, 1, self.p2pkh_redeem_script, self.txin_spend_p2wpkh_amount) pk2 = self.sk.get_public_key().to_hex() tx.witnesses.append(Script([sig2, pk2])) self.assertEqual(tx.serialize(), self.p2pkh_and_p2wpkh_to_p2pkh_result)
def test_signed_send_to_p2wpkh(self): # Non-segregated witness transaction tx = Transaction([self.txin1], [self.txout1]) sig = self.sk.sign_input(tx, 0, self.p2pkh_addr.to_script_pub_key()) pk = self.sk.get_public_key().to_hex() self.txin1.script_sig = Script([sig, pk]) self.assertEqual(tx.serialize(), self.create_send_to_p2wpkh_result)
def main(): # always remember to setup the network setup('testnet') # # This script creates a P2SH address containing a CHECKSEQUENCEVERIFY plus # a P2PKH locking funds with a key as well as for 20 blocks # # set values relative_blocks = 20 seq = Sequence(TYPE_RELATIVE_TIMELOCK, relative_blocks) # secret key corresponding to the pubkey needed for the P2SH (P2PKH) transaction p2pkh_sk = PrivateKey( 'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9') # get the address (from the public key) p2pkh_addr = p2pkh_sk.get_public_key().get_address() # create the redeem script redeem_script = Script([ seq.for_script(), 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160', p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]) # create a P2SH address from a redeem script addr = P2shAddress.from_script(redeem_script) print(addr.to_string())
def test_send_to_non_std(self): tx = Transaction([self.txin], [self.txout, self.change_txout]) from_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r') sig = self.sk.sign_input(tx, 0, from_addr.to_script_pub_key()) pk = self.sk.get_public_key().to_hex() self.txin.script_sig = Script([sig, pk]) self.assertEqual(tx.serialize(), self.create_non_std_tx_result)
def from_raw(txinputraw, cursor=0, has_segwit=False): """ Imports a TxInput from a Transaction's hexadecimal data Attributes ---------- txinputraw : string (hex) The hexadecimal raw string of the Transaction cursor : int The cursor of which the algorithm will start to read the data has_segwit : boolean Is the Tx Input segwit or not """ txinputraw = to_bytes(txinputraw) # read the 32 bytes of TxInput ID inp_hash = txinputraw[cursor:cursor + 32][::-1] if not len(inp_hash): raise Exception("Input transaction hash not found. Probably malformed raw transaction") output_n = txinputraw[cursor + 32:cursor + 36][::-1] cursor += 36 # read the size (bytes length) of the integer representing the size of the Script's raw # data and the size of the Script's raw data unlocking_script_size, size = vi_to_int(txinputraw[cursor:cursor + 9]) cursor += size unlocking_script = txinputraw[cursor:cursor + unlocking_script_size] cursor += unlocking_script_size sequence_number = txinputraw[cursor:cursor + 4] cursor += 4 return TxInput(txid = inp_hash.hex(), txout_index=int(output_n.hex(), 16), script_sig=Script.from_raw(unlocking_script,has_segwit=has_segwit), sequence=sequence_number),cursor
def test_spend_p2wpkh(self): tx = Transaction([self.txin_spend], [self.txout2], has_segwit=True) sig = self.sk.sign_segwit_input(tx, 0, self.p2pkh_redeem_script, self.txin_spend_amount) pk = self.sk.get_public_key().to_hex() tx.witnesses = [Script([sig, pk])] self.assertEqual(tx.serialize(), self.spend_p2pkh_result)
def copy(cls, tx): """Deep copy of Transaction""" ins = [TxInput.copy(txin) for txin in tx.inputs] outs = [TxOutput.copy(txout) for txout in tx.outputs] wits = [Script.copy(witness) for witness in tx.witnesses] return cls(ins, outs, tx.locktime, tx.version, tx.has_segwit, wits)
def from_raw(txoutputraw,cursor=0,has_segwit=False): """ Imports a TxOutput from a Transaction's hexadecimal data Attributes ---------- txinputraw : string (hex) The hexadecimal raw string of the Transaction cursor : int The cursor of which the algorithm will start to read the data has_segwit : boolean Is the Tx Output segwit or not """ txoutputraw = to_bytes(txoutputraw) # read the amount of the TxOutput value = int.from_bytes(txoutputraw[cursor:cursor + 8][::-1], 'big') cursor += 8 # read the size (bytes length) of the integer representing the size of the locking # Script's raw data and the size of the locking Script's raw data lock_script_size, size = vi_to_int(txoutputraw[cursor:cursor + 9]) cursor += size lock_script = txoutputraw[cursor:cursor + lock_script_size] cursor += lock_script_size return TxOutput(amount=value, script_pubkey=Script.from_raw(lock_script, has_segwit=has_segwit)),cursor
def main(): # always remember to setup the network setup('testnet') # could also instantiate from existing WIF key priv = PrivateKey.from_wif( 'cVdte9ei2xsVjmZSPtyucG43YZgNkmKTqhwiUA8M4Fc3LdPJxPmZ') # compressed is the default print("\nPrivate key WIF:", priv.to_wif(compressed=True)) # get the public key pub = priv.get_public_key() # compressed is the default print("Public key:", pub.to_hex(compressed=True)) # get address from public key address = pub.get_segwit_address() # print the address and hash - default is compressed address print("Native Address:", address.to_string()) segwit_hash = address.to_hash() print("Segwit Hash:", segwit_hash) print("Segwit Version:", address.get_type()) # test to_string addr2 = P2wpkhAddress.from_hash(segwit_hash) print("Created P2wpkhAddress from Segwit Hash and calculate address:") print("Native Address:", addr2.to_string()) # # display P2SH-P2WPKH # # create segwit address addr3 = PrivateKey.from_wif( 'cTmyBsxMQ3vyh4J3jCKYn2Au7AhTKvqeYuxxkinsg6Rz3BBPrYKK').get_public_key( ).get_segwit_address() # wrap in P2SH address addr4 = P2shAddress.from_script(addr3.to_script_pub_key()) print("P2SH(P2WPKH):", addr4.to_string()) # # display P2WSH # p2wpkh_key = PrivateKey.from_wif( 'cNn8itYxAng4xR4eMtrPsrPpDpTdVNuw7Jb6kfhFYZ8DLSZBCg37') script = Script([ 'OP_1', p2wpkh_key.get_public_key().to_hex(), 'OP_1', 'OP_CHECKMULTISIG' ]) p2wsh_addr = P2wshAddress.from_script(script) print("P2WSH of P2PK:", p2wsh_addr.to_string()) # # display P2SH-P2WSH # p2sh_p2wsh_addr = P2shAddress.from_script(p2wsh_addr.to_script_pub_key()) print("P2SH(P2WSH of P2PK):", p2sh_p2wsh_addr.to_string())
def test_signed_low_s_SIGSINGLE_tx_1_input_2_outputs(self): tx = Transaction([self.sig_txin1], [self.sig_txout1, self.sig_txout2] ) sig = self.sig_sk1.sign_input( tx, 0, self.sig_from_addr1.to_script_pub_key(), SIGHASH_SINGLE) pk = self.sig_sk1.get_public_key().to_hex() self.sig_txin1.script_sig = Script([sig, pk]) self.assertEqual(tx.serialize(), self.sig_sighash_single_result)
def test_signed_SIGALLSINGLE_ANYONEtx_2in_2_out(self): # note that this would have failed due to absurdly high fees but we # ignore it for our purposes tx = Transaction([self.sig_txin1, self.sig_txin2], [self.sig_txout1, self.sig_txout2] ) sig = self.sig_sk1.sign_input(tx, 0, Script(['OP_DUP', 'OP_HASH160', self.sig_from_addr1.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG']), SIGHASH_ALL|SIGHASH_ANYONECANPAY) sig2 = self.sig_sk2.sign_input(tx, 1, self.sig_from_addr2.to_script_pub_key(), SIGHASH_SINGLE|SIGHASH_ANYONECANPAY) pk = self.sig_sk1.get_public_key().to_hex() pk2 = self.sig_sk2.get_public_key().to_hex() self.sig_txin1.script_sig = Script([sig, pk]) self.sig_txin2.script_sig = Script([sig2, pk2]) self.assertEqual(tx.serialize(), self.sign_sighash_all_single_anyone_2in_2out_result)
def test_spend_p2sh_csv_p2pkh(self): redeem_script = Script([ self.seq.for_script(), 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160', self.sk_csv_p2pkh.get_public_key().to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]) txout = TxOutput(to_satoshis(11), self.another_addr.to_script_pub_key()) tx = Transaction([self.txin_seq], [txout]) sig = self.sk_csv_p2pkh.sign_input(tx, 0, redeem_script) self.txin_seq.script_sig = Script([ sig, self.sk_csv_p2pkh.get_public_key().to_hex(), redeem_script.to_hex() ]) self.assertEqual(tx.serialize(), self.spend_p2sh_csv_p2pkh_result)
def main(): # always remember to setup the network setup('testnet') # the key that corresponds to the P2WPKH address priv = PrivateKey("cVdte9ei2xsVjmZSPtyucG43YZgNkmKTqhwiUA8M4Fc3LdPJxPmZ") pub = priv.get_public_key() fromAddress = pub.get_segwit_address() print(fromAddress.to_string()) # amount is needed to sign the segwit input fromAddressAmount = to_satoshis(0.01) # UTXO of fromAddress txid = '13d2d30eca974e8fa5da11b9608fa36905a22215e8df895e767fc903889367ff' vout = 0 toAddress = P2pkhAddress('mrrKUpJnAjvQntPgz2Z4kkyr1gbtHmQv28') # create transaction input from tx id of UTXO txin = TxInput(txid, vout) # the script code required for signing for p2wpkh is the same as p2pkh script_code = Script([ 'OP_DUP', 'OP_HASH160', pub.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]) # create transaction output txOut = TxOutput(to_satoshis(0.009), toAddress.to_script_pub_key()) # create transaction without change output - if at least a single input is # segwit we need to set has_segwit=True tx = Transaction([txin], [txOut], has_segwit=True) print("\nRaw transaction:\n" + tx.serialize()) sig = priv.sign_segwit_input(tx, 0, script_code, fromAddressAmount) tx.witnesses.append(Script([sig, pub.to_hex()])) # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + tx.serialize()) print("\nTxId:", tx.get_txid())
def test_p2wsh_creation_1multisig(self): p2wpkh_key = PrivateKey.from_wif( 'cNn8itYxAng4xR4eMtrPsrPpDpTdVNuw7Jb6kfhFYZ8DLSZBCg37') script = Script([ 'OP_1', p2wpkh_key.get_public_key().to_hex(), 'OP_1', 'OP_CHECKMULTISIG' ]) p2wsh_addr = P2wshAddress.from_script(script) self.assertTrue(p2wsh_addr.to_string(), self.correct_p2wsh_address)
def main(): # always remember to setup the network setup('testnet') # the key that corresponds to the P2WPKH address priv = PrivateKey('cNho8fw3bPfLKT4jPzpANTsxTsP8aTdVBD6cXksBEXt4KhBN7uVk') pub = priv.get_public_key() # the p2sh script and the corresponding address redeem_script = pub.get_segwit_address().to_script_pub_key() p2sh_addr = P2shAddress.from_script(redeem_script) # the UTXO of the P2SH-P2WPKH that we are trying to spend inp = TxInput('95c5cac558a8b47436a3306ba300c8d7af4cd1d1523d35da3874153c66d99b09', 0) # exact amount of UTXO we try to spent amount = 0.0014 # the address to send funds to to_addr = P2pkhAddress('mvBGdiYC8jLumpJ142ghePYuY8kecQgeqS') # the output sending 0.001 -- 0.0004 goes to miners as fee -- no change out = TxOutput(to_satoshis(0.001), to_addr.to_script_pub_key()) # create a tx with at least one segwit input tx = Transaction([inp], [out], has_segwit=True) # script code is the script that is evaluated for a witness program type; each # witness program type has a specific template for the script code # script code that corresponds to P2WPKH (it is the classic P2PKH) script_code = pub.get_address().to_script_pub_key() # calculate signature using the appropriate script code # remember to include the original amount of the UTXO sig = priv.sign_segwit_input(tx, 0, script_code, to_satoshis(amount)) # script_sig is the redeem script passed as a single element inp.script_sig = Script([redeem_script.to_hex()]) # finally, the unlocking script is added as a witness tx.witnesses.append(Script([sig, pub.to_hex()])) # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + tx.serialize())
def setUp(self): setup('testnet') # values for testing unsigned tx, signed tx all, signed tx with low s, # sighash none self.txin = TxInput('fb48f4e23bf6ddf606714141ac78c3e921c8c0bebeb7c8abb2c799e9ff96ce6c', 0) self.addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') self.txout = TxOutput(to_satoshis(0.1), Script(['OP_DUP', 'OP_HASH160', self.addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG']) ) self.change_addr = P2pkhAddress('mytmhndz4UbEMeoSZorXXrLpPfeoFUDzEp') self.change_txout = TxOutput(to_satoshis(0.29), self.change_addr.to_script_pub_key()) self.change_low_s_addr = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w') self.change_low_s_txout = TxOutput(to_satoshis(0.29), self.change_low_s_addr.to_script_pub_key()) self.sk = PrivateKey('cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9') self.from_addr = P2pkhAddress('myPAE9HwPeKHh8FjKwBNBaHnemApo3dw6e') self.core_tx_result = '02000000016cce96ffe999c7b2abc8b7bebec0c821e9c378ac41417106f6ddf63be2f448fb0000000000ffffffff0280969800000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac4081ba01000000001976a914c992931350c9ba48538003706953831402ea34ea88ac00000000' self.core_tx_signed_result = '02000000016cce96ffe999c7b2abc8b7bebec0c821e9c378ac41417106f6ddf63be2f448fb000000006a473044022079dad1afef077fa36dcd3488708dd05ef37888ef550b45eb00cdb04ba3fc980e02207a19f6261e69b604a92e2bffdf6ddbed0c64f55d5003e9dfb58b874b07aef3d7012103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708ffffffff0280969800000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac4081ba01000000001976a914c992931350c9ba48538003706953831402ea34ea88ac00000000' self.core_tx_signed_low_s_SIGALL_result = '02000000016cce96ffe999c7b2abc8b7bebec0c821e9c378ac41417106f6ddf63be2f448fb000000006a473044022044ef433a24c6010a90af14f7739e7c60ce2c5bc3eab96eaee9fbccfdbb3e272202205372a617cb235d0a0ec2889dbfcadf15e10890500d184c8dda90794ecdf79492012103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708ffffffff0280969800000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac4081ba01000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000' self.core_tx_signed_low_s_SIGNONE_result = '02000000016cce96ffe999c7b2abc8b7bebec0c821e9c378ac41417106f6ddf63be2f448fb000000006b483045022100b4ef8ec12b39b21c4b5d57ce82c0c8762a8e9fbe5322a0f00bd5de0dba5152fe02203edb3128b6df0c891770e377fdc8be5b46a2eab16c63bf57507d075a98557236022103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708ffffffff0280969800000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac4081ba01000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000' self.core_tx_signed_low_s_SIGNONE_txid = '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f' # values for testing sighash single and sighash all/none/single with # anyonecanpay self.sig_txin1 = TxInput("76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f", 0) self.sig_txin2 = TxInput('76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 1) self.sig_from_addr1 = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') self.sig_from_addr2 = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w') self.sig_sk1 = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo') self.sig_sk2 = PrivateKey('cVf3kGh6552jU2rLaKwXTKq5APHPoZqCP4GQzQirWGHFoHQ9rEVt') self.sig_to_addr1 = P2pkhAddress('myPAE9HwPeKHh8FjKwBNBaHnemApo3dw6e') self.sig_txout1 = TxOutput(to_satoshis(0.09), Script(['OP_DUP', 'OP_HASH160', self.sig_to_addr1.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG']) ) self.sig_to_addr2 = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w') self.sig_txout2 = TxOutput(to_satoshis(0.009), Script(['OP_DUP', 'OP_HASH160', self.sig_to_addr2.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG']) ) self.sig_sighash_single_result = '02000000010f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402202cfd7077fe8adfc5a65fb3953fa3482cad1413c28b53f12941c1082898d4935102201d393772c47f0699592268febb5b4f64dabe260f440d5d0f96dae5bc2b53e11e032102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000' self.sign_sighash_all_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b483045022100e30383d4006ef8b796ed397a81d2c55e6db3c05b370cb26179110816e57356e6022068fcd18a2a6984839a1fa7670693ed5c787da96589cd0f5ca81e3f11e613bd11012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a47304402206b728374b8879fd7a10cbd4f347934d583f4301aa5d592211487732c235b85b6022030acdc07761f227c27010bd022df4b22eb9875c65a59e8e8a5722229bc7362f4012102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000' self.sign_sighash_none_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402202a2804048b7f84f2dd7641ec05bbaf3da9ae0d2a9f9ad476d376adfd8bf5033302205170fee2ab7b955d72ae2beac3bae15679d75584c37d78d82b07df5402605bab022102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a473044022021a82914b002bd02090fbdb37e2e739e9ba97367e74db5e1de834bbab9431a2f02203a11f49a3f6ac03b1550ee04f9d84deee2045bc038cb8c3e70869470126a064d022102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000' self.sign_sighash_single_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402206118d21952932deb8608f772017fe76827ccdc8b750ead0f5636429ab5883a6802207f6ded77e22785b0e6c682c05260c2e073d1e1522d4c02fb78df6cdd2862e853032102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a47304402205012090ddf07ee2e7767020f09224001360243f8dbe05c5011c54eed9fb90d4802203358e227c891f609c3baf98d975d9ee72666fb511c808419d24ec5cccaf3938e032102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000' self.sign_sighash_all_single_anyone_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b4830450221008837e1300f41566cbcd9649ea21a6c1574cce7bf4bc288b878b545e9370041ab022040d0abdd2a0945463b85553922f27a755492e4e2ba89ae68cb14079103072dbb812102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a473044022067943abe9fa7584ba9816fc9bf002b043f7f97e11de59155d66e0411a679ba2c02200a13462236fa520b80b4ed85c7ded363b4c9264eb7b2d9746200be48f2b6f4cb832102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
def main(): # always remember to setup the network setup('testnet') # # This script spends from a P2SH address containing a P2PK script # # create transaction input from tx id of UTXO (contained 0.1 tBTC) txin = TxInput( '7db363d5a7fabb64ccce154e906588f1936f34481223ea8c1f2c935b0a0c945b', 0) # secret key needed to spend P2PK that is wrapped by P2SH p2pk_sk = PrivateKey( 'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9') p2pk_pk = p2pk_sk.get_public_key().to_hex() # create the redeem script - needed to sign the transaction redeem_script = Script([p2pk_pk, 'OP_CHECKSIG']) to_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') txout = TxOutput(to_satoshis(0.09), to_addr.to_script_pub_key()) # no change address - the remaining 0.01 tBTC will go to miners) # create transaction from inputs/outputs -- default locktime is used tx = Transaction([txin], [txout]) # print raw transaction print("\nRaw unsigned transaction:\n" + tx.serialize()) # use the private key corresponding to the address that contains the # UTXO we are trying to spend to create the signature for the txin - # note that the redeem script is passed to replace the scriptSig sig = p2pk_sk.sign_input(tx, 0, redeem_script) #print(sig) # set the scriptSig (unlocking script) txin.script_sig = Script([sig, redeem_script.to_hex()]) signed_tx = tx.serialize() # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + signed_tx) print("\nTxId:", tx.get_txid())
def test_spend_p2wsh(self): tx = Transaction([self.txin_spend], [self.txout2], has_segwit=True) sig1 = self.sk1.sign_segwit_input(tx, 0, self.p2wsh_redeem_script, self.txin_spend_amount) sig2 = self.sk2.sign_segwit_input(tx, 0, self.p2wsh_redeem_script, self.txin_spend_amount) pk = self.p2wsh_redeem_script.to_hex() tx.witnesses = [Script(['OP_0', sig1, sig2, pk])] #print(tx.serialize()) self.assertEqual(tx.serialize(), self.spend_p2pkh_result)
def main(): # always remember to setup the network setup('testnet') priv0 = PrivateKey("cN1XE3ESGgdvr4fWsB7L3BcqXncUauF8Fo8zzv4Sm6WrkiGrsxrG") pub = priv0.get_public_key() fromAddress = pub.get_segwit_address() priv1 = PrivateKey("cN1XE3ESGgdvr4fWsB7L3BcqXncUauF8Fo8zzv4Sm6WrkiGrsxrG") # P2SH Script: OP_M <Public key 1> <Public key 2> ... OP_N OP_CHECKMULTISIG p2sh_redeem_script = Script(['OP_1', priv1.get_public_key().to_hex(), 'OP_1', 'OP_CHECKMULTISIG']) toAddress = P2wshAddress.from_script(p2sh_redeem_script) # set values txid = 'd222d91e2da368ac38e84aa615c557e4caeacce02aa5dbca10d840fd460fc938' vout = 0 amount = to_satoshis(0.01764912) # create transaction input from tx id of UTXO txin = TxInput(txid, vout) redeem_script1 = Script( ['OP_DUP', 'OP_HASH160', priv0.get_public_key().to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG']) # create transaction output txOut1 = TxOutput(to_satoshis(0.0001), toAddress.to_script_pub_key()) txOut2 = TxOutput(to_satoshis(0.01744912), fromAddress.to_script_pub_key()) # create transaction tx = Transaction([txin], [txOut1, txOut2], has_segwit=True) print("\nRaw transaction:\n" + tx.serialize()) sig1 = priv0.sign_segwit_input(tx, 0, redeem_script1, amount) tx.witnesses.append(Script([sig1, pub.to_hex()])) # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + tx.serialize()) print("\nTxId:", tx.get_txid())
def __init__(self, txid, txout_index, script_sig=Script([]), sequence=DEFAULT_TX_SEQUENCE): """See TxInput description""" # expected in the format used for displaying Bitcoin hashes self.txid = txid self.txout_index = txout_index self.script_sig = script_sig # if user provided a sequence it would be as string (for now...) if type(sequence) is str: self.sequence = unhexlify(sequence) else: self.sequence = sequence
def main(): # always remember to setup the network setup('testnet') priv1 = PrivateKey("cN1XE3ESGgdvr4fWsB7L3BcqXncUauF8Fo8zzv4Sm6WrkiGrsxrG") priv2 = PrivateKey("cR8AkcbL2pgBswrHp28AftEznHPPLA86HiTog8MpNCibxwrsUcZ4") p2wsh_witness_script = Script([ 'OP_1', priv1.get_public_key().to_hex(), priv2.get_public_key().to_hex(), 'OP_2', 'OP_CHECKMULTISIG' ]) fromAddress = P2wshAddress.from_script(p2wsh_witness_script) toAddress = P2wpkhAddress.from_address( "tltc1qedur7y052upuzd7wzh60d2f86szgpuspmml8ce") # set values txid = '2042195c40a92353f2ffe30cd0df8d177698560e81807e8bf9174a9c0e98e6c2' vout = 0 amount = to_satoshis(0.01) # create transaction input from tx id of UTXO txin = TxInput(txid, vout) txOut1 = TxOutput(to_satoshis(0.0001), toAddress.to_script_pub_key()) txOut2 = TxOutput(to_satoshis(0.0098), fromAddress.to_script_pub_key()) tx = Transaction([txin], [txOut1, txOut2], has_segwit=True) sig1 = priv1.sign_segwit_input(tx, 0, p2wsh_witness_script, amount) tx.witnesses.append(Script(['OP_0', sig1, p2wsh_witness_script.to_hex()])) # print raw signed transaction ready to be broadcasted print("\nRaw signed transaction:\n" + tx.serialize()) print("\nTxId:", tx.get_txid())