Example #1
0
def create_tx_io(amount, addr, wallet_nodes, change_nodes, fee):
    txins = []
    txouts = []
    spendables = []
    wifs = []

    dust_threshold = Decimal('0.00000543')
    collected = Decimal(0)
    single = None
    
    assert amount > dust_threshold
    for op in unspents:
        op_amount = convention.satoshi_to_btc( op.as_dict()['coin_value'] )
        if op_amount >= amount + fee:
            single = op
            collected = op_amount
    
    if not single:
        for op in unspents:
            spendables.append(op)
            op_amount = convention.satoshi_to_btc( op.as_dict()['coin_value'] )
            collected += op_amount
            if collected >= amount + fee:
                break
        else:
            raise Exception("Insufficient funds!")
    else:
        spendables.append(single)
    
    for op in spendables:
        txin = op.tx_in()
        txins.append( txin )
        
        op_script = serialize.h2b( op.as_dict()['script_hex'] )
        hash160 = serialize.h2b( script.tools.opcode_list(op_script)[2] )
        prev_addr = Key(hash160=hash160, netcode=NETCODE).address()
        # from pycoin import networks
        # address_prefix = networks.address_prefix_for_netcode(NETCODE)
        # prev_addr = txin.bitcoin_address(address_prefix=address_prefix)
        
        for nodes in (wallet_nodes, change_nodes):
            if prev_addr in nodes['used'].keys():
                wifs.append( nodes['used'][prev_addr]['key'].wif() )
    
    change = collected - (amount + fee)
    
    amount_btc = convention.btc_to_satoshi(amount)
    spend = TxOut( amount_btc, standard_tx_out_script(addr) )
    txouts.append(spend)
    
    if change > dust_threshold:
        change_addr = get_unused_node(change_nodes, change=True)['key'].address()
        change_btc = convention.btc_to_satoshi(change)
        change_txout = TxOut( change_btc, standard_tx_out_script(change_addr) )
        txouts.append(change_txout)
    
    return (txins, txouts, spendables, wifs)
Example #2
0
    def update(self):
        cursor = self.db.cursor()
        addresses = self.getalladdresses()
        for address in addresses:
            bci_balance = BCI.getbalance([address['address']])
            if bci_balance!=address['balance']:
                now = int(time.time())

                sql = 'UPDATE addresses SET balance=?, balance_at=?, balance_source=? WHERE address=?'
                values = (bci_balance, now, 'blockchain.info', address['address'])
                cursor.execute(sql, values)

                new_unspents = BCI.listunspent([address['address']])
                # Make this in sql transaction even unspents are outdated ??
                cursor.execute("DELETE FROM unspents WHERE address=?", (address['address'],)) 
                if len(new_unspents)>0:
                    values = []
                    for new_unspent in new_unspents:
                        values.append([
                            address['address'],
                            new_unspent['txid'],
                            new_unspent['scriptPubKey'],
                            btc_to_satoshi(new_unspent['amount']),
                            new_unspent['vout'],
                            new_unspent['confirmations'],
                            now,
                            'blockchain.info',
                        ])
                    sql = '''INSERT INTO unspents (address, txid, scriptPubKey, amount, vout, confirmations, updated_at, source)
                             VALUES (?, ?, ?, ?, ?, ?, ?, ?)'''
                    cursor.executemany(sql, values)
Example #3
0
def populate_unspents(nodes):
    global balance
    global unspents
    
    if nodes['used'] == {}:
        return
    
    addresses = nodes['used'].keys()
    response = json.load( urlopen("http://%s.blockr.io/api/v1/address/unspent/" % BLOCKR + \
                        ','.join(addresses)) )
    data = response['data']
    if type(data) == type({}):
        data = [data]
    
    for entry in data:
        if entry['unspent'] == []:
            continue
        
        for unspent in entry['unspent']:
            balance += Decimal(unspent['amount'])
            amount = convention.btc_to_satoshi(unspent['amount'])
            script = serialize.h2b(unspent['script'])
            txid = serialize.h2b_rev(unspent['tx'])
            
            unspent_spendable = Spendable( amount, script, txid, unspent['n'] )
            unspents.append(unspent_spendable)
            
    time.sleep(1)       # Don't overload blockr.io API
