예제 #1
0
    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'
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
def send_to_p2wpkh(amount_to_send, fee):
    transaction = Transaction([], [])
    addr = BOB.public_key.get_segwit_address()
    from_addr = P2pkhAddress(BOB.public_key.get_address().to_string())
    print(from_addr.to_hash160())
    for i in range(len(utxos)):
        txin = TxInput(utxos[i][0], utxos[i][1])
        # sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')
        # print(sk.get_public_key().get_address().to_string())
        # print(alice_public_key_BTC.get_address().to_string())
        transaction.inputs.append(txin)
    for i in range(0, 10):
        txout = TxOutput(to_satoshis((amount_to_send - fee) / 10),
                         addr.to_script_pub_key())
        transaction.outputs.append(txout)
        # txout = TxOutput(to_satoshis(0.425/2), POOL.p2pkh_script_pubkey("btc-test3"))
        # transaction.outputs.append(txout)
    for i in range(len(utxos)):
        sig = BOB.secret_key.sign_input(
            transaction, i,
            Script([
                'OP_DUP', 'OP_HASH160',
                from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
            ]))
        transaction.inputs[i].script_sig = Script([
            sig, BOB.public_key.to_hex()
        ])  # , BOB.p2pkh_script_pubkey().to_hex()])
        # transaction = Transaction([txin], [txout])

    # print(txin.script_sig.to_bytes())
    return transaction
예제 #5
0
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 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())
예제 #7
0
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())
예제 #8
0
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 setUp(self):
        setup('testnet')
        self.sk1 = PrivateKey.from_wif("cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo")
        self.sk2 = PrivateKey.from_wif("cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9")

        # 2-2 Multi-sign Script
        self.p2wsh_script = Script(['OP_2', self.sk1.get_public_key().to_hex(), self.sk2.get_public_key().to_hex(),
                                    'OP_2', 'OP_CHECKMULTISIG'])

        # tb1q89t0jucv7un4qq85u0a0tkc9qkepvg3vra72r00msx58wqplewfsfrlunx
        self.p2wsh_addr = P2wshAddress.from_script(self.p2wsh_script)

        # n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR
        self.p2pkh_addr = self.sk1.get_public_key().get_address()

        # P2PKH to P2WSH
        self.txin1 = TxInput("6e9a0692ed4b3328909d66d41531854988dc39edba5df186affaefda91824e69", 0)
        self.txout1 = TxOutput(to_satoshis(0.0097), self.p2wsh_addr.to_script_pub_key())

        # P2WSH to P2PKH
        self.txin_spend = TxInput("6233aca9f2d6165da2d7b4e35d73b039a22b53f58ce5af87dddee7682be937ea", 0)
        self.txin_spend_amount = to_satoshis(0.0097)
        self.txout2 = TxOutput(to_satoshis(0.0096), self.p2pkh_addr.to_script_pub_key())
        self.p2wsh_redeem_script = self.p2wsh_script

        # Multiple input multiple output
        # P2PKH UTXO
        self.txin1_multiple = TxInput("24d949f8c77d7fc0cd09c8d5fccf7a0249178c16170c738da19f6c4b176c9f4b", 0)
        self.txin1_multiple_amount = to_satoshis(0.005)
        # P2WSH UTXO
        self.txin2_multiple = TxInput("65f4d69c91a8de54dc11096eaa315e84ef91a389d1d1c17a691b72095100a3a4", 0)
        self.txin2_multiple_amount = to_satoshis(0.0069)
        # P2WPKH UTXO
        self.txin3_multiple = TxInput("6c8fc6453a2a3039c2b5b55dcc59587e8b0afa52f92607385b5f4c7e84f38aa2", 0)
        self.txin3_multiple_amount = to_satoshis(0.0079)

        self.output1_multiple = TxOutput(to_satoshis(0.001), self.p2wsh_addr.to_script_pub_key())
        self.output2_multiple = TxOutput(to_satoshis(0.001), self.sk1.get_public_key().get_segwit_address().to_script_pub_key())
        self.output3_multiple = TxOutput(to_satoshis(0.0177), self.p2pkh_addr.to_script_pub_key())

        # result
        self.create_send_to_p2pkh_result = "0200000001694e8291daeffaaf86f15dbaed39dc8849853115d4669d9028334bed92069a6e000000006a473044022038516db4e67c9217b871c690c09f60a57235084f888e23b8ac77ba01d0cba7ae022027a811be50cf54718fc6b88ea900bfa9c8d3e218208fef0e185163e3a47d9a08012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0110cd0e00000000002200203956f9730cf7275000f4e3faf5db0505b216222c1f7ca1bdfb81a877003fcb9300000000"
        self.spend_p2pkh_result = "02000000000101ea37e92b68e7dedd87afe58cf5532ba239b0735de3b4d7a25d16d6f2a9ac33620000000000ffffffff0100a60e00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac040047304402205c88b6c247c6b59e1cc48493b66629b6c011d97b99ecf991b595e891542cf1a802204fa0e3c238818a65adc87a0b2511ba780e4b57ff6c1ba6b27815b1dca7b72c1c01483045022100cec7df71d36a37b979b693c9408ddc1f63325654566fd1b4ee7b6fc18ec601e502203ed5a2c68096d403686cf60b6c1d740b8ae254ec94fc4c35d54f70e4c59a28340147522102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a5462103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af3270852ae00000000"
        self.multiple_input_multiple_ouput_result = "020000000001034b9f6c174b6c9fa18d730c17168c1749027acffcd5c809cdc07f7dc7f849d924000000006a47304402206932c93458a6ebb85f9fd6f69666cd383a3b8c8d517a096501438840d90493070220544d996a737ca9affda3573635b09e215be1ffddbee9b1260fc3d85d61d90ae5012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffffa4a3005109721b697ac1d1d189a391ef845e31aa6e0911dc54dea8919cd6f4650000000000ffffffffa28af3847e4c5f5b380726f952fa0a8b7e5859cc5db5b5c239302a3a45c68f6c0000000000ffffffff03a0860100000000002200203956f9730cf7275000f4e3faf5db0505b216222c1f7ca1bdfb81a877003fcb93a086010000000000160014fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a10021b00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac000400483045022100ff3d84fea8f9ed0f467a4451846a834f94ee00538c5f70637540b8d3ec762e8802204f35aadacaff8e3c5b7d9ba9bb068141f6950feb9da68707249a485f519cbd9d01483045022100b0e1a9f73cb4674d780e24e0a1a7dc96719ce119eb2df2804653990ae2ca32e402203398b490e9caa872463191ba7a4ae84845a94d3b4025ee845491a9f71ea623390147522102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a5462103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af3270852ae024730440220733fcbd21517a1559e9561668e480ffd0a24b62520cfa16ca7689b20f7f82be402204f053a27f19e0bd1346676c74c65e9e452515bc6510ab307ac3a3fb6d3c89ca7012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54600000000"
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(
        "tb1qtstf97nhk2gycz7vl37esddjpxwt3ut30qp5pn")

    # 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())
