Esempio n. 1
0
    def into_transaction(self, dust_secret: CBitcoinSecret,
                         dust_outpoint: OutPointWithTx, feerate):
        if dust_outpoint.prevout.scriptPubKey != pubkey_to_P2PKH_scriptPubkey(
                dust_secret.pub):
            print(b2x(dust_outpoint.prevout.scriptPubKey))
            print(b2x(pubkey_to_P2PKH_scriptPubkey(dust_secret.pub)))
            raise Exception("Outpoint has incorrect scriptPubKey")

        sum_in = dust_outpoint.prevout.nValue

        fees = int(tx_size(1, 2) / 1000 * feerate)
        refund = sum_in - fees - self._life_signal_amount

        print('fee: %f' % fees)
        print('amount: %f' % (sum_in - fees))

        redeemScript = self.redeemScript

        unsigned_tx = CTransaction([CTxIn(dust_outpoint.outpoint)], [
            CTxOut(self._life_signal_amount,
                   redeemScript.to_p2sh_scriptPubKey()),
            CTxOut(refund, pubkey_to_P2PKH_scriptPubkey(dust_secret.pub))
        ])

        # spend the dust input
        sighash = SignatureHash(dust_outpoint.prevout.scriptPubKey,
                                unsigned_tx, 0, SIGHASH_ALL)
        sig = dust_secret.sign(sighash) + bytes([SIGHASH_ALL])
        sigScript = CScript([sig, dust_secret.pub])

        signed_input = [CTxIn(unsigned_tx.vin[0].prevout, sigScript)]

        return CTransaction(signed_input, unsigned_tx.vout,
                            unsigned_tx.nLockTime)
Esempio n. 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()))
Esempio n. 3
0
    def withdrawfromvault(self, fromvaultaddress, toaddress, amount):
        vault = self.getvault(fromvaultaddress)
        received = self.chaindb.listreceivedbyvault(fromvaultaddress)
        received = received.values()[0]
        if received['value'] < amount + 2 * utils.calculate_fees(None):
            self.logger.warning("Insufficient funds in vault, exiting, return")
            return

        # create transaction
        tx = CTransaction()

        # to the receiver
        txout = CTxOut()
        txout.nValue = amount
        txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress)
        tx.vout.append(txout)

        # from the sender
        nValueIn = 0
        nValueOut = amount

        txin = CTxIn()
        txin.prevout = COutPoint()
        txin.prevout.hash = received['txhash']
        txin.prevout.n = received['n']
        txin.scriptSig = received['scriptPubKey']
        tx.vin.append(txin)

        # calculate nValueIn
        nValueIn = received['value']
        # calculate the total excess amount
        excessAmount = nValueIn - nValueOut
        # calculate the fees
        fees = 2 *                                                                                                                                                                 utils.calculate_fees(tx)
        # create change transaction, if there is any change left
        if excessAmount > fees:
            change_txout = CTxOut()
            change_txout.nValue = excessAmount - fees
            account = self.getaccount()
            changeaddress = fromvaultaddress
            self.logger.debug("Change address: %s" % changeaddress)
            change_txout.scriptPubKey = \
                utils.vault_address_to_pay_to_vault_script(changeaddress)
            tx.vout.append(change_txout)

        # calculate txhash
        tx.calc_sha256()
        txhash = str(tx.sha256)
        key = CKey()
        key.set_pubkey(vault['public_key'])
        key.set_privkey(vault['private_key'])
        signature = key.sign(txhash)
        vaultscript = utils.create_vault_script(vault['address'], \
            vault['master_address'], vault['timeout'], vault['maxfees'])
        scriptSig = chr(OP_VAULT_WITHDRAW) + chr(len(signature)) + signature + \
                chr(len(vaultscript)) + vaultscript
        self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig))
        txin.scriptSig = scriptSig
        return tx
Esempio n. 4
0
def spend_command(args):
    args.addr = CBitcoinAddress(args.addr)

    redeemScript = hodl_redeemScript(args.privkey, args.nLockTime)
    scriptPubKey = redeemScript.to_p2sh_scriptPubKey()

    proxy = bitcoin.rpc.Proxy()

    prevouts = []
    for prevout in args.prevouts:
        try:
            txid, n = prevout.split(':')

            txid = lx(txid)
            n = int(n)

            outpoint = COutPoint(txid, n)
        except ValueError:
            args.parser.error('Invalid output: %s' % prevout)

        try:
            prevout = proxy.gettxout(outpoint)
        except IndexError:
            args.parser.error('Outpoint %s not found' % outpoint)

        prevout = prevout['txout']
        if prevout.scriptPubKey != scriptPubKey:
            args.parser.error('Outpoint not correct scriptPubKey')

        prevouts.append((outpoint, prevout))

    sum_in = sum(prev_txout.nValue for outpoint, prev_txout in prevouts)

    tx_size = (
        4 +  # version field
        2 +  # # of txins
        len(prevouts) * 153 +  # txins, including sigs
        1 +  # # of txouts
        34 +  # txout
        4  # nLockTime field
    )

    feerate = int(proxy._call('estimatefee', 1) * COIN)  # satoshi's per KB
    if feerate <= 0:
        feerate = 10000
    fees = int(tx_size / 1000 * feerate)

    unsigned_tx = CTransaction(
        [CTxIn(outpoint, nSequence=0) for outpoint, prevout in prevouts],
        [CTxOut(sum_in - fees, args.addr.to_scriptPubKey())], args.nLockTime)

    signed_tx = CTransaction([
        CTxIn(txin.prevout,
              spend_hodl_redeemScript(args.privkey, args.nLockTime,
                                      unsigned_tx, i),
              nSequence=0) for i, txin in enumerate(unsigned_tx.vin)
    ], unsigned_tx.vout, unsigned_tx.nLockTime)

    print(b2x(signed_tx.serialize()))
