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 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('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_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 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 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 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 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_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') # 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 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 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 test_sigsingle_send(self): """ SIGHASH_SINGLE:signs all inputs but only txin_index output """ tx = Transaction([self.txin1_sigsingle], [self.txout1_sigsingle], 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_sigsingle_amount, SIGHASH_SINGLE) tx.witnesses = [Script([sig_signone, pk])] tx.outputs.append(self.txout2_sigsingle) self.assertEqual(tx.serialize(), self.test_sigsingle_send_result)
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_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 test_signone_send(self): """ SIGHASH_NONE:signs all of the inputs """ # First, only txin1 and txout1 are added to the transaction. tx = Transaction([self.txin1_signone], [self.txout1_signone], 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_signone_amount, SIGHASH_NONE) tx.witnesses = [Script([sig_signone, pk])] # Adding additional output signatures will not be affected tx.outputs.append(self.txout2_signone) self.assertEqual(tx.serialize(), self.test_signone_send_result)
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 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())
def test_spend_p2sh(self): tx = Transaction([self.txin_spend], [self.txout2]) sig = self.p2pk_sk.sign_input(tx, 0, self.p2pk_redeem_script) self.txin_spend.script_sig = Script( [sig, self.p2pk_redeem_script.to_hex()]) self.assertEqual(tx.serialize(), self.spend_p2sh_result)
def test_signed_send_to_p2sh(self): tx = Transaction([self.txin], [self.txout]) sig = self.sk.sign_input(tx, 0, self.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_p2sh_and_send_result)
def test_spend_non_std(self): tx = Transaction([self.txin_spend], [self.txout_spend]) self.assertEqual(tx.serialize(), self.spend_non_std_tx_result)
def main(): # always remember to setup the network setup('testnet') # create transaction input from tx id of UTXO (contained 0.39 tBTC) # 0.1 tBTC txin = TxInput( '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 0) # 0.29 tBTC txin2 = TxInput( '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 1) # create transaction output using P2PKH scriptPubKey (locking script) addr = P2pkhAddress('myPAE9HwPeKHh8FjKwBNBaHnemApo3dw6e') txout = TxOutput( to_satoshis(0.3), 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 change_addr = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w') change_txout = TxOutput( to_satoshis(0.08), 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, txin2], [txout, change_txout]) # print raw transaction print("\nRaw unsigned transaction:\n" + tx.serialize()) # # use the private keys corresponding to the addresses that contains the # UTXOs we are trying to spend to create the signatures # sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo') sk2 = PrivateKey('cVf3kGh6552jU2rLaKwXTKq5APHPoZqCP4GQzQirWGHFoHQ9rEVt') # we could have derived the addresses from the secret keys from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') from_addr2 = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w') # sign the first input sig = sk.sign_input( tx, 0, Script([ 'OP_DUP', 'OP_HASH160', from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]), SIGHASH_ALL | SIGHASH_ANYONECANPAY) #print(sig) # sign the second input sig2 = sk2.sign_input( tx, 1, Script([ 'OP_DUP', 'OP_HASH160', from_addr2.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]), SIGHASH_SINGLE | SIGHASH_ANYONECANPAY) #print(sig2) # get public key as hex pk = sk.get_public_key() pk = pk.to_hex() #print (pk) # get public key as hex pk2 = sk2.get_public_key() pk2 = pk2.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) print("\nTxId:", tx.get_txid())
def main(): # always remember to setup the network setup('testnet') # # This script spends from a P2SH address containing a CSV+P2PKH script as # created from examples/create_p2sh_csv_p2pkh.py # # We assume that some 11.1 tBTC have been send to that address and that we know # the txid and the specific UTXO index (or vout). # # set values relative_blocks = 20 txid = '76c102821b916a625bd3f0c3c6e35d5c308b7c23e78b8866b06a3a466041db0a' vout = 0 seq = Sequence(TYPE_RELATIVE_TIMELOCK, relative_blocks) # create transaction input from tx id of UTXO (contained 11.1 tBTC) txin = TxInput(txid, vout, sequence=seq.for_input_sequence()) # secret key needed to spend P2PKH that is wrapped by P2SH p2pkh_sk = PrivateKey( 'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9') p2pkh_pk = p2pkh_sk.get_public_key().to_hex() p2pkh_addr = p2pkh_sk.get_public_key().get_address() # create the redeem script - needed to sign the transaction redeem_script = Script([ seq.for_script(), 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160', p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]) # to confirm that address is the same as the one that the funds were sent #addr = P2shAddress.from_script(redeem_script) #print(addr.to_string()) # send/spend to any random address to_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') txout = TxOutput(to_satoshis(11), to_addr.to_script_pub_key()) # no change address - the remaining 0.1 tBTC will go to miners) # create transaction from inputs/outputs 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 = p2pkh_sk.sign_input(tx, 0, redeem_script) #print(sig) # set the scriptSig (unlocking script) -- unlock the P2PKH (sig, pk) plus # the redeem script, since it is a P2SH txin.script_sig = Script([sig, p2pkh_pk, 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 get_issue_tx_info(conf, op_return_bstring, interactive=False): # load apropriate blockchain libraries if (conf.blockchain == 'litecoin'): from litecoinutils.setup import setup from litecoinutils.proxy import NodeProxy from litecoinutils.transactions import Transaction, TxInput, TxOutput from litecoinutils.keys import P2pkhAddress, P2wpkhAddress from litecoinutils.script import Script from litecoinutils.utils import to_satoshis, is_address_bech32 else: from bitcoinutils.setup import setup from bitcoinutils.proxy import NodeProxy from bitcoinutils.transactions import Transaction, TxInput, TxOutput from bitcoinutils.keys import P2pkhAddress, P2wpkhAddress from bitcoinutils.script import Script from bitcoinutils.utils import to_satoshis, is_address_bech32 op_return_hex = binascii.hexlify(op_return_bstring).decode() if interactive: print('\nConfigured values are:\n') print('working_directory:\t{}'.format(conf.working_directory)) print('issuing_address:\t{}'.format(conf.issuing_address)) print('blockchain:\t\t{}'.format(conf.blockchain)) print('full_node_url:\t\t{}'.format(conf.full_node_url)) print('full_node_rpc_user:\t{}'.format(conf.full_node_rpc_user)) print('testnet:\t\t{}'.format(conf.testnet)) print('tx_fee_per_byte:\t{}'.format(conf.tx_fee_per_byte)) print('Bytes for OP_RETURN:\n{}'.format(op_return_bstring)) print('Hex for OP_RETURN:\n{}'.format(op_return_hex)) op_return_cert_protocol = op_return_hex if interactive: consent = input('Do you want to continue? [y/N]: ').lower() in ('y', 'yes') if not consent: sys.exit() #import time #start = time.time() # test explicitly when non interactive if not conf.full_node_rpc_password and interactive: conf.full_node_rpc_password = getpass.getpass( '\nPlease enter the password for the node\'s RPC user: '******'testnet') else: setup('mainnet') host, port = conf.full_node_url.split( ':') # TODO: update when NodeProxy accepts full url! proxy = NodeProxy(conf.full_node_rpc_user, conf.full_node_rpc_password, host, port).get_proxy() # checks if address is native segwit or not. is_addr_bech32 = is_address_bech32(conf.issuing_address) # create transaction tx_outputs = [] unspent = sorted(proxy.listunspent(1, 9999999, [conf.issuing_address]), key=lambda x: x['amount'], reverse=False) if not unspent: raise ValueError("No UTXOs found") issuing_pubkey = proxy.getaddressinfo(conf.issuing_address)['pubkey'] tx = None tx_inputs = [] tx_input_data = {} inputs_amount = 0 # coin selection: use smallest UTXO and if not enough satoshis add next # smallest, etc. until sufficient tx fees are accumulated # TODO wrt dust instead of adding another UTXO we should just remove the # change_output and allocate the remaining (<546sats) to fees for utxo in unspent: txin = TxInput(utxo['txid'], utxo['vout']) tx_input_data[utxo['txid']] = utxo['amount'] tx_inputs.append(txin) inputs_amount += utxo['amount'] # currently bitcoin lib requires explicit instantiation; made method to # check this; update if/when the library fixes/automates this change_script_out = None if is_addr_bech32: change_script_out = P2wpkhAddress( conf.issuing_address).to_script_pub_key() else: change_script_out = P2pkhAddress( conf.issuing_address).to_script_pub_key() change_output = TxOutput(to_satoshis(inputs_amount), change_script_out) op_return_output = TxOutput( to_satoshis(0), Script(['OP_RETURN', op_return_cert_protocol])) tx_outputs = [change_output, op_return_output] tx = Transaction(tx_inputs, tx_outputs, has_segwit=is_addr_bech32) # sign transaction to get its size r = proxy.signrawtransactionwithwallet(tx.serialize()) if r['complete'] == None: if interactive: sys.exit("Transaction couldn't be signed by node") else: raise RuntimeError("Transaction couldn't be signed by node") signed_tx = r['hex'] signed_tx_size = proxy.decoderawtransaction(signed_tx)['vsize'] # calculate fees and change in satoshis tx_fee = signed_tx_size * conf.tx_fee_per_byte change_amount = to_satoshis(inputs_amount) - tx_fee # the default Bitcoin (and litecoin) Core node doesn't allow the creation of dust # UTXOs https://bitcoin.stackexchange.com/questions/10986/what-is-meant-by-bitcoin-dust # if change is less than 546 (2940 for litecoin) satoshis that is considered dust # (with the default node parameters) then include another UTXO if conf.blockchain == 'litecoin': if change_amount >= 3000: break else: if change_amount >= 550: break if (change_amount < 0): if interactive: sys.exit( "Specified address cannot cover the transaction fee of: {} satoshis" .format(tx_fee)) else: raise RuntimeError( "insufficient satoshis, cannot create transaction") # update tx out for change and re-sign tx.outputs[0].amount = change_amount return tx.serialize(), conf.issuing_address, tx_input_data
def test_signed_low_s_SIGALL_tx_1_input_2_outputs(self): tx = Transaction([self.txin], [self.txout, self.change_low_s_txout]) sig = self.sk.sign_input( tx, 0, self.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.core_tx_signed_low_s_SIGALL_result)