예제 #11
0
def split_funds():
    setup.setup('testnet')
    id_in = Id(
        'a8fac854dc0fea70c7a7fe94bbf013195c7eef83e2052b01a55d8cf5f08cfa53')
    tx_input = TxInput(
        '98ebd3a3455cc907f29919713fa1799a2d9d60168f5fb1ae94074b1a8078100e', 4)

    id1 = Id(
        '616c26241bb007883f13aff556bb07d28374b52b81aa675f30dcf35c04103da4')
    id2 = Id(
        'f74b11ae3ca8d2c2d0424296f0de316198b4fda2ca984b5e3c6681abd2c72b2c')
    id3 = Id(
        'f2b019b04121adca7b6541a08761454b14ffd705248a51e7f3b6cfbf64f2b26b')
    id4 = Id(
        '89270091320614b25f88b84497ff4e4a017cbf1d25c1462b1352ea44f45708db')
    out1 = TxOutput(to_satoshis(0.0000115), id1.p2pkh)
    out2 = TxOutput(to_satoshis(0.0000115), id2.p2pkh)
    out3 = TxOutput(to_satoshis(0.0000115), id3.p2pkh)
    out4 = TxOutput(to_satoshis(0.0000115), id4.p2pkh)

    tx = Transaction([tx_input], [out1, out2, out3, out4])
    sign = id_in.private_key.sign_input(tx, 0, id_in.p2pkh)
    tx_input.script_sig = Script([sign, id_in.public_key.to_hex()])
    print_tx(tx)
예제 #12
0
    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 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)
예제 #14
0
 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')

    #
    # 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(to_satoshis(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 main():
    # always remember to setup the network
    setup('regtest')

    # create transaction input from tx id of UTXO (contained 0.4 tBTC)
    txin = TxInput(
        '4d9a6baf45d4b57c875fe83d5e0834568eae4b5ef6e61d13720ef6685168e663', 0)
    # provide unlocking script
    # note that no signing is required to unlock: OP_ADD OP_5 OP_EQUAL
    txin.script_sig = Script(['OP_2', 'OP_3'])

    # create transaction output using P2PKH scriptPubKey (locking script)
    addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r')
    # locking script expects 2 numbers that when added equal 5 (silly example)
    txout = TxOutput(to_satoshis(0.8), addr.to_script_pub_key())

    # create transaction from inputs/outputs -- default locktime is used
    tx = Transaction([txin], [txout])

    # print raw transaction
    print("\nRaw transaction:\n" + tx.serialize())
def main():
    setup('testnet')

    txin = TxInput(
        '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 0)

    from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')

    print("From Address  : ", from_addr)

    sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')

    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())

    tx = Transaction([txin], [txout])

    print("Raw transaction", tx.serialize())
예제 #18
0
    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'
utxos = {}
funds = Decimal(0)
txids = proxy.listreceivedbyaddress( 0, True, True, from_p2sh.to_string() )[0]['txids']

for txid in txids:
	tx = proxy.gettransaction( txid )
	utxos[txid] = tx
	amount = tx['amount']
	funds -= amount

	print( " utxo tx id: " + str(txid) )
	print( tx )
	print( "utxo amount: " + str(amount) )

funds = int(to_satoshis( funds ))
if funds == 0:
	print( "no funds" )
	exit
print( "      funds: " + str(funds) + " satoshis" )


#
#  4) accept a P2PKH address to send the funds to
#

to_privkey = PrivateKey()
to_pubkey  = to_privkey.get_public_key()
to_address = to_pubkey.get_address()