Esempio n. 5
0
    def withdrawfromvault(self, fromvaultaddress, toaddress, amount):
        vault = self.getvault(fromvaultaddress)
        received = self.chaindb.listreceivedbyvault(fromvaultaddress)
        received = received.values()[0]
        if received['value'] < amount + 2 * utils.calculate_fees(None):
            self.logger.warning("Insufficient funds in vault, exiting, return")
            return

        # create transaction
        tx = CTransaction()

        # to the receiver
        txout = CTxOut()
        txout.nValue = amount
        txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress)
        tx.vout.append(txout)

        # from the sender
        nValueIn = 0
        nValueOut = amount

        txin = CTxIn()
        txin.prevout = COutPoint()
        txin.prevout.hash = received['txhash']
        txin.prevout.n = received['n']
        txin.scriptSig = received['scriptPubKey']
        tx.vin.append(txin)

        # calculate nValueIn
        nValueIn = received['value']
        # calculate the total excess amount
        excessAmount = nValueIn - nValueOut
        # calculate the fees
        fees = 2 * utils.calculate_fees(tx)
        # create change transaction, if there is any change left
        if excessAmount > fees:
            change_txout = CTxOut()
            change_txout.nValue = excessAmount - fees
            account = self.getaccount()
            changeaddress = fromvaultaddress
            self.logger.debug("Change address: %s" % changeaddress)
            change_txout.scriptPubKey = \
                utils.vault_address_to_pay_to_vault_script(changeaddress)
            tx.vout.append(change_txout)

        # calculate txhash
        tx.calc_sha256()
        txhash = str(tx.sha256)
        key = CKey()
        key.set_pubkey(vault['public_key'])
        key.set_privkey(vault['private_key'])
        signature = key.sign(txhash)
        vaultscript = utils.create_vault_script(vault['address'], \
            vault['master_address'], vault['timeout'], vault['maxfees'])
        scriptSig = chr(OP_VAULT_WITHDRAW) + chr(len(signature)) + signature + \
                chr(len(vaultscript)) + vaultscript
        self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig))
        txin.scriptSig = scriptSig
        return tx
Esempio n. 6
0
    def overridevaulttx(self, fromvaultaddress, toaddress):
        vault = self.getvault(fromvaultaddress)
        # select the input addresses
        received = self.chaindb.listallreceivedbyvault(fromvaultaddress)
        if not received:
            self.logger.warning("Empty vault, exiting, return")
            return None, None
        received = received.values()[0]
        if received['value'] < 2 * utils.calculate_fees(None):
            self.logger.warning("Insufficient funds in vault, exiting, return")
            return None, None
        # calculate remaining amount
        amount = received['value'] - 2 * utils.calculate_fees(None)
        # create transaction
        tx = CTransaction()

        # to the receiver
        txout = CTxOut()
        txout.nValue = amount
        txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress)
        tx.vout.append(txout)

        # from the sender
        nValueIn = 0
        nValueOut = amount

        txin = CTxIn()
        txin.prevout = COutPoint()
        txin.prevout.hash = received['txhash']
        txin.prevout.n = received['n']
        txin.scriptSig = received['scriptPubKey']
        tx.vin.append(txin)

        # calculate nValueIn
        nValueIn = received['value']
        # calculate the total excess amount
        excessAmount = nValueIn - nValueOut
        # calculate the fees
        fees = utils.calculate_fees(tx)
        # calculate txhash
        tx.calc_sha256()
        txhash = str(tx.sha256)
        key = CKey()
        key.set_pubkey(vault['public_key'])
        key.set_privkey(vault['private_key'])
        signature = key.sign(txhash)
        # get the script
        vaultscript = utils.create_vault_script(vault['address'], \
                vault['master_address'], vault['timeout'], vault['maxfees'])
        scriptSig = chr(OP_VAULT_OVERRIDE) + chr(len(vault['master_public_key'])) + \
        vault['master_public_key'] + chr(len(signature)) + signature + \
        chr(len(vaultscript)) + vaultscript
        self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig))
        txin.scriptSig = scriptSig
        return amount, tx
Esempio n. 7
0
    def overridevaulttx(self, fromvaultaddress, toaddress):
        vault = self.getvault(fromvaultaddress)
        # select the input addresses
        received = self.chaindb.listallreceivedbyvault(fromvaultaddress)
        if not received:
            self.logger.warning("Empty vault, exiting, return")
            return None, None
        received = received.values()[0]
        if received['value'] < 2 * utils.calculate_fees(None):
            self.logger.warning("Insufficient funds in vault, exiting, return")
            return None, None
        # calculate remaining amount
        amount = received['value'] - 2 * utils.calculate_fees(None)
        # create transaction
        tx = CTransaction()

        # to the receiver
        txout = CTxOut()
        txout.nValue = amount
        txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress)
        tx.vout.append(txout)

        # from the sender
        nValueIn = 0
        nValueOut = amount

        txin = CTxIn()
        txin.prevout = COutPoint()
        txin.prevout.hash = received['txhash']
        txin.prevout.n = received['n']
        txin.scriptSig = received['scriptPubKey']
        tx.vin.append(txin)

        # calculate nValueIn
        nValueIn = received['value']
        # calculate the total excess amount
        excessAmount = nValueIn - nValueOut
        # calculate the fees
        fees = utils.calculate_fees(tx)
        # calculate txhash
        tx.calc_sha256()
        txhash = str(tx.sha256)
        key = CKey()
        key.set_pubkey(vault['public_key'])
        key.set_privkey(vault['private_key'])
        signature = key.sign(txhash)
        # get the script
        vaultscript = utils.create_vault_script(vault['address'], \
                vault['master_address'], vault['timeout'], vault['maxfees'])
        scriptSig = chr(OP_VAULT_OVERRIDE) + chr(len(vault['master_public_key'])) + \
        vault['master_public_key'] + chr(len(signature)) + signature + \
        chr(len(vaultscript)) + vaultscript
        self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig))
        txin.scriptSig = scriptSig
        return amount, tx
