Пример #1
0
 def unsigned_settlement(self):
     """Generate the settlement transaction."""
     # Put outputs in the order of the inputs, so that both versions are the same
     if self.anchor.scriptSig.my_index == 0:
         transaction = CMutableTransaction([self.anchor], [self.our, self.their])
     elif self.anchor.scriptSig.my_index == 1:
         transaction = CMutableTransaction([self.anchor], [self.their, self.our])
     else:
         raise Exception("Unknown index", self.anchor.scriptSig.my_index)
     return CMutableTransaction.from_tx(transaction)
Пример #2
0
    def as_tx(self):
        sum_in = sum(prevtx.nValue for _, prevtx, _ in self.prevouts)
        sig_size = sum(redeemer.spendbytes for _, _, redeemer in self.prevouts)
        tx_size = (
            4 +  # version field
            2 +  # # of txins
            len(self.prevouts) * 41 +  # txins, excluding sigs
            sig_size +  # txins, sigs only
            1 +  # # of txouts
            34 +  # txout
            4  # nLockTime field
        )
        feerate = int(self.proxy._call('estimatefee', 1) * COIN)
        # satoshi's per KB
        if feerate <= 0:
            feerate = 10000
        fees = int(tx_size * feerate / 1000)

        tx = CMutableTransaction(
            [CTxIn(outpoint, nSequence=0) for outpoint, _, _ in self.prevouts],
            [CTxOut(sum_in - fees, self.payto.to_scriptPubKey())], 0)

        for n, (_, _, redeemer) in enumerate(self.prevouts):
            redeemer.mutate_spend(tx, n)

        unsigned_tx = CTransaction.from_tx(tx)

        for n, (_, _, redeemer) in enumerate(self.prevouts):
            txin = CMutableTxIn.from_txin(tx.vin[n])
            txin.scriptSig = redeemer.sign_spend(unsigned_tx, n)
            tx.vin[n] = CTxIn.from_txin(txin)

        print(b2x(tx.serialize()))
Пример #3
0
 def open_channel(self, my_money, their_money, fees, their_coins,
                  their_change, their_pubkey, their_addr):
     """Respond to a requested open."""
     assert self.state == 'begin'
     # Get inputs and change output
     coins, change = self.select_coins(my_money + 2 * fees)
     # Make the anchor script
     anchor_output_script = self.anchor_script(self.private_key.pub,
                                               their_pubkey)
     # Construct the anchor utxo
     payment = CMutableTxOut(my_money + their_money + 2 * fees,
                             anchor_output_script.to_p2sh_scriptPubKey())
     # Anchor tx
     transaction = CMutableTransaction(their_coins + coins,
                                       [payment, change, their_change])
     # Half-sign
     transaction = self.bitcoind.signrawtransaction(transaction)['tx']
     # Create channel in DB
     self.anchor.prevout = CMutableOutPoint(transaction.GetHash(), 0)
     self.anchor.scriptSig = AnchorScriptSig(0, b'', anchor_output_script)
     self.our.nValue = my_money
     self.our.scriptPubKey = self.bitcoind.getnewaddress()
     self.their.nValue = their_money
     self.their.scriptPubKey = their_addr
     # Event: channel opened
     channel_opened.send(self.cmd_id, address=self.address)
     self.bob.open_accept(transaction, anchor_output_script,
                          self.our.scriptPubKey)
     self.state = 'open_wait_1.5'
Пример #4
0
def submit_opreturn(rpc_connection, address, data):
    from bitcoin.core import CTxIn, CMutableTxOut, CScript, CMutableTransaction, COIN, CENT, b2x, b2lx
    from bitcoin.core.script import OP_CHECKSIG, OP_RETURN

    txouts = []

    unspent = sorted([y for y in rpc_connection.listunspent(0) if str(y['address']) == address], key=lambda x: hash(x['amount']))

    txins = [CTxIn(unspent[-1]['outpoint'])]

    value_in = unspent[-1]['amount']

    change_pubkey = rpc_connection.validateaddress(address)['pubkey']
    change_out = CMutableTxOut(int(value_in - 2*CENT), CScript([change_pubkey, OP_CHECKSIG]))
    digest_outs = [CMutableTxOut(CENT, CScript([OP_RETURN, data]))]
    txouts = [change_out] + digest_outs
    tx = CMutableTransaction(txins, txouts)
    
    print tx.serialize().encode('hex')
    r = rpc_connection.signrawtransaction(tx)
    assert r['complete']
    tx = r['tx']


    #print b2x(tx.serialize())
    #print len(tx.serialize()), 'bytes'
    print(b2lx(rpc_connection.sendrawtransaction(tx)))