print( "destination: " + to_address.to_string() )
예제 #20
0
    def setUp(self):
        setup('testnet')
        self.sk = PrivateKey.from_wif(
            "cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo")
        # n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR
        self.p2pkh_addr = self.sk.get_public_key().get_address()

        # tb1ql5eh45als8sgdkt2drsl344q55g03sj2krzqe3
        self.p2wpkh_addr = self.sk.get_public_key().get_segwit_address()

        # P2PKH to P2WPKH
        self.txin1 = TxInput(
            "5a7b3aaa66d6b7b7abcdc9f1d05db4eee94a700297a319e19454e143875e1078",
            0)
        self.txout1 = TxOutput(to_satoshis(0.0099),
                               self.p2wpkh_addr.to_script_pub_key())

        # P2WPKH to P2PKH
        self.txin_spend = TxInput(
            "b3ca1c4cc778380d1e5376a5517445104e46e97176e40741508a3b07a6483ad3",
            0)
        self.txin_spend_amount = to_satoshis(0.0099)
        self.txout2 = TxOutput(to_satoshis(0.0098),
                               self.p2pkh_addr.to_script_pub_key())
        self.p2pkh_redeem_script = Script([
            'OP_DUP', 'OP_HASH160',
            self.p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ])

        # P2WPKH P2PKH to P2PKH
        self.txin_spend_p2pkh = TxInput(
            "1e2a5279c868d61fb2ff0b1c2b04aa3eff02cd74952a8b4e799532635a9132cc",
            0)
        self.txin_spend_p2pkh_amount = to_satoshis(0.01)

        self.txin_spend_p2wpkh = TxInput(
            "fff39047310fbf04bdd0e0bc75dde4267ae4d25219d8ad95e0ca1cee907a60da",
            0)
        self.txin_spend_p2wpkh_amount = to_satoshis(0.0095)

        self.txout3 = TxOutput(to_satoshis(0.0194),
                               self.p2pkh_addr.to_script_pub_key())

        # SIGHASH NONE type send
        self.txin1_signone = TxInput(
            "fb4c338a00a75d73f9a6bd203ed4bd8884edeb111fac25a7946d5df6562f1942",
            0)
        self.txin1_signone_amount = to_satoshis(0.01)

        self.txout1_signone = TxOutput(to_satoshis(0.0080),
                                       self.p2pkh_addr.to_script_pub_key())
        self.txout2_signone = TxOutput(to_satoshis(0.0019),
                                       self.p2pkh_addr.to_script_pub_key())

        # SIGHASH SINGLE type send
        self.txin1_sigsingle = TxInput(
            "b04909d4b5239a56d676c1d9d722f325a86878c9aa535915aa0df97df47cedeb",
            0)
        self.txin1_sigsingle_amount = to_satoshis(0.0193)

        self.txout1_sigsingle = TxOutput(to_satoshis(0.01),
                                         self.p2pkh_addr.to_script_pub_key())
        self.txout2_sigsingle = TxOutput(to_satoshis(0.0092),
                                         self.p2pkh_addr.to_script_pub_key())

        # SIGHASH_ALL | SIGHASH_ANYONECANPAY type send
        self.txin1_siganyonecanpay_all = TxInput(
            "f67e97a2564dceed405e214843e3c954b47dd4f8b26ea48f82382f51f7626036",
            0)
        self.txin1_siganyonecanpay_all_amount = to_satoshis(0.0018)

        self.txin2_siganyonecanpay_all = TxInput(
            "f4afddb77cd11a79bed059463085382c50d60c7f9e4075d8469cfe60040f68eb",
            0)
        self.txin2_siganyonecanpay_all_amount = to_satoshis(0.0018)

        self.txout1_siganyonecanpay_all = TxOutput(
            to_satoshis(0.0018), self.p2pkh_addr.to_script_pub_key())
        self.txout2_siganyonecanpay_all = TxOutput(
            to_satoshis(0.0017), self.p2pkh_addr.to_script_pub_key())

        # SIGHASH_NONE | SIGHASH_ANYONECANPAY type send
        self.txin1_siganyonecanpay_none = TxInput(
            "d2ae5d4a3f390f108769139c9b5757846be6693b785c4e21eab777eec7289095",
            0)
        self.txin1_siganyonecanpay_none_amount = to_satoshis(0.009)

        self.txin2_siganyonecanpay_none = TxInput(
            "ee5062d426677372e6de96e2eb47d572af5deaaef3ef225f3179dfa1ece3f4f5",
            0)
        self.txin2_siganyonecanpay_none_amount = to_satoshis(0.007)

        self.txout1_siganyonecanpay_none = TxOutput(
            to_satoshis(0.008), self.p2pkh_addr.to_script_pub_key())
        self.txout2_siganyonecanpay_none = TxOutput(
            to_satoshis(0.007), self.p2pkh_addr.to_script_pub_key())

        # SIGHASH_SINGLE | SIGHASH_ANYONECANPAY type send
        self.txin1_siganyonecanpay_single = TxInput(
            "c7bb5672266c8a5b64fe91e953a9e23e3206e3b1a2ddc8e5999b607b82485042",
            0)
        self.txin1_siganyonecanpay_single_amount = to_satoshis(0.01)

        self.txout1_siganyonecanpay_single = TxOutput(
            to_satoshis(0.005), self.p2pkh_addr.to_script_pub_key())
        self.txout2_siganyonecanpay_single = TxOutput(
            to_satoshis(0.0049), self.p2pkh_addr.to_script_pub_key())

        # result
        self.create_send_to_p2wpkh_result = "020000000178105e8743e15494e119a39702704ae9eeb45dd0f1c9cdabb7b7d666aa3a7b5a000000006b4830450221009ad68e1ecdd38d6abe515a52582a441a56f0fedb21816eb2f583183685da2eb502203c4fc7522ad7ab0c1854180cfd337e484ad3ba70d23bcf4380c6e2ff4e6e7985012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff01301b0f0000000000160014fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a00000000"
        self.spend_p2pkh_result = "02000000000101d33a48a6073b8a504107e47671e9464e10457451a576531e0d3878c74c1ccab30000000000ffffffff0120f40e00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac0247304402201c7ec9b049daa99c78675810b5e36b0b61add3f84180eaeaa613f8525904bdc302204854830d463a4699b6d69e37c08b8d3c6158185d46499170cfcc24d4a9e9a37f012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54600000000"
        self.p2pkh_and_p2wpkh_to_p2pkh_result = "02000000000102cc32915a633295794e8b2a9574cd02ff3eaa042b1c0bffb21fd668c879522a1e000000006a47304402200fe842622e656a6780093f60b0597a36a57481611543a2e9576f9e8f1b34edb8022008ba063961c600834760037be20f45bbe077541c533b3fd257eae8e08d0de3b3012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffffda607a90ee1ccae095add81952d2e47a26e4dd75bce0d0bd04bf0f314790f3ff0000000000ffffffff01209a1d00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac00024730440220274bb5445294033a36c360c48cc5e441ba8cc2bc1554dcb7d367088ec40a0d0302202a36f6e03f969e1b0c582f006257eec8fa2ada8cd34fe41ae2aa90d6728999d1012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54600000000"
        self.test_signone_send_result = "0200000000010142192f56f65d6d94a725ac1f11ebed8488bdd43e20bda6f9735da7008a334cfb0000000000ffffffff0200350c00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac30e60200000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac02483045022100d3e7d4fceb7cded91f5d09ef192b5308d325ead1047ee5972a62747b8a937da502205e6bdeebe048f7923be75e36b6d39a78891fccbf0084ac1445f27a77261a13c2022102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54600000000"
        self.test_sigsingle_send_result = "02000000000101ebed7cf47df90daa155953aac97868a825f322d7d9c176d6569a23b5d40949b00000000000ffffffff0240420f00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88acc0090e00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac02483045022100e315efea11d21b0819425f164751e4bbdd20f7fee8b0ee949da466ee013b73b7022048cb056d4823272518023222b39cdead68dc3a9b1e60aae37a8dd5a5108d2a62032102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54600000000"
        self.test_siganyonecanpay_all_send_result = "02000000000102366062f7512f38828fa46eb2f8d47db454c9e34348215e40edce4d56a2977ef60000000000ffffffffeb680f0460fe9c46d875409e7f0cd6502c3885304659d0be791ad17cb7ddaff40000000000ffffffff0220bf0200000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac10980200000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac02483045022100b963e68c5d133c16c0bb9cdf82c2ace5acd5c03fc03a4572699ac2712bbe772202202075cf8e35d4093e71635c49844a009a16ff08b9ee2ff5876ef2f3bd17b93c63812102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a5460247304402206fb60dc79b5ca6c699d04ec96c4f196938332c2909fd17c04023ebcc7408f36e02202b071771a58c84e20b7bf1fcec05c0ef55c1100436a055bfcb2bf7ed1c0683a9012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54600000000"
        self.test_siganyonecanpay_none_send_result = "02000000000102959028c7ee77b7ea214e5c783b69e66b8457579b9c136987100f393f4a5daed20000000000fffffffff5f4e3eca1df79315f22eff3aeea5daf72d547ebe296dee672736726d46250ee0000000000ffffffff0200350c00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac60ae0a00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac0247304402203bbcbd2003244e9ccde7f705d3017f3baa2cb2d47efb63ede7e39704eff3987702206932aa4b402de898ff2fd3b2182f344dc9051b4c326dacc07b1e59059042f3ad822102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54602483045022100bd00b75aaefc0ab139f44b5347a8159d7158ae911bbf5a76f7fe1b93e2b0f1d50220724189279c0c497e15b4e3e1d1291f0b15e3dc460e8b2adf8597dbbd3af32440012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54600000000"
        self.test_siganyonecanpay_single_send_result = "02000000000101425048827b609b99e5c8dda2b1e306323ee2a953e991fe645b8a6c267256bbc70000000000ffffffff0220a10700000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac107a0700000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac02483045022100ff22bf77115243a01f1c39eca2d3a222e1e176d272b3eab561b6d625af0ee21a0220520b07b72ba5ab11f33a0ed921aac29a05ad09cc65107f3931a25711679562b0832102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a54600000000"
