示例#1
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)
示例#2
0
def sign_unvault_revault(tx,
                         privkey,
                         pubkeys,
                         pub_server,
                         prev_value,
                         sign_all=False):
    """Signs a transaction revaulting an unvault transaction.

    This is the "all stakeholders sign" path of the script, not encumbered by a
    timelock.
    This path is used for both the emergency and cancel transactions.
    These transactions are crucial to preserve our security assumptions (i.e. a
    revaulting transaction will be confirmed), so stakeholders exchange
    SINGLE | ANYONECANPAY signatures to allow any of them to increase
    the feerate by appending an input and an output.

    :param tx: The unsigned transaction, a CMutableTransaction.
    :param privkey: (bytes) The private key to sign the transaction with.
    :param pubkeys: The pubkeys of the stakeholders.
    :param pub_server: The pubkey of the cosigning server.
    :param prev_value: The prevout's value in satoshis.
    :param sign_all: If set to True, sign we SIGHASH_ALL instead.

    :return: The signatures for the provided privkeys (a list).
    """
    sighash = SIGHASH_ALL if sign_all else SINGLE_ANYONECANPAY
    tx_hash = SignatureHash(unvault_script(*pubkeys, pub_server), tx, 0,
                            sighash, prev_value, SIGVERSION_WITNESS_V0)
    return CKey(privkey).sign(tx_hash) + bytes([sighash])
示例#3
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}
示例#4
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:])
示例#5
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))
示例#6
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}
示例#7
0
def sign_emergency_vault_tx(tx, privkey, pubkeys, prev_value, sign_all=False):
    """Signs the transaction which moves a vault's coins to the offline 4of4.

    This transaction is crucial to preserve our security assumptions (i.e. a
    revaulting transaction will be confirmed), so stakeholders exchange
    SINGLE | ANYONECANPAY signatures to allow any of them to increase
    the feerate by appending an input and an output.

    :param vault_txid: The id of the transaction funding the vault, as bytes.
    :param privkey: (bytes) The private key to sign the transaction with.
    :param pubkeys: A list containing the public key of each stakeholder.
    :param prev_value: The vault output (previout output) value in satoshis.
    :param sign_all: If set to True, sign we SIGHASH_ALL instead.

    :return: A list, one signature per given privkey.
    """
    sighash = SIGHASH_ALL if sign_all else SINGLE_ANYONECANPAY
    tx_hash = SignatureHash(vault_script(pubkeys),
                            tx,
                            0,
                            sighash,
                            amount=prev_value,
                            sigversion=SIGVERSION_WITNESS_V0)
    # A signature per pubkey
    return CKey(privkey).sign(tx_hash) + bytes([sighash])
示例#8
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}
示例#9
0
def creates_add_input(bitcoind, tx):
    """Creates and add an input to a CMutableTransaction, SIGHASH_ALL.

    :returns: The txid of the first stage fee bumping tx (for convenience)
    """
    # First we get some coins
    privkey = CKey(os.urandom(32))
    scriptPubKey = CScript([OP_0, Hash160(privkey.pub)])
    address = CBitcoinAddress.from_scriptPubKey(scriptPubKey)
    # Let's say we want to increase the fees by 5000 sats
    amount = 5000

    # Bitcoind is nice and will create the first stage transaction
    first_txid = bitcoind.rpc.sendtoaddress(str(address), amount / COIN)
    vout_index = get_output_index(
        bitcoind.rpc.getrawtransaction(first_txid, 1), amount)
    # === We don't generate a block yet ! ===

    tx.vin.append(
        CTxIn(COutPoint(lx(first_txid), vout_index), nSequence=0xfffffffe))
    # Sign the new input with ALL
    tx_hash = SignatureHash(address.to_redeemScript(), tx, 1, SIGHASH_ALL,
                            amount, SIGVERSION_WITNESS_V0)
    sig = privkey.sign(tx_hash) + bytes([SIGHASH_ALL])
    tx.wit.vtxinwit.append(CTxInWitness(CScriptWitness([sig, privkey.pub])))

    return first_txid
示例#10
0
def spend_hodl_redeemScript(privkey, nLockTime, unsigned_tx, n):
    """Spend a hodl output

    Returns the complete scriptSig
    """
    redeemScript = hodl_redeemScript(privkey, nLockTime)
    sighash = SignatureHash(redeemScript, unsigned_tx, n, SIGHASH_ALL)
    sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
    return CScript([sig, redeemScript])