Пример #5
0
def bump_feerate(bitcoind, tx, feerate_add, prevouts_amount=None):
    """Bump the feerate of a CTransaction.

    :param bitcoind: The bitcoind RPC connection, to access the wallet.
    :param tx: The CTransaction which is to be bumped.
    :param feerate_add: How much to increase the feerate, in sat/vbyte.
    :param prevouts_amount: The sum of the value of all the consumed outputs.

    :return: (CTransaction) The modified transaction.
    """
    # Work on a copy
    vin = [CMutableTxIn.from_txin(txin) for txin in tx.vin]
    vout = [CMutableTxOut.from_txout(txout) for txout in tx.vout]
    # FIXME: Add this to python-bitcoinlib
    wit = CTxWitness([
        CTxInWitness.from_txinwitness(txinwit) for txinwit in tx.wit.vtxinwit
    ])
    mut_tx = CMutableTransaction(vin,
                                 vout,
                                 witness=wit,
                                 nLockTime=tx.nLockTime,
                                 nVersion=tx.nVersion)

    fees = fees_to_add(bitcoind, mut_tx, feerate_add, prevouts_amount)
    if bitcoind.getbalance() * COIN > fees:
        return add_input(bitcoind, mut_tx, fees)

    raise Exception("Could not bump fees, no suitable utxo available!")
Пример #6
0
def redeem(proxy, redeemerGuy, contract, fundtx, secret):
    print('redeemPubKey', redeemerGuy['addr'])
    # TODO: Compare with script on blockchain?
    redeemScript = CScript(x(contract['redeemScript']))
    txin = CMutableTxIn(fundtx['outpoint'])
    txout = CMutableTxOut(fundtx['amount'] - FEE,
                          redeemerGuy['addr'].to_scriptPubKey())

    # Create the unsigned raw transaction.
    tx = CMutableTransaction([txin], [txout])
    sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL)
    # TODO: protect privkey better, separate signing from rawtx creation
    #privkey = self.bitcoind.dumpprivkey(self.redeemPubKey)
    sig = redeemerGuy['key'].sign(sighash) + bytes([SIGHASH_ALL])
    preimage = secret.encode('utf-8')
    # preimage = x(secret)
    txin.scriptSig = CScript([sig, redeemerGuy['key'].pub, preimage,
                              OP_TRUE, redeemScript])

    # print("txin.scriptSig", b2x(txin.scriptSig))
    txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey()
    print('Raw redeem transaction hex: ', b2x(tx.serialize()))
    VerifyScript(txin.scriptSig, txin_scriptPubKey,
                 tx, 0, (SCRIPT_VERIFY_P2SH,))
    print("Script verified, sending raw transaction...")
    txid = proxy.sendrawtransaction(tx)
    fund_tx = str(fundtx['outpoint'])
    redeem_tx = b2x(lx(b2x(txid)))
    return {"redeem_tx": redeem_tx, "fund_tx": fund_tx}