예제 #21
0
def spend_p2sh_cltv_p2pkh(proxy, block_height, sender_priv_key, p2sh_addr,
                          rec_addr):
    """
    Spends funds from a P2SH address with an absolute locktime to a P2PKH receiver address.
    :param proxy: JSON RPC proxy for connecting to the network.
    :param block_height: Block height the lock is valid for.
    :param sender_priv_key: Private key of the address locking the funds.
    :param p2sh_addr: P2SH address containing the funds.
    :param rec_addr: P2PKH address receiving the funds.
    """

    # mine 100 blocks and send bitcoin to the P2SH address
    proxy.generatetoaddress(100, p2sh_addr)
    # mine 100 blocks to make mined bitcoin spendable, emulates 'bitcoin-cli -generate 100'
    for _ in range(100):
        proxy.generatetoaddress(1, proxy.getnewaddress())

    # retrieve unspent UTXOs for the P2SH address
    p2sh_addr_unspent = proxy.listunspent(0, 99999999, [p2sh_addr])

    # create absolute-block locking sequence for the transaction inputs
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, block_height)

    # create transaction inputs for unspent UTXOs
    # and calculate the total unspent bitcoins they contain
    tx_inputs = []
    total_unspent = 0
    for utxo in p2sh_addr_unspent:
        tx_inputs.append(
            TxInput(utxo['txid'],
                    utxo['vout'],
                    sequence=seq.for_input_sequence()))
        total_unspent += utxo['amount']
    print("Unspent bitcoin in address {} : {}".format(p2sh_addr,
                                                      total_unspent))

    # get the public key of the receiving address for the funds to be sent to
    rec_pub_key = proxy.getaddressinfo(rec_addr)['pubkey']
    rec_pk = PublicKey(rec_pub_key)

    # calculate fee
    satoshis_per_kb = requests \
        .get('https://api.blockcypher.com/v1/btc/test3') \
        .json()['medium_fee_per_kb']
    # formula: |inputs| * 180 + 34 * |outputs| +- |inputs|
    tx_size = len(tx_inputs) * 180 + 34 * 1 + 10 + len(tx_inputs)
    # we calculate fees in terms of bitcoin
    fee = (tx_size / 1024) * (satoshis_per_kb / 10e8)

    # create the transaction output
    tx_output = TxOutput(to_satoshis(Decimal(total_unspent) - Decimal(fee)),
                         rec_pk.get_address().to_script_pub_key())
    # set a lock time in blocks for the transaction
    lock = Locktime(block_height)
    # create the transaction
    tx = Transaction(tx_inputs, [tx_output], lock.for_transaction())
    unsigned_tx = tx.serialize()
    print('Raw unsigned transaction:', unsigned_tx)

    # we need to rebuild the redeem script from the P2SH private key
    # make the locking P2PKH address private key
    sender_sk = PrivateKey(sender_priv_key)
    # retrieve the public key of the locking address
    sender_pk = sender_sk.get_public_key()
    # rebuild the redeem script
    redeem_script = Script([
        seq.for_script(), 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        sender_pk.get_address().to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # for every input of the transaction
    for i, txin in enumerate(tx.inputs):
        # create the signature for redeeming the funds
        sig = sender_sk.sign_input(tx, i, redeem_script)
        # and sign the input
        txin.script_sig = Script(
            [sig, sender_pk.to_hex(),
             redeem_script.to_hex()])

    signed_tx = tx.serialize()
    print('Raw signed transaction:', signed_tx)
    print('Transaction ID:', tx.get_txid())

    # verify that the transaction is valid
    ver = proxy.testmempoolaccept([signed_tx])
    if ver[0]['allowed']:
        # if the transaction is valid send the transaction to the blockchain
        print('Transaction is valid.')
        proxy.sendrawtransaction(signed_tx)
        print('{} Bitcoin sent to address {}'.format(
            Decimal(total_unspent) - Decimal(fee), rec_addr))
    else:
        # otherwise, display the reason the transaction failed
        print('Transaction rejected. Reason:', ver[0]['reject-reason'])
예제 #22
0
def main():

    #Connect to the regtest network
    setup('regtest')
    proxy = NodeProxy('user', 'bitcoin').get_proxy()

    #Accept absolute future block amount User
    current_blocks = proxy.getblockcount()
    absolute_blocks = int(
        input(
            f'\nPlease input the future block height. The current block height is: {current_blocks}.\nIt must match the one in the redeem script from which the P2SH address (with the locked funds) was derived\n'
        ))

    #Accept the Private Key from User
    sk = PrivateKey(
        input(
            '\nPlease enter your Private Key (used to create the address from which the P2SH Address was derived)\n'
        ))

    #Accept the P2SH Address with the funds
    p2sh_addr = input(
        '\nPlease enter the P2SH address which has the locked funds\n')

    #Import the address into the wallet
    proxy.importaddress(f'{p2sh_addr}')
    print(
        f'\nThe P2SH address {p2sh_addr} has been imported into the wallet.\n')

    #Get all UTXOs for this address
    all_utxos = proxy.listunspent(1, 9999999, [f'{p2sh_addr}'])
    print(f'\nAll the UTXO Objects for this address are:\n{all_utxos}\n')

    #Calculate total funds available. Aggregate all UTXO amounts.
    def totalFunds():
        total = Decimal(0)
        for utxo in all_utxos:
            total += Decimal(utxo["amount"])
        return total

    total_funds = totalFunds()
    print("Total funds available: ", total_funds)

    #Instantiate the timelock sequence
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, absolute_blocks)

    #Create an array of inputs from these UTXOs
    def getInputs():
        inputs = []
        count = 0
        for utxo in all_utxos:
            #create inputs and append them into an array
            #First, create an input
            utxo = all_utxos[count]
            txin = TxInput(utxo["txid"],
                           utxo["vout"],
                           sequence=seq.for_input_sequence())
            #then, append it to the array
            inputs.append(txin)
            ++count
        return inputs

    inputs = getInputs()

    print(f'The inputs created from these outputs are:\n {inputs}')

    #Use User's Secret Key (Accepted above) to recreate the Public Key
    pk = sk.get_public_key()

    #We recreate the P2PKH Addr to recreate the other half of the redeemScript
    p2pkh_addr = pk.get_address()

    #We recreate the redeem script
    redeem_script = Script([
        absolute_blocks, 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    #Confirm that the P2SH address is the same one to which funds were sent by receating the P2SH from this redeem script
    addr = P2shAddress.from_script(redeem_script).to_string()
    print(
        f'\nCheck if this is the address with the locked funds:\n{addr} vs what you input above {p2sh_addr}'
    )

    #Accept the receiving P2PKH from User
    destination_addr = P2pkhAddress(
        input(
            '\nPlease enter the address you want to send the locked funds to:\n'
        ))

    #Calculate txn size to estimate fee from inputs only so we subtract it from funds
    tx_test = Transaction(inputs, [],
                          Locktime(absolute_blocks).for_transaction())
    tx_size = tx_test.get_size()
    # 0.0001 is an appropriate fee per byte so we use that
    est_tx_fee = tx_size / 1000 * 0.0001

    #Create a txout transferring total locked funds (minus estimated fees).
    txout = TxOutput(to_satoshis(total_funds - Decimal(est_tx_fee)),
                     destination_addr.to_script_pub_key())

    #Create Txn. Passing in the inputs, output, and the future absolute lock time
    tx = Transaction(inputs, [txout],
                     Locktime(absolute_blocks).for_transaction())

    #Print the newly created txn
    print(f'\nThe raw unsigned txn is: {tx.serialize()}\n')

    #Calulate the Appropriate Transaction Fee According to Txn Size.
    #First, get the fee estimate from network. Useful only for mainnet and testnet.
    def getFee():
        fee = proxy.estimatesmartfee(5, "ECONOMICAL")
        if fee["errors"]:
            print(
                'Network data not enough to calculate fee. Setting default fee: 0.0001 BTC'
            )
            return 0.0001
        else:
            return fee["feerate"]


#Then, calculate the size of our Txn and then multiply it by the per-byte fee

    est_fee = getFee()  #per byte
    tx_size = tx.get_size()
    print(f'\nThe transaction size is:\n{tx_size} bytes')
    tx_fee = tx_size / 1000 * est_fee
    print(f'\nThe recommended fee for this transaction is:\n{tx_fee}')

    #Need to sign all inputs
    def signInputs():
        input_index = 0
        for input in inputs:
            #Use the Secret Key corresponding to the P2SH to create the signature for the txn/ sign all inputs
            #Redeem script is passed to replace the scriptSig
            inputSig = sk.sign_input(tx, input_index, redeem_script)
            input.script_sig = Script(
                [inputSig, pk.to_hex(),
                 redeem_script.to_hex()])
            ++input_index

    signInputs()

    signed_tx = tx.serialize()

    #Print the signed raw txn, ready to be checked for validity
    print(f"\nRaw signed transaction:\n{signed_tx}")
    print(
        f"\nTransaction ready to be broadcast. Transaction Id: {tx.get_txid()}"
    )

    #Test for validity
    isValid = proxy.testmempoolaccept([f'{signed_tx}'])
    print(f'\nTransaction validity check result:\n{isValid}')

    #Broadcast txn
    #needs signed_tx
    if isValid[0]["allowed"]:
        if input('\nSend transaction to network? Y / N: ') == 'Y':
            sent_tx_id = proxy.sendrawtransaction(f'{signed_tx}')
            print(
                f'\n***The transaction with id {sent_tx_id} has been sent to the network***'
            )
        else:
            print(
                f'\nUser decided not to send the funds and exited the program.'
            )
            exit()
    else:
        reason = isValid[0]["reject-reason"]
        print(f'\nThe signed raw transaction is invalid. Reason: {reason}')
def issue_op_return(conf, op_return_bstring, interactive=False):

    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('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_address_bech32 = False
    if (conf.issuing_address.startswith('bc') or
            conf.issuing_address.startswith('tb')):
        is_address_bech32 = True

    # 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 = []
    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_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_address_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_address_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 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 satoshis that is considered dust (with the
        # default node parameters) then include another UTXO
        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
    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']

    # send transaction
    if interactive:
        print('The fee will be {} satoshis.\n'.format(tx_fee))
        consent = input('Do you want to issue on the blockchain? [y/N]: ').lower() in ('y', 'yes')
        if not consent:
            sys.exit()

    tx_id = proxy.sendrawtransaction(signed_tx)

    #end = time.time()
    #print("publish_hash.issue_op_return()", end-start, " seconds")

    return tx_id
예제 #24
0
def main():
    setup.setup('testnet')
    eps = 200  # value owned by each participant in enable-refund transaction. Could be 1 satoshi
    delta = 10  # upper bound for tx to be confirmed
    T = 2100200  # funds for payment locked until this time
    t_channel = 35  # upper bound for closing a channel

    id_in_channel_left = Id('616c26241bb007883f13aff556bb07d28374b52b81aa675f30dcf35c04103da4')
    tx_in_channel_left = TxInput('14c5b01c28a133fb55c03cfd756d70ccdacbdc0229c4a96d49c65c25df53afb5', 0)
    id_in_channel_right = Id('f74b11ae3ca8d2c2d0424296f0de316198b4fda2ca984b5e3c6681abd2c72b2c')
    tx_in_channel_right = TxInput('14c5b01c28a133fb55c03cfd756d70ccdacbdc0229c4a96d49c65c25df53afb5', 1)

    id_channel_left = Id('e6ad38d70bf775e7e74bcd598e9282141dac09f79374565c3ebdf61e4f9ef4ed')
    id_channel_right = Id('a3dbcea1e46edecbd1da13231f385ebe7f2beea382e3f7227c4c00d21b7e8455')

    tx_channel = createOpenChannelTx(tx_in_channel_left, tx_in_channel_right, to_satoshis(0.000009), to_satoshis(0.000009),
                                  id_channel_left.public_key, id_channel_right.public_key)

    tx_channel = signOpenChannelTxLeft(tx_channel, id_in_channel_left)
    tx_channel = signOpenChannelTxRight(tx_channel, id_in_channel_right)
    print_tx(tx_channel, 'tx channel open')
    tx_channel_id = '7b2ff59b6070a70249fd3f06efd1e0944d69597e5871e72098304adae94e7316'

    id_er_in = Id('89270091320614b25f88b84497ff4e4a017cbf1d25c1462b1352ea44f45708db')
    tx_er_input = TxInput('14c5b01c28a133fb55c03cfd756d70ccdacbdc0229c4a96d49c65c25df53afb5', 3)

    id_er_u1 = Id('3223c869874bad6933f14d1bf3bc9354125641e0aef3484dcf313c24a18655c7')
    id_er_u2 = Id('ac54ff9bc498ac9fa15f1e76a670fa0acdc85316fb6a97fc161f3871ab59e3bd')
    id_er_u3 = Id('05b91a17dbe63db245c6a2ba84a9a2b01ed86b494b61cc2dad5a0a44fe6ddc0e')

    tx_er_rel_timelock = t_channel + 2 * delta

    tx_er = createTxER(tx_er_input, [id_er_u1.public_key, id_er_u2.public_key, id_er_u3.public_key], tx_er_rel_timelock, eps)
    signTxER(tx_er, id_er_in)
    print_tx(tx_er, 'tx_er, 3 out')

    tx_er_id = '1e3c3465793126d4115f49750fab61a66c20bfbece436016d00066730704969b'

    id_state_left = Id('ce7bca0ec8d38f945390e64627f4b669eca9afd2bae77d036421ce96b6767728')  # left can receive a - c coins
    id_state_right = Id('ad5813d9719179da0e561aa22295017559b247a3bb325ce438bc8247bf79962e')  # right can receive b coins
    id_refund_mulsig_left = Id('e34d37fdeb88addac291ae0fa084f33490d756d8298e7219b0d4f073616dd251')  # left will receive c coins if publish tx_refund (using tx_er output)
    id_refund_mulsig_right = Id('4d87652d513e0f7a5be51894b7fa862c8ca3ea8ef222f6b6ea7ed6a949f67672') # left will receive c coins if publish tx_refund (using tx_er output)
    id_pay_right = Id('0a08c11255f48d66b0d1dcab0e3b9479a7e1275d078663fde3dc9fd92355e784')  # right will receive c coins after T if publish tx_pay

    tx_state_in = TxInput(tx_channel_id, 0)
    state_lock_script = getTxStateLockScript(T, delta, id_pay_right.public_key,
                             id_refund_mulsig_left.public_key, id_refund_mulsig_right.public_key)

    lock_amount = to_satoshis(0.00000500)
    tx_state = createTxState(tx_state_in, id_state_left.public_key, id_state_right.public_key, id_pay_right.public_key,
                             id_refund_mulsig_left.public_key, id_refund_mulsig_right.public_key,
                             lock_amount, to_satoshis(0.00000300), to_satoshis(0.00000100), T, delta)

    sig_tx_state_left = getChannelStateScriptSigLeft(tx_state, id_channel_left, id_channel_right.public_key)
    sig_tx_state_right = getChannelStateScriptSigRight(tx_state, id_channel_right, id_channel_left.public_key)
    tx_state = signChannelStateTx(tx_state, sig_tx_state_left, sig_tx_state_right)
    print_tx(tx_state, 'tx state')
    tx_state_id = '229caba8498d320c60b78f347ad70ff8e324bd39a9318e3a94a788dc53f1516f'

    tx_er_for_refund_input = TxInput(tx_er_id, 0, sequence=Sequence(TYPE_RELATIVE_TIMELOCK, tx_er_rel_timelock).for_input_sequence())
    tx_state_lock_input = TxInput(tx_state_id, 0, sequence=Sequence(TYPE_RELATIVE_TIMELOCK, delta).for_input_sequence())

    id_refund_receiver = Id('e2bd3bf28c7e0994ef87a8d61b67f4f926ab2e315bc9f1e55da2394a594b4e66')    # new address for refund
    id_pay_receiver = Id('9d2b4722df4e870ef4fd6a7be03b39c9a056bf0562852018e0c995cbc0d5756c')       # new address for pay to right

    tx_refund, sig_left = createTxRefund(tx_er_for_refund_input, tx_state_lock_input, id_er_u1, id_refund_mulsig_left,
                                 state_lock_script, id_refund_receiver, lock_amount, to_satoshis(0.00000600), eps, tx_er_rel_timelock)

    sig_right = txRefundGetRightSignature(tx_refund, id_refund_mulsig_right, state_lock_script)
    tx_refund = signTxRefundStateInput(tx_refund, sig_left, sig_right)
    print_tx(tx_refund, 'tx refund')

    tx_pay = createTxPayAndSign(tx_state_lock_input, id_pay_right, state_lock_script, id_pay_receiver,
                                lock_amount, to_satoshis(0.00000600))
    print_tx(tx_pay, 'tx pay')
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())
예제 #26
0
BOB = Participant(wif='cRTBStSdJeYt3BV2JGfdJb46m8T67Ht7zm2pkKup6gwV6EqZkzvQ',
                  network="btc-test3")
CAROL = Exchange(wif="Bqj17XDLkQA11SJcihX3qwwVC4PJWfQXxGh8V2gM1C8RCs5zxooi",
                 network="bcy-tst")
# BCY network
carol_utxo_to_spend = UTXO(
    txid="280f6b3f36ead225f86d22d6e5c4569d0c118265f1d576a29b5ffc01af05c225",
    output_idx=2,
    value=98000,  # 0.00099
    redeem_script=None,
)

carol_htlc_utxo = UTXO(
    txid="0e581acea0303f144286874cc7b6323e8f8bbc6e7ea7542b9cb77bfbea0e1662",
    output_idx=0,
    value=to_satoshis(0.00088000),  # 0.00099
    redeem_script=None,
)


class TestExchange(TestCase):
    def test_make_htlc(self):
        setup('testnet')
        HTLC_tx, HTLC_utxo = CAROL.make_HTLC(
            utxo=carol_utxo_to_spend,
            recipient_pubkeyhash=ALICE.pubkey_hash(network="bcy-tst"),
            secret_hash=BOB_SECRET.digest_hex(),
            locktime=10)
        CAROL.commit_HTLC()
        CAROL.broadcast_transaction(CAROL.HTLC_ser, network="bcy-tst")
        HTLC_output_tx = ALICE.make_HTLC_output_tx(utxo=HTLC_utxo,
예제 #27
0
def main():
    setup.setup('testnet')
    eps = 200  # value owned by each participant in enable-(payment/refund) transaction. Could be 1 satoshi
    delta = 10  # upper bound for tx to be confirmed
    T = 2100200  # funds for payment locked until this time
    t_channel = 35  # upper bound for closing a channel

    id_in_channel_left = Id(
        '616c26241bb007883f13aff556bb07d28374b52b81aa675f30dcf35c04103da4')
    tx_in_channel_left = TxInput(
        '14c5b01c28a133fb55c03cfd756d70ccdacbdc0229c4a96d49c65c25df53afb5', 0)
    id_in_channel_right = Id(
        'f74b11ae3ca8d2c2d0424296f0de316198b4fda2ca984b5e3c6681abd2c72b2c')
    tx_in_channel_right = TxInput(
        '14c5b01c28a133fb55c03cfd756d70ccdacbdc0229c4a96d49c65c25df53afb5', 1)

    id_channel_left = Id(
        'e6ad38d70bf775e7e74bcd598e9282141dac09f79374565c3ebdf61e4f9ef4ed')
    id_channel_right = Id(
        'a3dbcea1e46edecbd1da13231f385ebe7f2beea382e3f7227c4c00d21b7e8455')

    tx_channel = createOpenChannelTx(tx_in_channel_left, tx_in_channel_right,
                                     to_satoshis(0.000009),
                                     to_satoshis(0.000009),
                                     id_channel_left.public_key,
                                     id_channel_right.public_key)

    tx_channel = signOpenChannelTxLeft(tx_channel, id_in_channel_left)
    tx_channel = signOpenChannelTxRight(tx_channel, id_in_channel_right)
    print_tx(tx_channel, 'tx channel open')
    # publish tx_channel -> https://blockstream.info/testnet/tx/7b2ff59b6070a70249fd3f06efd1e0944d69597e5871e72098304adae94e7316/
    tx_channel_id = '7b2ff59b6070a70249fd3f06efd1e0944d69597e5871e72098304adae94e7316'

    id_ep_in = Id(
        'f2b019b04121adca7b6541a08761454b14ffd705248a51e7f3b6cfbf64f2b26b')
    tx_ep_input = TxInput(
        '14c5b01c28a133fb55c03cfd756d70ccdacbdc0229c4a96d49c65c25df53afb5', 2)
    id_er_in = Id(
        '89270091320614b25f88b84497ff4e4a017cbf1d25c1462b1352ea44f45708db')
    tx_er_input = TxInput(
        '14c5b01c28a133fb55c03cfd756d70ccdacbdc0229c4a96d49c65c25df53afb5', 3)

    id_er_u1 = Id(
        '3223c869874bad6933f14d1bf3bc9354125641e0aef3484dcf313c24a18655c7')
    id_er_u2 = Id(
        'ac54ff9bc498ac9fa15f1e76a670fa0acdc85316fb6a97fc161f3871ab59e3bd')
    id_er_u3 = Id(
        '05b91a17dbe63db245c6a2ba84a9a2b01ed86b494b61cc2dad5a0a44fe6ddc0e')

    id_ep_u1 = Id(
        'd0f7165a36f496ff7599add67e7152869ee0e515bab290c4b77a559623034c82')
    id_ep_u2 = Id(
        'd869d0308b94a12c6831576d7c55231a59cdace9a46b2ea32d83a035dbb9b4fb')
    id_ep_u3 = Id(
        '2dcd22336e478779c8b5e8788c52ee359d5de5d3ef0cc33eb669e6e616bfa95d')

    tx_er_rel_timelock = t_channel + 2 * delta
    tx_ep_rel_timelock = t_channel

    tx_er = createEnableTx(tx_er_input, [id_er_u1.public_key],
                           tx_er_rel_timelock, eps)
    signEnableTx(tx_er, id_er_in)
    print_tx(tx_er, 'tx_er, 1 out')
    # 195 bytes
    tx_er = createEnableTx(tx_er_input,
                           [id_er_u1.public_key, id_er_u2.public_key],
                           tx_er_rel_timelock, eps)
    signEnableTx(tx_er, id_er_in)
    print_tx(tx_er, 'tx_er, 2 out')
    # 233 bytes
    tx_er = createEnableTx(
        tx_er_input,
        [id_er_u1.public_key, id_er_u2.public_key, id_er_u3.public_key],
        tx_er_rel_timelock, eps)
    signEnableTx(tx_er, id_er_in)
    print_tx(tx_er, 'tx_er, 3 out')
    # 271 bytes. enable-refund tx size in bytes = 157 + 38 * outs_number

    tx_ep = createEnableTx(
        tx_ep_input,
        [id_ep_u1.public_key, id_ep_u2.public_key, id_ep_u3.public_key],
        tx_ep_rel_timelock, eps)
    signEnableTx(tx_ep, id_ep_in)
    print_tx(tx_ep, 'tx_ep, 3 out')
    # same as enable-refund

    # publish tx_er -> https://blockstream.info/testnet/tx/1e3c3465793126d4115f49750fab61a66c20bfbece436016d00066730704969b/
    tx_er_id = '1e3c3465793126d4115f49750fab61a66c20bfbece436016d00066730704969b'
    # publish tx_ep -> https://blockstream.info/testnet/tx/19c04e7bb09cbbd6f18ed4bff18a6c0d7491ddf5119ff1e70b2cfdbc4455612c/
    tx_ep_id = '19c04e7bb09cbbd6f18ed4bff18a6c0d7491ddf5119ff1e70b2cfdbc4455612c'

    id_state_left = Id(
        'ce7bca0ec8d38f945390e64627f4b669eca9afd2bae77d036421ce96b6767728'
    )  # left can receive a - c coins
    id_state_right = Id(
        'ad5813d9719179da0e561aa22295017559b247a3bb325ce438bc8247bf79962e'
    )  # right can receive b coins
    id_refund_mulsig_left = Id(
        'e34d37fdeb88addac291ae0fa084f33490d756d8298e7219b0d4f073616dd251'
    )  # left will receive c coins if publish tx_refund (using tx_er output)
    id_refund_mulsig_right = Id(
        '4d87652d513e0f7a5be51894b7fa862c8ca3ea8ef222f6b6ea7ed6a949f67672'
    )  # left will receive c coins if publish tx_refund (using tx_er output)
    id_pay_mulsig_left = Id(
        '0a08c11255f48d66b0d1dcab0e3b9479a7e1275d078663fde3dc9fd92355e784'
    )  # right will receive c coins if publish tx_inst_pay (using tx_ep output)
    id_pay_mulsig_right = Id(
        '0a08c11255f48d66b0d1dcab0e3b9479a7e1275d078663fde3dc9fd92355e784'
    )  # right will receive c coins if publish tx_inst_pay (using tx_ep output)
    id_pay_right = Id(
        '0a08c11255f48d66b0d1dcab0e3b9479a7e1275d078663fde3dc9fd92355e784'
    )  # right will receive c coins after T if publish tx_pay

    tx_state_in = TxInput(tx_channel_id, 0)
    state_lock_script = getTxStateLockScript(T, delta, id_pay_right.public_key,
                                             id_refund_mulsig_left.public_key,
                                             id_refund_mulsig_right.public_key,
                                             id_pay_mulsig_left.public_key,
                                             id_pay_mulsig_right.public_key)

    lock_amount = to_satoshis(0.00000500)
    tx_state = createTxState(
        tx_state_in, id_state_left.public_key, id_state_right.public_key,
        id_pay_right.public_key, id_refund_mulsig_left.public_key,
        id_refund_mulsig_right.public_key, id_pay_mulsig_left.public_key,
        id_pay_mulsig_right.public_key, lock_amount, to_satoshis(0.00000300),
        to_satoshis(0.00000100), T, delta)

    sig_tx_state_left = getChannelStateScriptSigLeft(
        tx_state, id_channel_left, id_channel_right.public_key)
    sig_tx_state_right = getChannelStateScriptSigRight(
        tx_state, id_channel_right, id_channel_left.public_key)
    tx_state = signChannelStateTx(tx_state, sig_tx_state_left,
                                  sig_tx_state_right)
    print_tx(tx_state, 'tx state')
    # 457 bytes
    # publish tx_state -> https://blockstream.info/testnet/tx/229caba8498d320c60b78f347ad70ff8e324bd39a9318e3a94a788dc53f1516f/
    tx_state_id = '229caba8498d320c60b78f347ad70ff8e324bd39a9318e3a94a788dc53f1516f'

    tx_er_for_refund_input = TxInput(
        tx_er_id,
        0,
        sequence=Sequence(TYPE_RELATIVE_TIMELOCK,
                          tx_er_rel_timelock).for_input_sequence())
    tx_ep_for_refund_input = TxInput(
        tx_ep_id,
        0,
        sequence=Sequence(TYPE_RELATIVE_TIMELOCK,
                          tx_ep_rel_timelock).for_input_sequence())
    tx_state_lock_input = TxInput(
        tx_state_id,
        0,
        sequence=Sequence(TYPE_RELATIVE_TIMELOCK, delta).for_input_sequence())

    id_refund_receiver = Id(
        'e2bd3bf28c7e0994ef87a8d61b67f4f926ab2e315bc9f1e55da2394a594b4e66'
    )  # new address for refund
    id_pay_receiver = Id(
        '9d2b4722df4e870ef4fd6a7be03b39c9a056bf0562852018e0c995cbc0d5756c'
    )  # new address for pay to right
    id_inst_pay_receiver = Id(
        '6f76abd9416387f1e34e66a8fa3f13c73a601617e6851ccc6200cca7957443c3'
    )  # new address for inst pay to right

    tx_refund, sig_left = createTxRefund(tx_er_for_refund_input,
                                         tx_state_lock_input, id_er_u1,
                                         id_refund_mulsig_left,
                                         state_lock_script,
                                         id_refund_receiver, lock_amount,
                                         to_satoshis(0.00000600), eps,
                                         tx_er_rel_timelock)

    sig_right = txRefundGetRightSignature(tx_refund, id_refund_mulsig_right,
                                          state_lock_script)
    tx_refund = signTxRefundStateInput(tx_refund, sig_left, sig_right)
    print_tx(tx_refund, 'tx refund')
    # 379 bytes
    # publish tx_state -> https://blockstream.info/testnet/tx/98c5369111480b3fbac3e4ab1fd9d05f8dcdb19d20562aff21c3602f34be5882
    tx_refund_id = '98c5369111480b3fbac3e4ab1fd9d05f8dcdb19d20562aff21c3602f34be5882'

    tx_pay = createTxPayAndSign(tx_state_lock_input, id_pay_right,
                                state_lock_script, id_pay_receiver,
                                lock_amount, to_satoshis(0.00000600))
    print_tx(tx_pay, 'tx pay')
    # 197 bytes

    tx_inst_pay, sig_state_left = createTxInstPay(
        tx_ep_for_refund_input, tx_state_lock_input, id_pay_mulsig_left,
        state_lock_script, id_inst_pay_receiver.p2pkh, lock_amount,
        to_satoshis(0.00000600), eps)
    tx_inst_pay = signTxInstPayStateInput(tx_inst_pay, sig_state_left,
                                          id_ep_u1, id_pay_mulsig_right,
                                          state_lock_script,
                                          tx_ep_rel_timelock)
    print_tx(tx_inst_pay, 'tx inst pay')
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())