Esempio n. 8
0
    def accuse(self, dust_op: OutPointWithTx, wallet_op: OutPointWithTx,
               user_index, secret_sgx):
        ls_tx = self._life_signals[user_index].into_transaction(
            secret_sgx, dust_op, feerate)
        # FIXME: hardcode zero here because life signal is always the first output in a life signal tx
        nOut_for_ls = 0

        ls = self._life_signals[user_index]

        if ls_tx.vout[
                nOut_for_ls].scriptPubKey != ls.redeemScript.to_p2sh_scriptPubKey(
                ):
            raise Exception("SGX can't spend the life signal")

        if wallet_op.prevout.scriptPubKey != self.scriptPubkey():
            raise Exception("wallet utxo mismatch")

        print('ls value: %f' % ls_tx.vout[nOut_for_ls].nValue)
        sum_in = ls_tx.vout[0].nValue + wallet_op.prevout.nValue
        fees = int(tx_size(2, 1) / 1000 * feerate)

        print('fee: %f' % fees)
        print('amount: %f' % (sum_in - fees))

        # note: nVersion=2 is required by CSV
        unsigned_tx = CTransaction([
            CTxIn(COutPoint(ls_tx.GetTxid(), nOut_for_ls),
                  nSequence=ls.relative_timeout),
            CTxIn(wallet_op.outpoint)
        ], [
            CTxOut(wallet_op.prevout.nValue,
                   self.scriptPubkey(exclude_indices=(user_index, )))
        ],
                                   nVersion=2)

        # spend the life signal
        lifesignal_sigScript = self._life_signals[
            user_index].scriptSig_by_key2(unsigned_tx, 0)

        # spend the wallet
        wallet_sigScript = self._scriptSig_by_sgx(secret_sgx, unsigned_tx, 1)

        # return the life signal as well as both transactions
        return ls, ls_tx, CTransaction([
            CTxIn(unsigned_tx.vin[0].prevout,
                  scriptSig=lifesignal_sigScript,
                  nSequence=ls.relative_timeout),
            CTxIn(wallet_op.outpoint, wallet_sigScript)
        ], unsigned_tx.vout, unsigned_tx.nLockTime, unsigned_tx.nVersion)
Esempio n. 9
0
    def test_is_coinbase(self):
        tx = CTransaction()
        self.assertFalse(tx.is_coinbase())

        tx.vin.append(CTxIn())

        # IsCoinBase() in reference client doesn't check if vout is empty
        self.assertTrue(tx.is_coinbase())

        tx.vin[0].prevout.n = 0
        self.assertFalse(tx.is_coinbase())

        tx.vin[0] = CTxIn()
        tx.vin.append(CTxIn())
        self.assertFalse(tx.is_coinbase())
Esempio n. 10
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)))
Esempio n. 11
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
Esempio n. 12
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)
Esempio n. 13
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()
Esempio n. 14
0
    def add_input(self,
                  serial_id: int,
                  prevtx: str,
                  prevtx_vout: int,
                  script_sig: str,
                  sequence: int,
                  privkey: str = None) -> None:
        # the dummy runner sends empty info, skip
        if len(prevtx) == 0:
            return

        # Find the txid of the transaction
        prev_tx = CTransaction.deserialize(bytes.fromhex(prevtx))
        txin = CTxIn(COutPoint(prev_tx.GetTxid(), prevtx_vout),
                     nSequence=sequence)

        # Get the previous output for its outscript + value
        prev_vout = prev_tx.vout[prevtx_vout]

        self.inputs.append({'input': txin,
                            'serial_id': serial_id,
                            'sats': prev_vout.nValue,
                            'prev_outscript': prev_vout.scriptPubKey.hex(),
                            'redeemscript': script_sig,
                            'privkey': privkey,
                            })
    def build_bounce_tx(self, txid_hex):
        #Generate p2sh script pub key.
        redeem_script = self.fund_redeem_script(self.my)
        redeem_script_hash160 = self.hash160_script(redeem_script)
        txin_script_pub_key = CScript(
            [OP_HASH160, redeem_script_hash160["bin"], OP_EQUAL])

        #Generate address to receive bounce.
        if "bounce" not in self.key_pairs:
            self.key_pairs["bounce"] = self.key_pair_from_address(
                self.jsonrpc[self.my].getnewaddress(), self.my)

        #Setup tx inputs and outputs.
        txid = lx(txid_hex)
        vout = 0
        txin = CTxIn(COutPoint(txid, vout), CScript(), 0)  #Sequence number 0.
        txout = CTxOut(
            (self.send_amount -
             decimal.Decimal(coinbend.config["mining_fee"]["standard"])) *
            COIN,
            CBitcoinAddress(
                self.key_pairs["bounce"]["addr"]["base58"]).to_scriptPubKey())

        #Locktime is unsigned int 4, unix timestamp in little endian format.
        #(Conversion to little endian is handled by the library already.)
        nlock_time = datetime.datetime.now() + datetime.timedelta(
            seconds=self.future_minutes * 60)
        nlock_time = int(nlock_time.strftime("%s"))

        #Create unsigned transaction.
        tx = CTransaction([txin], [txout], nlock_time)
        return b2x(tx.serialize())
Esempio n. 16
0
 def __init__(self,
              hash=b'\x00' * 32,
              vin=CTxIn(),
              sig=b'\x00' * 65,
              height=0):
     """Create a new transaction lock
     hash is the transaction id being locked
     vin is the masternode funding address
     sig is the masternodes signature for the lock
     height is the block the lock is effective
     If their contents are not already immutable, immutable copies will be
     made.
     """
     if not len(hash) == 32:
         raise ValueError(
             'CTransactionLock: hash must be exactly 32 bytes; got %d bytes'
             % len(hash))  # noqa
     object.__setattr__(self, 'hash', hash)
     object.__setattr__(self, 'vin', vin)
     if not len(sig) == 65:
         raise ValueError(
             'CTransactionLock: sig must be exactly 65 bytes; got %d bytes'
             % len(sig))  # noqa
     object.__setattr__(self, 'sig', sig)
     object.__setattr__(self, 'height', height)
