Beispiel #1
0
 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)
Beispiel #2
0
 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_multiple_input_multiple_ouput(self):
        tx = Transaction(
            [self.txin1_multiple, self.txin2_multiple, self.txin3_multiple], [
                self.output1_multiple, self.output2_multiple,
                self.output3_multiple
            ],
            has_segwit=True,
            witnesses=[])

        sig1 = self.sk1.sign_input(tx, 0, self.p2pkh_addr.to_script_pub_key())
        pk1 = self.sk1.get_public_key().to_hex()
        self.txin1_multiple.script_sig = Script([sig1, pk1])
        tx.witnesses.append(Script([]))

        sig_p2sh1 = self.sk1.sign_segwit_input(tx, 1, self.p2wsh_redeem_script,
                                               self.txin2_multiple_amount)
        sig_p2sh2 = self.sk2.sign_segwit_input(tx, 1, self.p2wsh_redeem_script,
                                               self.txin2_multiple_amount)
        pk2 = self.p2wsh_redeem_script.to_hex()
        tx.witnesses.append(Script(['OP_0', sig_p2sh1, sig_p2sh2, pk2]))

        sig3 = self.sk1.sign_segwit_input(tx, 2,
                                          self.p2pkh_addr.to_script_pub_key(),
                                          self.txin3_multiple_amount)
        pk3 = self.sk1.get_public_key().to_hex()
        tx.witnesses.append(Script([sig3, pk3]))

        print(tx.serialize())
        self.assertEqual(tx.serialize(),
                         self.multiple_input_multiple_ouput_result)
Beispiel #4
0
 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)
Beispiel #5
0
 def test_spend_p2wpkh(self):
     tx = Transaction([self.txin_spend], [self.txout2], has_segwit=True)
     sig = self.sk.sign_segwit_input(tx, 0, self.p2pkh_redeem_script,
                                     self.txin_spend_amount)
     pk = self.sk.get_public_key().to_hex()
     tx.witnesses = [Script([sig, pk])]
     self.assertEqual(tx.serialize(), self.spend_p2pkh_result)
Beispiel #6
0
def createTxPayAndSign(tx_state_input: TxInput, id_state_pay_right: Id,
                       tx_state_lock_script: Script, id_pay_receiver: Id,
                       lock_coins: float, fee: float) -> Transaction:
    """
    Right can spend locked coins after time T wherever he wants

    :param tx_state_input: tx_state locked output reference
    :param id_state_pay_right: id for signing spend of tx_state.out_lock by right user
    :param tx_state_lock_script: lock script of tx_state.out_lock (for creating a signature)
    :param id_pay_receiver: id that will own coins if transaction will be published
    :param lock_coins: coins locked in tx_state
    :param fee: coins paid to miners
    :return: transaction for pay to right user, valid after time T
    """

    out_pay = TxOutput(lock_coins - fee, id_pay_receiver.p2pkh)
    tx_pay = Transaction([tx_state_input], [out_pay])

    signature = id_state_pay_right.private_key.sign_input(
        tx_pay, 0, tx_state_lock_script)
    tx_state_input.script_sig = Script([
        signature,
        id_state_pay_right.public_key.to_hex(), 'OP_0', 'OP_0', 'OP_0', 'OP_0',
        'OP_0', 'OP_0'
    ])

    return tx_pay
Beispiel #7
0
def createTxInstPay(tx_ep_input: TxInput, tx_state_input: TxInput,
                    id_state_inst_pay_left: Id, tx_state_lock_script: Script,
                    inst_pay_lock_script: Script, lock_coins: float,
                    fee: float, eps: float) -> (Transaction, str):
    """
    Left user creates tx_inst_pay and signature for tx_state which funds this tx_inst_pay

    :param tx_ep_input: enable-payment transaction output reference
    :param tx_state_input: tx_state locked output reference
    :param id_state_inst_pay_left: id for signing spend of tx_state.out_lock by left user
    :param tx_state_lock_script: lock script of tx_state.out_lock (for creating a signature)
    :param inst_pay_lock_script: ScriptPubKey for new transactio, for example, p2pkh (to right user pubkey hash)
    :param lock_coins: coins locked in tx_state
    :param fee: coins paid to miners
    :param eps: coins from enable-refund transaction
    :return: tx for instant payment and signature of left user for it
    """

    out_inst_pay = TxOutput(lock_coins + eps - fee, inst_pay_lock_script)

    tx_inst_pay = Transaction([tx_ep_input, tx_state_input], [out_inst_pay])

    # should be also signed by right for 2/2 multisig
    sig_state_left = id_state_inst_pay_left.private_key.sign_input(
        tx_inst_pay, 0, tx_state_lock_script)

    return tx_inst_pay, sig_state_left