Пример #7
0
    def close_tx(self, fee: int, privkey_dest: str) -> str:
        """Create a (mutual) close tx"""
        txin = CTxIn(COutPoint(bytes.fromhex(self.txid), self.output_index))

        out_privkey = privkey_expand(privkey_dest)

        txout = CTxOut(self.amount - fee,
                       CScript([script.OP_0,
                                Hash160(coincurve.PublicKey.from_secret(out_privkey.secret).format())]))

        tx = CMutableTransaction(vin=[txin], vout=[txout])
        sighash = script.SignatureHash(self.redeemscript(), tx, inIdx=0,
                                       hashtype=script.SIGHASH_ALL,
                                       amount=self.amount,
                                       sigversion=script.SIGVERSION_WITNESS_V0)

        sigs = [key.sign(sighash, hasher=None) for key in self.funding_privkeys_for_tx()]
        # BOLT #3:
        # ## Closing Transaction
        # ...
        #    * `txin[0]` witness: `0 <signature_for_pubkey1> <signature_for_pubkey2>`
        witness = CScriptWitness([bytes(),
                                  sigs[0] + bytes([script.SIGHASH_ALL]),
                                  sigs[1] + bytes([script.SIGHASH_ALL]),
                                  self.redeemscript()])
        tx.wit = CTxWitness([CTxInWitness(witness)])
        return tx.serialize().hex()
Пример #8
0
def refund(proxy, refundGuy, contract):
    redeemScript = CScript(x(contract['redeemScript']))
    txin = CMutableTxIn(fundtx['outpoint'])
    txout = CMutableTxOut(fundtx['amount'] - FEE,
                          refundGuy['addr'].to_scriptPubKey())

    tx = CMutableTransaction([txin], [txout])
    txin.nSequence = 0
    tx.nLockTime = contract['redeemblocknum']
    sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL)

    sig = refundGuy['key'].sign(sighash) + bytes([SIGHASH_ALL])

    txin.scriptSig = CScript([sig, refundGuy['key'].pub, OP_FALSE, redeemScript])

    txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey()
    print('Raw redeem transaction hex: {0}'.format(b2x(tx.serialize())))
    res = VerifyScript(txin.scriptSig, txin_scriptPubKey,
                       tx, 0, (SCRIPT_VERIFY_P2SH,))
    print("Script verified, sending raw transaction... (NOT)", res)

    txid = proxy.sendrawtransaction(tx)
    refund_tx = b2x(lx(b2x(txid)))
    fund_tx = str(fundtx['outpoint'])
    return {"refund_tx": refund_tx, "fund_tx": fund_tx}
Пример #9
0
def create_trx(op_return_val, issuing_transaction_fee, issuing_address,
               tx_outs, tx_inputs):
    """

    :param op_return_val:
    :param issuing_transaction_fee:
    :param issuing_address:
    :param tx_outs:
    :param tx_input:
    :return:
    """
    cert_out = CMutableTxOut(0, CScript([OP_RETURN, op_return_val]))
    tx_ins = []
    value_in = 0
    for tx_input in tx_inputs:
        tx_ins.append(CTxIn(COutPoint(tx_input.tx_hash,
                                      tx_input.tx_out_index)))
        value_in += tx_input.coin_value

    # send change back to our address
    amount = value_in - issuing_transaction_fee
    if amount > 0:
        change_out = create_transaction_output(issuing_address, amount)
        tx_outs = tx_outs + [change_out]
    tx_outs = tx_outs + [cert_out]
    transaction = CMutableTransaction(tx_ins, tx_outs)
    return transaction
Пример #10
0
def create_signed_transaction_multi(txin, txout, txin_scriptPubKey,
                                    txin_scriptSig):
    tx = CMutableTransaction(txin, txout)
    txin.scriptSig = CScript(txin_scriptSig)
    VerifyScript(txin.scriptSig, CScript(txin_scriptPubKey),
                 tx, 0, (SCRIPT_VERIFY_P2SH,))
    return tx