Esempio n. 17
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()))
Esempio n. 18
0
 def native(self):
     tx_hex = self.output.transaction_hash
     # Convert a little-endian hex string to bytes
     txid = lx(tx_hex)
     vout = self.output.index
     outpoint = COutPoint(txid, vout)
     return CTxIn(outpoint)
Esempio n. 19
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
Esempio n. 20
0
    def add_input(self,
                  serial_id: int,
                  prevtx: str,
                  prevtx_vout: int,
                  max_witness_len: int,
                  script: str,
                  sequence: int,
                  privkey: str = None) -> None:
        # Find the txid of the transaction
        prev_tx = CTransaction.deserialize(bytes.fromhex(prevtx))
        txin = CTxIn(COutPoint(prev_tx.GetTxid(), prevtx_vout),
                     nSequence=sequence)

        # Get the previous output for its outscript + value
        prev_vout = prev_tx.vout[prevtx_vout]

        self.inputs.append({
            'input': txin,
            'serial_id': serial_id,
            'sats': prev_vout.nValue,
            'prev_outscript': prev_vout.scriptPubKey.hex(),
            'redeemscript': script,
            'max_witness_len': max_witness_len,
            'privkey': privkey,
        })
Esempio n. 21
0
    def appeal(self, user_index, user_secret: CBitcoinSecret,
               lifesignal_op: OutPointWithTx):
        ls = self._life_signals[user_index]
        if lifesignal_op.prevout.scriptPubKey != ls.redeemScript.to_p2sh_scriptPubKey(
        ):
            raise Exception("mismatch scriptPubkey")

        # spend the life signal into a black hole
        unsigned_tx = CTransaction([CTxIn(lifesignal_op.outpoint)],
                                   [CTxOut(0, CScript([True]))],
                                   nVersion=2)

        return CTransaction([
            CTxIn(lifesignal_op.outpoint,
                  scriptSig=ls.scriptSig_by_key1(user_secret, unsigned_tx, 0))
        ],
                            unsigned_tx.vout,
                            nVersion=2)
Esempio n. 22
0
    def get_inputs(self):
        vin = []
        for i in range(self.model.rowCount()):
            prev_hash, prev_vout = str(self.model.item(i, 0).text()).split(':')
            in_script = str(self.model.item(i, 1).data(RawRole).toString())
            sequence = int(self.model.item(i, 2).text())

            outpoint = COutPoint(lx(prev_hash), int(prev_vout))
            i_input = CTxIn(outpoint, in_script.decode('hex'), sequence)
            vin.append(i_input)
        return vin
Esempio n. 23
0
 def add_input():
     try:
         outpoint = COutPoint(lx(str(input_prev_tx.text())), input_prev_vout.get_amount())
         in_script = Script.from_human(str(input_script.toPlainText()))
         new_input = CTxIn(outpoint, in_script.get_hex().decode('hex'), input_sequence.get_amount())
     except Exception as e:
         self.status_message(str(e), True)
         return
     else:
         self.inputs_tree.add_input(new_input)
         rm_input_edit.setRange(0, len(self.inputs_tree.get_inputs()) - 1)
Esempio n. 24
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)
Esempio n. 25
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)
Esempio n. 26
0
 def test_init_with_field_keyword_args(self):
     ins = (
         CTxIn(COutPoint(lx('537ecb89e5ed7e872f988447432e6791c0a58b069c4ec8647e1683a383e867a3'), 0),
               x('473044022043b9aee9187effd7e6c7bc444b09162570f17e36b4a9c02cf722126cc0efa3d502200b3ba14c809fa9a6f7f835cbdbbb70f2f43f6b30beaf91eec6b8b5981c80cea50121025edf500f18f9f2b3f175f823fa996fbb2ec52982a9aeb1dc2e388a651054fb0f'))
     )
     outs = (
         CTxOut(114263, x('76a91495efca2c6a6f0e0f0ce9530219b48607a962e77788ac')),
         CTxOut(2125893, x('76a914f28abfb465126d6772dcb4403b9e1ad2ea28a03488ac'))
     )
     fields_data = {'Timestamp': 1432478808}
     tx = Transaction(ins, outs, 0, 2, peercoin_fields, fields_data)
     self.assertEqual(tx.fields, peercoin_fields)
     self.assertEqual(tx.Timestamp, 1432478808)
Esempio n. 27
0
    def __create_new_timestamp_tx_template(self, outpoint, txout_value, change_scriptPubKey):
        """Create a new timestamp transaction template

        The transaction created will have one input and two outputs, with the
        timestamp output set to an invalid dummy.

        The fee is set to zero, but nSequence is set to opt-in to transaction
        replacement, so you can find an appropriate fee iteratively.
        """

        return CTransaction([CTxIn(outpoint, nSequence=0xfffffffd)],
                            [CTxOut(txout_value, change_scriptPubKey),
                             CTxOut(-1, CScript())])
Esempio n. 28
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)
Esempio n. 29
0
 def bump_delay(self, tx, vin, delay):
     assert 0 < delay < 2**16
     if tx.nVersion < 2:
         tx.nVersion = 2
     seq = tx.vin[vin].nSequence
     assert seq == 0xFFFFFFFF or seq & 0x80000000 == 0
     if seq == 0xFFFFFFFF:
         d = 0
     d = seq & 0xFFFF
     if d < delay:
         d = delay
     otx = tx.vin[vin]
     tx.vin[vin] = CTxIn(otx.prevout, otx.scriptSig, d)