Beispiel #8
0
def createTxRefund(tx_er_input: TxInput, tx_state_input: TxInput, id_er: Id,
                   id_state_ref_left: Id, tx_state_lock_script: Script,
                   id_refund: Id, lock_coins: float, fee: float, eps: float,
                   rel_lock: int) -> (Transaction, str):
    """
    Left user creates transaction for refund based on tx_state and tx_er, and signs it

    :param tx_er_input: enable-refund transaction output reference
    :param tx_state_input: tx_state locked output reference
    :param id_er: id that owns output of enable-refund transaction
    :param id_state_ref_left: id for signing spend of tx_state.out_lock by left user
    :param tx_state_lock_script: lock script of tx_state.out_lock (for creating a signature)
    :param id_refund: id that will own coins if transaction will be published
    :param lock_coins: coins locked in tx_state
    :param fee: coins paid to miners
    :param eps: coins from enable-refund transaction
    :param rel_lock: relative lock on tx_er_input (for creating a signature)
    :return: tx_refund, signed by left user
    """

    out_refund = TxOutput(lock_coins + eps - fee, id_refund.p2pkh)

    tx_refund = Transaction([tx_er_input, tx_state_input], [out_refund])

    er_in_lock_script = getEnableTxOutputLockScript(id_er.public_key, rel_lock)
    sig_er_in = id_er.private_key.sign_input(tx_refund, 0, er_in_lock_script)
    tx_er_input.script_sig = Script([sig_er_in, id_er.public_key.to_hex()])

    # should be also signed by right for 2/2 multisig
    sig_state_left = id_state_ref_left.private_key.sign_input(
        tx_refund, 1, tx_state_lock_script)

    return tx_refund, sig_state_left
Beispiel #9
0
def createTxState(tx_in: TxInput, pubkey_left: PublicKey, pubkey_right: PublicKey,
                  pubkey_pay_right: PublicKey,
                  pubkey_mulsig_left: PublicKey, pubkey_mulsig_right: PublicKey,
                  lock_val: float, left_val: float, right_val: float, T: int, delta: int) -> Transaction:

    """
    Move coins from left user balance to a new "lock" output.
    Before: 'a' coins to L, 'b' coins to R.
    After: 'a - c' coins to L, 'b' coins to R, 'c' coins locked.

    :param tx_in: reference to channel open transaction
    :param pubkey_left: public key owned by left user to receive his coins from channel
    :param pubkey_right: public key owned by right user to receive his coins from channel
    :param pubkey_pay_right: public key owned by right user for payment after time T
    :param pubkey_mulsig_left: public key owned by left user for refund if enable-refund tx is published
    :param pubkey_mulsig_right: public key owned by right user for refund if enable-refund tx is published
    :param lock_val: amount of coins to lock: 'c'
    :param left_val: coins or left user: '******'
    :param right_val: coins or right user: '******'
    :param T: locked funds can pe paid after this time wherever right user wants
    :param delta: upper bound on time for transaction to be confirmed by the network
    :return: tx_state
    """

    out_lock_script = getTxStateLockScript(T, delta, pubkey_pay_right, pubkey_mulsig_left, pubkey_mulsig_right)

    tx_out_lock = TxOutput(lock_val, out_lock_script)
    tx_out_left = TxOutput(left_val, P2pkhAddress(pubkey_left.get_address().to_string()).to_script_pub_key())
    tx_out_right = TxOutput(right_val, P2pkhAddress(pubkey_right.get_address().to_string()).to_script_pub_key())

    tx = Transaction([tx_in], [tx_out_lock, tx_out_left, tx_out_right])

    return tx