Пример #11
0
def test_emergency_txout(bitcoind):
    """Test mostly the emergency tx locktime"""
    amount = Decimal("50") - Decimal("500") / Decimal(COIN)
    privkeys = [CKey(os.urandom(32)) for _ in range(4)]
    pubkeys = [k.pub for k in privkeys]
    txo = emergency_txout(pubkeys, COIN * amount)
    addr = str(CBitcoinAddress.from_scriptPubKey(txo.scriptPubKey))
    # This makes a transaction with only one vout
    txid = bitcoind.pay_to(addr, amount)
    new_amount = amount - Decimal("500") / Decimal(COIN)
    addr = bitcoind.getnewaddress()
    txin = CTxIn(COutPoint(lx(txid), 0), nSequence=4464)
    txout = CTxOut(new_amount * COIN, CBitcoinAddress(addr).to_scriptPubKey())
    tx = CMutableTransaction([txin], [txout], nVersion=2)
    tx_hash = SignatureHash(emergency_script(pubkeys), tx, 0, SIGHASH_ALL,
                            int(amount * COIN), SIGVERSION_WITNESS_V0)
    sigs = [k.sign(tx_hash) + bytes([SIGHASH_ALL]) for k in privkeys]
    witness_script = [bytes(0), *sigs, emergency_script(pubkeys)]
    tx.wit = CTxWitness([CTxInWitness(CScriptWitness(witness_script))])
    # 1 month of locktime
    bitcoind.generate_block(4464 - 2)
    with pytest.raises(VerifyRejectedError, match="non-BIP68-final"):
        bitcoind.send_tx(tx.serialize().hex())
    bitcoind.generate_block(1)
    bitcoind.send_tx(tx.serialize().hex())
    assert bitcoind.has_utxo(addr)
Пример #12
0
def open_channel(address, mymoney, theirmoney, fees, their_coins, their_change,
                 their_pubkey, their_out_addr):  # pylint: disable=too-many-arguments, line-too-long
    """Open a payment channel."""
    # Get inputs and change output
    coins, change = select_coins(mymoney + 2 * fees)
    # Make the anchor script
    anchor_output_script = anchor_script(get_pubkey(), their_pubkey)
    # Construct the anchor utxo
    payment = CMutableTxOut(mymoney + theirmoney + 2 * fees,
                            anchor_output_script.to_p2sh_scriptPubKey())
    # Anchor tx
    transaction = CMutableTransaction(their_coins + coins,
                                      [payment, change, their_change])
    # Half-sign
    transaction = g.bit.signrawtransaction(transaction)['tx']
    # Create channel in DB
    our_addr = g.bit.getnewaddress()
    channel = Channel(
        address=address,
        anchor_point=COutPoint(transaction.GetHash(), 0),
        anchor_index=0,
        their_sig=b'',
        anchor_redeem=anchor_output_script,
        our_balance=mymoney,
        our_addr=our_addr,
        their_balance=theirmoney,
        their_addr=their_out_addr,
    )
    database.session.add(channel)
    database.session.commit()
    # Event: channel opened
    CHANNEL_OPENED.send('channel', address=address)
    return (transaction, anchor_output_script, our_addr)
Пример #13
0
def partial_spend_p2sh_mediator(redeemScript,
                                rein,
                                mediator_address,
                                mediator_sig=False):
    txin_redeemScript = CScript(x(redeemScript))
    txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey()
    txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey)
    (txins, total_value) = unspent_txins(txin_p2sh_address, rein.testnet)
    if len(txins) == 0:
        raise ValueError('No unspent txins found')
    txins_str = ""
    txins_obj = []
    for txid, vout in txins:
        txins_str += " " + txid + "-" + str(vout)
        txins_obj.append(CMutableTxIn(COutPoint(lx(txid), vout)))
    fee = 0.00025
    amount = round(total_value - fee, 8)
    if amount <= 0:
        raise ValueError('Not enough value in the inputs')
    if mediator_sig:
        txout = CMutableTxOut(
            amount * COIN,
            CBitcoinAddress(mediator_address).to_scriptPubKey())
        tx = CMutableTransaction(txins_obj, [txout])
        seckey = CBitcoinSecret(rein.user.dkey)
        ntxins = len(txins_obj)
        sig = ""
        for i in range(0, ntxins):
            sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL)
            sig += " " + b2x(seckey.sign(sighash) + x("01"))
        return (txins_str[1:], "{:.8f}".format(amount), str(mediator_address),
                sig[1:])
    return (txins_str[1:], "{:.8f}".format(amount), str(mediator_address))
