Ejemplo n.º 1
0
    def refund_tx(self, payer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction refunding the funder of
            the P2SH address.
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([payer_sig + '\x01', OP_FALSE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("refund_tx: TXID is %s", txid)
        self.logger.info("refund_tx: RAW TX is %s", b2x(serial_tx))

        return serial_tx
Ejemplo n.º 2
0
def spend_escrow(serial_tx, redeem_script, payer_sig, redeemer_sig):
    '''
        Sends a transaction fulfilling the redeem script of escrow tx
    '''
    # Read in transaction
    temp_tx = CTransaction.deserialize(serial_tx)
    tx = CMutableTransaction.from_tx(temp_tx)

    txin = tx.vin[0]

    # Set script sig
    txin.scriptSig = CScript([OP_0,
                             payer_sig + '\x01',
                             redeemer_sig + '\x01',
                             redeem_script])

    # Verify script
    redeem_script = CScript(redeem_script)
    serial_tx = tx.serialize()
    VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(),
                 tx, 0, [SCRIPT_VERIFY_P2SH])

    serial_tx = tx.serialize()
    txid = b2lx(Hash(serial_tx))

    print("spend_escrow: TXID is %s" % txid)
    print("spend_escrow: RAW TX is %s" % b2x(serial_tx))

    return serial_tx
Ejemplo n.º 3
0
    def spend_escrow(self, payer_sig, redeemer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction fulfilling the redeem script of escrow tx
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([
            OP_FALSE, payer_sig + '\x01', redeemer_sig + '\x01', OP_TRUE,
            redeem_script
        ])

        # Verify script
        redeem_script = CScript(redeem_script)
        serial_tx = tx.serialize()
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_escrow: TXID is %s", txid)
        self.logger.info("spend_escrow: RAW TX is %s", b2x(serial_tx))

        return serial_tx
Ejemplo n.º 4
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()))
Ejemplo n.º 5
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)
Ejemplo n.º 6
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
Ejemplo n.º 7
0
 def signed_commitment(self):
     """Return the fully signed commitment transaction."""
     transaction = CMutableTransaction([self.anchor], [self.our, self.their])
     transaction = CMutableTransaction.from_tx(transaction)
     for tx_out in transaction.vout:
         tx_out.scriptPubKey = tx_out.scriptPubKey.to_scriptPubKey()
     sighash = SignatureHash(self.anchor.scriptSig.redeem, transaction, 0, SIGHASH_ALL)
     sig = g.seckey.sign(sighash) + bytes([SIGHASH_ALL])
     transaction.vin[0].scriptSig = transaction.vin[0].scriptSig.to_script(sig)
     # verify signing worked
     VerifyScript(transaction.vin[0].scriptSig,
                  self.anchor.scriptSig.redeem.to_p2sh_scriptPubKey(),
                  transaction, 0, (SCRIPT_VERIFY_P2SH,))
     return transaction
Ejemplo n.º 8
0
def spend_preimage(redeem_script, preimages, redeemer_sig, serial_tx):
    """
    Creates a transaction fulfilling the redeem script of the preimage P2SH.

    Arguements:
        redeem_script (bytes): The script that specifies the conditions that a tx has
                        to fulfill to transfer funds from the `funding_tx`
        preimages (list): The preimages that hash into the hash values
                          specified in the `redeem_script`
        redeemer_sig (bytes): The signature of the redeemer on the `serial_tx`
        serial_tx (bytes): The serial transaction

    Returns:
        The serial raw transaction that passes the script verification
    """
    # Read in transaction
    temp_tx = CTransaction.deserialize(serial_tx)
    tx = CMutableTransaction.from_tx(temp_tx)

    txin = tx.vin[0]

    # Setup preimages in reverse order
    script = []
    for p in reversed(preimages):
        script += [p]

    # Create script sig
    txin.scriptSig = CScript([redeemer_sig + '\x01'] + script +
                             [redeem_script])

    # Verify script
    redeem_script = CScript(redeem_script)
    try:
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])
    except ValidationError:
        print("spend_preimage: Script failed to verify")
        return None

    serial_tx = tx.serialize()
    txid = b2lx(Hash(serial_tx))

    print("spend_preimage: TXID is %s" % txid)
    print("spend_preimage: RAW TX is %s" % b2x(serial_tx))

    return serial_tx