Esempio n. 30
0
def main():

    proxy = bitcoin.rpc.Proxy()

    assert len(sys.argv) > 1

    digests = []
    for f in sys.argv[1:]:
        try:
            with open(f, 'rb') as fd:
                digests.append(Hash(fd.read()))
        except FileNotFoundError as exp:
            if len(f)/2 in (20, 32):
                digests.append(x(f))
            else:
                raise exp
        except IOError as exp:
            print(exp, file=sys.stderr)
            continue

    for digest in digests:
        unspent = sorted(proxy.listunspent(0),
                         key=lambda _x: hash(_x['amount']))

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

        change_addr = proxy.getnewaddress()
        change_pubkey = proxy.validateaddress(change_addr)['pubkey']
        change_out = CMutableTxOut(params.MAX_MONEY, CScript([change_pubkey, OP_CHECKSIG]))

        digest_outs = [CMutableTxOut(0, CScript([OP_RETURN, digest]))]

        txouts = [change_out] + digest_outs

        tx = CMutableTransaction(txins, txouts)


        FEE_PER_BYTE = 0.00025*COIN/1000
        while True:
            tx.vout[0].nValue = int(value_in - max(len(tx.serialize()) * FEE_PER_BYTE, 0.00011*COIN))

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

            if value_in - tx.vout[0].nValue >= len(tx.serialize()) * FEE_PER_BYTE:
                print(b2x(tx.serialize()))
                print(len(tx.serialize()), 'bytes', file=sys.stderr)
                print(b2lx(proxy.sendrawtransaction(tx)))
                break
Esempio n. 31
0
    def from_utxo(txid_in: str,
                  tx_index_in: int,
                  sats: int,
                  privkey: str,
                  fee: int,
                  local_node_privkey: str,
                  local_funding_privkey: str,
                  remote_node_privkey: str,
                  remote_funding_privkey: str,
                  chain_hash: str = regtest_hash) -> Tuple['Funding', str]:
        """Make a funding transaction by spending this utxo using privkey: return Funding, tx."""

        # Create dummy one to start: we will fill in txid at the end.
        funding = Funding('', 0, sats - fee, local_node_privkey,
                          local_funding_privkey, remote_node_privkey,
                          remote_funding_privkey, chain_hash)

        # input private key.
        inkey = privkey_expand(privkey)
        inkey_pub = coincurve.PublicKey.from_secret(inkey.secret)

        # use RBF'able input (requirement for dual-funded things)
        txin = CTxIn(COutPoint(bytes.fromhex(txid_in), tx_index_in),
                     nSequence=0xFFFFFFFD)
        txout = CTxOut(
            sats - fee,
            CScript([script.OP_0,
                     sha256(funding.redeemscript()).digest()]))
        tx = CMutableTransaction([txin], [txout],
                                 nVersion=2,
                                 nLockTime=funding.locktime)

        # now fill in funding txid.
        funding.txid = tx.GetTxid().hex()
        funding.tx = tx

        # while we're here, sign the transaction.
        address = P2WPKHBitcoinAddress.from_scriptPubKey(
            CScript([script.OP_0, Hash160(inkey_pub.format())]))

        sighash = script.SignatureHash(address.to_redeemScript(),
                                       tx,
                                       0,
                                       script.SIGHASH_ALL,
                                       amount=sats,
                                       sigversion=script.SIGVERSION_WITNESS_V0)
        sig = inkey.sign(sighash, hasher=None) + bytes([script.SIGHASH_ALL])

        tx.wit = CTxWitness(
            [CTxInWitness(CScriptWitness([sig, inkey_pub.format()]))])
        return funding, tx.serialize().hex()
Esempio n. 32
0
def create_trx(op_return_val, issuing_transaction_cost,
               issuing_address, txouts, tx_input):
    cert_out = CMutableTxOut(0, CScript([OP_RETURN, op_return_val]))
    txins = [CTxIn(tx_input.outpoint)]
    value_in = tx_input.amount

    # send change back to our address
    amount = value_in - issuing_transaction_cost.total
    if amount > 0:
        change_out = create_transaction_output(issuing_address, amount)
        txouts = txouts + [change_out]
    txouts = txouts + [cert_out]
    tx = CMutableTransaction(txins, txouts)
    return tx
Esempio n. 33
0
def create_spend_vault_txout(vault_txid, vault_vout, txout, rbf=False):
    """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.
    :param rbf: If set to true, signal for RBF.

    :return: The *unsigned* transaction, a CMutableTransaction.
    """
    sequence = 0xfffffffe if rbf else 0xffffffff
    tmp_txin = CTxIn(COutPoint(vault_txid, vault_vout), nSequence=sequence)
    return CMutableTransaction([tmp_txin], [txout], nVersion=2)
Esempio n. 34
0
import binascii
from bitcoin.core import COutPoint, CTxIn, CTxOut, CTransaction, CBlock



coinbase = "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73"
scriptPubKeyHex = "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac"

# construct previous out point
previousOut = COutPoint()
previousOut.hash = 0
previousOut.n = 4294967295

# construct txin
txin = CTxIn()
txin.coinbase = binascii.unhexlify(coinbase)
txin.scriptSig = binascii.unhexlify(coinbase)
txin.prevout = previousOut

# construct txout
txout = CTxOut()
txout.nValue = 5000000000
txout.scriptPubKey = binascii.unhexlify(scriptPubKeyHex)

# create transaction
tx = CTransaction()
tx.vin.append(txin)
tx.vout.append(txout)
tx.calc_sha256()
print tx
Esempio n. 35
0
import binascii
import hashlib

from bitcoin.key import CKey

from bitcoin.core import COutPoint, CTxIn, CTxOut, CTransaction

# from utils
def myhash(s):
    return hashlib.sha256(hashlib.sha256(s).digest()).digest()

previous = COutPoint()
txin = CTxIn()
txout = CTxOut()
tx = CTransaction()

# get the outpoint from which we want to spend
previous.hash = 0xeccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2
previous.n = 0x01000000
txin.prevout = previous
txin.scriptSig = binascii.unhexlify("76a914010966776006953d5567439e5e39f86a0d273bee88ac")

# create output transaction
txout.nValue = 0x605af40500000000
txout.scriptPubKey = binascii.unhexlify("76a914097072524438d003d23a2f23edb65aae1bb3e46988ac")

