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())
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()))
Beispiel #3
0
def recover_command(args):
    args.fee_per_kb = int(args.fee_per_kb * COIN)
    addr = CBitcoinAddress(args.addr)

    tx = CTransaction()

    sum_value_in = 0
    dummy_scriptSig = CScript([b'\x00'*74])
    inputs = {}
    for outpoint, txout in tuple(args.wallet.unspent_txouts.items())[0:500]:
        sum_value_in += txout.nValue
        tx.vin.append(CTxIn(outpoint, dummy_scriptSig))
        inputs[outpoint] = txout

    tx.vout.append(CTxOut(-1, addr.to_scriptPubKey()))

    fees = int((len(tx.serialize())/1000) * args.fee_per_kb)

    tx.vout[0].nValue = sum_value_in - fees

    # 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)

    print(b2x(tx.serialize()))
Beispiel #4
0
def spend_command(pubkey, nLockTime, prevOuts):
    addr = P2PKHBitcoinAddress.from_pubkey(x(pubkey))
    address = addr
    redeemScript = hodl_redeemScript(pubkey, nLockTime)
    scriptPubKey = redeemScript.to_p2sh_scriptPubKey()
    proxy = bitcoin.rpc.Proxy(btc_conf_file=bitcoin.params.CONF_FILE)
    prevouts = []
    for prevout in prevOuts:
        try:
            txid, n = prevout.split(':')
            txid = lx(txid)
            n = int(n)
            outpoint = COutPoint(txid, n)
        except ValueError:
            raise Exception('Invalid output: %s' % prevout)
        try:
            prevout = proxy.gettxout(outpoint)
        except IndexError:
            raise Exception('Outpoint %s not found' % outpoint)
        prevout = prevout['txout']
        if prevout.scriptPubKey != scriptPubKey:
            raise Exception('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 +  # number of txins
        len(prevouts) * 153 +  # txins, including sigs
        1 +  # number 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, redeemScript, nSequence=0)
        for outpoint, prevout in prevouts
    ], [CTxOut(sum_in - fees, address.to_scriptPubKey())], nLockTime)

    return ({'redeemTransaction': b2x(unsigned_tx.serialize())})