Example #4
0
def tx_from_json_dict(r):
    version = r.get("version")
    lock_time = r.get("locktime")
    txs_in = []
    for vin in r.get("vin"):
        if "coinbase" in vin:
            previous_hash = b'\0' * 32
            script = h2b(vin.get("coinbase"))
            previous_index = 4294967295
        else:
            previous_hash = h2b_rev(vin.get("txid"))
            scriptSig = vin.get("scriptSig")
            if "hex" in scriptSig:
                script = h2b(scriptSig.get("hex"))
            else:
                script = tools.compile(scriptSig.get("asm"))
            previous_index = vin.get("vout")
        sequence = vin.get("sequence")
        txs_in.append(TxIn(previous_hash, previous_index, script, sequence))
    txs_out = []
    for vout in r.get("vout"):
        coin_value = btc_to_satoshi(decimal.Decimal(vout.get("value")))
        script = tools.compile(vout.get("scriptPubKey").get("asm"))
        txs_out.append(TxOut(coin_value, script))
    tx = Tx(version, txs_in, txs_out, lock_time)
    bh = r.get("blockhash")
    if bh:
        bh = h2b_rev(bh)
    tx.confirmation_block_hash = bh
    return tx
Example #5
0
    def send(self, ddestination_address, dcolourid=None):
        self.colordata.update()

        coins_to = []
        total_spent = 0
        for daa in [ddestination_address]:
            address, amount = daa[0], daa[1]
            amount = btc_to_satoshi(amount)
            total_spent += amount
            coins_to.append((amount, address))

        selected_utxos, total_value = self.selectUTXOs(self.getAllUTXOs(), dcolourid, total_spent)
        change = (total_value - total_spent) - 10000
        if change >= 1:
            coins_to.append((change, self.addresses[0].pubkey))

        coins_from = [utxo.get_pycoin_coin_source() for utxo in selected_utxos]
        secret_exponents = [encoding.wif_to_secret_exponent(address.privkey) for address in self.addresses]

        unsigned_tx = UnsignedTx.standard_tx(coins_from, coins_to)
        solver = SecretExponentSolver(secret_exponents)
        new_tx = unsigned_tx.sign(solver)
        s = io.BytesIO()
        new_tx.stream(s)
        tx_bytes = s.getvalue()
        tx_hex = binascii.hexlify(tx_bytes).decode("utf8")
        recommended_tx_fee = tx_fee.recommended_fee_for_tx(new_tx)

        print tx_hex

        URL = "http://blockchain.info/pushtx"
        urllib2.urlopen(URL, data=tx_hex)
Example #6
0
def bitcoin(public, private, address, amount):
     coins_from = []
     coins_sources = blockchain_info.coin_sources_for_address(public)
     coins_from.extend(coins_sources)
     value = sum(cs[-1].coin_value for cs in coins_sources)

     secret_exponents = [encoding.wif_to_secret_exponent(private)]

     amount = btc_to_satoshi(amount)
     coins_to = []
     coins_to.append((amount, address))
     actual_tx_fee = value - amount
     if actual_tx_fee < 0:
         print("not enough source coins (%s BTC) for destination (%s BTC). Short %s BTC" %   (satoshi_to_btc(total_value), satoshi_to_btc(total_spent), satoshi_to_btc(-actual_tx_fee)))
         return None;

     if actual_tx_fee > 0:
        coins_to.append((actual_tx_fee, public))

     unsigned_tx = UnsignedTx.standard_tx(coins_from, coins_to)
     solver = SecretExponentSolver(secret_exponents)
     new_tx = unsigned_tx.sign(solver)
     s = io.BytesIO()
     new_tx.stream(s)
     tx_bytes = s.getvalue()
     tx_hex = binascii.hexlify(tx_bytes).decode("utf8")

     return tx_bytes