Пример #14
0
def open_channel(address, mymoney, theirmoney, fees, their_coins, their_change, their_pubkey, their_out_addr): # pylint: disable=too-many-arguments
    """Open a payment channel."""
    # Get inputs and change output
    coins, change = select_coins(mymoney + 2 * fees)
    # Make the anchor script
    anchor_output_script = anchor_script(get_pubkey(), their_pubkey)
    anchor_output_address = anchor_output_script.to_p2sh_scriptPubKey()
    # Construct the anchor utxo
    payment = CMutableTxOut(mymoney + theirmoney + 2 * fees, anchor_output_address)
    # Anchor tx
    transaction = CMutableTransaction(
        their_coins + coins,
        [payment, change, their_change])
    # Half-sign
    transaction = g.bit.signrawtransaction(transaction)['tx']
    # Create channel in DB
    channel = Channel(address,
                      CMutableTxIn(CMutableOutPoint(transaction.GetHash(), 0),
                                   AnchorScriptSig(0, b'', anchor_output_script)),
                      CMutableTxOut(mymoney, g.bit.getnewaddress()),
                      CMutableTxOut(theirmoney, their_out_addr))
    channel.put()
    # Event: channel opened
    CHANNEL_OPENED.send('channel', address=address)
    return (transaction, anchor_output_script, channel.our.scriptPubKey)
Пример #15
0
def spend_p2sh_mediator(redeemScript, txins_str, amounts, daddrs, sig, rein):
    txin_redeemScript = CScript(x(redeemScript))
    txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey()
    txins_obj = []
    for txin_str in txins_str.split():
        txin_list = txin_str.split("-")
        txins_obj.append(
            CMutableTxIn(COutPoint(lx(txin_list[0]), int(txin_list[1]))))
    txouts = []
    len_amounts = len(amounts)
    for i in range(0, len_amounts):
        txouts.append(
            CMutableTxOut(
                round(amounts[i], 8) * COIN,
                CBitcoinAddress(daddrs[i]).to_scriptPubKey()))
    tx = CMutableTransaction(txins_obj, txouts)
    seckey = CBitcoinSecret(rein.user.dkey)
    ntxins = len(txins_obj)
    sig_list = []
    for s in sig.split():
        sig_list.append(x(s))
    sig2_str = ""
    for i in range(0, ntxins):
        sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL)
        sig2 = seckey.sign(sighash) + x("01")
        sig2_str += " " + b2x(sig2)
        txins_obj[i].scriptSig = CScript(
            [OP_0, sig2, sig_list[i], txin_redeemScript])
        VerifyScript(txins_obj[i].scriptSig, txin_scriptPubKey, tx, i,
                     (SCRIPT_VERIFY_P2SH, ))
    tx_bytes = tx.serialize()
    hash = sha256(sha256(tx_bytes).digest()).digest()
    txid = b2x(hash[::-1])
    txid_causeway = broadcast_tx(b2x(tx_bytes), rein)
    return (txid, sig2_str[1:])
Пример #16
0
    def refund(self, contract):
        fundtx = self.find_transaction_to_address(contract.p2sh)
        print("Fund tx found in refund: ", fundtx)
        refundPubKey = self.find_refundAddr(contract)
        print('refundPubKey: {0}'.format(refundPubKey))

        redeemScript = CScript(x(contract.redeemScript))
        txin = CMutableTxIn(fundtx['outpoint'])
        txout = CMutableTxOut(fundtx['amount'] - FEE,
                              refundPubKey.to_scriptPubKey())

        # Create the unsigned raw transaction.
        tx = CMutableTransaction([txin], [txout])
        # Set nSequence and nLockTime
        txin.nSequence = 0
        tx.nLockTime = contract.redeemblocknum
        sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL)
        privkey = self.bitcoind.dumpprivkey(refundPubKey)
        sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])

        # Sign without secret
        txin.scriptSig = CScript([sig, privkey.pub, OP_FALSE, redeemScript])

        # txin.nSequence = 2185
        txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey()
        print('Raw redeem transaction hex: {0}'.format(b2x(tx.serialize())))
        res = VerifyScript(txin.scriptSig, txin_scriptPubKey,
                           tx, 0, (SCRIPT_VERIFY_P2SH,))
        print("Script verified, sending raw transaction... (NOT)", res)
        txid = self.bitcoind.sendrawtransaction(tx)
        refund_tx = b2x(lx(b2x(txid)))
        fund_tx = str(fundtx['outpoint'])
        return {"refund_tx": refund_tx, "fund_tx": fund_tx}