# set inputs and outputs
tx.vin.append(txin)
tx.vout.append(txout)
sertx = tx.serialize() + binascii.unhexlify("01000000")
Esempio n. 36
0
    def sendtoaddress(self, toaddress, amount):        
        # select the input addresses
        funds = 0
        subaccounts = []
        accounts = self.getaccounts()
        for account in accounts:
            for address, subaccount in account.iteritems():
                if subaccount['balance'] == 0:
                    continue
                else:
                    subaccounts.append(subaccount)
                    # print "got one subaccount", subaccount
                    # print "subaccounts: ", subaccounts
                    funds = funds + subaccount['balance']
                    if funds >= amount + utils.calculate_fees(None):
                        break
        
        # print "subaccounts 2: ", subaccounts
        # incase of insufficient funds, return
        if funds < amount + utils.calculate_fees(None):
            print "In sufficient funds, exiting, return"
            return
            
        # create transaction
        tx = CTransaction()
        
        # print "subaccounts 3: ", subaccounts
        # to the receiver
        txout = CTxOut()
        txout.nValue = amount
        txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(toaddress)
        tx.vout.append(txout)
        
        # from the sender
        nValueIn = 0
        nValueOut = amount
        public_keys = []
        private_keys = []
        # secrets = []
        # print "subaccounts 4: ", subaccounts
        for subaccount in subaccounts:
            # print "subaccount: ", subaccount
            # get received by from address
            previous_txouts = subaccount['received']
            # print "Previous txouts", previous_txouts
            for received in previous_txouts:
                txin = CTxIn()
                txin.prevout = COutPoint()
                txin.prevout.hash = received['txhash']
                txin.prevout.n = received['n']
                txin.scriptSig = binascii.unhexlify(received['scriptPubKey'])
                tx.vin.append(txin)
                nValueIn = nValueIn + received['value']
                public_keys.append(subaccount['public_key']) 
                private_keys.append(subaccount['private_key'])
                # secrets.append(subaccount['secret'])
                if nValueIn >= amount + utils.calculate_fees(tx):
                    break
            if nValueIn >= amount + utils.calculate_fees(tx):
                break

        # calculate the total excess amount
        excessAmount = nValueIn - nValueOut
        # calculate the fees
        fees = utils.calculate_fees(tx)
        # create change transaction, if there is any change left
        if excessAmount > fees:
            change_txout = CTxOut()
            change_txout.nValue = excessAmount - fees
            changeaddress = subaccounts[0]['address']
            change_txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(changeaddress)
            tx.vout.append(change_txout)
        
        # calculate txhash
        tx.calc_sha256()
        txhash = str(tx.sha256)
        # sign the transaction
        for public_key, private_key, txin in zip(public_keys, private_keys, tx.vin):
            key = CKey()
            key.set_pubkey(public_key)
            key.set_privkey(private_key)
            signature = key.sign(txhash)
            # scriptSig = chr(len(signature)) + hash_type + signature + chr(len(public_key)) + public_key
            scriptSig = chr(len(signature)) + signature + chr(len(public_key)) + public_key
            print "Adding signature: ", binascii.hexlify(scriptSig)
            txin.scriptSig = scriptSig
            print "Tx Validity: ", tx.is_valid()
        return tx
Esempio n. 37
0
# You'll need to send some funds to it to create a txout to spend.
txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey)
print('Pay to:',str(txin_p2sh_address))

# Same as the txid:vout the createrawtransaction RPC call requires
#
# lx() takes *little-endian* hex and converts it to bytes; in Bitcoin
# transaction hashes are shown little-endian rather than the usual big-endian.
# There's also a corresponding x() convenience function that takes big-endian
# hex and converts it to bytes.
txid = lx('bff785da9f8169f49be92fa95e31f0890c385bfb1bd24d6b94d7900057c617ae')
vout = 0

# Create the txin structure, which includes the outpoint. The scriptSig
# defaults to being empty.
txin = CTxIn(COutPoint(txid, vout))

# Create the txout. This time we create the scriptPubKey from a Bitcoin
# address.
txout = CTxOut(0.0005*COIN, CBitcoinAddress('323uf9MgLaSn9T7vDaK1cGAZ2qpvYUuqSp').to_scriptPubKey())

# Create the unsigned transaction.
tx = CTransaction([txin],[txout])

# Calculate the signature hash for that transaction. Note how the script we use
# is the redeemScript, not the scriptPubKey. That's because when the CHECKSIG
# operation happens EvalScript() will be evaluating the redeemScript, so the
# corresponding SignatureHash() function will use that same script when it
# replaces the scriptSig in the transaction being hashed with the script being
# executed.
sighash = SignatureHash(txin_redeemScript, tx, 0, SIGHASH_ALL)
Esempio n. 38
0
 def stream_deserialize(cls, f):
     hash = ser_read(f, 32)
     vin = CTxIn.stream_deserialize(f)
     sig = BytesSerializer.stream_deserialize(f)
     height = struct.unpack(b"<I", ser_read(f, 4))[0]
     return cls(hash, vin, sig, height)
    def build_refund_tx(self, setup_tx_id, refund_amount=None):
        #Check refund amount.
        if refund_amount != None:
            if refund_amount > self.trade.to_send:
                raise Exception("Invalid refund amount.")

        #Create redeem script.    
        redeem_script = bond_redeem_script(self.ecdsa_us, self.ecdsa_them, self.factory.ecdsa_arbiters[0])
        
        #Generate p2sh script pub key.
        redeem_script_hash160 = hash160_script(redeem_script)

        txin_script_pub_key = CScript([OP_HASH160, redeem_script_hash160["bin"], OP_EQUAL])

        #Setup tx inputs.
        txid = lx(setup_tx_id)
        txin = CTxIn(COutPoint(txid, self.vout))
        txouts = []

        #Our output.
        our_address = deconstruct_address(self.change_address)["hash"]
        our_pub_key = CScript([OP_DUP, OP_HASH160, our_address, OP_EQUALVERIFY, OP_CHECKSIG])

        #Their output.
        their_address = deconstruct_address(self.their_address)["hash"]
        their_pub_key = CScript([OP_DUP, OP_HASH160, their_address, OP_EQUALVERIFY, OP_CHECKSIG])

        #Append outputs.
        if refund_amount == None:
            #Inital full refund.
            remaining = self.upload_amount
            txouts.append(CTxOut(remaining.as_decimal * COIN, our_pub_key))
        else:
            """
            Micro-payment channel i.e. the contract. 

            The refund amount leaves "room" for a TX fee so you just do normal calculations and the difference constitutes the TX fee.
            """
            remaining = self.upload_amount - refund_amount
            if remaining > C("0"):
                txouts.append(CTxOut(remaining.as_decimal * COIN, our_pub_key))
            txouts.append(CTxOut(refund_amount.as_decimal * COIN, their_pub_key))

        #Create unsigned transaction.
        if refund_amount == None:
            txin.nSequence = 0 #Enable ntimelocks.
            tx = CTransaction([txin], txouts, self.nlock_time)
        else:
            txin.nSequence = 0xffffffff #Make transaction final!
            tx = CTransaction([txin], txouts)

        #Return unsigned transaction hex.
        tx_hex = b2x(tx.serialize())
        txid = calculate_txid(tx_hex)
        our_first_sig = self.sign_refund_tx(tx_hex, 1)
        our_second_sig = self.sign_refund_tx(tx_hex, 2)
        return {
            "tx_hex": tx_hex,
            "txid": txid,
            "first_sig": our_first_sig,
            "second_sig": our_second_sig
        }