示例#11
0
def mkhash(basescript, tx, vin, sigflags, drop_codesep=0):
    if drop_codesep > 0:
        sclst = list(basescript)
        assert basescript == CScript(sclst)  # not fancy
        for _ in range(dropcs):
            assert OP_CODESEPARATOR in sclst
            sclst = sclst[sclst.index(OP_CODESEPARATOR) + 1:]
        basescript = CScript(sclst)
    return SignatureHash(basescript, tx, vin, sigflags)
示例#12
0
 def settlement_sig(self):
     """Generate a signature for the settlement transaction."""
     transaction = self.unsigned_settlement()
     transaction.vin[0].scriptSig = transaction.vin[0].scriptSig.to_script()
     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])
     return sig
示例#13
0
    def spend_redeemScript(self, who, privkey, unsigned_tx: CTransaction,
                           n_in):
        if who not in ('user', 'exch'):
            raise ValueError("who must be either user or exch")

        branch = OP_FALSE if who == 'user' else OP_TRUE
        redeemScript = self.deposit_redeemScript
        sighash = SignatureHash(redeemScript, unsigned_tx, n_in, SIGHASH_ALL)
        sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
        return CScript([sig, branch, redeemScript])
示例#14
0
    def sig_hash(self, input, redeem_script=None):
        # FIXME: This is going to break if no redeem_script is supplied.
        # The idea in allowing it to be None was that in some cases,
        # the redeem_script could be determined from the input object.
        # This is probably a bad idead, so the default value for redeem_script
        # should be eliminated.

        # We only allow SIGHASH_ALL at this time
        # https://en.bitcoin.it/wiki/OP_CHECKSIG#Hashtype_SIGHASH_ALL_.28default.29
        return SignatureHash(redeem_script.cscript, self.native(), input.index,
                             SIGHASH_ALL)
示例#15
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)
示例#16
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
示例#17
0
 def signed_settlement(self, their_sig):
     """Return the fully signed settlement transaction."""
     transaction = self.unsigned_settlement()
     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.sig = their_sig
     transaction.vin[0].scriptSig = transaction.vin[0].scriptSig.to_script(sig)
     VerifyScript(transaction.vin[0].scriptSig,
                  self.anchor.scriptSig.redeem.to_p2sh_scriptPubKey(),
                  transaction, 0, (SCRIPT_VERIFY_P2SH,))
     return transaction
 def create_signature(self, privkey, reedem_script):
     """
     Exports a raw signature suitable for use in a multisig transaction
     """
     seckey = CBitcoinSecret.from_secret_bytes(x(bitcointools.encode_privkey(privkey, "hex")))
     signatures = []
     for i in range(len(self.tx.vin)):
         sighash = SignatureHash(CScript(x(reedem_script)), self.tx, i, SIGHASH_ALL)
         signatures.append({
             "index": i,
             "signature": (seckey.sign(sighash) + struct.pack('<B', SIGHASH_ALL)).encode("hex")
         })
     return signatures
示例#19
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
    def sign(self, privkey):
        """
        Sign each of the inputs with the private key. Inputs should all be sent to
        the same scriptPubkey so we should only need one key.
        """
        seckey = CBitcoinSecret.from_secret_bytes(x(bitcointools.encode_privkey(privkey, "hex")))

        for i in range(len(self.tx.vin)):
            txin_scriptPubKey = self.tx.vin[i].scriptSig
            sighash = SignatureHash(txin_scriptPubKey, self.tx, i, SIGHASH_ALL)
            sig = seckey.sign(sighash) + struct.pack('<B', SIGHASH_ALL)
            self.tx.vin[i].scriptSig = CScript([sig, seckey.pub])

            VerifyScript(self.tx.vin[i].scriptSig, txin_scriptPubKey, self.tx, i, (SCRIPT_VERIFY_P2SH,))
示例#21
0
def split_coins(amount_to_send, txid_to_spend, utxo_index, n, network):
    txin_scriptPubKey = address.to_scriptPubKey()
    txin = create_txin(txid_to_spend, utxo_index)
    txout_scriptPubKey = address.to_scriptPubKey()
    txout = create_txout(amount_to_send / n, txout_scriptPubKey)
    tx = CMutableTransaction([txin], [txout] * n)
    sighash = SignatureHash(txin_scriptPubKey, tx, 0, SIGHASH_ALL)
    txin.scriptSig = CScript(
        [private_key.sign(sighash) + bytes([SIGHASH_ALL]), public_key])
    VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0,
                 (SCRIPT_VERIFY_P2SH, ))
    response = broadcast_transaction(tx, network)
    print(response.status_code, response.reason)
    print(response.text)