Example #7
0
def get_unsigned_tx(parser):
    args = parser.parse_args()
    # if there is only one item passed, it's assumed to be hex
    if len(args.txinfo) == 1:
        try:
            s = io.BytesIO(h2b(args.txinfo[0]))
            return UnsignedTx.parse(s)
        except Exception:
            parser.error("can't parse %s as hex\n" % args.txinfo[0])

    coins_from = []
    coins_to = []
    for txinfo in args.txinfo:
        if '/' in txinfo:
            parts = txinfo.split("/")
            if len(parts) == 2:
                # we assume it's an output
                address, amount = parts
                amount = btc_to_satoshi(amount)
                coins_to.append((amount, address))
            else:
                try:
                    # we assume it's an input of the form
                    #  tx_hash_hex/tx_output_index_decimal/tx_out_val/tx_out_script_hex
                    tx_hash_hex, tx_output_index_decimal, tx_out_val, tx_out_script_hex = parts
                    tx_hash = h2b(tx_hash_hex)
                    tx_output_index = int(tx_output_index_decimal)
                    tx_out_val = btc_to_satoshi(decimal.Decimal(tx_out_val))
                    tx_out_script = h2b(tx_out_script_hex)
                    tx_out = TxOut(tx_out_val, tx_out_script)
                    coins_source = (tx_hash, tx_output_index, tx_out)
                    coins_from.append(coins_source)
                except Exception:
                    parser.error("can't parse %s\n" % txinfo)
        else:
            print("looking up funds for %s from blockchain.info" % txinfo)
            coins_sources = blockchain_info.unspent_tx_outs_info_for_address(txinfo)
            coins_from.extend(coins_sources)

    unsigned_tx = UnsignedTx.standard_tx(coins_from, coins_to)
    return unsigned_tx
Example #8
0
 def spendables_for_address(self, bitcoin_address):
     URL = "%s/api/addr/%s/utxo" % (self.base_url, bitcoin_address)
     r = json.loads(urlopen(URL).read().decode("utf8"))
     spendables = []
     for u in r:
         value = btc_to_satoshi(str(u.get("amount")))
         script = h2b(u.get("scriptPubKey"))
         prev_hash = h2b_rev(u.get("txid"))
         prev_index = u.get("vout")
         spendable = Spendable(value, script, prev_hash, prev_index)
         spendables.append(spendable)
     return spendables
Example #9
0
 def spendables_for_address(self, bitcoin_address):
     url = "{0}/addr/{1}/utxo".format(self.base_url, bitcoin_address)
     result = json.loads(urlopen(url).read().decode("utf8"))
     spendables = []
     for utxo in result:
         value = btc_to_satoshi(str(utxo["amount"]))
         prev_index = utxo["vout"]
         prev_hash = h2b_rev(utxo["txid"])
         script = h2b(utxo["scriptPubKey"])
         spendable = Spendable(value, script, prev_hash, prev_index)
         spendables.append(spendable)
     return spendables
Example #10
0
def create_coinbase_tx(parser):
    args = parser.parse_args()
    try:
        if len(args.txinfo) != 1:
            parser.error("coinbase transactions need exactly one output parameter (wif/BTC count)")
        wif, btc_amount = args.txinfo[0].split("/")
        satoshi_amount = btc_to_satoshi(btc_amount)
        secret_exponent, compressed = encoding.wif_to_tuple_of_secret_exponent_compressed(wif)
        public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.secp256k1.generator_secp256k1, secret_exponent)
        public_key_sec = encoding.public_pair_to_sec(public_pair, compressed=compressed)
        coinbase_tx = Tx.coinbase_tx(public_key_sec, satoshi_amount)
        return coinbase_tx
    except Exception:
        parser.error("coinbase transactions need exactly one output parameter (wif/BTC count)")
Example #11
0
 def spendables_for_address(self, bitcoin_address):
     """
     Return a list of Spendable objects for the
     given bitcoin address.
     """
     URL = "%s/api/addr/%s/utxo" % (self.base_url, bitcoin_address)
     r = json.loads(urlopen(URL).read().decode("utf8"))
     spendables = []
     for u in r:
         coin_value = btc_to_satoshi(str(u.get("amount")))
         script = h2b(u.get("scriptPubKey"))
         previous_hash = h2b_rev(u.get("txid"))
         previous_index = u.get("vout")
         spendables.append(Spendable(coin_value, script, previous_hash, previous_index))
     return spendables