Beispiel #10
0
def get_trx_amount_fees(total_amount, trxin_set, p2pkh_addr_to_obj):
    """

    Calculate fees with approximation as to the size of the transactionself.
    Trying not introduce side effects to the harvested input transactions objects.

    """

    # set amount first without fees
    txout_just_for_size_calc = TxOutput(total_amount,
                                        p2pkh_addr_to_obj.to_script_pub_key())

    tx_just_for_size_calc = Transaction(trxin_set, [txout_just_for_size_calc])

    # https://live.blockcypher.com/btc-testnet/
    # High Priority (1-2 blocks)    Medium Priority (3-6 blocks)    Low Priority (7+ blocks)
    # 0.00059 BTC/KB     0.00001 BTC/KB     0.00001 BTC/KB
    trxsize_bytes = len(tx_just_for_size_calc.serialize().encode('utf-8'))
    trx_KB = (trxsize_bytes / 1024)  # * 0.00001  # Choose Medium Fee
    trx_KB *= (1 + ESTIMATE_OF_PERCENTAGE_SIGNING_BLOAT_IN_TRX_SIZE)
    trx_fees_in_btc = trx_KB * 0.00001
    total_amount = total_amount

    print("Size in KB: " + str(trx_KB) + ", estimated btc fees: " +
          str(trx_fees_in_btc) + ", total amount to be transferred: " +
          str(total_amount) + "\n")

    return trx_fees_in_btc
Beispiel #11
0
    def test_siganyonecanpay_none_send(self):
        """
        SIGHASH_NONE | SIGHASH_ANYONECANPAY:signs only the txin_index input
        """
        tx = Transaction([self.txin1_siganyonecanpay_none],
                         [self.txout1_siganyonecanpay_none],
                         has_segwit=True)
        pk = self.sk.get_public_key().to_hex()

        sig_signone = self.sk.sign_segwit_input(
            tx, 0, self.p2pkh_redeem_script,
            self.txin1_siganyonecanpay_none_amount,
            SIGHASH_NONE | SIGHASH_ANYONECANPAY)
        tx.witnesses = [Script([sig_signone, pk])]

        tx.inputs.append(self.txin2_siganyonecanpay_none)
        tx.outputs.append(self.txout2_siganyonecanpay_none)

        sig = self.sk.sign_segwit_input(tx, 1, self.p2pkh_redeem_script,
                                        self.txin2_siganyonecanpay_none_amount,
                                        SIGHASH_ALL)
        tx.witnesses.append(Script([sig, pk]))

        self.assertEqual(tx.serialize(),
                         self.test_siganyonecanpay_none_send_result)
Beispiel #12
0
def main():
    # always remember to setup the network
    setup('testnet')

    priv1 = PrivateKey("cN1XE3ESGgdvr4fWsB7L3BcqXncUauF8Fo8zzv4Sm6WrkiGrsxrG")
    priv2 = PrivateKey("cR8AkcbL2pgBswrHp28AftEznHPPLA86HiTog8MpNCibxwrsUcZ4")
    
    p2sh_redeem_script = Script(
        ['OP_1', priv1.get_public_key().to_hex(), priv2.get_public_key().to_hex(),'OP_2', 'OP_CHECKMULTISIG'])

    fromAddress = P2wshAddress.from_script(p2sh_redeem_script)

    toAddress = P2wpkhAddress.from_address("tb1qtstf97nhk2gycz7vl37esddjpxwt3ut30qp5pn")

    # set values
    txid = '2042195c40a92353f2ffe30cd0df8d177698560e81807e8bf9174a9c0e98e6c2'
    vout = 0
    amount = 0.01

    # create transaction input from tx id of UTXO
    txin = TxInput(txid, vout)

    txOut1 = TxOutput(0.0001, toAddress.to_script_pub_key())
    txOut2 = TxOutput(0.0098, fromAddress.to_script_pub_key())

    tx = Transaction([txin], [txOut1, txOut2], has_segwit=True)

    sig1 = priv1.sign_segwit_input(tx, 0, p2sh_redeem_script, amount)
    tx.witnesses.append(Script(['OP_0', sig1, p2sh_redeem_script.to_hex()]))

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + tx.serialize())
    print("\nTxId:", tx.get_txid())
 def test_signed_send_to_p2wsh(self):
     # Non-segregated witness transaction
     tx = Transaction([self.txin1], [self.txout1])
     sig = self.sk1.sign_input(tx, 0, self.p2pkh_addr.to_script_pub_key())
     pk = self.sk1.get_public_key().to_hex()
     self.txin1.script_sig = Script([sig, pk])
     self.assertEqual(tx.serialize(), self.create_send_to_p2pkh_result)