示例#22
0
def get_unsigned_tx(funding_tx,
                    redeem_script,
                    address,
                    amount,
                    lock_time=0,
                    n_sequence=0,
                    vout=0):
    """
    Returns a raw transaction and it's signature hash
    that pays to address from funding_tx

    Arguments:
        funding_tx (str): the 'input' tx
        redeem_script (str): The redeem script
        address (str): The output address that would receive `amount`
        lock_time (int, optional): The time the tx should be locked to
        n_sequence (int, optional): The sequence number to use in tx
        vout (int, optional):  The index of the output point of `funding_tx`

    Returns:
        A tuple containing:
            1/ The serial tx
            2/ The tx hash
    """

    # Set P2SH funding tx in little-endian
    fx = lx(funding_tx)

    # nSequence must be any number less than 0xffffffff to enable nLockTime
    txin = CMutableTxIn(COutPoint(fx, vout), nSequence=n_sequence)

    # if(nlock_time != 0):
    #     txin = CMutableTxIn(COutPoint(fx, vout), nSequence=n_sequence)
    # else:
    #     txin = CMutableTxIn(COutPoint(fx, vout))

    # Convert amount to Satoshi's
    amount *= COIN

    # Create the txout to address
    script_pubkey = CBitcoinAddress(address).to_scriptPubKey()
    txout = CMutableTxOut(amount, script_pubkey)

    # Create the unsigned transaction.
    tx = CMutableTransaction([txin], [txout], nLockTime=lock_time)

    # Calculte TX sig hash
    sighash = SignatureHash(CScript(redeem_script), tx, 0, SIGHASH_ALL)

    return (tx.serialize(), sighash)
示例#23
0
文件: bXcat.py 项目: xiaoqge/ZBXCAT
def redeem_after_timelock(contract):
    p2sh = contract.p2sh
    fundtx = find_transaction_to_address(p2sh)
    amount = fundtx['amount'] / COIN

    if (fundtx['address'].__str__() != p2sh):
        print("no fund transaction found to the contract p2sh address ", p2sh)
        quit()
    print("Found fundtx:", fundtx)
    # Parsing redeemblocknum from the redeemscript of the p2sh
    redeemblocknum = find_redeemblocknum(contract)
    blockcount = bitcoind.getblockcount()
    print("Current block:", blockcount, "Can redeem from block:",
          redeemblocknum)
    if (still_locked(contract)):
        print("too early for redeeming with timelock try again at block",
              redeemblocknum, "or later")
        return 0

    print("Found {0} in p2sh {1}, redeeming...".format(amount, p2sh))

    redeemPubKey = find_refundAddr(contract)
    print('refundPubKey', redeemPubKey)

    redeemScript = CScript(x(contract.redeemScript))
    txin = CMutableTxIn(fundtx['outpoint'])
    txout = CMutableTxOut(fundtx['amount'] - FEE,
                          redeemPubKey.to_scriptPubKey())
    # Create the unsigned raw transaction.
    txin.nSequence = 0
    tx = CMutableTransaction([txin], [txout])
    tx.nLockTime = redeemblocknum

    sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL)
    # TODO: figure out how to better protect privkey
    privkey = bitcoind.dumpprivkey(redeemPubKey)
    sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
    txin.scriptSig = CScript([sig, privkey.pub, OP_FALSE, redeemScript])

    # exit()

    # print("txin.scriptSig", b2x(txin.scriptSig))
    txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey()
    # print('Redeem txhex', b2x(tx.serialize()))
    VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0,
                 (SCRIPT_VERIFY_P2SH, ))
    print("script verified, sending raw tx")
    txid = bitcoind.sendrawtransaction(tx)
    print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid))))
    return b2x(lx(b2x(txid)))