def SignatureHash(script, txTo, inIdx, hashtype):
    if inIdx >= len(txTo.vin):
        return (1, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))
    txtmp = CTransaction()
    txtmp.copy(txTo)

    for txin in txtmp.vin:
        txin.scriptSig = b''
    txtmp.vin[inIdx].scriptSig = script.vch

    if (hashtype & 0x1f) == SIGHASH_NONE:
        txtmp.vout = []

        for i in range(len(txtmp.vin)):
            if i != inIdx:
                txtmp.vin[i].nSequence = 0

    elif (hashtype & 0x1f) == SIGHASH_SINGLE:
        outIdx = inIdx
        if outIdx >= len(txtmp.vout):
            return (1,
                    "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout)))

        tmp = txtmp.vout[outIdx]
        txtmp.vout = []
        for i in range(outIdx):
            txtmp.vout.append(CTxOut())
        txtmp.vout.append(tmp)

        for i in range(len(txtmp.vin)):
            if i != inIdx:
                txtmp.vin[i].nSequence = 0

    if hashtype & SIGHASH_ANYONECANPAY:
        tmp = txtmp.vin[inIdx]
        txtmp.vin = []
        txtmp.vin.append(tmp)

    s = txtmp.serialize()
    s += struct.pack(b"<I", hashtype)

    hash = Hash(s)

    return (hash, )
def SignatureHash(script, txTo, inIdx, hashtype):
    if inIdx >= len(txTo.vin):
        return (0, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))
    txtmp = CTransaction()
    txtmp.copy(txTo)

    for txin in txtmp.vin:
        txin.scriptSig = b''
    txtmp.vin[inIdx].scriptSig = script.vch

    if (hashtype & 0x1f) == SIGHASH_NONE:
        txtmp.vout = []

        for i in range(len(txtmp.vin)):
            if i != inIdx:
                txtmp.vin[i].nSequence = 0

    elif (hashtype & 0x1f) == SIGHASH_SINGLE:
        outIdx = inIdx
        if outIdx >= len(txtmp.vout):
            return (0, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout)))

        tmp = txtmp.vout[outIdx]
        txtmp.vout = []
        for i in range(outIdx):
            txtmp.vout.append(CTxOut())
        txtmp.vout.append(tmp)

        for i in range(len(txtmp.vin)):
            if i != inIdx:
                txtmp.vin[i].nSequence = 0

    if hashtype & SIGHASH_ANYONECANPAY:
        tmp = txtmp.vin[inIdx]
        txtmp.vin = []
        txtmp.vin.append(tmp)

    s = txtmp.serialize()
    s += struct.pack(b"<I", hashtype)

    hash = Hash(s)

    return (hash,)
    def build_claim_tx(self, txid_hex):
        if self.secret_info["plaintext"] == None:
            raise Exception("We don't know the secret yet.")

        #Create redeem script.
        redeem_script = self.fund_redeem_script(self.their)

        #Convert to p2sh address.
        their_fund_address = self.script_to_address(redeem_script, self.their)

        #Check there is enough in the p2sh address.
        their_fund_tx = self.jsonrpc[self.their].gettransaction(
            txid_hex)["details"]
        found = 0
        for tx_input in their_fund_tx:
            #Check it's the right input.
            if tx_input["address"] == their_fund_address:
                found = 1
                if tx_input["amount"] + self.recv_amount > decimal.Decimal(
                        coinbend.config["mining_fee"]["standard"]):
                    raise Exception(
                        "Their contract has not been sufficently funded.")
                break
            else:
                continue

        #Their side of the contract hasn't been funded.
        if not found:
            raise Exception("Their contract fund output was not detected.")

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

        #Load private key for signing.
        seckey = CBitcoinSecret(self.key_pairs[self.my]["priv"]["wif"])

        #Generate p2sh script pub key.
        redeem_script_hash160 = self.hash160_script(redeem_script)
        txin_script_pub_key = CScript(
            [OP_HASH160, redeem_script_hash160["bin"], OP_EQUAL])

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

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

        #Sign transactions.
        sighash = SignatureHash(redeem_script["bin"], tx, 0, SIGHASH_ALL)
        sig = seckey.sign(sighash) + bytes([SIGHASH_ALL])
        txin.scriptSig = CScript([
            bytes(self.secret_info["plaintext"].encode("ascii")), sig, OP_3,
            redeem_script["bin"]
        ])

        #Return signed transaction hex.
        return b2x(tx.serialize())
    def build_fund_tx(self, redeem_script):
        if type(self.send_amount) != decimal.Decimal:
            raise Exception("Please only use decimal types for the amount.")
        if self.send_amount < decimal.Decimal(
                coinbend.config["minimum_trade"]):
            raise Exception("Amount is too small.")

        #Because every Satoshi counts.
        decimal.getcontext().prec = 50

        #Create a change address.
        if "change" not in self.key_pairs:
            self.key_pairs["change"] = self.key_pair_from_address(
                self.jsonrpc[self.my].getnewaddress(), self.my)

        #Get wallet balance.
        balance = self.jsonrpc[self.my].getbalance()

        #Check we have enough.
        if balance < self.send_amount:
            raise Exception("Insufficent balance to cover fund.")

        #List unclaimed outputs.
        unspent_outputs = self.jsonrpc[self.my].listunspent()

        #Setup tx inputs.
        change_amount = decimal.Decimal("0")
        txins = []
        total = decimal.Decimal("0")
        indexes = []
        i = 0
        for unspent_output in unspent_outputs:
            #Skip outputs that don't satisfy min confirmations.
            if unspent_output["confirmations"] < self.minimum_confirmations:
                i += 1
                continue

            #Check scriptPubKey is pay to pub key hash.
            if self.jsonrpc[self.my].decodescript(
                    unspent_output["scriptPubKey"])["type"] != "pubkeyhash":
                i += 1
                continue

            #Record key pairs.
            if unspent_output["address"] not in self.key_pairs:
                self.key_pairs[
                    unspent_output["address"]] = self.key_pair_from_address(
                        unspent_output["address"], self.my)

            #Build new txin.
            txid = lx(unspent_output["txid"])
            vout = unspent_output["vout"]
            txin = CTxIn(COutPoint(txid, vout))
            txins.append(txin)
            indexes.append(i)
            total += unspent_output["amount"]
            i += 1

            if total > self.send_amount:
                break

            if total == self.send_amount:
                break

        #Insufficent funds.
        if total < self.send_amount:
            raise Exception("Not enough valid inputs to fund contract.")

        #Calculate change.
        change = total - self.send_amount

        #Build txouts.
        txouts = []
        redeem_script_hash160 = self.hash160_script(redeem_script)
        p2sh_script_pub_key = CScript(
            [OP_HASH160, redeem_script_hash160["bin"], OP_EQUAL])
        txouts.append(
            CTxOut(
                (self.send_amount -
                 decimal.Decimal(coinbend.config["mining_fee"]["standard"])) *
                COIN, p2sh_script_pub_key))
        if change > decimal.Decimal("0"):
            change_seckey = CBitcoinSecret(
                self.key_pairs["change"]["priv"]["wif"])
            change_script_pub_key = CScript([
                OP_DUP, OP_HASH160,
                Hash160(change_seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG
            ])
            txouts.append(CTxOut(change * COIN, change_script_pub_key))

        #Build unsigned transaction.
        tx = CTransaction(txins, txouts)
        unsigned_tx_hex = b2x(tx.serialize())

        #Sign transaction.
        signed_tx_hex = self.jsonrpc[self.my].signrawtransaction(
            unsigned_tx_hex)["hex"]
        return signed_tx_hex
# 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)

# 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])

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

# Verify the signature worked. This calls EvalScript() and actually executes
# the opcodes in the scripts to see if everything worked out. If it doesn't an
# exception will be raised.
print(b2x(txin_scriptPubKey))
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))