Example #12
0
def spendables_for_address(bitcoin_address):
    """
    Return a list of Spendable objects for the
    given bitcoin address.
    """
    URL = "http://btc.blockr.io/api/v1/address/unspent/%s" % bitcoin_address
    r = json.loads(urlopen(URL).read().decode("utf8"))
    spendables = []
    for u in r.get("data", {}).get("unspent", []):
        coin_value = btc_to_satoshi(u.get("amount"))
        script = h2b(u.get("script"))
        previous_hash = h2b_rev(u.get("tx"))
        previous_index = u.get("n")
        spendables.append(Spendable(coin_value, script, previous_hash, previous_index))
    return spendables
Example #13
0
def main():
    parser = argparse.ArgumentParser(description="Create a Bitcoin transaction.")

    parser.add_argument('-s', "--source-address", help='source Bitcoin address', required=True, nargs="+", metavar='source_address')
    parser.add_argument('-d', "--destination-address", help='destination Bitcoin address/amount', required=True, metavar='dest_address/amount_in_btc', nargs="+")
    parser.add_argument('-f', "--wif-file", help='WIF items for source Bitcoin addresses', required=True, metavar="path-to-WIF-values", type=argparse.FileType('r'))
    args = parser.parse_args()

    total_value = 0
    coins_from = []
    for bca in args.source_address:
        coins_sources = blockchain_info.coin_sources_for_address(bca)
        coins_from.extend(coins_sources)
        total_value += sum(cs[-1].coin_value for cs in coins_sources)

    secret_exponents = []
    for l in args.wif_file:
        print l
        secret_exponents.append(encoding.wif_to_secret_exponent(l[:-1]))

    coins_to = []
    total_spent = 0
    for daa in args.destination_address:
        address, amount = daa.split("/")
        amount = btc_to_satoshi(amount)
        total_spent += amount
        coins_to.append((amount, address))

    actual_tx_fee = total_value - total_spent
    if actual_tx_fee < 0:
        print("not enough source coins (%s BTC) for destination (%s BTC). Short %s BTC" % (satoshi_to_btc(total_value), satoshi_to_btc(total_spent), satoshi_to_btc(-actual_tx_fee)))
        sys.exit(1)

    print("transaction fee: %s BTC" % satoshi_to_btc(actual_tx_fee))
    unsigned_tx = UnsignedTx.standard_tx(coins_from, coins_to)
    solver = SecretExponentSolver(secret_exponents)
    new_tx = unsigned_tx.sign(solver)
    s = io.BytesIO()
    new_tx.stream(s)
    tx_bytes = s.getvalue()
    tx_hex = binascii.hexlify(tx_bytes).decode("utf8")
    recommended_tx_fee = tx_fee.recommended_fee_for_tx(new_tx)
    if actual_tx_fee > recommended_tx_fee:
        print("warning: transaction fee of exceeds expected value of %s BTC" % satoshi_to_btc(recommended_tx_fee))
    elif actual_tx_fee < recommended_tx_fee:
        print("warning: transaction fee lower than (casually calculated) expected value of %s BTC, transaction might not propogate" % satoshi_to_btc(recommended_tx_fee))
    print("copy the following hex to http://blockchain.info/pushtx to put the transaction on the network:\n")
    print(tx_hex)
Example #14
0
 def spendables_for_address(self, address):
     """
     Return a list of Spendable objects for the
     given bitcoin address.
     """
     url_append = "unspent/%s" % address
     URL = "%s/address/%s" % (self.url, url_append)
     r = json.loads(url_open(URL).read().decode("utf8"))
     spendables = []
     for u in r.get("data", {}).get("unspent", []):
         coin_value = btc_to_satoshi(u.get("amount"))
         script = h2b(u.get("script"))
         previous_hash = h2b_rev(u.get("tx"))
         previous_index = u.get("n")
         spendables.append(Spendable(coin_value, script, previous_hash, previous_index))
     return spendables
