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 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_p2pkh_and_p2wpkh_to_p2pkh(self): tx = Transaction([self.txin_spend_p2pkh, self.txin_spend_p2wpkh], [self.txout3], has_segwit=True,witnesses = []) # 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.append(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 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('tb1qlffsz7cgzmyzhklleu97afru7vwjytux4z4zsl') 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 create_HODL_address(key, lock, is_priv=False): setup(os.getenv("BUY_LAMBO_BTC_NET", "regtest")) # Get public key (given or found from private key) public_key = PrivateKey(key).get_public_key() if is_priv else PublicKey(key) # Get address from public key address_from_key = public_key.get_address() # Set lock sequence prefix seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, lock) # create the redeem script - needed to sign the transaction redeem_script = Script( [ seq.for_script(), "OP_CHECKLOCKTIMEVERIFY", "OP_DROP", "OP_DUP", "OP_HASH160", address_from_key.to_hash160(), "OP_EQUALVERIFY", "OP_CHECKSIG", ] ) # create a P2SH address from a redeem script addr = P2shAddress.from_script(redeem_script) print("Time-locked address: {}".format(addr.to_string()))
def getTxStateLockScript(T: int, delta: int, pubkey_pay_right: PublicKey, pubkey_mulsig_left: PublicKey, pubkey_mulsig_right: PublicKey) -> Script: """ tx_state lock script encodes possibilities to either refund locked coins to left or pay to right :param T: locked funds can pe paid after this time wherever right user wants :param delta: upper bound on time for transaction to be confirmed by the network :param pubkey_pay_right: public key owned by right user for payment after time T :param pubkey_mulsig_left: public key owned by left user for refund if enable-refund tx is published :param pubkey_mulsig_right: public key owned by right user for refund if enable-refund tx is published :return: tx_state lock script """ # signature script: # - for refund (with enable-refund tx + ∆): "OP_0 <left_signature> <right_signature>" # - for payment (time() >= T): "<signature_right> <pubkey_right> OP_0 OP_0 OP_0 OP_0 OP_0 OP_0" lock_script = Script([ 'OP_2', pubkey_mulsig_left.to_hex(), pubkey_mulsig_right.to_hex(), 'OP_2', 'OP_CHECKMULTISIG', 'OP_IF', delta, 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP', 'OP_TRUE', # check if refund and lock for ∆ 'OP_ELSE', T, 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160', pubkey_pay_right.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG', # check if payment 'OP_ENDIF' ]) return lock_script
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 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_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(Decimal('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('regtest') # # This script creates a P2SH address containing a # CHECKLOCKTIMEVERIFY plus a P2PKH locking funds with a key # until a certain block_height is reached # # set values block_height = 140 seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, block_height) # secret key corresponding to the pubkey needed for the P2SH (P2PKH) transaction p2pkh_sk = PrivateKey('cSbKZh6a6wNUAQ8pr2KLKeZCQ4eJnFmN35wtReaoU4kCP97XQu6W') # 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_CHECKLOCKTIMEVERIFY', '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 main(): #Connect to the regtest setup('regtest') proxy = NodeProxy('user', 'bitcoin').get_proxy() #Accept a Public Key from User and derive a P2PKH address from it pk = PublicKey.from_hex(input('Please input your Public Key\n')) pk_p2pkh_addr = pk.get_address() #Accept future absolute block amount from User current_blocks = proxy.getblockcount() absolute_blocks = int( input( f'\nPlease input the future block height. The current block height is: {current_blocks}\n' )) #Set the timelock sequence and create a redeemScript accordingly redeem_script = Script([ absolute_blocks, 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160', pk_p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]) #Generate a P2SH Address from the redeemScript and show it p2sh_addr = P2shAddress.from_script(redeem_script) print( f'\nThe P2SH Address is:\n{p2sh_addr.to_string()} Now, go on and send some funds to it.\n' )
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 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 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( 0.9, Script(['OP_ADD', 'OP_5', 'OP_EQUAL']) ) self.change_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r') self.change_txout = TxOutput( 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( 0.8, self.change_addr.to_script_pub_key()) self.spend_non_std_tx_result = '020000000163e6685168f60e72131de6f65e4bae8e5634085e3de85f877cb5d445af6b9a4d00000000025253ffffffff0100b4c404000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00000000'
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_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)
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 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']) #TODELETE #txin_script_pub_key = redeem_script.to_p2sh_script_pub_key() to_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR') txout = TxOutput(Decimal('0.08'), 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_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 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)