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 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('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_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 revoke_address(conf, interactive=False): if(conf.blockchain == 'litecoin'): from litecoinutils.setup import setup from litecoinutils.keys import P2pkhAddress, P2wpkhAddress from litecoinutils.utils import is_address_bech32 else: from bitcoinutils.setup import setup from bitcoinutils.keys import P2pkhAddress, P2wpkhAddress from bitcoinutils.utils import is_address_bech32 # initialize full node connection if(conf.testnet): setup('testnet') else: setup('mainnet') if(is_address_bech32(conf.issuing_address)): address = P2wpkhAddress(conf.issuing_address).to_hash160() else: address = P2pkhAddress(conf.issuing_address).to_hash160() op_return_bstring = cred_protocol.revoke_address_cmd(address) revoked_txid = publish_hash.issue_op_return(conf, op_return_bstring) if interactive: print('\nTx hash: {}'.format(revoked_txid)) else: return revoked_txid
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 setUp(self): setup('testnet') # values for testing create non std tx self.txin = TxInput( "e2d08a63a540000222d6a92440436375d8b1bc89a2638dc5366833804287c83f", 1) self.to_addr = P2pkhAddress('msXP94TBncQ9usP6oZNpGweE24biWjJs2d') self.sk = PrivateKey( 'cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA') self.txout = TxOutput(to_satoshis(0.9), Script(['OP_ADD', 'OP_5', 'OP_EQUAL'])) self.change_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r') self.change_txout = TxOutput(to_satoshis(2), self.change_addr.to_script_pub_key()) self.create_non_std_tx_result = '02000000013fc8874280336836c58d63a289bcb1d87563434024a9d622020040a5638ad0e2010000006a47304402201febc032331342baaece4b88c7ab42d7148c586b9a48944cbebde95636ac7424022018f0911a4ba664ac8cc21457a58e3a1214ba92b84cb60e57f4119fe655b3a78901210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff02804a5d05000000000393558700c2eb0b000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00000000' # values for testing create non std tx self.txin_spend = TxInput( "4d9a6baf45d4b57c875fe83d5e0834568eae4b5ef6e61d13720ef6685168e663", 0) self.txin_spend.script_sig = Script(['OP_2', 'OP_3']) self.txout_spend = TxOutput(to_satoshis(0.8), self.change_addr.to_script_pub_key()) self.spend_non_std_tx_result = '020000000163e6685168f60e72131de6f65e4bae8e5634085e3de85f877cb5d445af6b9a4d00000000025253ffffffff0100b4c404000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00000000'
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') # 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') # 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') # # 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 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_creation_address(self): a1 = P2pkhAddress.from_address(self.address) self.assertEqual(a1.to_hash160(), self.hash160) a2 = P2pkhAddress.from_address(self.addressc) self.assertEqual(a2.to_hash160(), self.hash160c)
def test_creation_hash(self): a1 = P2pkhAddress.from_hash160(self.hash160) self.assertEqual(a1.to_string(), self.address) a2 = P2pkhAddress.from_hash160(self.hash160c) self.assertEqual(a2.to_string(), self.addressc)
def validate_certificate(cert, issuer_identifier, blockchain_services): filename = os.path.basename(cert) tmp_filename = '__' + filename shutil.copy(cert, tmp_filename) # returned proof can be ignored here but could compare with proof later on issuer_address, _ = get_issuer_address_and_proof(tmp_filename) proof = get_and_remove_chainpoint_proof(tmp_filename) if proof == None: return False, "no chainpoint_proof in metadata" # get the hash after removing the metadata filehash = '' with open(tmp_filename, 'rb') as pdf_file: filehash = hashlib.sha256(pdf_file.read()).hexdigest() # instantiate chainpoint object cp = ChainPointV2() chain, testnet, txid = get_chain_testnet_txid_from_chainpoint_proof( proof, issuer_address) # make request to get txs regarding this address # issuance is the first element of data_before_issuance data_before_issuance, data_after_issuance = \ network_utils.get_all_op_return_hexes(issuer_address, txid, blockchain_services, chain, testnet) # validate receipt valid, reason = cp.validate_receipt(proof, data_before_issuance[0], filehash, issuer_identifier) # display error except when the certificate expired; this is because we want # revoked certificate error to be displayed before cert expired error # TODO clean hard-coded reason if not valid and not reason.startswith("certificate expired"): return False, reason # load apropriate blockchain libraries if (chain == 'litecoin'): from litecoinutils.setup import setup from litecoinutils.keys import P2pkhAddress, P2wpkhAddress, PublicKey from litecoinutils.utils import is_address_bech32 else: from bitcoinutils.setup import setup from bitcoinutils.keys import P2pkhAddress, P2wpkhAddress, PublicKey from litecoinutils.utils import is_address_bech32 # set appropriate network (required for addr->pkh in revoke address) if testnet: setup('testnet') else: setup('mainnet') # check if cert's issuance is after a revoke address cmd on that address # and if yes then the issuance is invalid (address was revoked) # we check before checking for cert revocations since if the issuance was # after an address revocation it should show that as an invalid reason # 0 index is the actual issuance -- ignore it for i in range(len(data_before_issuance))[1:]: cred_dict = cred_protocol.parse_op_return_hex(data_before_issuance[i]) if cred_dict: if cred_dict['cmd'] == cred_protocol.hex_op('op_revoke_address'): if (is_address_bech32(issuer_address)): issuer_pkh = P2wpkhAddress(issuer_address).to_hash160() else: issuer_pkh = P2pkhAddress(issuer_address).to_hash160() if issuer_pkh == cred_dict['data']['pkh']: return False, "address was revoked" # check if cert or batch was revoked from oldest to newest for op_return in reversed(data_after_issuance): cred_dict = cred_protocol.parse_op_return_hex(op_return) if cred_dict: if cred_dict['cmd'] == cred_protocol.hex_op('op_revoke_batch'): if txid == cred_dict['data']['txid']: return False, "batch was revoked" elif cred_dict['cmd'] == cred_protocol.hex_op('op_revoke_creds'): if txid == cred_dict['data']['txid']: # compare the certificate hash bytes filehash_bytes = utils.hex_to_bytes(filehash) ripemd_filehash = utils.ripemd160(filehash_bytes) ripemd_hex = utils.bytes_to_hex(ripemd_filehash) if ripemd_hex == cred_dict['data']['hashes'][0]: return False, "cert hash was revoked" if len(cred_dict['data']['hashes']) > 1: if ripemd_hex == cred_dict['data']['hashes'][1]: return False, "cert hash was revoked" elif cred_dict['cmd'] == cred_protocol.hex_op('op_revoke_address'): # if address revocation is found stop looking since all other # revocations will be invalid if (is_address_bech32(issuer_address)): issuer_pkh = P2wpkhAddress(issuer_address).to_hash160() else: issuer_pkh = P2pkhAddress(issuer_address).to_hash160() if issuer_pkh == cred_dict['data']['pkh']: break # if not revoked but not valid this means that it was expired; now that we # checked for revocations we can show the expiry error if not valid: return False, reason # now that the issuer (anchoring) was validated validate the certificate # with the owner's public key (vpdf v2) # get owner and owner_proof removing the latter owner, owner_proof = get_owner_and_remove_owner_proof(tmp_filename) if owner: # get public key pk = PublicKey.from_hex(owner['pk']) # get file hash sha256_hash = None with open(tmp_filename, 'rb') as pdf: sha256_hash = hashlib.sha256(pdf.read()).hexdigest() # finally check if owner signature is valid #print(pk.get_address().to_string(), pk.to_hex(), sha256_hash, owner_proof) try: if (pk.verify(owner_proof, sha256_hash)): pass except Exception: #BadSignatureError: return False, 'owner signature could not be validated' finally: # cleanup os.remove(tmp_filename) else: # cleanup now that we know it validated os.remove(tmp_filename) # in a valid credential the reason could contain an expiry date return True, reason
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 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())