Ejemplo n.º 9
0
 def get(cls, address):
     """Get a Channel with the specified address."""
     row = g.dat.execute(
         "SELECT * from CHANNELS WHERE address = ?", (address,)).fetchone()
     if row is None:
         raise Exception("Unknown address", address)
     address, commitment = row
     commitment = CMutableTransaction.deserialize(commitment)
     commitment = CMutableTransaction.from_tx(commitment)
     assert len(commitment.vin) == 1
     assert len(commitment.vout) == 2
     commitment.vin[0].scriptSig = AnchorScriptSig.from_script(
         commitment.vin[0].scriptSig)
     for tx_out in commitment.vout:
         tx_out.scriptPubKey = CBitcoinAddress.from_scriptPubKey(tx_out.scriptPubKey)
     return cls(address,
                commitment.vin[0],
                commitment.vout[0],
                commitment.vout[1])
Ejemplo n.º 10
0
def spend_escrow(redeem_script, payer_sig, redeemer_sig, serial_tx):
    """
    Creates a transaction fulfilling the redeem script of the escrow P2SH.

    Arguements:
        redeem_script (bytes): The script that specifies the conditions that a tx has
                        to fulfill to transfer funds from the `funding_tx`
        payer_sig (bytes): The signature of the payer on the `serial_tx`
        redeemer_sig (bytes): The signature of the redeemer on the `serial_tx`
        serial_tx (bytes): The serial transaction

    Returns:
        The serial raw transaction that passes the script verification
    """
    # Read in transaction
    temp_tx = CTransaction.deserialize(serial_tx)
    tx = CMutableTransaction.from_tx(temp_tx)

    txin = tx.vin[0]

    # Set script sig
    txin.scriptSig = CScript(
        [OP_0, payer_sig + '\x01', redeemer_sig + '\x01', redeem_script])

    # Verify script
    redeem_script = CScript(redeem_script)
    serial_tx = tx.serialize()

    try:
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])
    except ValidationError:
        print("spend_escrow: Script failed to verify")
        return None

    serial_tx = tx.serialize()
    txid = b2lx(Hash(serial_tx))

    print("spend_escrow: TXID is %s" % txid)
    print("spend_escrow: RAW TX is %s" % b2x(serial_tx))

    return serial_tx
Ejemplo n.º 11
0
    def get_keys_from_tx(self, serial_tx, n_keys=15):
        '''Extracts n_keys from tx in serial form'''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        # Keys are in txin.scriptSig
        txin = tx.vin[0]
        script = txin.scriptSig

        # Extract keys from script
        keys = []
        for i, op in enumerate(script):
            if i in range(1, n_keys + 1):
                keys += [op]

        # Serialize keys in correct order
        serial_keys = ""
        for op in reversed(keys):
            serial_keys += op

        return serial_keys