Пример #17
0
def create_signed_transaction_multiple_receivers(txin, txout, txin_scriptPubKey,
                                                 txin_scriptSig):
    tx = CMutableTransaction([txin], txout)
    txin.scriptSig = CScript(txin_scriptSig)
    # print(txin.scriptSig)
    # VerifyScript(txin.scriptSig, CScript(txin_scriptPubKey),
    #              tx, 0, (SCRIPT_VERIFY_P2SH,))
    return tx
Пример #18
0
def create_signed_transaction(txin, txout, txin_scriptPubKey,
                              txin_scriptSig):
    tx = CMutableTransaction([txin], flatten([txout]))
    txin.scriptSig = CScript(txin_scriptSig)
    # print(txin.scriptSig)
    # VerifyScript(txin.scriptSig, CScript(txin_scriptPubKey),
    #              tx, 0, (SCRIPT_VERIFY_P2SH,))
    return tx
 def test_sendrawtransaction(self):
     num_outputs = 5
     given_transaction = CMutableTransaction([], [make_txout() for x in range(0, num_outputs)])
     expected_txid = b2lx(given_transaction.GetHash())
     given_transaction_hex = b2x(given_transaction.serialize())
     proxy = FakeBitcoinProxy()
     resulting_txid = proxy.sendrawtransaction(given_transaction_hex)
     self.assertEqual(resulting_txid, expected_txid)
Пример #20
0
 def test_json_roundtrip(self):
     VALUES = [
         42,
         0,
         -42,
         2100000000000000,
         -2100000000000000,
         "basic string",
         "\u1111Unicode",
         "\U00010000Wide Unicode",
         "\x00\n\t\r\nEscape codes",
         "\"'\"Quotes",
         "",
         None,
         b"\x00\x01\xFFBinary data",
         b"",
         CBase58Data.from_bytes(b'\x00\x01\xFF', 42),
         P2SHBitcoinAddress.from_bytes(b'\x00\x01\xFF'),
         P2PKHBitcoinAddress.from_bytes(b'\x00\x01\xFF'),
         CMutableTxIn(COutPoint(b'\x00' * 16 + b'\xFF' * 16, 42),
                      CScript(b'\x00\x01\xFF'), 42),
         CMutableTxOut(42, CScript(b'\x00\x01\xFF')),
         CMutableTransaction([
             CMutableTxIn(COutPoint(b'\x00' * 32, 42),
                          CScript(b'\x00\x01\xFF'), 42),
             CMutableTxIn(COutPoint(b'\xFF' * 32, 42),
                          CScript(b'\xFF\x01\x00'), 43)
         ], [
             CMutableTxOut(42, CScript(b'\x00\x01\xFF')),
             CMutableTxOut(43, CScript(b'\xFF\x01\x00'))
         ], 42, 3),
         [
             1,
             b'\x00\x01\xFF',
             "List Test",
         ],
         {
             'a': 1,
             'key': b'\xFF\x01\x00',
             1: 'Dictionary Test'
         },
         [
             {
                 3: [
                     0,
                     1,
                     2,
                 ],
             },
             [
                 [
                     b'\xFFRecursion Test',
                 ],
             ],
         ],
     ]
     for value in VALUES:
         self.assertEqual(from_json(to_json(value)), value)
    def test_fundrawtransaction_adds_output(self):
        num_outputs = 5
        unfunded_transaction = CMutableTransaction([], [make_txout() for x in range(0, num_outputs)])
        proxy = FakeBitcoinProxy()

        funded_transaction_hex = proxy.fundrawtransaction(b2x(unfunded_transaction.serialize()))["hex"]
        funded_transaction = CMutableTransaction.deserialize(x(funded_transaction_hex))

        self.assertTrue(len(funded_transaction.vout) > num_outputs)
        self.assertEqual(len(funded_transaction.vout), num_outputs + 1)