Beispiel #14
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)
 def test_signed_low_s_SIGSINGLE_tx_1_input_2_outputs(self):
     tx = Transaction([self.sig_txin1], [self.sig_txout1, self.sig_txout2] )
     sig = self.sig_sk1.sign_input( tx, 0,
                                   self.sig_from_addr1.to_script_pub_key(),
                                  SIGHASH_SINGLE)
     pk = self.sig_sk1.get_public_key().to_hex()
     self.sig_txin1.script_sig = Script([sig, pk])
     self.assertEqual(tx.serialize(), self.sig_sighash_single_result)
 def test_signed_tx_1_input_2_outputs(self):
     tx = Transaction([self.txin], [self.txout, self.change_txout])
     sig = self.sk.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                             self.from_addr.to_hash160(),
                                             'OP_EQUALVERIFY', 'OP_CHECKSIG']) )
     pk = self.sk.get_public_key().to_hex()
     self.txin.script_sig = Script([sig, pk])
     self.assertEqual(tx.serialize(), self.core_tx_signed_result)
def btc_payment(source_address, outputs, fee_satoshi_kb, network='mainnet'):
    try:
        setup(network)
        outputs_list = []
        p2sh_num = 0
        p2pkh_num = 0
        total_amount_to_spend = _calculate_total_amount(outputs)
        print(total_amount_to_spend)
        txin = []
        utxo_amount = 0

        for address, value in outputs.items():
            addr_type = _check_address_type(address)
            addr = ''
            if addr_type is P2PKH_ADDRESS:
                addr = P2pkhAddress(address)
                txout = TxOutput(
                    Decimal(value) / Decimal(SATOSHIS_PER_BITCOIN),
                    Script([
                        'OP_DUP', 'OP_HASH160',
                        addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
                    ]))
                outputs_list.append(txout)
                p2pkh_num += 1
            elif addr_type is P2SH_ADDRESS:
                addr = P2shAddress(address)
                txout = TxOutput(
                    Decimal(value) / Decimal(SATOSHIS_PER_BITCOIN),
                    Script(['OP_HASH160',
                            addr.to_hash160(), 'OP_EQUAL']))
                outputs_list.append(txout)
                p2sh_num += 1

        utxo_set, fee = _get_unspent_transactions(source_address,
                                                  total_amount_to_spend,
                                                  p2pkh_num, p2sh_num,
                                                  fee_satoshi_kb)

        for utxo in utxo_set:
            txin.append(TxInput(utxo['txid'], utxo['vout']))
            utxo_amount += utxo['amount']

        change = utxo_amount - fee - total_amount_to_spend
        change_addr = P2pkhAddress(source_address)
        change_txout = TxOutput(
            Decimal(change) / Decimal(SATOSHIS_PER_BITCOIN),
            Script([
                'OP_DUP', 'OP_HASH160',
                change_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
            ]))
        outputs_list.append(change_txout)
        tx = Transaction(txin, outputs_list)

        return tx.serialize(), utxo_set
    except UnspentTransactionsError:
        raise UnspentTransactionsError
    except:
        raise BtcPaymentError("Problem during creation of raw transaction")
Beispiel #18
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 test_spend_p2wsh(self):
        tx = Transaction([self.txin_spend], [self.txout2], has_segwit=True)
        sig1 = self.sk1.sign_segwit_input(tx, 0, self.p2wsh_redeem_script, self.txin_spend_amount)
        sig2 = self.sk2.sign_segwit_input(tx, 0, self.p2wsh_redeem_script, self.txin_spend_amount)

        pk = self.p2wsh_redeem_script.to_hex()
        tx.witnesses = [ Script(['OP_0', sig1, sig2, pk]) ]
        #print(tx.serialize())
        self.assertEqual(tx.serialize(), self.spend_p2pkh_result)