Ejemplo n.º 12
0
    def spend_preimage(self, preimages, redeemer_sig, serial_tx,
                       redeem_script):
        '''
            Sends a transaction fulfilling the redeem script
            of the preimage P2SH
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Setup preimages in reverse order
        script = []
        for p in reversed(preimages):
            script += [p]

        # Create script sig
        txin.scriptSig = CScript([redeemer_sig + '\x01'] + script +
                                 [OP_TRUE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_preimage: TXID is %s", txid)
        self.logger.info("spend_preimage: RAW TX is %s", b2x(serial_tx))

        return serial_tx
Ejemplo n.º 13
0
            if unspent_tx.vout[0].nValue < args.amount:
                continue

            if check_full_rbf_optin(unspent_tx):
                tx1 = unspent_tx
                logging.info('Found unconfirmed full-RBF tx1 %s' % b2lx(txid))
                break

            else:
                txids_seen.add(txid)

    else:
        logging.info('No unconfirmed full-RBF tx1 found; creating new tx')


tx2 = CMutableTransaction.from_tx(tx1) if tx1 is not None else CMutableTransaction()

# There might be a better way to fund the new outputs, so delete all but the
# first input. Of course, we can't delete all the inputs - the new transaction
# wouldn't conflict with the old one and you'd pay everyone twice!
tx2.vin = tx2.vin[0:1]

if not args.first_seen_safe and len(tx2.vout) > 0:
    # Delete the change output.
    #
    # Unfortunately there isn't any way to ask Bitcoin Core if a given address
    # is a change address; if you're sending yourself funds to test the feature
    # it's not possible to distinguish change from send-to-self outputs.
    #
    # So instead we always build transactions such that the first output is
    # change, and we delete only that output. Not pretty - you don't want to do
Ejemplo n.º 14
0
            # FIXME: this still fails if amount doesn't leave enough for fees
            if unspent_tx.vout[0].nValue < args.amount:
                continue

            if check_full_rbf_optin(unspent_tx):
                tx1 = unspent_tx
                logging.info('Found unconfirmed full-RBF tx1 %s' % b2lx(txid))
                break

            else:
                txids_seen.add(txid)

    else:
        logging.info('No unconfirmed full-RBF tx1 found; creating new tx')

tx2 = CMutableTransaction.from_tx(
    tx1) if tx1 is not None else CMutableTransaction()

# There might be a better way to fund the new outputs, so delete all but the
# first input. Of course, we can't delete all the inputs - the new transaction
# wouldn't conflict with the old one and you'd pay everyone twice!
tx2.vin = tx2.vin[0:1]

if not args.first_seen_safe and len(tx2.vout) > 0:
    # Delete the change output.
    #
    # Unfortunately there isn't any way to ask Bitcoin Core if a given address
    # is a change address; if you're sending yourself funds to test the feature
    # it's not possible to distinguish change from send-to-self outputs.
    #
    # So instead we always build transactions such that the first output is
    # change, and we delete only that output. Not pretty - you don't want to do
Ejemplo n.º 15
0
try:
    args.txid = lx(args.txid)
except ValueError as err:
    parser.error('Invalid txid: %s' % str(err))

if len(args.txid) != 32:
    parser.error('Invalid txid: Wrong length.')

try:
    rpc.gettransaction(args.txid)
except IndexError as err:
    parser.exit('Invalid txid: Not in wallet.')

txinfo = rpc.getrawtransaction(args.txid, True)
tx = CMutableTransaction.from_tx(txinfo['tx'])

if 'confirmations' in txinfo and txinfo['confirmations'] > 0:
    parser.exit("Transaction already mined; %d confirmations." % txinfo['confirmations'])

# Find a txout that was being used for change
change_txout = None
for vout in tx.vout:
    try:
        addr = CBitcoinAddress.from_scriptPubKey(vout.scriptPubKey)
    except ValueError:
        continue

    if rpc.validateaddress(addr)['ismine']:
        change_txout = vout
        break
Ejemplo n.º 16
0
try:
    args.txid = lx(args.txid)
except ValueError as err:
    parser.error('Invalid txid: %s' % str(err))

if len(args.txid) != 32:
    parser.error('Invalid txid: Wrong length.')

try:
    rpc.gettransaction(args.txid)
except IndexError as err:
    parser.exit('Invalid txid: Not in wallet.')

txinfo = rpc.getrawtransaction(args.txid, True)
tx = CMutableTransaction.from_tx(txinfo['tx'])

if 'confirmations' in txinfo and txinfo['confirmations'] > 0:
    parser.exit("Transaction already mined; %d confirmations." %
                txinfo['confirmations'])

# Find a txout that was being used for change
change_txout = None
for vout in tx.vout:
    try:
        addr = CBitcoinAddress.from_scriptPubKey(vout.scriptPubKey)
    except ValueError:
        continue

    if rpc.validateaddress(addr)['ismine']:
        change_txout = vout
Ejemplo n.º 17
0
        new_txin = CMutableTxIn(new_outpoint)
        tx.vin.append(new_txin)

        value_in += new_amount
        change_txout.nValue += new_amount
        value_out += new_amount

        # Resign the tx so we can figure out how large the new input's scriptSig will be.
        r = rpc.signrawtransaction(tx)
        assert(r['complete'])

        tx.vin[-1].scriptSig = r['tx'].vin[-1].scriptSig

r = rpc.signrawtransaction(tx)
assert(r['complete'])
tx = CMutableTransaction.from_tx(r['tx'])

logging.debug('Payment tx %s' % b2x(tx.serialize()))
logging.info('Payment tx size: %.3f KB, fees: %s, %s BTC/KB' % \
        (len(tx.serialize()) / 1000,
         str_money_value(value_in-value_out),
         str_money_value((value_in-value_out) / len(tx.serialize()) * 1000)))


if not args.dryrun:
    txid = rpc.sendrawtransaction(tx)
    logging.info('Sent payment tx: %s' % b2lx(txid))

if not args.dryrun:
    logging.info('Sleeping for %d seconds' % args.delay)
    time.sleep(args.delay)
        new_txin = CMutableTxIn(new_outpoint, nSequence=tx1_nSequence)
        tx.vin.append(new_txin)

        value_in += new_amount
        change_txout.nValue += new_amount
        value_out += new_amount

        r = rpc.signrawtransaction(tx)
        assert(r['complete'])

        tx.vin[-1].scriptSig = r['tx'].vin[-1].scriptSig

r = rpc.signrawtransaction(tx)
assert(r['complete'])
tx = CMutableTransaction.from_tx(r['tx'])

print('Payment raw transaction %s' % b2x(tx.serialize()))
print('Payment raw transaction size: %.3f KB, fees: %s, %s BTC/KB' % \
             (len(tx.serialize()) / 1000,
              str_money_value(value_in-value_out),
              str_money_value((value_in-value_out) / len(tx.serialize()) * 1000)))



txid = rpc.sendrawtransaction(tx)
print('Sent payment with txid: %s' % b2lx(txid))


print('Waiting for %d seconds before double spending' % 2)
time.sleep(10)
Ejemplo n.º 19
0
def test_increase_revault_tx_feerate(bitcoind):
    """This tests that any of the stakeholders can increase the feerate of any
    of the revaulting transactions in a timely manner. Will justice rule?"""
    # The stakeholders, the first two are the traders.
    stk_privkeys = [os.urandom(32) for i in range(4)]
    stk_pubkeys = [CKey(k).pub for k in stk_privkeys]
    # Same, but for the EDV
    emer_privkeys = [os.urandom(32) for i in range(4)]
    emer_pubkeys = [CKey(k).pub for k in emer_privkeys]
    # The co-signing server, required by the spend tx
    serv_privkey = os.urandom(32)
    serv_pubkey = CKey(serv_privkey).pub

    # Test the vault emergency
    amount_vault = 50 * COIN - 500
    txid = send_vault_tx(bitcoind, stk_pubkeys, amount_vault)
    amount_emer = amount_vault - 500
    CTx = create_emergency_vault_tx(lx(txid), 0, amount_emer, emer_pubkeys)
    sigs = [
        sign_emergency_vault_tx(CTx, p, stk_pubkeys, amount_vault)
        for p in stk_privkeys
    ]
    # Sanity checks don't hurt
    assert all(sig[-1] == SIGHASH_ALL | SIGHASH_ANYONECANPAY for sig in sigs)
    CMTx = CMutableTransaction.from_tx(
        form_emergency_vault_tx(CTx, stk_pubkeys, sigs))
    fees_before = tx_fees(bitcoind, CMTx)
    first_txid = creates_add_input(bitcoind, CMTx)
    fees_after = tx_fees(bitcoind, CMTx)
    assert fees_after > fees_before
    bitcoind.send_tx(CMTx.serialize().hex(), wait_for_mempool=[first_txid])

    # Test the emer unvault
    amount_vault = 50 * COIN - 500
    amount_unvault = amount_vault - 500
    txid = send_unvault_tx(bitcoind, stk_privkeys, stk_pubkeys, serv_pubkey,
                           amount_vault, amount_unvault)
    amount_emer = amount_unvault - 500
    CTx = create_emer_unvault_tx(txid, 0, emer_pubkeys, amount_emer)
    sigs = [
        sign_emer_unvault_tx(CTx, p, stk_pubkeys, serv_pubkey, amount_unvault)
        for p in stk_privkeys
    ]
    # Sanity checks don't hurt
    assert all(sig[-1] == SIGHASH_ALL | SIGHASH_ANYONECANPAY for sig in sigs)
    CMTx = CMutableTransaction.from_tx(
        form_emer_unvault_tx(CTx, sigs, stk_pubkeys, serv_pubkey))
    fees_before = tx_fees(bitcoind, CMTx)
    first_txid = creates_add_input(bitcoind, CMTx)
    fees_after = tx_fees(bitcoind, CMTx)
    assert fees_after > fees_before
    bitcoind.send_tx(CMTx.serialize().hex(), wait_for_mempool=[first_txid])

    # Test the cancel unvault
    amount_vault = 50 * COIN - 500
    amount_unvault = amount_vault - 500
    txid = send_unvault_tx(bitcoind, stk_privkeys, stk_pubkeys, serv_pubkey,
                           amount_vault, amount_unvault)
    amount_cancel = amount_unvault - 500
    CTx = create_cancel_tx(txid, 0, emer_pubkeys, amount_cancel)
    sigs = [
        sign_cancel_tx(CTx, p, stk_pubkeys, serv_pubkey, amount_unvault)
        for p in stk_privkeys
    ]
    # Sanity checks don't hurt
    assert all(sig[-1] == SIGHASH_ALL | SIGHASH_ANYONECANPAY for sig in sigs)
    CMTx = CMutableTransaction.from_tx(
        form_cancel_tx(CTx, sigs, stk_pubkeys, serv_pubkey))
    fees_before = tx_fees(bitcoind, CMTx)
    first_txid = creates_add_input(bitcoind, CMTx)
    fees_after = tx_fees(bitcoind, CMTx)
    assert fees_after > fees_before
    bitcoind.send_tx(CMTx.serialize().hex(), wait_for_mempool=[first_txid])