Пример #22
0
 def commitment(self, ours=False):
     """Return an unsigned commitment transaction."""
     first = CMutableTxOut(self.our_balance,
                           self.our_addr.to_scriptPubKey())
     second = CMutableTxOut(self.their_balance,
                            self.their_addr.to_scriptPubKey())
     if not ours:
         first, second = second, first
     return CMutableTransaction([CMutableTxIn(self.anchor_point)],
                                [first, second])
Пример #23
0
 def put(self):
     """Persist self."""
     commitment = CMutableTransaction([self.anchor], [self.our, self.their])
     commitment = CMutableTransaction.from_tx(commitment)
     commitment.vin[0].scriptSig = commitment.vin[0].scriptSig.to_script()
     for tx_out in commitment.vout:
         tx_out.scriptPubKey = tx_out.scriptPubKey.to_scriptPubKey()
     with g.dat:
         g.dat.execute("INSERT OR REPLACE INTO CHANNELS VALUES (?, ?)",
                       (self.address, commitment.serialize()))
Пример #24
0
def test_create_transaction_object_1(inputs_1, outputs_1):
    r = PaymentService.create_transaction_object(inputs=inputs_1, outputs=outputs_1)

    tx_in: List[CMutableTxIn] = [
        CMutableTxIn(COutPoint(lx('4521418569de2f78d5d2d3c535567ac9c48c95314c53a67788d4dcdc9a8d915b'), 0))]

    pk = CBitcoinAddress('16moGJwkzWhNC1pfnfJptKj9G1ogQz16xd').to_scriptPubKey()
    tx_out: List[CMutableTxOut] = [CMutableTxOut(100000, pk)]

    expected = CMutableTransaction(tx_in, tx_out)
    assert b2x(r.serialize()) == b2x(expected.serialize())
Пример #25
0
def create_unvault_spend(unvault_txid, unvault_vout, txout):
    """Creates a transaction spending from an unvault transaction.

    :param unvault_txid: The id of the unvaulting transaction.
    :param unvault_vout: The index of the unvault output in this transaction.
    :param txout: The txo (a CTxOut) to spend the coins to.

    :return: The unsigned transaction, a CMutableTransaction.
    """
    txin = CTxIn(COutPoint(unvault_txid, unvault_vout))
    return CMutableTransaction([txin], [txout], nVersion=2)
Пример #26
0
 def sig_for_them(self):
     """Generate a signature for the mirror commitment transaction."""
     transaction = CMutableTransaction([self.anchor], [self.their, self.our])
     transaction = CMutableTransaction.from_tx(transaction) # copy
     # convert scripts to CScript
     transaction.vin[0].scriptSig = transaction.vin[0].scriptSig.to_script()
     for tx_out in transaction.vout:
         tx_out.scriptPubKey = tx_out.scriptPubKey.to_scriptPubKey()
     # sign
     sighash = SignatureHash(self.anchor.scriptSig.redeem, transaction, 0, SIGHASH_ALL)
     sig = g.seckey.sign(sighash) + bytes([SIGHASH_ALL])
     return sig