Beispiel #20
0
def get_standard_ct_punish(tx_in: TxInput, payee: Id, script_ct: Script, secret, val: float, fee: float)-> Transaction:

    tx_out = TxOutput(val-fee, payee.p2pkh)
    tx = Transaction([tx_in], [tx_out])
    
    sig = payee.sk.sign_input(tx, 0 , Script(script_ct))

    tx_in.script_sig = Script([secret, sig])
    
    return tx
Beispiel #21
0
def spend_all():
    """ creates & broadcasts a transactions that spend all UTXOs from the P2SH"""
    # loads script data (Script, p2sh_addr)
    script, p2sh_addr = csv_script(recreate=True)

    # load transaction data(PrivateKey, timelock, P2pkhAddresses) from data.json
    data = tools.load_data_json(priv=True, timelock_tx=True, p2pk=True)
    priv_key = data['priv_key']
    tx_lock = data['timelock_tx'] 
    p2pkh_addr = data['p2pk_addr']

    # query cli to detect transactions send to the p2sh adddress
    # gathers txid, vout, and amount of p2sh's UTXOs to create TxInputs
    p2sh_utxos, p2sh_balance = [], 0
    wallet_txs = tools.talk_to_cli('bitcoin-cli listtransactions * 900', True)
    for tx in json.loads(wallet_txs):
        if tx['address'] == p2sh_addr and tx['category'] == 'send':
            p2sh_utxos.append(TxInput(tx['txid'], tx['vout'], sequence=tx_lock))
            p2sh_balance += (-tx['amount'])
    # confirm that bitcoin-cli was able to locate transactions to p2sh address
    if not p2sh_utxos:
        errors.missing_utxos()  # prints error msg & raises systemExit

    # check current network fees and compute fee estimate
    resp = requests.get('https://api.blockcypher.com/v1/btc/test3').json()
    fee_per_kb = resp['medium_fee_per_kb']
    # per Output: 34 bytes | per Input: 200 bytes (estimate)
    script_size = 1 * 34 + len(p2sh_utxos) * 200
    fee = (script_size * fee_per_kb) / 100000000
    if fee >= p2sh_balance:
        fee = tools.user_custom_fee(fee, p2sh_balance)        

    # create and sign transaction
    tx_out = TxOutput((p2sh_balance-fee), p2pkh_addr.to_script_pub_key())
    # no change address, spending entire balance
    tx = Transaction(p2sh_utxos, [tx_out])
    pub_key = priv_key.get_public_key().to_hex()
    for i, txin in enumerate(p2sh_utxos):
        sig = priv_key.sign_input(tx, i, script)
        txin.script_sig = Script([sig, pub_key, script.to_hex()])
    tx_signed, tx_id = tx.serialize(), tx.get_txid()

    # writes tx_id into data.json and displays tx_signed (+details) to the user
    tools.update_data_json(outputs={'tx_id': tx_id, 'tx_signed': tx_signed})
    print('\nSpending from P2SH transaction')
    print(' -> to_addr:', p2pkh_addr.to_address())
    print(' -> amount:', p2sh_balance-fee)
    print(' -> fee:', fee)
    print(' -> tx_id:', tx_id)
    print(' -> tx_signed:',tx_signed, '\n')

    # broadcast signed transaction over bitcoin-cli
    r = tools.talk_to_cli(f'bitcoin-cli sendrawtransaction {tx_signed}', True)
    if len(r) == 64:
        print('\nTransaction broadcasted via bitcoin-cli successfully\n')
Beispiel #22
0
def get_gen_split_tx(tx_in: TxInput, id_l: Id, id_r: Id, script: Script, val_l: int, val_r, fee: float) -> Transaction:
    tx_out0 = TxOutput(val_l-0.5*fee, id_l.p2pkh)
    tx_out1 = TxOutput(val_r-0.5*fee, id_r.p2pkh)
    tx = Transaction([tx_in], [tx_out0, tx_out1])

    sig_l = id_l.sk.sign_input(tx, 0, Script(script))
    sig_r = id_r.sk.sign_input(tx, 0, Script(script))

    tx_in.script_sig = Script([sig_r, sig_l])

    return tx
