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)
Exemple #2
0
class TestCreateP2shTransaction(unittest.TestCase):
    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_spend_non_std(self):
        tx = Transaction([self.txin_spend], [self.txout_spend])
        self.assertEqual(tx.serialize(), self.spend_non_std_tx_result)
Exemple #3
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(
        Decimal('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(Decimal('0.29'), change_addr.to_script_pub_key())
    #change_txout = TxOutput(Decimal('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()
    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)
Exemple #4
0
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(Decimal('0.09'), redeem_script.to_p2sh_script_pub_key())

    # no change address - the remaining 0.01 tBTC will go to miners)

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

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to create the signature for the txin
    sig = sk.sign_input(tx, 0, from_addr.to_script_pub_key())
    #print(sig)

    # get public key as hex
    pk = sk.get_public_key()
    pk = pk.to_hex()
    #print (pk)

    # set the scriptSig (unlocking script)
    txin.script_sig = Script([sig, pk])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
    print("\nTxId:", tx.get_txid())
def main():
    # always remember to setup the network
    setup('testnet')  # same params as regest, which the node should run

    # create transaction input from tx id of UTXO (contained 0.4 tBTC)
    txin = TxInput(
        'e2d08a63a540000222d6a92440436375d8b1bc89a2638dc5366833804287c83f', 1)

    # create transaction output using P2PKH scriptPubKey (locking script)
    addr = P2pkhAddress('msXP94TBncQ9usP6oZNpGweE24biWjJs2d')
    # locking script expects 2 numbers that when added equal 5 (silly example)
    txout = TxOutput(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(2, change_addr.to_script_pub_key())

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

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to sign the input
    sk = PrivateKey('cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA')

    # note that we pass the scriptPubkey as one of the inputs of sign_input
    # because it is used to replace the scriptSig of the UTXO we are trying to
    # spend when creating the transaction digest
    from_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r')
    sig = sk.sign_input(
        tx, 0,
        Script([
            'OP_DUP', 'OP_HASH160',
            from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ]))
    #print(sig)

    # get public key as hex
    pk = sk.get_public_key()
    pk = pk.to_hex()
    #print (pk)

    # set the scriptSig (unlocking script)
    txin.script_sig = Script([sig, pk])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
def main():
    # always remember to setup the network
    setup('testnet')

    #
    # 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())
print(address2)
to_address = P2pkhAddress(address2)
to_address.to_string()

# 14. Add a small fee. A few satoshis is fine.
fee = 0.0001
amount = Decimal(btc_to_send) - Decimal(fee)
print("Amount:", amount)

txout = TxOutput(amount, to_address.to_script_pub_key())

# 15. Create the transaction using the input and output.
tx = Transaction([txin], [txout])

# 16. Sign the input.
sig = priv.sign_input(tx, 0, redeem_script)

# 17. Create the signature.
txin.script_sig = Script([sig, pub.to_hex(), redeem_script.to_hex()])

signed_tx = tx.serialize()
print("\nTxId:", tx.get_txid())


# 18. Print the raw transaction.
tx.get_txid()
tx.get_size()
tx

tx.has_segwit
#
#  7) display the raw unsigned transaction
#

	if i:
		print( "raw unsigned transaction:\n" + tx.serialize() )


#
#  8) sign the transaction
#

	j = 0
	for txin in txins:
		signature = from_privkey.sign_input( tx, j, redeem_script )
		txin.script_sig = Script( [signature, from_pubkey.to_hex(), redeem_script.to_hex()] )
		j += 1


#
#  9) display the raw signed transaction
#

	if i:
		print( "raw signed transaction:\n" + tx.serialize() )

	fee = int(tx.get_size() * satoshi_per_byte)


#
Exemple #9
0
class TestCreateP2shTransaction(unittest.TestCase):
    def setUp(self):
        setup('testnet')
        self.txin = TxInput(
            "76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f",
            0)
        self.from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
        self.sk = PrivateKey(
            'cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')
        self.p2pk_sk = PrivateKey(
            'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
        self.p2pk_redeem_script = Script(
            [self.p2pk_sk.get_public_key().to_hex(), 'OP_CHECKSIG'])
        self.txout = TxOutput(to_satoshis(0.09),
                              self.p2pk_redeem_script.to_p2sh_script_pub_key())
        self.create_p2sh_and_send_result = '02000000010f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b483045022100fd3a3fd4aeec5db0f3f9c5c5ef7f60f37920be7464a80edacbc3b6b9d0624173022031ce309330e60b19d39cec8c5597460c840adcdd66f7dbbf896eef3ec42b472f012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff01405489000000000017a9142910fc0b1b7ab6c9789c5a67c22c5bcde5b903908700000000'

        self.txin_spend = TxInput(
            '7db363d5a7fabb64ccce154e906588f1936f34481223ea8c1f2c935b0a0c945b',
            0)
        # self.p2pk_sk , self.p2pk_redeem_script from above
        self.to_addr = self.from_addr
        self.txout2 = TxOutput(to_satoshis(0.08),
                               self.to_addr.to_script_pub_key())
        self.spend_p2sh_result = '02000000015b940c0a5b932c1f8cea231248346f93f18865904e15cecc64bbfaa7d563b37d000000006c47304402204984c2089bf55d5e24851520ea43c431b0d79f90d464359899f27fb40a11fbd302201cc2099bfdc18c3a412afb2ef1625abad8a2c6b6ae0bf35887b787269a6f2d4d01232103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708acffffffff0100127a00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac00000000'

        # P2SH(CSV+P2PKH)
        self.sk_csv_p2pkh = PrivateKey(
            'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
        self.seq = Sequence(TYPE_RELATIVE_TIMELOCK, 200)
        self.txin_seq = TxInput(
            'f557c623e55f0affc696b742630770df2342c4aac395e0ed470923247bc51b95',
            0,
            sequence=self.seq.for_input_sequence())
        self.another_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
        self.spend_p2sh_csv_p2pkh_result = '0200000001951bc57b24230947ede095c3aac44223df70076342b796c6ff0a5fe523c657f5000000008a483045022100c123775e69ec27094f7940facb9ad769c09f48a7fc88250a2fce67bd92c9b4cf02204ebdbed84af46e584fe6db9a23c420b7370879e883b555e119465f84bf34d82f012103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af327081e02c800b27576a914c3f8e5b0f8455a2b02c29c4488a550278209b66988acc80000000100ab9041000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac00000000'

    def test_signed_send_to_p2sh(self):
        tx = Transaction([self.txin], [self.txout])
        sig = self.sk.sign_input(tx, 0, self.from_addr.to_script_pub_key())
        pk = self.sk.get_public_key().to_hex()
        self.txin.script_sig = Script([sig, pk])
        self.assertEqual(tx.serialize(), self.create_p2sh_and_send_result)

    def test_spend_p2sh(self):
        tx = Transaction([self.txin_spend], [self.txout2])
        sig = self.p2pk_sk.sign_input(tx, 0, self.p2pk_redeem_script)
        self.txin_spend.script_sig = Script(
            [sig, self.p2pk_redeem_script.to_hex()])
        self.assertEqual(tx.serialize(), self.spend_p2sh_result)

    def test_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)
Exemple #10
0
def buy_lambo(key, lock, from_addr, to_addr):
    setup(os.getenv("BUY_LAMBO_BTC_NET", "regtest"))

    # Create a proxy to JSON-RPC api
    chain = NodeProxy(os.getenv("BUY_LAMBO_RPC_USER", "rpcuser"),
                      os.getenv("BUY_LAMBO_RPC_PASSWORD",
                                "rpcpassword")).get_proxy()

    # Try executing a command to see if node is running
    try:
        chain.getblockcount()
    except Exception:
        print("Error: Node isn't working!")
        return

    # Check addresses
    if not chain.validateaddress(from_addr)["isvalid"]:
        print("Error: `from_addr` is not a valid address!")
        return
    if not chain.validateaddress(to_addr)["isvalid"]:
        print("Error: `to_addr` is not a valid address!")
        return

    # Set lock sequence prefix
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, lock)

    # Get public key (found from private key)
    private_key = PrivateKey(key)
    public_key = private_key.get_public_key()

    # Add address to wallet so we can get utxos from bitcoin core
    chain.importaddress(from_addr)

    # Get UTXOs
    utxos = chain.listunspent(1, 9999999, [from_addr])

    # Create inputs
    txin = []
    total_btc = Decimal(0)
    for utxo in utxos:
        # Note that for each input we set the correct nSequence
        txin.append(
            TxInput(utxo["txid"],
                    utxo["vout"],
                    sequence=seq.for_input_sequence()))
        total_btc = total_btc + utxo["amount"]

    if total_btc == 0:
        return print("\nThere aren't any UTXOs :(.")

    # Create a fee-less output
    txout = TxOutput(total_btc - Decimal(0.1),
                     P2pkhAddress(to_addr).to_script_pub_key())

    # Create dummy transaction (to calculate size)
    tx = Transaction([TxInput.copy(inpt) for inpt in txin], [txout],
                     locktime=Locktime(lock).for_transaction())

    # create the redeem script - needed to sign the transaction
    redeem_script = Script([
        seq.for_script(),
        "OP_CHECKLOCKTIMEVERIFY",
        "OP_DROP",
        "OP_DUP",
        "OP_HASH160",
        public_key.get_address().to_hash160(),
        "OP_EQUALVERIFY",
        "OP_CHECKSIG",
    ])

    # 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
    for ind, txinput in enumerate(tx.inputs):
        sig = private_key.sign_input(tx, ind, redeem_script)
        txinput.script_sig = Script(
            [sig, public_key.to_hex(),
             redeem_script.to_hex()])

    # Calculate fees
    sat_per_byte = requests.get(
        "https://bitcoinfees.earn.com/api/v1/fees/recommended").json(
        )["fastestFee"]
    fee = Decimal(
        max((len(bytes.fromhex(tx.serialize())) * sat_per_byte) /
            SATOSHIS_PER_BITCOIN, 0))
    if fee == 0:
        print("WARNING: There isn't enough balance to calculate fees.")

    # Create final tx with correct txout value
    txout = TxOutput(total_btc - fee,
                     P2pkhAddress(to_addr).to_script_pub_key())
    tx = Transaction([TxInput.copy(inpt) for inpt in tx.inputs], [txout],
                     locktime=Locktime(lock).for_transaction())
    for ind, txinput in enumerate(tx.inputs):
        sig = private_key.sign_input(tx, ind, redeem_script)
        txinput.script_sig = Script(
            [sig, public_key.to_hex(),
             redeem_script.to_hex()])
    signed_tx = tx.serialize()

    # print raw transaction
    print("\nRaw unsigned transaction:\n{}".format(
        Transaction(txin, [txout]).serialize()))

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n{}".format(signed_tx))
    print("\nTxId: {}".format(tx.get_txid()))

    # Check if is valid and send it
    if chain.testmempoolaccept([signed_tx])[0]["allowed"]:
        chain.sendrawtransaction(signed_tx)
        print("\nSent to Block-chain! Have fun with those {} BTC.".format(
            total_btc - fee))
    else:
        print("\nCan't send (yet)!")
        print("Reason: `{}`".format(
            chain.testmempoolaccept([signed_tx])[0]["reject-reason"]))
Exemple #11
0
# Create signature to unlock inputs
# I have to rebuild redeem_script from P2SH private key
# Secret key of P2SH address
p2pkh_sk = PrivateKey(priv_key)
# Get the P2PKH public key
p2pkh_pk = p2pkh_sk.get_public_key().to_hex()
# Get the P2PKH 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'])

# Signature
sign = p2pkh_sk.sign_input(p2sh_out_tx, 0, redeem_script)

# Unlock transaction's input using signature, P2SH public key and redeem_script
txin.script_sig = Script([sign, p2pkh_pk, redeem_script.to_hex()])



# ***** Display the raw signed transaction

# Print Raw Signed Transaction
r_s_t = p2sh_out_tx.serialize()
print('\nRaw Signed Transaction: %s' %r_s_t)



# *** Display the transaction ID
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 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'])

    #TESTE_SUZANA
    addressObj = P2shAddress.from_script(redeem_script)
    print("addressObj=" + addressObj.to_address())
    #TESTE_SUZANA

    # you can initially spend a specific UTXO that you know (e.g. with the txid after you send some funds to the address).  Then if everything works you can use the address to find all tx in that address and spend them. Make sure the timelock works and that you can spend the funds as expected.

    # The 2nd program should display the raw signed transaction that is to be sent to a bitcoin node plus _send_ the transaction to a node. The last part is not possible with the bitcoin-utils library since I have not impl. a node proxy yet. So you have to use another lib or finish with the cli commands (commented out of course) that I have to run in order to send the raw tx to a bitcoin node.
    # The P2SH addr could be recalculated in 2nd program since we have the redeem script! Providing the P2SH addr saves you from this small calculation and 'connects' the 2 programs :-)

    # Re fees, I would rather you calculate the 'appropriate' fee and explain in comments how/why you did it this way. Ideally, you would consult an online service to get an estimate of the appropriate fee. This is minor for assignment purposes but major for production systems.

    #https://bitcoin.stackexchange.com/questions/83650/how-does-nsequence-check-sequence-verify-work
    #The 2nd program requires a private key as well... that is what unlock the funds.

    ##### NAO PRECISA PARA O ASSIGNMENT DAQUI EM DIANTE #######

    # 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')

    #SUZANA ---- ASSINA COM P2SH do SCRIPT
    txout = TxOutput(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())
Exemple #13
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'])
Exemple #14
0
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 as
    # well as for an absolute amount of blocks or an absolute amount of seconds since the transaction.
    #

    parser = argparse.ArgumentParser(
        description=
        'Give the private key, a future time expressed either in block height or in UNIX Epoch time and '
        'the P2SH address to send the funds')
    parser.add_argument('key', help="Add the private key.")
    parser.add_argument(
        '-param',
        type=int,
        help="Add the number of blocks or the time expressed in seconds.")
    parser.add_argument('-to_address',
                        type=str,
                        help="Add the adress that will sent/spend")
    args = parser.parse_args()

    # set values
    key = args.key
    absolute_param = args.param
    send_address = args.to_address

    # set Locktime
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, absolute_param)
    locktime = Locktime(absolute_param)

    # set proxy
    username = "******"
    password = "******"
    proxy = NodeProxy(username, password).get_proxy()

    # secret key corresponding to the pubkey needed for the P2SH (P2PKH) transaction
    p2pkh_sk = PrivateKey(key)

    p2pkh_pk = p2pkh_sk.get_public_key()

    # get the address (from the public key)
    p2pkh_addr = p2pkh_pk.get_address()

    # print("Private key: " + p2pkh_sk. to_wif(compressed=True))
    # print("Public key: " + p2pkh_pk.to_hex(compressed=True))
    # print("P2PKH Address: " + p2pkh_addr.to_string())

    # 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'
    ])

    # accept a P2SH address to get the funds from
    addr = P2shAddress.from_script(redeem_script)
    print("The P2SH address to get the funds from is : " + addr.to_string())

    # check if the P2SH address has any UTXOs to get funds from

    proxy.importaddress(addr.to_string(), "P2SH to get the funds from")
    minconf = 0
    maxconf = 99999999
    my_list = proxy.listunspent(minconf, maxconf, [addr.to_string()])

    # Gather all funds that the P2SH address received to send to the P2PKH address provided

    txin_list = []
    btc_to_send = 0
    for i in my_list:
        txin = TxInput(i['txid'], i['vout'], sequence=seq.for_input_sequence())
        txin_list.append(txin)
        btc_to_send = btc_to_send + i['amount']

    if btc_to_send == 0:
        print("No btc found to send")
        quit()

    # accept a P2PKH address to send the funds to
    to_addr = P2pkhAddress(send_address)
    print("The P2PKH address to send the funds to is : " + to_addr.to_string())

    # calculate the appropriate fees with respect to the size of the transaction
    response = requests.get("https://mempool.space/api/v1/fees/recommended")
    fee_per_byte = response.json()['fastestFee']
    print("Fastest fee per byte is : %d " % fee_per_byte)

    # calculate transaction size as described at
    # https://bitcoin.stackexchange.com/questions/1195/how-to-calculate-transaction-size-before-sending-legacy-non-segwit-p2pkh-p2sh
    tx_size = len(my_list) * 180 + 34 + 10 + len(my_list)
    total_fees = tx_size * fee_per_byte / (1024 * 10**8)
    print('Total fees are : ', total_fees)

    # Calculate the final amount
    amount = btc_to_send - total_fees
    # print(amount)

    # Create transaction output
    txout = TxOutput(to_satoshis(amount), to_addr.to_script_pub_key())

    # Create transaction after the inputs and the outputs
    tx = Transaction(txin_list, [txout], locktime.for_transaction())

    # For each transaction - when dealing with multiple inputs, you will need to sign all of them
    for i, txin in enumerate(my_list):
        sig = p2pkh_sk.sign_input(tx, i, 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.to_hex(),
             redeem_script.to_hex()])

    # display the raw signed transaction, ready to be broadcasted
    signed_tx = tx.serialize()
    print("\nRaw signed transaction:\n" + signed_tx)

    # display the raw unsigned transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # display the transaction id
    print("\nTxId:", tx.get_txid())

    # verify that the transaction is valid and will be accepted by the Bitcoin nodes
    # if the transaction is valid, send it to the blockchain

    is_valid = proxy.testmempoolaccept([signed_tx])
    # print(is_valid)
    if is_valid[0]['allowed']:
        print("Transaction is valid!")
        print("Sending transaction to blockchain..")
        proxy.sendrawtransaction(signed_tx)
    else:
        print("Transaction not valid")
        quit()