Пример #27
0
    def redeem_contract(self, contract, secret):
        print("Parsing script for redeem_contract...")
        scriptarray = self.parse_script(contract.redeemScript)
        redeemblocknum = scriptarray[8]
        redeemPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[6]))
        refundPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[13]))
        p2sh = contract.p2sh
        #checking there are funds in the address
        amount = self.check_funds(p2sh)
        if(amount == 0):
            print("address ", p2sh, " not funded")
            quit()
        fundtx = self.find_transaction_to_address(p2sh)
        amount = fundtx['amount'] / COIN
        # print("Found fund_tx: ", fundtx)
        p2sh = P2SHBitcoinAddress(p2sh)
        if fundtx['address'] == p2sh:
            print("Found {0} in p2sh {1}, redeeming...".format(amount, p2sh))

            blockcount = self.bitcoind.getblockcount()
            print("\nCurrent blocknum at time of redeem on Zcash:", blockcount)
            if blockcount < int(redeemblocknum):
                print('redeemPubKey', redeemPubKey)
                zec_redeemScript = CScript(x(contract.redeemScript))
                txin = CMutableTxIn(fundtx['outpoint'])
                txout = CMutableTxOut(fundtx['amount'] - FEE, redeemPubKey.to_scriptPubKey())
                # Create the unsigned raw transaction.
                tx = CMutableTransaction([txin], [txout])
                sighash = SignatureHash(zec_redeemScript, tx, 0, SIGHASH_ALL)
                # TODO: protect privkey better, separate signing from rawtx creation
                privkey = self.bitcoind.dumpprivkey(redeemPubKey)
                sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
                preimage = secret.encode('utf-8')
                txin.scriptSig = CScript([sig, privkey.pub, preimage, OP_TRUE, zec_redeemScript])

                # print("txin.scriptSig", b2x(txin.scriptSig))
                txin_scriptPubKey = zec_redeemScript.to_p2sh_scriptPubKey()
                print('Raw redeem transaction hex: ', b2x(tx.serialize()))
                VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
                print("Script verified, sending raw transaction...")
                txid = self.bitcoind.sendrawtransaction(tx)
                fund_tx = str(fundtx['outpoint'])
                redeem_tx =  b2x(lx(b2x(txid)))
                return  {"redeem_tx": redeem_tx, "fund_tx": fund_tx}
            else:
                print("nLocktime exceeded, refunding")
                print('refundPubKey', refundPubKey)
                txid = self.bitcoind.sendtoaddress(refundPubKey, fundtx['amount'] - FEE)
                fund_tx = str(fundtx['outpoint'])
                refund_tx =  b2x(lx(b2x(txid)))
                return  {"refund_tx": refund_tx, "fund_tx": fund_tx}
        else:
            print("No contract for this p2sh found in database", p2sh)
    def test_fundrawtransaction_hex_hash(self):
        unfunded_transaction = CMutableTransaction([], [make_txout() for x in range(0, 5)])
        proxy = FakeBitcoinProxy()

        funded_transaction_hex = proxy.fundrawtransaction(b2x(unfunded_transaction.serialize()))["hex"]
        funded_transaction = CMutableTransaction.deserialize(x(funded_transaction_hex))

        self.assertTrue(unfunded_transaction is not funded_transaction)
        self.assertEqual(type(funded_transaction), type(unfunded_transaction))
        self.assertNotEqual(len(funded_transaction.vin), 0)
        self.assertTrue(len(funded_transaction.vin) > len(unfunded_transaction.vin))
        self.assertEqual(type(funded_transaction.vin[0]), CTxIn)
Пример #29
0
def create_unvault_spend(unvault_txid, unvault_vout, txout, rbf=False):
    """Creates a transaction spending from an unvault transaction.

    :param unvault_txid: The id of the unvaulting transaction.
    :param unvault_vout: The index of the unvault output in this transaction.
    :param txout: The txo (a CTxOut) to spend the coins to.
    :param rbf: If set to True, signal RBF.

    :return: The unsigned transaction, a CMutableTransaction.
    """
    sequence = 0xfffffffe if rbf else 0xffffffff
    txin = CTxIn(COutPoint(unvault_txid, unvault_vout), nSequence=sequence)
    return CMutableTransaction([txin], [txout], nVersion=2)
Пример #30
0
def create_spend_vault_txout(vault_txid, vault_vout, txout):
    """Creates a transaction spending a vault txout.

    Note that this transaction only ever has one input and one output.

    :param vault_txid: The id of the transaction funding the vault, as bytes.
    :param vault_vout: The index of the vault output in this transaction.
    :param txout: The CTxOut to pay to.

    :return: The *unsigned* transaction, a CMutableTransaction.
    """
    tmp_txin = CTxIn(COutPoint(vault_txid, vault_vout))
    return CMutableTransaction([tmp_txin], [txout], nVersion=2)