Beispiel #23
0
    def create_ft(self, input_l: TxInput, input_r: TxInput, val_l: float, val_r: float) -> Transaction:
        txs_in = [input_l, input_r]
        tx_out = TxOutput(val_l + val_r - self.fee, scripts.get_script_ft_output(self.id_l, self.id_r))
        tx = Transaction(txs_in, [tx_out])

        sig_l = self.id_l.sk.sign_input(tx, 0 , self.id_l.p2pkh)
        sig_r = self.id_r.sk.sign_input(tx, 1 , self.id_r.p2pkh)

        input_l.script_sig = Script([sig_l, self.id_l.pk.to_hex()])
        input_r.script_sig = Script([sig_r, self.id_r.pk.to_hex()])
        return tx
Beispiel #24
0
def get_htlc(tx_in: TxInput, id_l: Id, id_r: Id, secret, hashed_secret, val_l: float, val_r: float, fee: float, l: bool, timelock) -> Transaction:
    tx_out = TxOutput(val_l-fee/2, scripts.get_script_lightning_locked(id_l, id_r, hashed_secret, timelock)) # output to l

    tx = Transaction([tx_in], [tx_out])

    scriptFToutput = scripts.get_script_ft_output(id_l, id_r)

    sig = id_l.sk.sign_input(tx, 0, scriptFToutput) # referenced tx is ft

    tx_in.script_sig = Script([sig, secret])

    return tx
Beispiel #25
0
    def create_close_tx(self, valA: float, valB: float) -> Transaction:
        tx_in = TxInput(self.ft.get_txid(), 0)
        tx_out_l = TxOutput(valA - self.fee, self.id_l.p2pkh)
        tx_out_r = TxOutput(valB - self.fee, self.id_r.p2pkh)

        tx = Transaction([tx_in], [tx_out_l, tx_out_r])

        sig_l = self.id_l.sk.sign_input(tx, 0 , scripts.get_script_ft_output(self.id_l, self.id_r))
        sig_r = self.id_r.sk.sign_input(tx, 0 , scripts.get_script_ft_output(self.id_l, self.id_r))

        tx_in.script_sig = Script([sig_r, sig_l])
        return tx
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 test_sigsingle_send(self):
        """
        SIGHASH_SINGLE:signs all inputs but only txin_index output
        """
        tx = Transaction([self.txin1_sigsingle], [self.txout1_sigsingle], has_segwit=True,witnesses = [])
        pk = self.sk.get_public_key().to_hex()

        sig_signone = self.sk.sign_segwit_input(tx, 0, self.p2pkh_redeem_script, self.txin1_sigsingle_amount,
                                                SIGHASH_SINGLE)
        tx.witnesses.append(Script([sig_signone, pk]))

        tx.outputs.append(self.txout2_sigsingle)
        self.assertEqual(tx.serialize(), self.test_sigsingle_send_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)
Beispiel #29
0
def get_gen_punish_tx(tx_in: TxInput, payee: Id, script: Script, id_as: Id, secret_rev, val: int, fee: float, l: bool) -> Transaction:
    tx_out = TxOutput(val-fee, payee.p2pkh)
    tx = Transaction([tx_in], [tx_out])

    sig = payee.sk.sign_input(tx, 0, Script(script))
    sig_as = id_as.sk.sign_input(tx, 0, Script(script))

    if l:
        tx_in.script_sig = Script([secret_rev, sig_as, 0x0, sig])
    else:
        tx_in.script_sig = Script([secret_rev, sig_as, sig, 0x0])

    return tx
Beispiel #30
0
def get_gen_ct_tx(tx_in: TxInput, id_l: Id, id_r: Id, id_as_l: Id, hashed_secret_rev_l, id_as_r: Id, hashed_secret_rev_r, val: float, fee: float, timelock: int) -> Transaction:
    timelock = 0x2
    tx_out = TxOutput(val-fee, scripts.get_script_split(id_l, id_r, id_as_l, hashed_secret_rev_l, id_as_r, hashed_secret_rev_r, timelock))
    tx = Transaction([tx_in], [tx_out])

    scriptFToutput = scripts.get_script_ft_output(id_l, id_r)

    sig_l = id_l.sk.sign_input(tx, 0 , scriptFToutput)
    sig_r = id_r.sk.sign_input(tx, 0 , scriptFToutput)

    tx_in.script_sig = Script([sig_r, sig_l])

    return tx