Example #15
0
 def spendables_for_addresses(self, bitcoin_addresses):
     """
     Return a list of Spendable objects for the
     given bitcoin address.
     """
     r = []
     for i in xrange(0, len(bitcoin_addresses), CHUNK_SIZE):
         addresses = bitcoin_addresses[i:i+CHUNK_SIZE]
         url = "%s/api/addrs/%s/utxo" % (self.base_url, ",".join(addresses))
         r.extend(json.loads(urlopen(url).read().decode("utf8")))
     spendables = []
     for u in r:
         coin_value = btc_to_satoshi(str(u.get("amount")))
         script = h2b(u.get("scriptPubKey"))
         previous_hash = h2b_rev(u.get("txid"))
         previous_index = u.get("vout")
         spendables.append(Spendable(coin_value, script, previous_hash, previous_index))
     return spendables
Example #16
0
    def listunspent(self, orderby='address', orderdir='ASC', tospend=0):
        cursor = self.db.cursor()
        sql = "SELECT address, txid, scriptPubKey, amount, vout, confirmations, updated_at, source FROM unspents ORDER BY "+orderby+" "+orderdir
        unspents = []
        tospend = btc_to_satoshi(tospend)
        amount = 0
        for unspent in cursor.execute(sql):      
            unspents.append({
                'address': unspent[0], 
                'txid': unspent[1],
                'scriptPubKey': unspent[2], 
                'amount': float(satoshi_to_btc(unspent[3])), 
                'vout': unspent[4], 
                'confirmations': unspent[5], 
                'updated_at': unspent[6], 
                'source': unspent[7]
            })

        return unspents
Example #17
0
def get_tx(tx_hash):
    """
    Get a Tx by its hash.
    """
    # TODO: fix this
    j = get_json_for_hash(tx_hash)
    txs_in = []
    for j_in in j.get("in"):
        if j_in.get("coinbase"):
            txs_in.append(TxIn.coinbase_tx_in(binascii.unhexlify(j_in["coinbase"])))
        else:
            txs_in.append(TxIn(
                h2b_rev(j_in["prev_out"]["hash"]),
                int(j_in["prev_out"]["n"]),
                tools.compile(j_in["scriptSig"])))

    txs_out = []
    for j_out in j.get("out"):
        txs_out.append(TxOut(int(btc_to_satoshi(j_out["value"])), tools.compile(j_out["scriptPubKey"])))

    tx = Tx(int(j["ver"]), txs_in, txs_out, int(j["lock_time"]))
    assert tx.hash() == tx_hash
    return tx
Example #18
0
alice_xval = alice_sec[1:]
alice_cc = alice_ident0.chain_code()

masked_xval = xor_bytes(alice_xval, secret)
masked_cc = xor_bytes(alice_cc, sha_secret)

alice_masked_pcode_nosuffix = payment_code_no_suffix(alice_sign, masked_xval, masked_cc)
alice_masked_pcode = pcode_b58( payment_code(alice_sign, masked_xval, masked_cc) )
print "Alice's Masked Payment Code:\n", alice_masked_pcode, '\n'


from pycoin.tx.TxOut import *
from pycoin.tx import Tx, tx_utils, Spendable, pay_to
from pycoin import convention

amount = convention.btc_to_satoshi(first_nondust['amount'])
dustbtc = convention.btc_to_satoshi(DUST)
feebtc = convention.btc_to_satoshi(FEE)

unspent = Spendable( amount, standard_tx_out_script(first_address), \
            serialize.h2b_rev(first_nondust['tx']), first_nondust['n'] )

txout = TxOut( dustbtc, standard_tx_out_script(bob_notif.address()) )
change = TxOut( amount - (dustbtc + feebtc), standard_tx_out_script(change_addresses.pop()) )
op_return_script = pay_to.ScriptNulldata(alice_masked_pcode_nosuffix)
op_return_txout = TxOut(0, op_return_script.script())

notif_tx = Tx( 1, [unspent.tx_in()], [txout, change, op_return_txout], unspents=[unspent] )
tx_utils.sign_tx( notif_tx, [first_node.wif()] )
print "Signed Notification TX as hex:\n", notif_tx.as_hex()