Exemple #15
0
def main():
    # always remember to setup the network
    setup('regtest')

    # RPC credentials for communicating with the node
    rpcuser = '******'
    rpcpass = '******'
    proxy = NodeProxy(rpcuser, rpcpass).get_proxy()

    # set values
    block_height = 140

    # secret key needed to spend P2PKH that is wrapped by P2SH
    p2pkh_sk = PrivateKey(
        'cSbKZh6a6wNUAQ8pr2KLKeZCQ4eJnFmN35wtReaoU4kCP97XQu6W')
    # this is the P2SH address the funds have been locked in
    p2shaddress = '2NGWStpuXtke1VXCTgNnzUgWbun7eY2f3nH'
    # this is the address the funds will be sent to
    to_addr = P2pkhAddress('mnS1ng5D1hdvLkYAK2oS8R1C4e37aQdVoC')

    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, block_height)
    lock = Locktime(block_height)

    # import the address as watch-only
    print('importaddress')
    proxy.importaddress(p2shaddress, "P2SH absolute timelock", True)
    # find all UTXOs for this address. 10.000.000 should be enough
    print('listunspent')
    list_unspent = proxy.listunspent(0, 9999999, [p2shaddress])

    # create transaction inputs for all UTXOs. Calculate the total amount of
    # bitcoins they contain
    txin_list = []
    total_amount = 0
    for i in list_unspent:
        txin = TxInput(i['txid'], i['vout'], sequence=seq.for_input_sequence())
        txin_list.append(txin)
        total_amount = total_amount + i['amount']
    if total_amount == 0:
        print("No funds to move")
        sys.exit(0)

    # derive public key and adddress from the private key
    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_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # get fees using API. Although we may be running in regtest, we'll use the
    # fees as if we were using testnet (fees are in satoshis)
    url = 'https://api.blockcypher.com/v1/btc/test3'
    resp = requests.get(url)
    fee_per_kb = resp.json()['medium_fee_per_kb']

    # calculate transaction size according to:
    # in*180 + out*34 + 10 plus or minus 'in'
    # https://bitcoin.stackexchange.com/questions/1195/how-to-calculate-transaction-size-before-sending-legacy-non-segwit-p2pkh-p2sh
    # we'll play it safe and use the upper bound
    tx_size = len(txin_list) * 180 + 34 + 10 + len(txin_list)
    fees = tx_size * fee_per_kb / (1024 * 10**8)
    print('fees:', fees)

    # create the output
    txout = TxOutput(
        Decimal(total_amount) - Decimal(fees), to_addr.to_script_pub_key())

    # create transaction from inputs/outputs
    tx = Transaction(txin_list, [txout], lock.for_transaction())

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to create the signatures for all txins -
    # note that the redeem script is passed to replace the scriptSig
    for i, txin in enumerate(txin_list):
        sig = p2pkh_sk.sign_input(tx, i, redeem_script)
        # 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()])

    # serialize the transaction
    signed_tx = tx.serialize()

    # test if the transaction will be accepted by the mempool
    print('testmempoolaccept')
    res = proxy.testmempoolaccept([signed_tx])
    print(res)
    if not res[0]['allowed']:
        print("Transaction not valid")
        sys.exit(1)

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())
    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
    print("\nTxId:", tx.get_txid())