# Done! Print the transaction to standard output with the bytes-to-hex
# function.
print(b2x(tx.serialize()))
    def build_setup(self):
        #Get wallet balance.
        currency = self.trade.to_send.currency
        coin_rpc = self.coins[currency]["rpc"]["sock"]
        balance = C(coin_rpc.getbalance())
        self.tx_fee_amount = self.coins[currency]["tx_fee"]
        
        #Check we have enough.
        if balance < self.trade.to_send:
            raise Exception("Insufficent balance to cover fund.") 
        
        #List unclaimed inputs.
        self.green_address.load_inputs()
        unspent_inputs = self.green_address.inputs

        #Check unclaimed outputs go to the right green address.
        deposit_tx = self.green_address.deposit_tx_hex
        print(deposit_tx)
        deposit_tx = CTransaction.deserialize(binascii.unhexlify(deposit_tx))
        print(deposit_tx)
        ret = parse_address(None, deposit_tx, currency)
        print(ret)
        ret = ret[0]
        print(ret)
        if ret["type"] != "p2sh":
            raise Exception("Invalid green address deposit tx.")
        else:
            p2sh_index = ret["vout"]
            green_address_hash = deconstruct_address(self.green_address.address)["hash"]
            if deposit_tx.vout[p2sh_index].scriptPubKey != CScript([OP_HASH160, green_address_hash, OP_EQUAL]):
                raise Exception("Unexpected green address output.")
        
        #Setup tx inputs.
        txins = []
        green_total = C("0")
        indexes = []
        for unspent_input in unspent_inputs:
            #Skip outputs that don't satisfy min confirmations.
            confirmations = int(self.config["confirmations"])
            if unspent_input["confirmations"] < confirmations:
                continue

            #Skip non p2sh outputs.
            if unspent_input["vout"] != p2sh_index:
                continue
            
            #Build new txin.
            txid = lx(unspent_input["txid"])
            vout = unspent_input["vout"]
            txin = CTxIn(COutPoint(txid, vout))
            txins.append(txin)
            green_total += C(unspent_input["amount"])

            break
        
        #Insufficent funds.
        if green_total < self.green_address.trade.to_send:
            print("Exception .. insufficent funds.")
            print(green_total)
            print(self.green_address.trade.to_send)
            raise Exception("Not enough valid inputs to fund contract.")

        #Calculate collateral amount.
        total = C(0)
        collateral = C(0)
        to_send = C(0)
        for contract_hash in list(self.contracts):
            contract = self.contracts[contract_hash]
            collateral += contract.our_chunk_size
            to_send += contract.upload_amount + contract.our_chunk_size + self.tx_fee_amount
            print("Our chunk size: " + str(contract.our_chunk_size))

        """
        Trade fees are initially applied based on being able to match 100%. If there's change it means not everything was matched and hence you're being charged fees for coins that aren't even being traded. The code bellow recalculates the fees.
        """
        fees = self.trade.fees
        to_send += fees
        if to_send < self.green_address.trade.to_send:
            print("Fees reduced.")
            ceiling = self.green_address.trade.to_send - to_send 
            fees = ceiling * self.trade_fee
            #I'm not sure this is correct.
        print("Trade fees: " + str(fees))

        #Add fees to collateral.
        collateral += fees
        print("Collateral: " + str(collateral))
        total += collateral
        
        #Collateral / fee output.
        txouts = []
        ecdsa_fee = ECDSACrypt(self.config["fee_key_pair"]["pub"])
        collateral_script_pub_key = CScript([OP_DUP, OP_HASH160, Hash160(ecdsa_fee.get_public_key("bin")), OP_EQUALVERIFY, OP_CHECKSIG])
        txouts.append(CTxOut(collateral.as_decimal * COIN, collateral_script_pub_key))

        #Contract outputs.
        for contract_hash in list(self.contracts):
            contract = self.contracts[contract_hash]
            redeem_script = bond_redeem_script(contract.ecdsa_us, contract.ecdsa_them, self.ecdsa_arbiters[0])
            redeem_script_hash160 = hash160_script(redeem_script)
            p2sh_script_pub_key = CScript([OP_HASH160, redeem_script_hash160["bin"], OP_EQUAL])
            contract_amount = contract.upload_amount + self.tx_fee_amount
            print("Contract amount: " + str(contract_amount))
            txouts.append(CTxOut(contract_amount.as_decimal * COIN, p2sh_script_pub_key))
            total += contract_amount

        #Change output.
        if total < self.green_address.trade.to_send:
            change = self.green_address.trade.to_send - total
            if change > C("0"):
                change_script_pub_key = CScript([OP_DUP, OP_HASH160, Hash160(self.ecdsa_1.get_public_key("bin")), OP_EQUALVERIFY, OP_CHECKSIG])
                txouts.append(CTxOut(change.as_decimal * COIN, change_script_pub_key))
            
        #Build unsigned transaction.
        tx = CTransaction(txins, txouts)

        #Return unsigned transaction hex.
        tx_hex = b2x(tx.serialize())
        txid = calculate_txid(tx_hex)
        our_first_sig = sign_setup_tx(tx_hex, self.green_address.redeem_script, self.green_address.ecdsa_1)
        our_second_sig = sign_setup_tx(tx_hex, self.green_address.redeem_script, self.green_address.ecdsa_2)

        self.setup["tx_hex"] = tx_hex
        self.setup["txid"] = txid
        self.setup["sig_1"] = our_first_sig
        self.setup["sig_2"] = our_second_sig
        return {
            "tx_hex": tx_hex,
            "txid": txid,
            "first_sig": our_first_sig,
            "second_sig": our_second_sig
        }