示例#24
0
def partial_spend_p2sh(redeemScript,
                       rein,
                       daddr=None,
                       alt_amount=None,
                       alt_daddr=None):
    if daddr is None:
        daddr = rein.user.daddr
    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(
            'Primary escrow is empty. Please inform client to add funds.')
    txins_str = ""
    txins_obj = []
    for txid, vout in txins:
        txins_str += " " + txid + "-" + str(vout)
        txins_obj.append(CMutableTxIn(COutPoint(lx(txid), vout)))
    fee = float(PersistConfig.get(rein, 'fee', 0.001))
    amount = round(total_value - fee, 8)
    if alt_amount:
        amount = round(amount - alt_amount, 8)
    if amount <= 0. or alt_amount > total_value - fee:
        click.echo("amount: " + str(amount) + " alt_amount: " +
                   str(alt_amount) + " total_value: " + str(total_value))
        raise ValueError(
            'Primary escrow balance too low. Please inform client to add funds.'
        )
    txouts = []
    txout = CMutableTxOut(amount * COIN,
                          CBitcoinAddress(daddr).to_scriptPubKey())
    txouts.append(txout)
    if alt_amount:
        txout_alt = CMutableTxOut(
            round(alt_amount, 8) * COIN,
            CBitcoinAddress(alt_daddr).to_scriptPubKey())
        txouts.append(txout_alt)
    tx = CMutableTransaction(txins_obj, txouts)
    ntxins = len(txins_obj)
    seckey = CBitcoinSecret(rein.user.dkey)
    sig = ""
    for i in range(0, ntxins):
        sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL)
        sig += " " + b2x(seckey.sign(sighash)) + "01"
    if alt_amount:
        return (txins_str[1:], "{:.8f}".format(amount), daddr,
                "{:.8f}".format(alt_amount), alt_daddr, sig[1:])
    return (txins_str[1:], "{:.8f}".format(amount), daddr, sig[1:])
示例#25
0
def sign_spend_tx(tx, privkey, pubkeys, pub_server, prev_value):
    """Signs the transaction which spends the unvault_tx after the relative
    locktime with the given private keys.

    :param tx: The unsigned transaction, a CMutableTransaction.
    :param privkey: (bytes) The private key to sign the transaction with.
    :param pubkeys: A list of the 4 stakeholders' pubkeys, to form the script.
    :param pub_server: The public key of the cosigning server, to form the
                       script.
    :param prev_value: The prevout's value in satoshis.

    :return: A list of the signature for each given private key.
    """
    tx_hash = SignatureHash(unvault_script(*pubkeys, pub_server), tx, 0,
                            SIGHASH_ALL, prev_value, SIGVERSION_WITNESS_V0)
    return CKey(privkey).sign(tx_hash) + bytes([SIGHASH_ALL])
示例#26
0
文件: bXcat.py 项目: xiaoqge/ZBXCAT
def redeem_with_secret(contract, secret):
    # How to find redeemScript and redeemblocknum from blockchain?
    print("Redeeming contract using secret", contract.__dict__)
    p2sh = contract.p2sh
    minamount = float(contract.amount)
    #checking there are funds in the address
    amount = check_funds(p2sh)
    if (amount < minamount):
        print("address ", p2sh, " not sufficiently funded")
        return false
    fundtx = find_transaction_to_address(p2sh)
    amount = fundtx['amount'] / COIN
    p2sh = P2SHBitcoinAddress(p2sh)
    if fundtx['address'] == p2sh:
        print("Found {0} in p2sh {1}, redeeming...".format(amount, p2sh))

        redeemPubKey = find_redeemAddr(contract)
        print('redeemPubKey', redeemPubKey)

        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(redeemScript, tx, 0, SIGHASH_ALL)
        # TODO: figure out how to better protect privkey
        privkey = bitcoind.dumpprivkey(redeemPubKey)
        sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
        print("SECRET", secret)
        preimage = secret.encode('utf-8')
        txin.scriptSig = CScript(
            [sig, privkey.pub, preimage, OP_TRUE, redeemScript])

        # exit()

        # print("txin.scriptSig", b2x(txin.scriptSig))
        txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey()
        # print('Redeem txhex', b2x(tx.serialize()))
        VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0,
                     (SCRIPT_VERIFY_P2SH, ))
        print("script verified, sending raw tx")
        txid = bitcoind.sendrawtransaction(tx)
        print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid))))
        return b2x(lx(b2x(txid)))
    else:
        print("No contract for this p2sh found in database", p2sh)