def main():
    # always remember to setup the network
    setup('testnet')

    integer_expiry_time = 2000

    # ex.: 2000 in big endian is 07d0. After little endian conversion become: d007. Including two zeros in the end: d00700
    expiry_time_in_hex = integer_expiry_time.to_bytes(
        ((integer_expiry_time.bit_length() + 7) // 8),
        byteorder='little').hex() + '00'

    print("hex= " + expiry_time_in_hex)

    # 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(
        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(0.29, change_addr.to_script_pub_key())
    #change_txout = TxOutput(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')

    #testeSuzana----------------------------
    pub = sk.get_public_key()
    # compressed is the default
    print("Public key:", pub.to_hex(compressed=True))
    # get address from public key
    address = pub.get_address()
    # print the address and hash160 - default is compressed address
    print("Address:", address.to_address())
    print("Hash160:", address.to_hash160())
    print("from_addr:", from_addr.to_hash160())
    #testeSuzana -------------------------------------------------

    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)
Exemple #17
0
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_address())

    # send/spend to any random address
    to_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
    txout = TxOutput(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())
class TestCreateP2pkhTransaction(unittest.TestCase):
    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(Decimal('0.1'), Script(['OP_DUP', 'OP_HASH160', self.addr.to_hash160(),
                                           'OP_EQUALVERIFY', 'OP_CHECKSIG']) )
        self.change_addr = P2pkhAddress('mytmhndz4UbEMeoSZorXXrLpPfeoFUDzEp')
        self.change_txout = TxOutput(Decimal('0.29'), self.change_addr.to_script_pub_key())
        self.change_low_s_addr = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w')
        self.change_low_s_txout = TxOutput(Decimal('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(Decimal('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(Decimal('0.009'), Script(['OP_DUP', 'OP_HASH160',
                                                   self.sig_to_addr2.to_hash160(),
                                                   'OP_EQUALVERIFY',
                                                   'OP_CHECKSIG']) )
        self.sig_sighash_single_result = '02000000010f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402202cfd7077fe8adfc5a65fb3953fa3482cad1413c28b53f12941c1082898d4935102201d393772c47f0699592268febb5b4f64dabe260f440d5d0f96dae5bc2b53e11e032102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.sign_sighash_all_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b483045022100e30383d4006ef8b796ed397a81d2c55e6db3c05b370cb26179110816e57356e6022068fcd18a2a6984839a1fa7670693ed5c787da96589cd0f5ca81e3f11e613bd11012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a47304402206b728374b8879fd7a10cbd4f347934d583f4301aa5d592211487732c235b85b6022030acdc07761f227c27010bd022df4b22eb9875c65a59e8e8a5722229bc7362f4012102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.sign_sighash_none_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402202a2804048b7f84f2dd7641ec05bbaf3da9ae0d2a9f9ad476d376adfd8bf5033302205170fee2ab7b955d72ae2beac3bae15679d75584c37d78d82b07df5402605bab022102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a473044022021a82914b002bd02090fbdb37e2e739e9ba97367e74db5e1de834bbab9431a2f02203a11f49a3f6ac03b1550ee04f9d84deee2045bc038cb8c3e70869470126a064d022102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.sign_sighash_single_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402206118d21952932deb8608f772017fe76827ccdc8b750ead0f5636429ab5883a6802207f6ded77e22785b0e6c682c05260c2e073d1e1522d4c02fb78df6cdd2862e853032102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a47304402205012090ddf07ee2e7767020f09224001360243f8dbe05c5011c54eed9fb90d4802203358e227c891f609c3baf98d975d9ee72666fb511c808419d24ec5cccaf3938e032102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.sign_sighash_all_single_anyone_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b4830450221008837e1300f41566cbcd9649ea21a6c1574cce7bf4bc288b878b545e9370041ab022040d0abdd2a0945463b85553922f27a755492e4e2ba89ae68cb14079103072dbb812102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a473044022067943abe9fa7584ba9816fc9bf002b043f7f97e11de59155d66e0411a679ba2c02200a13462236fa520b80b4ed85c7ded363b4c9264eb7b2d9746200be48f2b6f4cb832102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'



    def test_unsigned_tx_1_input_2_outputs(self):
        tx = Transaction([self.txin], [self.txout, self.change_txout])
        self.assertEqual(tx.serialize(), self.core_tx_result)

    def test_signed_tx_1_input_2_outputs(self):
        tx = Transaction([self.txin], [self.txout, self.change_txout])
        sig = self.sk.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                                self.from_addr.to_hash160(),
                                                'OP_EQUALVERIFY', 'OP_CHECKSIG']) )
        pk = self.sk.get_public_key().to_hex()
        self.txin.script_sig = Script([sig, pk])
        self.assertEqual(tx.serialize(), self.core_tx_signed_result)

    def 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_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_signed_low_s_SIGSINGLE_tx_1_input_2_outputs(self):
        tx = Transaction([self.sig_txin1], [self.sig_txout1, self.sig_txout2] )
        sig = self.sig_sk1.sign_input( tx, 0,
                                      self.sig_from_addr1.to_script_pub_key(),
                                     SIGHASH_SINGLE)
        pk = self.sig_sk1.get_public_key().to_hex()
        self.sig_txin1.script_sig = Script([sig, pk])
        self.assertEqual(tx.serialize(), self.sig_sighash_single_result)

    def test_signed_SIGALL_tx_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)
        sig2 = self.sig_sk2.sign_input( tx, 1, Script(['OP_DUP', 'OP_HASH160',
                                         self.sig_from_addr2.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                 SIGHASH_ALL)
        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_2in_2out_result)

    def test_signed_SIGNONE(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_NONE)
        sig2 = self.sig_sk2.sign_input(tx, 1, Script(['OP_DUP', 'OP_HASH160',
                                                    self.sig_from_addr2.to_hash160(),
                                                    'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                       SIGHASH_NONE)
        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_none_2in_2out_result)

    def test_signed_SIGSINGLE_tx_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_SINGLE)
        sig2 = self.sig_sk2.sign_input(tx, 1, Script(['OP_DUP', 'OP_HASH160',
                                         self.sig_from_addr2.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                      SIGHASH_SINGLE)
        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_single_2in_2out_result)

    def test_signed_SIGALLSINGLE_ANYONEtx_2in_2_out(self):
        # note that this would have failed due to absurdly high fees but we
        # ignore it for our purposes
        tx = Transaction([self.sig_txin1, self.sig_txin2], [self.sig_txout1, self.sig_txout2] )
        sig = self.sig_sk1.sign_input(tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                         self.sig_from_addr1.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                 SIGHASH_ALL|SIGHASH_ANYONECANPAY)
        sig2 = self.sig_sk2.sign_input(tx, 1,
                                       self.sig_from_addr2.to_script_pub_key(),
                                 SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)
        pk = self.sig_sk1.get_public_key().to_hex()
        pk2 = self.sig_sk2.get_public_key().to_hex()
        self.sig_txin1.script_sig = Script([sig, pk])
        self.sig_txin2.script_sig = Script([sig2, pk2])
        self.assertEqual(tx.serialize(),
                         self.sign_sighash_all_single_anyone_2in_2out_result)
def 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(
        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(
        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())
Exemple #20
0
def tip_or_withdrawFunc(update, ctx):
    # Initialise bitcoin.py
    setup('mainnet')
    query = update.callback_query
    chID = query.message.chat.id
    msgID = query.message.message_id
    query.answer()
    data = str(query.data).split(",")
    sender = str(query.from_user.id)
    chatid = query.message.chat_id
    if sender == data[3]:
        if data[4] == "t":
            target = data[1]
            if data[0] == "Y":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)

                sender_wif = PrivateKey(db.getWIF(sender))
                fee = convertToSatoshis(Decimal(config.coin['minFee']))
                #target_address = P2wpkhAddress(getAddress(target))
                target_address = P2pkhAddress(getAddress(target))
                #sender_address = P2wpkhAddress(getAddress(sender))
                sender_address = P2pkhAddress(getAddress(sender))
                sender_balance = 0
                amount = convertToSatoshis(Decimal(data[2])) + fee

                unspent = requests.get(
                    f"{config.apiUrl}/unspent/{sender_address.to_string()}"
                ).json()["result"]
                txin = []
                for i in range(0, len(unspent)):
                    sender_balance += unspent[i]['value']
                    txin.append(
                        TxInput(unspent[i]['txid'], unspent[i]['index']))

                if sender_balance >= amount:
                    txout = []
                    txout = (TxOutput((amount - fee),
                                      Script([
                                          'OP_DUP', 'OP_HASH160',
                                          target_address.to_hash160(),
                                          'OP_EQUALVERIFY', 'OP_CHECKSIG'
                                      ])))

                    txchange = sender_balance - amount
                    if txchange > 0:
                        change_txout = (TxOutput(
                            txchange, sender_address.to_script_pub_key()))

                    script_code = Script([
                        'OP_DUP', 'OP_HASH160',
                        sender_wif.get_public_key().to_hash160(),
                        'OP_EQUALVERIFY', 'OP_CHECKSIG'
                    ])

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

                    # get public key as hex
                    pk = sender_wif.get_public_key().to_hex()

                    sigpk = []

                    for i in range(0, len(unspent)):
                        value = unspent[i]['value']
                        sig = sender_wif.sign_input(
                            tx, i,
                            Script([
                                'OP_DUP', 'OP_HASH160',
                                sender_address.to_hash160(), 'OP_EQUALVERIFY',
                                'OP_CHECKSIG'
                            ]))
                        sigpk.append(Script([sig, pk]))
                        txin[i].script_sig = sigpk[i]

                    #signed_tx = tx.serialize()
                    #print("\nRaw signed transaction:\n" + signed_tx)
                    #exit(0)

                    post_data = {'raw': tx.serialize()}

                    txid = requests.post(f"{config.apiUrl}/broadcast",
                                         data=post_data).json()['result']

                    if checkRus(chatid):
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"Успешно, отправлено @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}."
                        )
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"[Детали транзакции](https://ytn.ccore.online/transaction/{str(txid)})",
                            parse_mode="MarkdownV2")
                    else:
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"Success, sent @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}."
                        )
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"[View Transaction](https://ytn.ccore.online/transaction/{str(txid)})",
                            parse_mode="MarkdownV2")
                else:
                    if checkRus(chatid):
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            "У вас недостаточно средств, чтобы дать эту сумму чаевых"
                        )
                    else:
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            "You do not have enough funds to tip that amount")

            elif data[0] == "N":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)
                if checkRus(chatid):
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"Вы отказались от отправки @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}"
                    )
                else:
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"You declined sending @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}"
                    )

        elif data[4] == "w":
            if data[0] == "Y":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)

                sender_wif = PrivateKey(db.getWIF(sender))
                fee = convertToSatoshis(Decimal(config.coin['minFee']))
                #sender_address = P2wpkhAddress(getAddress(sender))
                sender_address = P2pkhAddress(getAddress(sender))
                sender_balance = 0
                amount = convertToSatoshis(Decimal(data[2])) + fee
                #target_address = P2wpkhAddress("ytn1q" + data[1])
                #target = data[1]
                target_address = P2pkhAddress("Y" + data[1])

                unspent = requests.get(
                    f"{config.apiUrl}/unspent/{sender_address.to_string()}"
                ).json()['result']

                txin = []
                for i in range(0, len(unspent)):
                    sender_balance += unspent[i]['value']
                    txin.append(
                        TxInput(unspent[i]['txid'], unspent[i]['index']))

                if sender_balance >= amount:
                    txout = []

                    txout = (TxOutput((amount - fee),
                                      Script([
                                          'OP_DUP', 'OP_HASH160',
                                          target_address.to_hash160(),
                                          'OP_EQUALVERIFY', 'OP_CHECKSIG'
                                      ])))

                    txchange = sender_balance - amount
                    if txchange > 0:
                        change_txout = (TxOutput(
                            txchange, sender_address.to_script_pub_key()))

                    script_code = Script([
                        'OP_DUP', 'OP_HASH160',
                        sender_wif.get_public_key().to_hash160(),
                        'OP_EQUALVERIFY', 'OP_CHECKSIG'
                    ])

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

                    # get public key as hex
                    pk = sender_wif.get_public_key().to_hex()

                    sigpk = []

                    for i in range(0, len(unspent)):
                        value = unspent[i]['value']
                        sig = sender_wif.sign_input(
                            tx, i,
                            Script([
                                'OP_DUP', 'OP_HASH160',
                                sender_address.to_hash160(), 'OP_EQUALVERIFY',
                                'OP_CHECKSIG'
                            ]))
                        sigpk.append(Script([sig, pk]))
                        txin[i].script_sig = sigpk[i]

                    #signed_tx = tx.serialize()
                    #print("\nRaw signed transaction:\n" + signed_tx)
                    #exit(0)

                    post_data = {'raw': tx.serialize()}

                    txid = requests.post(f"{config.apiUrl}/broadcast",
                                         data=post_data).json()['result']

                    if checkRus(chatid):
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"Успех, сняли {data[2]} {config.coin['ticker']} to address {target_address.to_string()} "
                        )
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"[Детали транзакции](https://ytn.ccore.online/transaction/{str(txid)})",
                            parse_mode="MarkdownV2")
                    else:
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"Success, withdrew {data[2]} {config.coin['ticker']} to address {target_address.to_string()} "
                        )
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"[View Transaction](https://ytn.ccore.online/transaction/{str(txid)})",
                            parse_mode="MarkdownV2")
                else:
                    if checkRus(chatid):
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            "У вас недостаточно средств для вывода указанной суммы."
                        )
                    else:
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            "You do not have enough funds to withdraw the specified amount."
                        )
            elif data[0] == "N":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)
                if checkRus(chatid):
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"Вы отказались снимать {data[2]} {config.coin['ticker']} to address {'Y' + data[1]}"
                    )
                else:
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"You declined withdrawing {data[2]} {config.coin['ticker']} to address {'Y' + data[1]}"
                    )