# Create the (in)famous correct brainwallet secret key.
h = hashlib.sha256(b'correct horse battery staple').digest()
seckey = CBitcoinSecret.from_secret_bytes(h)

# Same as the txid:vout the createrawtransaction RPC call requires
#
# lx() takes *little-endian* hex and converts it to bytes; in Bitcoin
# transaction hashes are shown little-endian rather than the usual big-endian.
# There's also a corresponding x() convenience function that takes big-endian
# hex and converts it to bytes.
txid = lx('7e195aa3de827814f172c362fcf838d92ba10e3f9fdd9c3ecaf79522b311b22d')
vout = 0

# Create the txin structure, which includes the outpoint. The scriptSig
# defaults to being empty.
txin = CTxIn(COutPoint(txid, vout))

# We also need the scriptPubKey of the output we're spending because
# SignatureHash() replaces the transaction scriptSig's with it.
#
# Here we'll create that scriptPubKey from scratch using the pubkey that
# corresponds to the secret key we generated above.
txin_scriptPubKey = CScript([OP_DUP, OP_HASH160, Hash160(seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG])

# Create the txout. This time we create the scriptPubKey from a Bitcoin
# address.
txout = CTxOut(0.001*COIN, CBitcoinAddress('1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8').to_scriptPubKey())

# Create the unsigned transaction.
tx = CTransaction([txin],[txout])
Esempio n. 41
0
#!/usr/bin/env python

from bitcoin.core import CBlock
from bitcoin.core import CTxIn, CTxOut, CTransaction

txin = CTxIn()
txout = CTxOut()

txin.scriptSig = 0x04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73
txin.prevout = 0x0000000000000000000000000000000000000000000000000000000000000000FFFFFFFF
print txin, txin.is_valid()
tx.vout.nValue = 5000000000
tx.vout.scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704

tx = CTransaction()
tx.vin = [txin]
tx.vout = [txout]
"""
tx.vout.scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG
"""

block = CBlock()
block.nVersion = 1
block.hashPrevBlock = 0
block.hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
block.nTime    = 1231006505
block.nBits    = 0x1d00ffff
block.nNonce   = 2083236893
block.vtx = [tx]
block.sha256 = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
print block.is_valid()
Esempio n. 42
0
def attack_command(args):
    #args.starting_height = 2**32-1
    #scan_command(args)
    fd = open('sent-txs','a')

    for txhash in args.rpc.getrawmempool():
        txhash = lx(txhash)
        tx = args.rpc.getrawtransaction(txhash)
        args.wallet.scan_tx(tx)

    args.fee_per_kb = int(args.fee_per_kb * COIN)

    # deque of transaction outputs, (COutPoint, CTxOut), that we have available
    # to spend. We use these outputs in order, oldest first.
    available_txouts = collections.deque()

    # gather up existing outputs
    total_funds = 0
    for outpoint, txout in args.wallet.unspent_txouts.items():
        total_funds += txout.nValue
        available_txouts.append((outpoint, txout))

    size_sent = 0
    while available_txouts:
        logging.info('Attacking! Sent %d bytes total, Funds left: %s in %d txouts' %
                     (size_sent, str_money_value(total_funds), len(available_txouts)))

        tx = CTransaction()

        # Gather up txouts until we have enough funds in to pay the fees on a
        # target-sized tx as well as the non-dust outputs.
        sum_value_in = 0

        # Assuming the whole tx is CTxOut's, each one is 46 bytes (1-of-1
        # CHECKMULTISIG) and the value out needs to be at least 1000 satoshis.
        avg_txout_size = 46 #25+1+8
        num_txouts = args.target_tx_size // avg_txout_size
        min_value_out = 10000
        sum_min_value_out = num_txouts * min_value_out

        fees = (args.target_tx_size/1000) * args.fee_per_kb

        inputs = {}
        tx_size = len(tx.serialize())
        dummy_scriptSig = CScript([b'\x00'*74])
        while (sum_value_in < fees + sum_min_value_out
               and tx_size < args.target_tx_size/2 # don't devote more than half the tx to inputs
               and available_txouts):
            outpoint, txout = available_txouts.popleft()

            try:
                args.rpc.gettxout(outpoint)
            except IndexError:
                continue

            inputs[outpoint] = txout
            sum_value_in += txout.nValue

            # The CTxIn has a dummy signature so size calculations will be right
            txin = CTxIn(outpoint, dummy_scriptSig)
            tx.vin.append(txin)
            tx_size += len(txin.serialize())

        total_funds -= sum_value_in

        # Recalculate number of txouts we'll have now that we've added the
        # txins. Of course, this will leave the actual value per txout a bit
        # high, but whatever.
        num_txouts = int(min((args.target_tx_size-len(tx.serialize())) / avg_txout_size,
                             (sum_value_in - fees) / min_value_out))

        # Split the funds out evenly among all transaction outputs.
        per_txout_value = (sum_value_in - fees) // num_txouts
        for i in range(num_txouts):
            scriptPubKey = args.wallet.make_multisig()
            txout = CTxOut(per_txout_value, scriptPubKey)
            tx.vout.append(txout)

        # Sign the transaction
        for (i, txin) in enumerate(tx.vin):
            prevout_scriptPubKey = inputs[txin.prevout].scriptPubKey
            sighash = SignatureHash(prevout_scriptPubKey, tx, i, SIGHASH_ALL)
            seckey = args.wallet.keypairs[prevout_scriptPubKey]
            sig = seckey.sign(sighash) + bytes([SIGHASH_ALL])

            if prevout_scriptPubKey[-1] == OP_CHECKMULTISIG:
                txin.scriptSig = CScript([OP_0, sig])

            elif prevout_scriptPubKey[-1] == OP_CHECKSIG and prevout_scriptPubKey[-2] == OP_EQUALVERIFY:
                txin.scriptSig = CScript([sig, seckey.pub])

            VerifyScript(txin.scriptSig, prevout_scriptPubKey, tx, i)

        # Add the new txouts to the list of available txouts
        tx_hash = tx.get_hash()
        sum_value_out = 0
        for i, txout in enumerate(tx.vout):
            outpoint = COutPoint(tx_hash, i)
            available_txouts.append((outpoint, txout))
            sum_value_out += txout.nValue

        total_funds += sum_value_out

        actual_fees = sum_value_in - sum_value_out
        serialized_tx = tx.serialize()
        logging.debug('Sending tx %s\n'
           '           value in: %s, value out: %s, fees: %s, fees/KB: %s\n'
           '           size: %d, # of inputs: %d, # of outputs: %d, txout.nValue: %s' %
                      (b2lx(tx_hash), str_money_value(sum_value_in), str_money_value(sum_value_out),
                       str_money_value(actual_fees),
                       str_money_value(actual_fees/(len(serialized_tx)/1000)),
                       len(serialized_tx), len(tx.vin), len(tx.vout), per_txout_value))
        size_sent += len(serialized_tx)

        #print(b2x(serialized_tx))
        #args.wallet.save()
        try:
            args.rpc.sendrawtransaction(tx)
            fd.write(b2x(serialized_tx) + '\n')
            fd.flush()
        except bitcoin.rpc.JSONRPCException as exp:
            print(b2x(tx.serialize()))
            #import pdb; pdb.set_trace()

        time.sleep(random.randrange(30,60))
Esempio n. 43
0
    def sendtovault(self, vault_address, amount):
        # select the input addresses
        funds = 0
        subaccounts = []
        accounts = self.getaccounts()
        for account in accounts:
            for address, subaccount in account.iteritems():
                if subaccount['balance'] == 0:
                    continue
                else:
                    subaccounts.append(subaccount)
                    funds = funds + subaccount['balance']
                    if funds >= amount + utils.calculate_fees(None):
                        break

        # incase of insufficient funds, return
        if funds < amount + utils.calculate_fees(None):
            self.logger.warning("Insufficient funds, exiting, return")
            raise exceptions.InsufficientBalanceException

        # create transaction
        tx = CTransaction()

        # to the receiver
        txout = CTxOut()
        txout.nValue = amount
        txout.scriptPubKey = utils.vault_address_to_pay_to_vault_script(vault_address)
        tx.vout.append(txout)

        # from the sender
        nValueIn = 0
        nValueOut = amount
        public_keys = []
        private_keys = []
        for subaccount in subaccounts:
            # get received by from address
            previous_txouts = subaccount['received']
            for received in previous_txouts:
                txin = CTxIn()
                txin.prevout = COutPoint()
                txin.prevout.hash = received['txhash']
                txin.prevout.n = received['n']
                txin.scriptSig = received['scriptPubKey']
                tx.vin.append(txin)
                nValueIn = nValueIn + received['value']
                public_keys.append(subaccount['public_key'])
                private_keys.append(subaccount['private_key'])
                if nValueIn >= amount + utils.calculate_fees(tx):
                    break
            if nValueIn >= amount + utils.calculate_fees(tx):
                break

        # calculate the total excess amount
        excessAmount = nValueIn - nValueOut
        # calculate the fees
        fees = utils.calculate_fees(tx)
        # create change transaction, if there is any change left
        if excessAmount > fees:
            change_txout = CTxOut()
            change_txout.nValue = excessAmount - fees
            changeaddress = self.getnewaddress()[1]
            change_txout.scriptPubKey = utils.address_to_pay_to_pubkey_hash(changeaddress)
            tx.vout.append(change_txout)

        # calculate txhash
        tx.calc_sha256()
        txhash = str(tx.sha256)
        self.logger.debug("Sending to vault %064x" % tx.sha256)
        # sign the transaction
        for public_key, private_key, txin in zip(public_keys, private_keys, tx.vin):
            key = CKey()
            key.set_pubkey(public_key)
            key.set_privkey(private_key)
            signature = key.sign(txhash)
            # scriptSig = chr(len(signature)) + hash_type + signature + chr(len(public_key)) + public_key
            scriptSig = chr(len(signature)) + signature + chr(len(public_key)) + public_key
            self.logger.debug("Adding signature: %s" % binascii.hexlify(scriptSig))
            txin.scriptSig = scriptSig
            self.logger.debug("Tx Validity: %064x" % tx.is_valid())
        # push data to vault
        tx.calc_sha256()
        self.set(str("vault:" + vault_address), {'txhash': tx.sha256})
        return (vault_address, tx)