示例#27
0
文件: tx.py 项目: mbaniasad/ahunavar
    def get_tx(self,
               redeem_script,
               address,
               amount,
               funding_tx,
               lock_time=0,
               vout=0):
        '''
               Returns a raw transaction and it's signature hash
               that pays to address from funding_tx

               Options:
               vout -> which vout of funding_tx
               nLockTime -> set's transaction locktime
        '''

        # Set P2SH funding tx in little-endian
        fx = lx(funding_tx)

        if lock_time > 0:
            nlock_time = lock_time
        else:
            nlock_time = 0

        # nSequence must be any number less than 0xffffffff to enable nLockTime
        if (nlock_time != 0):
            txin = CMutableTxIn(COutPoint(fx, vout), nSequence=0)
        else:
            txin = CMutableTxIn(COutPoint(fx, vout))

        # Convert amount to Satoshi's
        amount *= COIN

        # Create the txout to address
        script_pubkey = CBitcoinAddress(address).to_scriptPubKey()
        txout = CMutableTxOut(amount, script_pubkey)

        # Create the unsigned transaction.
        tx = CMutableTransaction([txin], [txout], nLockTime=nlock_time)

        # Calculte TX sig hash
        sighash = SignatureHash(CScript(redeem_script), tx, 0, SIGHASH_ALL)

        self.logger.info("get_tx: TX SIGHASH is %s", b2x(sighash))

        return (tx.serialize(), sighash)
示例#28
0
def maketx(tx):
    #txid from blockr. bitcoind does not support tx index!
    txid = lx(tx)
    vout = 0

    outp = COutPoint(txid, vout)
    print("output: %s" % outp)
    # Create the txin structure, which includes the outpoint
    txin = CMutableTxIn(outp)
    print(txin)

    txin_scriptPubKey = CScript(
        [OP_DUP, OP_HASH160,
         Hash160(seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG])

    print(txin_scriptPubKey)

    amount = 0.001 * COIN
    txout = CMutableTxOut(amount, CBitcoinAddress(a).to_scriptPubKey())

    print(txout)

    # Create the unsigned transaction.
    newtx = CMutableTransaction([txin], [txout])
    print(newtx)

    sighash = SignatureHash(txin_scriptPubKey, newtx, 0, SIGHASH_ALL)
    print(sighash)

    # Now sign it. We have to append the type of signature we want to the end, in
    # this case the usual SIGHASH_ALL.
    sig = seckey.sign(sighash) + bytes([SIGHASH_ALL])
    print(sig)

    # Set the scriptSig of our transaction input appropriately.
    txin.scriptSig = CScript([sig, seckey.pub])

    try:
        VerifyScript(txin.scriptSig, txin_scriptPubKey, newtx, 0,
                     (SCRIPT_VERIFY_P2SH, ))
    except:
        pass

    print('*' * 20)
    print(b2x(newtx.serialize()))
    """
示例#29
0
def add_input_output(bitcoind, tx):
    """Add an input and an output to a CMutableTransaction, SIGHASH_ALL."""
    # First we get some coins
    privkey = CKey(os.urandom(32))
    scriptPubKey = CScript([OP_0, Hash160(privkey.pub)])
    address = CBitcoinAddress.from_scriptPubKey(scriptPubKey)
    amount = Decimal("50") * Decimal(COIN) - Decimal("500")
    # This creates a one-output transaction
    txid = bitcoind.pay_to(str(address), amount / Decimal(COIN))
    # We bump the fees by 5000
    tx.vout.append(CTxOut(amount - Decimal("5000"), scriptPubKey))
    tx.vin.append(CTxIn(COutPoint(lx(txid), 0)))
    # Sign the new output with ALL
    tx_hash = SignatureHash(address.to_redeemScript(), tx, 1, SIGHASH_ALL,
                            int(amount), SIGVERSION_WITNESS_V0)
    sig = privkey.sign(tx_hash) + bytes([SIGHASH_ALL])
    tx.wit.vtxinwit.append(CTxInWitness(CScriptWitness([sig, privkey.pub])))
示例#30
0
def sign_unvault_spend(tx, privkeys, pubkeys, pub_server, prev_value):
    """Signs a transaction spending from an unvault transaction.

    This is the "all stakeholders sign" path of the script, not encumbered by a
    timelock.
    This path is used for both the emergency and cancel transactions.

    :param tx: The unsigned transaction, a CMutableTransaction.
    :param privkeys: The private keys to sign the transaction with (a list).
    :param pubkeys: The pubkeys of the stakeholders.
    :param pub_server: The pubkey of the cosigning server.
    :param prev_value: The prevout's value in satoshis.

    :return: The signatures for the provided privkeys (a list).
    """
    tx_hash = SignatureHash(unvault_script(*pubkeys, pub_server), tx, 0,
                            SIGHASH_ALL, prev_value, SIGVERSION_WITNESS_V0)
    return [CKey(key).sign(tx_hash) + bytes([SIGHASH_ALL]) for key in privkeys]