Beispiel #11
0
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")

"""
print sertx[:76]
print sertx[76:152]
print sertx[152:]
"""

dhash = myhash(sertx)
print binascii.hexlify(dhash)
print "9302bda273a887cb40c13e02a50b4071a31fd3aae3ae04021b0b843dd61ad18e"

# sign the transaction now

print "\n\n"
x = """
Beispiel #12
0
            txout_info = proxy.gettxout(txin.prevout)
        except IndexError:
            print('Already spent! line %d, txid %s %d' % \
                    (line, b2lx(txin.prevout.hash), txin.prevout.n),
                    file=sys.stderr)
            continue

        print('line %d: %s %d: %s' % \
                (line, b2lx(txin.prevout.hash), txin.prevout.n,
                    str_money_value(txout_info['txout'].nValue)),
                file=sys.stderr)

        sum_value_in += txout_info['txout'].nValue

        if txin.prevout not in prevouts:
            prevouts.add(txin.prevout)
            txins.append(txin)
        else:
            print('Dup! line %d, txid %s %d' % \
                    (line, b2lx(txin.prevout.hash), txin.prevout.n),
                    file=sys.stderr)

random.shuffle(txins)
tx = CTransaction(txins, [CTxOut(0, CScript([OP_RETURN]))])

print(b2x(tx.serialize()))

print('Total: %s  Size: %d' %
      (str_money_value(sum_value_in), len(tx.serialize())),
      file=sys.stderr)
Beispiel #13
0
    for txin in tx.vin:
        try:
            txout_info = proxy.gettxout(txin.prevout)
        except IndexError:
            print('Already spent! line %d, txid %s %d' % \
                    (line, b2lx(txin.prevout.hash), txin.prevout.n),
                    file=sys.stderr)
            continue

        print('line %d: %s %d: %s' % \
                (line, b2lx(txin.prevout.hash), txin.prevout.n,
                    str_money_value(txout_info['txout'].nValue)),
                file=sys.stderr)

        sum_value_in += txout_info['txout'].nValue

        if txin.prevout not in prevouts:
            prevouts.add(txin.prevout)
            txins.append(txin)
        else:
            print('Dup! line %d, txid %s %d' % \
                    (line, b2lx(txin.prevout.hash), txin.prevout.n),
                    file=sys.stderr)

random.shuffle(txins)
tx = CTransaction(txins, [CTxOut(0, CScript([OP_RETURN]))])

print(b2x(tx.serialize()))

print('Total: %s  Size: %d' % (str_money_value(sum_value_in), len(tx.serialize())), file=sys.stderr)
Beispiel #14
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))
    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
        }
Beispiel #16
0
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)

# 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])

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

# Verify the signature worked. This calls EvalScript() and actually executes
# the opcodes in the scripts to see if everything worked out. If it doesn't an
# exception will be raised.
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH, ))

# Done! Print the transaction to standard output with the bytes-to-hex
# function.
print(b2x(tx.serialize()))
Beispiel #17
0
def settle_to_single_addr(deposits: List[Deposit], addr: CBitcoinAddress):
    prevouts = []
    for d in deposits:
        try:
            txid, n = d.txid, d.nout

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

            outpoint = COutPoint(txid, n)
        except ValueError:
            raise ValueError('Invalid output: %s' % d)

        try:
            prevout = proxy.gettxout(outpoint)
        except IndexError:
            raise ValueError('Outpoint %s not found' % outpoint)

        prevout = prevout['txout']
        if prevout.scriptPubKey != d.params.deposit_redeemScript.to_p2sh_scriptPubKey(
        ):
            raise Exception('Outpoint not correct scriptPubKey')

        prevouts.append((outpoint, prevout))

    sum_in = sum(prev_txout.nValue for _, 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
    )

    estimated_fee = proxy._call('estimatesmartfee', 1)

    if 'errors' in estimated_fee:
        print(estimated_fee['errors'])
        feerate = -1
    else:
        feerate = int(estimated_fee['feerate'] * COIN)  # satoshi's per KB

    if feerate <= 0:
        feerate = 10000
    fees = int(tx_size / 1000 * feerate)

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

    # lock until the next block
    nLockTime = proxy.getblockcount()

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

    # sign the inputs
    signed_ins = [
        CTxIn(unsigned_tx.vin[i].prevout,
              d.params.spend_redeemScript('exch', exch_seckey, unsigned_tx, i),
              nSequence=0) for i, d in enumerate(deposits)
    ]

    signed_tx = CTransaction(signed_ins, unsigned_tx.vout,
                             unsigned_tx.nLockTime)

    print(b2x(signed_tx.serialize()))
Beispiel #18
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()))
            CScript([1, x('0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71'),
                        b'\x00'*33,
                     2, OP_CHECKMULTISIG]))
    tx.vout.append(multisig_txout)

for bad_addr in args.bad_addr:
    bad_addr = CBitcoinAddress(bad_addr)
    txout = CTxOut(args.dust, bad_addr.to_scriptPubKey())
    tx.vout.append(txout)


# Add inputs until we meet the fee1 threshold
unspent = sorted(rpc.listunspent(1), key=lambda x: x['amount'])
value_in = 0
value_out = sum([vout.nValue for vout in tx.vout])
while (value_in - value_out) / len(tx.serialize()) < feeperbyte1:
    # What's the delta fee that we need to get to our desired fees per byte at
    # the current tx size?
    delta_fee = math.ceil((feeperbyte1 * len(tx.serialize())) - (value_in - value_out))

    logging.debug('Delta fee: %s' % str_money_value(delta_fee))

    # If we simply subtract that from the change outpoint are we still above
    # the dust threshold?
    if change_txout.nValue - delta_fee > args.dust:
        change_txout.nValue -= delta_fee
        value_out -= delta_fee

    # Do we need to add another input?
    if value_in - value_out < 0:
        new_outpoint = unspent[-1]['outpoint']
Beispiel #20
0
# 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")
"""
print sertx[:76]
print sertx[76:152]
print sertx[152:]
"""

dhash = myhash(sertx)
print binascii.hexlify(dhash)
print "9302bda273a887cb40c13e02a50b4071a31fd3aae3ae04021b0b843dd61ad18e"

# sign the transaction now

print "\n\n"
x = """
0100000001eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f201