예제 #1
1
파일: taker.py 프로젝트: btcspry/joinmarket
	def recv_txio(self, nick, utxo_list, cj_pub, change_addr):	
		if nick not in self.nonrespondants:
			debug('nick(' + nick + ') not in nonrespondants ' + str(self.nonrespondants))
			return
		self.utxos[nick] = utxo_list
		order = self.db.execute('SELECT ordertype, txfee, cjfee FROM '
			'orderbook WHERE oid=? AND counterparty=?',
			(self.active_orders[nick], nick)).fetchone()
		utxo_data = common.bc_interface.query_utxo_set(self.utxos[nick])
		if None in utxo_data:
			common.debug('ERROR outputs unconfirmed or already spent. utxo_data='
				+ pprint.pformat(utxo_data))
			raise RuntimeError('killing taker, TODO handle this error')
		total_input = sum([d['value'] for d in utxo_data])
		real_cjfee = calc_cj_fee(order['ordertype'], order['cjfee'], self.cj_amount)
		self.outputs.append({'address': change_addr, 'value':
			total_input - self.cj_amount - order['txfee'] + real_cjfee})
		print 'fee breakdown for %s totalin=%d cjamount=%d txfee=%d realcjfee=%d' % (nick,
			total_input, self.cj_amount, order['txfee'], real_cjfee)
		cj_addr = btc.pubtoaddr(cj_pub, get_addr_vbyte())
		self.outputs.append({'address': cj_addr, 'value': self.cj_amount})
		self.cjfee_total += real_cjfee
		self.nonrespondants.remove(nick)
		if len(self.nonrespondants) > 0:
			debug('nonrespondants = ' + str(self.nonrespondants))
			return
		debug('got all parts, enough to build a tx cjfeetotal=' + str(self.cjfee_total))

		my_total_in = 0
		for u, va in self.input_utxos.iteritems():
			my_total_in += va['value']
		#my_total_in = sum([va['value'] for u, va in self.input_utxos.iteritems()])

		my_change_value = my_total_in - self.cj_amount - self.cjfee_total - self.my_txfee
		print 'fee breakdown for me totalin=%d txfee=%d cjfee_total=%d => changevalue=%d' % (my_total_in, 
			self.my_txfee, self.cjfee_total, my_change_value)
		if self.my_change_addr == None:
			if my_change_value != 0 and abs(my_change_value) != 1:
				#seems you wont always get exactly zero because of integer rounding
				# so 1 satoshi extra or fewer being spent as miner fees is acceptable
				print 'WARNING CHANGE NOT BEING USED\nCHANGEVALUE = ' + str(my_change_value)
		else:
			self.outputs.append({'address': self.my_change_addr, 'value': my_change_value})
		utxo_tx = [dict([('output', u)]) for u in sum(self.utxos.values(), [])]
		random.shuffle(utxo_tx)
		random.shuffle(self.outputs)
		tx = btc.mktx(utxo_tx, self.outputs)	
		debug('obtained tx\n' + pprint.pformat(btc.deserialize(tx)))
		self.msgchan.send_tx(self.active_orders.keys(), tx)

		#now sign it ourselves here
		for index, ins in enumerate(btc.deserialize(tx)['ins']):
			utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			if utxo not in self.input_utxos.keys():
				continue
			addr = self.input_utxos[utxo]['address']
			tx = btc.sign(tx, index, self.wallet.get_key_from_addr(addr))
		self.latest_tx = btc.deserialize(tx)
예제 #2
0
 def sign_tx(self, tx, i, priv):
     if self.my_cj_addr:
         return btc.sign(tx, i, priv)
     else:
         return btc.sign(tx,
                         i,
                         priv,
                         usenonce=btc.safe_from_hex(self.sign_k))
예제 #3
0
    def recv_tx(self, nick, txhex):
        try:
            self.tx = btc.deserialize(txhex)
        except IndexError as e:
            self.maker.msgchan.send_error(nick, 'malformed txhex. ' + repr(e))
        log.debug('obtained tx\n' + pprint.pformat(self.tx))
        goodtx, errmsg = self.verify_unsigned_tx(self.tx)
        if not goodtx:
            log.debug('not a good tx, reason=' + errmsg)
            self.maker.msgchan.send_error(nick, errmsg)
        # TODO: the above 3 errors should be encrypted, but it's a bit messy.
        log.debug('goodtx')
        sigs = []
        for index, ins in enumerate(self.tx['ins']):
            utxo = ins['outpoint']['hash'] + ':' + str(
                ins['outpoint']['index'])
            if utxo not in self.utxos:
                continue
            addr = self.utxos[utxo]['address']
            txs = btc.sign(txhex, index,
                           self.maker.wallet.get_key_from_addr(addr))
            sigs.append(
                base64.b64encode(
                    btc.deserialize(txs)['ins'][index]['script'].decode(
                        'hex')))
        # len(sigs) > 0 guarenteed since i did verify_unsigned_tx()

        jm_single().bc_interface.add_tx_notify(self.tx,
                                               self.unconfirm_callback,
                                               self.confirm_callback,
                                               self.cj_addr)
        log.debug('sending sigs ' + str(sigs))
        self.maker.msgchan.send_sigs(nick, sigs)
        self.maker.active_orders[nick] = None
예제 #4
0
def tx_sign_input(blockstack_tx,
                  idx,
                  private_key_info,
                  hashcode=bitcoin.SIGHASH_ALL):
    """
    Sign a particular input in the given transaction.
    @private_key_info can either be a private key, or it can be a dict with 'redeem_script' and 'private_keys' defined
    """
    if type(private_key_info) in [str, unicode]:
        # single private key
        return bitcoin.sign(blockstack_tx,
                            idx,
                            virtualchain.BitcoinPrivateKey(
                                str(private_key_info)).to_hex(),
                            hashcode=hashcode)

    else:
        assert type(private_key_info) in [dict]
        assert "redeem_script" in private_key_info
        assert "private_keys" in private_key_info

        redeem_script = private_key_info['redeem_script']
        private_keys = private_key_info['private_keys']

        assert type(redeem_script) in [str, unicode]
        redeem_script = str(redeem_script)

        # multisig
        return tx_sign_multisig(blockstack_tx,
                                idx,
                                str(redeem_script),
                                private_keys,
                                hashcode=bitcoin.SIGHASH_ALL)
예제 #5
0
파일: scripts.py 프로젝트: jmktx/blockstore
def tx_serialize_and_sign_multi( inputs, outputs, private_keys ):
    """
    Given a list of inputs, outputs, private keys, and optionally a partially-signed transaction:
    * make a transaction out of the inputs and outputs 
    * sign input[i] with private_key[i]
    
    Return the signed tx on success
    """
    
    if len(inputs) != len(private_keys):
        raise Exception("Must have the same number of private keys as inputs")
    
    private_key_objs = []
    for pk in private_keys:
        if isinstance( pk, pybitcoin.BitcoinPrivateKey ):
            private_key_objs.append( pk )
        else:
            private_key_objs.append( pybitcoin.BitcoinPrivateKey( pk ) )
            
    # make the transaction 
    unsigned_tx = pybitcoin.serialize_transaction( inputs, outputs )
    
    # sign with the appropriate private keys 
    for i in xrange(0, len(inputs)):
        signed_tx = bitcoin.sign( unsigned_tx, i, private_key_objs[i].to_hex() )
        unsigned_tx = signed_tx 
        
    return unsigned_tx 
예제 #6
0
def make_sign_and_push(
    ins_full, wallet, amount, output_addr=None, change_addr=None, hashcode=btc.SIGHASH_ALL, estimate_fee=False
):
    """Utility function for easily building transactions
    from wallets
    """
    total = sum(x["value"] for x in ins_full.values())
    ins = ins_full.keys()
    # random output address and change addr
    output_addr = wallet.get_new_addr(1, 1) if not output_addr else output_addr
    change_addr = wallet.get_new_addr(1, 0) if not change_addr else change_addr
    fee_est = estimate_tx_fee(len(ins), 2) if estimate_fee else 10000
    outs = [{"value": amount, "address": output_addr}, {"value": total - amount - fee_est, "address": change_addr}]

    tx = btc.mktx(ins, outs)
    de_tx = btc.deserialize(tx)
    for index, ins in enumerate(de_tx["ins"]):
        utxo = ins["outpoint"]["hash"] + ":" + str(ins["outpoint"]["index"])
        addr = ins_full[utxo]["address"]
        priv = wallet.get_key_from_addr(addr)
        if index % 2:
            priv = binascii.unhexlify(priv)
        tx = btc.sign(tx, index, priv, hashcode=hashcode)
    # pushtx returns False on any error
    print btc.deserialize(tx)
    push_succeed = jm_single().bc_interface.pushtx(tx)
    if push_succeed:
        return btc.txhash(tx)
    else:
        return False
예제 #7
0
def build_raw_tx(prev_tx_id,
                 prev_out_index,
                 src_btc_addr,
                 value,
                 dest_btc_addr,
                 scriptPubKey=None,
                 scriptSig=None):

    assert len(prev_tx_id) == len(prev_out_index) == len(src_btc_addr)
    assert len(value) == len(dest_btc_addr)

    if scriptPubKey is None:
        scriptPubKey = []
        for i in range(len(dest_btc_addr)):
            scriptPubKey.append(generate_std_scriptpubkey(dest_btc_addr[i]))
    else:
        assert len(scriptPubKey) == len(dest_btc_addr)

    tx = TX()

    if scriptSig is None:
        tx.build_p2pkh_std_tx(prev_tx_id, prev_out_index, value, scriptPubKey)
        raw_tx = tx.hex
        for i in range(len(src_btc_addr)):
            priv_key = src_btc_addr[i] + "/sk.pem"
            priv_key_hex = get_priv_key_hex(priv_key)
            raw_tx = sign(raw_tx, i, priv_key_hex)

    else:
        assert len(scriptPubKey) == len(src_btc_addr)
        tx.build_p2pkh_std_tx(prev_tx_id, prev_out_index, value, scriptPubKey,
                              scriptSig)
        raw_tx = tx.hex

    return raw_tx
예제 #8
0
def make_tx_add_notify():
    wallet_dict = make_wallets(1, [[1, 0, 0, 0, 0]], mean_amt=4, sdev_amt=0)[0]
    amount = 250000000
    txfee = 10000
    wallet = wallet_dict['wallet']
    sync_wallet(wallet)
    inputs = wallet.select_utxos(0, amount)
    ins = inputs.keys()
    input_value = sum([i['value'] for i in inputs.values()])
    output_addr = wallet.get_new_addr(1, 0)
    change_addr = wallet.get_new_addr(0, 1)
    outs = [{
        'value': amount,
        'address': output_addr
    }, {
        'value': input_value - amount - txfee,
        'address': change_addr
    }]
    tx = btc.mktx(ins, outs)
    de_tx = btc.deserialize(tx)
    for index, ins in enumerate(de_tx['ins']):
        utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
        addr = inputs[utxo]['address']
        priv = wallet.get_key_from_addr(addr)
        tx = btc.sign(tx, index, priv)

    unconfirm_called[0] = confirm_called[0] = False
    timeout_unconfirm_called[0] = timeout_confirm_called[0] = False
    jm_single().bc_interface.add_tx_notify(btc.deserialize(tx),
                                           unconfirm_callback,
                                           confirm_callback, output_addr,
                                           timeout_callback)
    return tx
예제 #9
0
def mk_spend_txids(wallet, dst, amount, h):
    l = len(h)
    outs = [{'value': int(amount), 'address': dst}]
    tx = b.mksend(h, outs, wallet["address"], fee)
    for i in range(l):
        tx = b.sign(tx, i, wallet["priv"])
    return (tx)
예제 #10
0
def tx_serialize_and_sign_multi(inputs, outputs, private_keys):
    """
    Given a list of inputs, outputs, private keys, and optionally a partially-signed transaction:
    * make a transaction out of the inputs and outputs 
    * sign input[i] with private_key[i]
    
    Return the signed tx on success
    """

    if len(inputs) != len(private_keys):
        raise Exception("Must have the same number of private keys as inputs")

    private_key_objs = []
    for pk in private_keys:
        if isinstance(pk, pybitcoin.BitcoinPrivateKey):
            private_key_objs.append(pk)
        else:
            private_key_objs.append(pybitcoin.BitcoinPrivateKey(pk))

    # make the transaction
    unsigned_tx = pybitcoin.serialize_transaction(inputs, outputs)

    # sign with the appropriate private keys
    for i in xrange(0, len(inputs)):
        signed_tx = bitcoin.sign(unsigned_tx, i, private_key_objs[i].to_hex())
        unsigned_tx = signed_tx

    return unsigned_tx
예제 #11
0
    def recv_tx(self, nick, txhex):
        try:
            self.tx = btc.deserialize(txhex)
        except IndexError as e:
            self.maker.msgchan.send_error(nick, 'malformed txhex. ' + repr(e))
        log.info('obtained tx\n' + pprint.pformat(self.tx))
        goodtx, errmsg = self.verify_unsigned_tx(self.tx)
        if not goodtx:
            log.info('not a good tx, reason=' + errmsg)
            self.maker.msgchan.send_error(nick, errmsg)
        # TODO: the above 3 errors should be encrypted, but it's a bit messy.
        log.info('goodtx')
        sigs = []
        for index, ins in enumerate(self.tx['ins']):
            utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
            if utxo not in self.utxos:
                continue
            addr = self.utxos[utxo]['address']
            txs = btc.sign(txhex, index,
                           self.maker.wallet.get_key_from_addr(addr))
            sigs.append(base64.b64encode(btc.deserialize(txs)['ins'][index][
                                             'script'].decode('hex')))
        # len(sigs) > 0 guarenteed since i did verify_unsigned_tx()

        jm_single().bc_interface.add_tx_notify(
                self.tx, self.unconfirm_callback,
                self.confirm_callback, self.cj_addr)
        self.maker.msgchan.send_sigs(nick, sigs)
        self.maker.active_orders[nick] = None
예제 #12
0
    def create_tx(self, from_account, to_addr, amount, fee=0):
        '''
        Create a serialized transaction from funds under 'from_account'

        returns signed serialized tx
        '''
        spendables = self.get_utxo(from_account, amount + fee)
        if not spendables:
            raise Exception("Account is empty or amount to send is 0")
        assert (fee >= 0 and amount > 0)

        keys = []
        total = 0
        for sp in spendables:
            keys.append(
                self.get_key(sp['key_info'][0], sp['key_info'][1],
                             sp['key_info'][2]))
            total += sp['value']
            del sp['key_info']

        change_addr = self.new_address(from_account, change=1)
        payables = [{
            'value': amount,
            'address': to_addr
        }, {
            'value': total - fee - amount,
            'address': change_addr
        }]

        tx = mktx(spendables, payables)
        for i, key in enumerate(keys):
            priv = key.get_private_key().hex()
            tx = sign(tx, i, priv)

        return tx
예제 #13
0
def build_tx(inputs, priv, addr, script, fee=0, send=False):
    """
    Build a transaction to post/cancel a book sale

    Args:
        inputs (list): list of UTXOs to use.
            Obtained with bitcoin.unspent()
        priv (str): private key for wallet
        addr (str): address to post sale to
        script (str): script with encoded message of sale/cancelation
        fee (int): satoshis to pay to miners to write to the blockchain
            There is no reason to do this.
        send (bool): if True, send to mempool

    Returns:
        signed_tx (str): signed transaction to send to mempool
        also, sends transaction to mempool
    """
    outputs = [{
        'value': 546,
        'address': settings.MARKET_ADDRESS
    }, {
        'value': 0,
        'script': script
    }]
    fee = fee
    tx = bitcoin.mksend(inputs, outputs, addr, fee)
    signed_tx = bitcoin.sign(tx, 0, priv)
    if send:
        bitcoin.pushtx(signed_tx)
    return signed_tx
예제 #14
0
def segwit_sign(tx,
                i,
                priv,
                amount,
                hashcode=SIGHASH_ALL,
                script=None,
                separator_index=None):
    i = int(i)
    txobj = tx if isinstance(tx, dict) else deserialize(tx)
    if not isinstance(tx, dict) and ((not is_python2 and isinstance(re, bytes))
                                     or not re.match('^[0-9a-fA-F]*$', tx)):
        return binascii.unhexlify(sign(binascii.hexlify(tx), i, priv))
    if len(priv) <= 33:
        priv = binascii.hexlify(priv)
    pub = privkey_to_pubkey(priv)
    address = pubkey_to_address(pub)
    wscript = mk_pubkey_script(address) if not script else script
    stripped_script = segwit_strip_script_separator(wscript, separator_index)
    signing_tx = segwit_signature_form(tx,
                                       i,
                                       stripped_script,
                                       amount,
                                       hashcode=hashcode)
    rawsig = ecdsa_raw_sign(
        hashlib.sha256(
            hashlib.sha256(
                binascii.unhexlify(signing_tx)).digest()).hexdigest(), priv)
    sig = der_encode_sig(*rawsig) + encode(hashcode, 16, 2)
    txobj['ins'][i]['txinwitness'] = [sig, pub if not script else script]
    return serialize(txobj)
예제 #15
0
def mk_spend_txids(wallet, dst, amount, h):
    l=len(h)
    outs = [{'value': int(amount), 'address': dst}]
    tx = b.mksend(h,outs, wallet["address"], fee)
    for i in range(l):
        tx=b.sign(tx, i, wallet["priv"])
    return(tx)
예제 #16
0
def make_sign_and_push(ins_full,
                       wallet,
                       amount,
                       output_addr=None,
                       change_addr=None,
                       hashcode=btc.SIGHASH_ALL):
    total = sum(x['value'] for x in ins_full.values())
    ins = ins_full.keys()
    #random output address and change addr
    output_addr = wallet.get_new_addr(1, 1) if not output_addr else output_addr
    change_addr = wallet.get_new_addr(1, 0) if not change_addr else change_addr
    outs = [{'value': amount,
             'address': output_addr}, {'value': total - amount - 100000,
                                       'address': change_addr}]

    tx = btc.mktx(ins, outs)
    de_tx = btc.deserialize(tx)
    for index, ins in enumerate(de_tx['ins']):
        utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
        addr = ins_full[utxo]['address']
        priv = wallet.get_key_from_addr(addr)
        if index % 2:
            priv = binascii.unhexlify(priv)
        tx = btc.sign(tx, index, priv, hashcode=hashcode)
    #pushtx returns False on any error
    print btc.deserialize(tx)
    push_succeed = jm_single().bc_interface.pushtx(tx)
    if push_succeed:
        return btc.txhash(tx)
    else:
        return False
예제 #17
0
파일: scripts.py 프로젝트: ghov/blockstore
def tx_serialize_subsidized_tx(blockstore_tx, payer_privkey_hex,
                               payer_utxo_inputs, payer_address, dust_fee,
                               op_fee):
    """
    Make a signed serialized transaction with the given operation and dust fees
    """
    tx_inputs, tx_outputs, locktime, version = tx_deserialize(blockstore_tx)

    subsidy_output = tx_make_subsidization_output(payer_utxo_inputs,
                                                  payer_address, op_fee,
                                                  dust_fee)

    # add our inputs and output
    subsidized_tx = tx_extend(blockstore_tx, payer_utxo_inputs,
                              [subsidy_output])

    # sign each of our inputs with our key, but use SIGHASH_ANYONECANPAY so the client can sign its inputs
    for i in xrange(0, len(payer_utxo_inputs)):
        idx = i + len(tx_inputs)
        subsidized_tx = bitcoin.sign(subsidized_tx,
                                     idx,
                                     payer_privkey_hex,
                                     hashcode=bitcoin.SIGHASH_ANYONECANPAY)

    return subsidized_tx
예제 #18
0
def make_tx_add_notify():
    wallet_dict = make_wallets(1, [[1, 0, 0, 0, 0]], mean_amt=4, sdev_amt=0)[0]
    amount = 250000000
    txfee = 10000
    wallet = wallet_dict['wallet']
    sync_wallet(wallet)
    inputs = wallet.select_utxos(0, amount)
    ins = inputs.keys()
    input_value = sum([i['value'] for i in inputs.values()])
    output_addr = wallet.get_new_addr(1, 0)
    change_addr = wallet.get_new_addr(0, 1)
    outs = [{'value': amount, 'address': output_addr},
            {'value': input_value - amount - txfee, 'address': change_addr}]
    tx = btc.mktx(ins, outs)
    de_tx = btc.deserialize(tx)
    for index, ins in enumerate(de_tx['ins']):
        utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
        addr = inputs[utxo]['address']
        priv = wallet.get_key_from_addr(addr)
        tx = btc.sign(tx, index, priv)

    unconfirm_called[0] = confirm_called[0] = False
    timeout_unconfirm_called[0] = timeout_confirm_called[0] = False
    jm_single().bc_interface.add_tx_notify(
        btc.deserialize(tx), unconfirm_callback,
        confirm_callback, output_addr, timeout_callback)
    return tx
예제 #19
0
def send_whole_wallet(fromprivkey, toaddr):
	transaction_fee = 20000 # .0002 BTC
	fromaddress = bitcoin.privtoaddr(fromprivkey)
	balance = sum(transaction['value'] for transaction in bitcoin.unspent(fromaddress))
	assert balance >= transaction_fee
	tx = bitcoin.mktx(bitcoin.history(fromaddress), [{'value': balance - transaction_fee, 'address': toaddr}])
	signed_tx = bitcoin.sign(tx, 0, fromprivkey)
	bitcoin.pushtx(signed_tx)
예제 #20
0
파일: script.py 프로젝트: nxtlvlrnd/dryer21
def send(fromprivkey, toaddr, value):
    transaction_fee = 20000
    print "Sending:", fromprivkey, toaddr, value
    tx = bitcoin.mksend(bitcoin.history(bitcoin.privtoaddr(fromprivkey)),
                        [toaddr + ":" + str(value)],
                        bitcoin.privtoaddr(fromprivkey), transaction_fee)
    signed_tx = bitcoin.sign(tx, 0, fromprivkey)
    bitcoin.pushtx(signed_tx)
예제 #21
0
def sendtx(key_info, op_return=''):
    addr, privkey = key_info
    confirmed_balance, inputs, unconfirmed = getbalance(addr)
    amount = confirmed_balance

    if not confirmed_balance >= amount:
        msg = "Balance insuficiente"

    else:
        # Transformar valores a Chatoshis
        used_amount = int(amount * COIN)

        # Utilizar solo las unspent que se necesiten
        used_balance = 0
        used_inputs = []

        for i in inputs:
            used_balance += i['value']
            used_inputs.append(i)
            if used_balance > used_amount:
                break

        used_fee = int((base_fee + fee_per_input * len(inputs)) * COIN)

        # Output
        outputs = []

        # Receptor
        if used_balance == used_amount:
            outputs.append({
                'address': addr,
                'value': (used_amount - used_fee)
            })
        else:
            outputs.append({'address': addr, 'value': used_amount})

        # Change
        if used_balance > used_amount + used_fee:
            outputs.append({
                'address': addr,
                'value': int(used_balance - used_amount - used_fee)
            })

        # OP_RETURN
        if len(op_return) > 0 and len(op_return) <= 255:
            payload = OP_RETURN_payload(op_return)
            script = '6a' + b2a_hex(payload).decode('utf-8', errors='ignore')
            outputs.append({'value': 0, 'script': script})

        # Transacción
        tx = mktx(used_inputs, outputs)

        # Firma
        for i in range(len(used_inputs)):
            tx = sign(tx, i, privkey)
        msg = tx

    return msg
예제 #22
0
	def recv_txio(self, nick, utxo_list, cj_pub, change_addr):	
		if nick not in self.nonrespondants:
			debug('nick(' + nick + ') not in nonrespondants ' + str(self.nonrespondants))
			return
		self.utxos[nick] = utxo_list
		order = self.db.execute('SELECT ordertype, txfee, cjfee FROM '
			'orderbook WHERE oid=? AND counterparty=?',
			(self.active_orders[nick], nick)).fetchone()
		utxo_data = common.bc_interface.query_utxo_set(self.utxos[nick])
		if None in utxo_data:
			common.debug('ERROR outputs unconfirmed or already spent. utxo_data='
				+ pprint.pformat(utxo_data))
			raise RuntimeError('killing taker, TODO handle this error')
		total_input = sum([d['value'] for d in utxo_data])
		real_cjfee = calc_cj_fee(order['ordertype'], order['cjfee'], self.cj_amount)
		self.outputs.append({'address': change_addr, 'value':
			total_input - self.cj_amount - order['txfee'] + real_cjfee})
		print 'fee breakdown for %s totalin=%d cjamount=%d txfee=%d realcjfee=%d' % (nick,
			total_input, self.cj_amount, order['txfee'], real_cjfee)
		cj_addr = btc.pubtoaddr(cj_pub, get_addr_vbyte())
		self.outputs.append({'address': cj_addr, 'value': self.cj_amount})
		self.cjfee_total += real_cjfee
		self.nonrespondants.remove(nick)
		if len(self.nonrespondants) > 0:
			debug('nonrespondants = ' + str(self.nonrespondants))
			return
		debug('got all parts, enough to build a tx cjfeetotal=' + str(self.cjfee_total))

		my_total_in = 0
		for u, va in self.input_utxos.iteritems():
			my_total_in += va['value']
		#my_total_in = sum([va['value'] for u, va in self.input_utxos.iteritems()])

		my_change_value = my_total_in - self.cj_amount - self.cjfee_total - self.my_txfee
		print 'fee breakdown for me totalin=%d txfee=%d cjfee_total=%d => changevalue=%d' % (my_total_in, 
			self.my_txfee, self.cjfee_total, my_change_value)
		if self.my_change_addr == None:
			if my_change_value != 0 and abs(my_change_value) != 1:
				#seems you wont always get exactly zero because of integer rounding
				# so 1 satoshi extra or fewer being spent as miner fees is acceptable
				print 'WARNING CHANGE NOT BEING USED\nCHANGEVALUE = ' + str(my_change_value)
		else:
			self.outputs.append({'address': self.my_change_addr, 'value': my_change_value})
		utxo_tx = [dict([('output', u)]) for u in sum(self.utxos.values(), [])]
		random.shuffle(utxo_tx)
		random.shuffle(self.outputs)
		tx = btc.mktx(utxo_tx, self.outputs)	
		debug('obtained tx\n' + pprint.pformat(btc.deserialize(tx)))
		self.msgchan.send_tx(self.active_orders.keys(), tx)

		#now sign it ourselves here
		for index, ins in enumerate(btc.deserialize(tx)['ins']):
			utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			if utxo not in self.input_utxos.keys():
				continue
			addr = self.input_utxos[utxo]['address']
			tx = btc.sign(tx, index, self.wallet.get_key_from_addr(addr))
		self.latest_tx = btc.deserialize(tx)
예제 #23
0
def send(fromprivkey, toaddr, value):
    transaction_fee = 20000  # .0002 BTC
    fromaddress = bitcoin.privtoaddr(fromprivkey)
    tx = bitcoin.mksend(bitcoin.history(fromaddress), [{
        'value': value,
        'address': toaddr
    }], fromaddress, transaction_fee)
    signed_tx = bitcoin.sign(tx, 0, fromprivkey)
    bitcoin.pushtx(signed_tx)
예제 #24
0
def test_p2p_broadcast(setup_tx_notify):
    #listen up kids, dont do this to generate private
    #keys that hold real money, or else you'll be robbed
    src_privkey = random.getrandbits(256)
    src_privkey = btc.encode(src_privkey, 16, 64) + '01'
    src_addr = btc.privtoaddr(src_privkey, magicbyte=get_p2pk_vbyte())
    dst_addr = btc.pubtoaddr('03' + btc.encode(random.getrandbits(256), 16),
                             get_p2pk_vbyte())

    jm_single().bc_interface.rpc('importaddress', [src_addr, "", False])
    jm_single().bc_interface.rpc('importaddress', [dst_addr, "", False])
    jm_single().bc_interface.rpc('generatetoaddress', [1, src_addr])
    jm_single().bc_interface.rpc('generate', [101])
    src_utxos = jm_single().bc_interface.rpc('listunspent',
                                             [0, 500, [src_addr]])

    inputs = [{
        'output': src_utxos[0]['txid'] + ':' + str(src_utxos[0]['vout'])
    }]
    miner_fee = 10000
    outs = [{
        'address': dst_addr,
        'value': int(src_utxos[0]['amount'] * 1e8) - miner_fee
    }]
    tx = btc.mktx(inputs, outs)
    tx = btc.sign(tx, 0, src_privkey)

    bad_tx = random.getrandbits(len(tx) * 4)
    bad_tx = btc.encode(bad_tx, 16, len(tx))

    utxo_before = jm_single().bc_interface.rpc('listunspent',
                                               [0, 500, [dst_addr]])

    #jm_single().bc_interface.rpc('sendrawtransaction', [tx])
    pushed = tor_broadcast_tx(tx,
                              None,
                              'regtest',
                              remote_hostport=('localhost', 18444))
    assert pushed

    pushed = tor_broadcast_tx(tx,
                              None,
                              'regtest',
                              remote_hostport=('localhost', 18444))
    assert not pushed  #node should already have the same tx, reject

    pushed = tor_broadcast_tx(bad_tx,
                              None,
                              'regtest',
                              remote_hostport=('localhost', 18444))
    assert not pushed  #bad tx should be rejected

    jm_single().bc_interface.rpc('generate', [1])
    utxo_after = jm_single().bc_interface.rpc('listunspent',
                                              [0, 500, [dst_addr]])

    return len(utxo_after) - 1 == len(utxo_before)
예제 #25
0
def direct_send(wallet, amount, mixdepth, destaddr, answeryes=False):
    """Send coins directly from one mixdepth to one destination address;
    does not need IRC. Sweep as for normal sendpayment (set amount=0).
    """
    #Sanity checks; note destaddr format is carefully checked in startup
    assert isinstance(mixdepth, int)
    assert mixdepth >= 0
    assert isinstance(amount, int)
    assert amount >= 0 and amount < 10000000000
    assert isinstance(wallet, Wallet)

    import bitcoin as btc
    from pprint import pformat
    if amount == 0:
        utxos = wallet.get_utxos_by_mixdepth()[mixdepth]
        if utxos == {}:
            log.error("There are no utxos in mixdepth: " + str(mixdepth) +
                      ", quitting.")
            return
        total_inputs_val = sum([va['value'] for u, va in utxos.iteritems()])
        fee_est = estimate_tx_fee(len(utxos), 1)
        outs = [{"address": destaddr, "value": total_inputs_val - fee_est}]
    else:
        initial_fee_est = estimate_tx_fee(8, 2)  #8 inputs to be conservative
        utxos = wallet.select_utxos(mixdepth, amount + initial_fee_est)
        if len(utxos) < 8:
            fee_est = estimate_tx_fee(len(utxos), 2)
        else:
            fee_est = initial_fee_est
        total_inputs_val = sum([va['value'] for u, va in utxos.iteritems()])
        changeval = total_inputs_val - fee_est - amount
        outs = [{"value": amount, "address": destaddr}]
        change_addr = wallet.get_internal_addr(mixdepth)
        outs.append({"value": changeval, "address": change_addr})

    #Now ready to construct transaction
    log.info("Using a fee of : " + str(fee_est) + " satoshis.")
    if amount != 0:
        log.info("Using a change value of: " + str(changeval) + " satoshis.")
    tx = btc.mktx(utxos.keys(), outs)
    stx = btc.deserialize(tx)
    for index, ins in enumerate(stx['ins']):
        utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
        addr = utxos[utxo]['address']
        tx = btc.sign(tx, index, wallet.get_key_from_addr(addr))
    txsigned = btc.deserialize(tx)
    log.info("Got signed transaction:\n")
    log.info(tx + "\n")
    log.info(pformat(txsigned))
    if not answeryes:
        if raw_input(
                'Would you like to push to the network? (y/n):')[0] != 'y':
            log.info("You chose not to broadcast the transaction, quitting.")
            return
    jm_single().bc_interface.pushtx(tx)
    txid = btc.txhash(tx)
    log.info("Transaction sent: " + txid + ", shutting down")
예제 #26
0
def tx_sign_all_unsigned_inputs( tx_hex, privkey ):
    """
    Sign a serialized transaction's unsigned inputs
    """
    inputs, outputs, locktime, version = blockstore.tx_deserialize( tx_hex )
    for i in xrange( 0, len(inputs)):
        if len(inputs[i]['script_sig']) == 0:
            tx_hex = bitcoin.sign( tx_hex, i, privkey )

    return tx_hex
예제 #27
0
파일: testlib.py 프로젝트: ghov/blockstore
def tx_sign_all_unsigned_inputs(tx_hex, privkey):
    """
    Sign a serialized transaction's unsigned inputs
    """
    inputs, outputs, locktime, version = blockstore.tx_deserialize(tx_hex)
    for i in xrange(0, len(inputs)):
        if len(inputs[i]['script_sig']) == 0:
            tx_hex = bitcoin.sign(tx_hex, i, privkey)

    return tx_hex
예제 #28
0
def sign_tx(unsigned_raw_tx, privatekey):
    tx2 = unsigned_raw_tx

    detx = bitcoin.deserialize(tx2)
    input_length = len(detx['ins'])

    for i in range(0, input_length):
        tx2 = bitcoin.sign(tx2, i, privatekey)

    return tx2
예제 #29
0
	def self_sign(self):
		#now sign it ourselves
		tx = btc.serialize(self.latest_tx)
		for index, ins in enumerate(self.latest_tx['ins']):
			utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			if utxo not in self.input_utxos.keys():
				continue
			addr = self.input_utxos[utxo]['address']
			tx = btc.sign(tx, index, self.wallet.get_key_from_addr(addr))
		self.latest_tx = btc.deserialize(tx)
예제 #30
0
 def self_sign(self):
     #now sign it ourselves
     tx = btc.serialize(self.latest_tx)
     for index, ins in enumerate(self.latest_tx['ins']):
         utxo = ins['outpoint']['hash'] + ':' + str(
             ins['outpoint']['index'])
         if utxo not in self.input_utxos.keys():
             continue
         addr = self.input_utxos[utxo]['address']
         tx = btc.sign(tx, index, self.wallet.get_key_from_addr(addr))
     self.latest_tx = btc.deserialize(tx)
예제 #31
0
def send_whole_wallet(fromprivkey, toaddr):
    transaction_fee = 20000  # .0002 BTC
    fromaddress = bitcoin.privtoaddr(fromprivkey)
    balance = sum(transaction['value']
                  for transaction in bitcoin.unspent(fromaddress))
    assert balance >= transaction_fee
    tx = bitcoin.mktx(bitcoin.history(fromaddress), [{
        'value': balance - transaction_fee,
        'address': toaddr
    }])
    signed_tx = bitcoin.sign(tx, 0, fromprivkey)
    bitcoin.pushtx(signed_tx)
예제 #32
0
def create_tx(username, form, op_return=''):
    privkey, address = get_keychain(username)
    unspent = get_unspent(address)

    inputs = unspent['inputs']

    balance = int(float(unspent['confirmed']) * 1e8)
    amount = int(float(form.amount.data) * 1e8)

    receptor = form.address.data

    if check_addr(receptor):
        return "Dirección inválida"

    elif amount > balance:
        return "Balance insuficiente"

    elif amount <= 0:
        return "Monto inválido"

    used_utxo = 0
    used_inputs = []

    for utxo in inputs:
        used_utxo += utxo['value']
        used_inputs.append(utxo)

        if used_utxo >= amount:
            break

    outputs = [{'address': receptor, 'value': amount}]

    template_tx = mktx(used_inputs, outputs)

    # size = unsigned tx + (65 bytes * signature)
    size = len(a2b_hex(template_tx)) + 65 * len(used_inputs)

    # FEE = 0.01 CHA/kb
    fee = int((size / 1024) * 0.01 * 1e8)
    # MAX FEE = 0.1 CHA
    fee = 1e7 if fee > 1e7 else fee

    if used_utxo == amount:
        outputs[0] = {'address': receptor, 'value': int(amount - fee)}

    tx = mksend(used_inputs, outputs, address, fee)

    for i, _ in enumerate(used_inputs):
        tx = sign(tx, i, privkey)

    return tx
예제 #33
0
def tx_make_subsidizable(blockstack_tx, fee_cb, max_fee, subsidy_key,
                         utxo_client):
    """
    Given an unsigned serialized transaction from Blockstack, make it into a subsidized transaction 
    for the client to go sign off on.
    * Add subsidization inputs/outputs
    * Make sure the subsidy does not exceed the maximum subsidy fee
    * Sign our inputs with SIGHASH_ANYONECANPAY
    """

    # get subsidizer key info
    private_key_obj, payer_address, payer_utxo_inputs = analyze_private_key(
        subsidy_key, utxo_client)

    tx_inputs, tx_outputs, locktime, version = tx_deserialize(blockstack_tx)

    # what's the fee?  does it exceed the subsidy?
    dust_fee, op_fee = fee_cb(tx_inputs, tx_outputs)
    if dust_fee is None or op_fee is None:
        log.error("Invalid fee structure")
        return None

    if dust_fee + op_fee > max_fee:
        log.error("Op fee (%s) + dust fee (%s) exceeds maximum subsidy %s" %
                  (dust_fee, op_fee, max_fee))
        return None

    else:
        log.debug(
            "%s will subsidize %s satoshi" %
            (pybitcoin.BitcoinPrivateKey(subsidy_key).public_key().address(),
             dust_fee + op_fee))

    subsidy_output = tx_make_subsidization_output(payer_utxo_inputs,
                                                  payer_address, op_fee,
                                                  dust_fee)

    # add our inputs and output
    subsidized_tx = tx_extend(blockstack_tx, payer_utxo_inputs,
                              [subsidy_output])

    # sign each of our inputs with our key, but use SIGHASH_ANYONECANPAY so the client can sign its inputs
    for i in xrange(0, len(payer_utxo_inputs)):
        idx = i + len(tx_inputs)
        subsidized_tx = bitcoin.sign(subsidized_tx,
                                     idx,
                                     private_key_obj.to_hex(),
                                     hashcode=bitcoin.SIGHASH_ANYONECANPAY)

    return subsidized_tx
예제 #34
0
파일: tx.py 프로젝트: tpae/moneywagon
    def get_hex(self, signed=True):
        """
        Given all the data the user has given so far, make the hex using pybitcointools
        """
        total_ins_satoshi = self.total_input_satoshis()
        if total_ins_satoshi == 0:
            raise ValueError("Can't make transaction, there are zero inputs")

        # Note: there can be zero outs (sweep or coalesc transactions)
        total_outs_satoshi = sum([x['value'] for x in self.outs])

        if not self.fee_satoshi:
            self.fee()  # use default of $0.02

        change_satoshi = total_ins_satoshi - (total_outs_satoshi +
                                              self.fee_satoshi)

        if change_satoshi < 0:
            raise ValueError(
                "Input amount (%s) must be more than all output amounts (%s) plus fees (%s). You need more %s."
                % (total_ins_satoshi, total_outs_satoshi, self.fee_satoshi,
                   self.crypto.upper()))

        ins = [x['input'] for x in self.ins]

        if change_satoshi > 0:
            if self.verbose:
                print("Adding change address of %s satoshis to %s" %
                      (change_satoshi, self.change_address))
            change = [{
                'value': change_satoshi,
                'address': self.change_address
            }]
        else:
            change = []  # no change ?!
            if self.verbose:
                print("Inputs == Outputs, no change address needed.")

        tx = mktx(ins, self.outs + change)

        if signed:
            for i, input_data in enumerate(self.ins):
                if not input_data['private_key']:
                    raise Exception(
                        "Can't sign transaction, missing private key for input %s"
                        % i)
                tx = sign(tx, i, input_data['private_key'])

        return tx
예제 #35
0
def segwit_sign(tx, i, priv, amount, hashcode=SIGHASH_ALL, script=None, separator_index=None):
    i = int(i)
    txobj = tx if isinstance(tx, dict) else deserialize(tx)
    if not isinstance(tx, dict) and ((not is_python2 and isinstance(re, bytes)) or not re.match('^[0-9a-fA-F]*$', tx)):
        return binascii.unhexlify(sign(binascii.hexlify(tx), i, priv))
    if len(priv) <= 33:
        priv = binascii.hexlify(priv)
    pub = privkey_to_pubkey(priv)
    address = pubkey_to_address(pub)
    wscript = mk_pubkey_script(address) if not script else script
    stripped_script = segwit_strip_script_separator(wscript, separator_index)
    signing_tx = segwit_signature_form(tx, i, stripped_script, amount, hashcode=hashcode)
    rawsig = ecdsa_raw_sign(hashlib.sha256(hashlib.sha256(binascii.unhexlify(signing_tx)).digest()).hexdigest(), priv)
    sig = der_encode_sig(*rawsig)+encode(hashcode, 16, 2)
    txobj['ins'][i]['txinwitness'] = [sig, pub if not script else script]
    return serialize(txobj)
예제 #36
0
def tx_serialize_subsidized_tx( blockstore_tx, payer_privkey_hex, payer_utxo_inputs, payer_address, dust_fee, op_fee ):
    """
    Make a signed serialized transaction with the given operation and dust fees
    """
    tx_inputs, tx_outputs, locktime, version = tx_deserialize( blockstore_tx )

    subsidy_output = tx_make_subsidization_output( payer_utxo_inputs, payer_address, op_fee, dust_fee )
    
    # add our inputs and output
    subsidized_tx = tx_extend( blockstore_tx, payer_utxo_inputs, [subsidy_output] )
   
    # sign each of our inputs with our key, but use SIGHASH_ANYONECANPAY so the client can sign its inputs
    for i in xrange( 0, len(payer_utxo_inputs)):
        idx = i + len(tx_inputs)
        subsidized_tx = bitcoin.sign( subsidized_tx, idx, payer_privkey_hex, hashcode=bitcoin.SIGHASH_ANYONECANPAY )
    
    return subsidized_tx
예제 #37
0
	def finishcallback(self, coinjointx):
		if coinjointx.all_responded:
			#now sign it ourselves
			tx = btc.serialize(coinjointx.latest_tx)
			for index, ins in enumerate(coinjointx.latest_tx['ins']):
				utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
				if utxo != self.taker.auth_utxo:
					continue
				addr = coinjointx.input_utxos[utxo]['address']
				tx = btc.sign(tx, index, coinjointx.wallet.get_key_from_addr(addr))
			print 'unsigned tx = \n\n' + tx + '\n'
			debug('created unsigned tx, ending')
			self.taker.msgchan.shutdown()
			return
		self.ignored_makers += coinjointx.nonrespondants
		debug('recreating the tx, ignored_makers=' + str(self.ignored_makers))
		self.create_tx()
예제 #38
0
	def self_sign_and_push(self):
		#now sign it ourselves
		tx = btc.serialize(self.latest_tx)
		for index, ins in enumerate(self.latest_tx['ins']):
			utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
			if utxo not in self.input_utxos.keys():
				continue
			addr = self.input_utxos[utxo]['address']
			tx = btc.sign(tx, index, self.wallet.get_key_from_addr(addr))
		txhex = btc.serialize(self.latest_tx)
		debug('\n' + txhex)
		debug('txid = ' + btc.txhash(tx))
		#TODO send to a random maker or push myself
		#TODO need to check whether the other party sent it
		#self.msgchan.push_tx(self.active_orders.keys()[0], txhex)	
		self.txid = common.bc_interface.pushtx(tx)
		if self.txid == None:
			debug('unable to pushtx')
예제 #39
0
def build_raw_tx(prev_tx_id, prev_out_index, value, src_btc_addr,
                 dest_btc_addr):
    #assert len(prev_tx_id) == len(prev_out_index) == len(value) == len(src_btc_addr)

    scriptPubKey = []
    for i in range(len(dest_btc_addr)):
        scriptPubKey.append(aux.generate_std_scriptpubkey(dest_btc_addr[i]))

    tx = Transaction.TX()
    tx.build_default_tx(prev_tx_id, prev_out_index, value, scriptPubKey)

    signed_tx = tx.hex
    for i in range(len(prev_tx_id)):
        priv_key = "wallet/" + src_btc_addr + "/sk.pem"
        priv_key_hex = aux.get_priv_key_hex(priv_key)

        signed_tx = sign(signed_tx, i, priv_key_hex)

    return signed_tx
예제 #40
0
 def finishcallback(self, coinjointx):
     if coinjointx.all_responded:
         #now sign it ourselves
         tx = btc.serialize(coinjointx.latest_tx)
         for index, ins in enumerate(coinjointx.latest_tx['ins']):
             utxo = ins['outpoint']['hash'] + ':' + str(
                 ins['outpoint']['index'])
             if utxo != self.taker.auth_utxo:
                 continue
             addr = coinjointx.input_utxos[utxo]['address']
             tx = btc.sign(tx, index,
                           coinjointx.wallet.get_key_from_addr(addr))
         print 'unsigned tx = \n\n' + tx + '\n'
         debug('created unsigned tx, ending')
         self.taker.msgchan.shutdown()
         return
     self.ignored_makers += coinjointx.nonrespondants
     debug('recreating the tx, ignored_makers=' + str(self.ignored_makers))
     self.create_tx()
예제 #41
0
def send_message(recipient_addr, scripts, fee=0, send=False):
    """
    Send encoded message

    Args:
        recipient_addr (str): address of user to send message too
        scripts (list): list of strings, each element is a single
            encoded message.  Multiple encodings are needed
            if the message is longer than 40 char.
        fee (int): Satoshis to pay in miner fees.
            Not actually required.
        send (bool): If True, send transactions to mempool.

    Returns:
        signed_txs (list): list of strings where each element
            is a signed transaction encoding a message

        Also sends transaction to the mempool.

    Notes: 
        This is currently sending the message to blockchain.info,
        but this is trivially changed if needed.
    """
    priv, pub, addr = books.read_wallet()
    signed_txs = []
    for script in scripts:
        outputs = [{'value': 546, 'address': recipient_addr}]
        inputs = bitcoin.unspent(addr)
        for _input in inputs:
            if _input > 1092:
                input_tx = _input
                break
        outputs.append({'value': 0, 'script': script})
        fee = fee
        tx = bitcoin.mksend(input_tx, outputs, addr, fee)
        signed_tx = bitcoin.sign(tx, 0, priv)
        if send:
            bitcoin.pushtx(signed_tx)
        signed_txs.append(signed_tx)
    if send:
        _write_message(recipient_addr, signed_txs)
    return signed_txs
    def sendCustomTransaction(self, privkeys, inputs, outputs, fee=0):
        success = False
        totalInputValue = 0
        UTXOs = []
        for tx_input in inputs:
            if 'spend' not in tx_input:
                totalInputValue += tx_input['value']
                UTXOs.append(tx_input)

        totalOutputValue = 0
        for tx_output in outputs:
            totalOutputValue += tx_output['value']

        diff = totalInputValue - totalOutputValue
        if fee != diff:
            pprint("Warning: Fee incorrect! aborting transaction")
        else:
            allKeysPresent = True
            allInputsConfirmed = True
            for tx_input in UTXOs:
                if tx_input['address'] not in privkeys:
                    print 'not found:', tx_input['address']
                    allKeysPresent = False

                if tx_input['block_height'] == None:
                    allInputsConfirmed = False

            if allKeysPresent == True and allInputsConfirmed == True:
                tx = bitcoin.mktx(UTXOs, outputs)
                for i in range(0, len(UTXOs)):
                    tx = bitcoin.sign(tx, i,
                                      str(privkeys[UTXOs[i]['address']]))

                try:
                    bitcoin.pushtx(tx)
                    success = True
                except:
                    e = sys.exc_info()
                    print e
                    success = False

        return success
    def sendCustomTransaction(self, privkeys, inputs, outputs, fee=0):
        success = False
        totalInputValue = 0
        UTXOs = []
        for tx_input in inputs:
            if 'spend' not in tx_input:
                totalInputValue += tx_input['value']
                UTXOs.append(tx_input)

        totalOutputValue = 0
        for tx_output in outputs:
            totalOutputValue += tx_output['value']

        diff = totalInputValue - totalOutputValue
        if fee != diff:
            pprint("Warning: Fee incorrect! aborting transaction")
        else:
            allKeysPresent = True
            allInputsConfirmed = True
            for tx_input in UTXOs:
                if tx_input['address'] not in privkeys:
                    print 'not found:', tx_input['address']
                    allKeysPresent = False

                if tx_input['block_height'] == None:
                    allInputsConfirmed = False

            if allKeysPresent == True and allInputsConfirmed == True:
                tx = bitcoin.mktx(UTXOs, outputs)
                for i in range(0, len(UTXOs)):
                    tx = bitcoin.sign(tx, i, str(privkeys[UTXOs[i]['address']]))

                try:
                    bitcoin.pushtx(tx)
                    success = True
                except:
                    e = sys.exc_info()
                    print e
                    success = False

        return success
예제 #44
0
파일: tx.py 프로젝트: bitcoinsSG/moneywagon
    def get_hex(self, signed=True):
        """
        Given all the data the user has given so far, make the hex using pybitcointools
        """
        total_ins_satoshi = self.total_input_satoshis()
        if total_ins_satoshi == 0:
            raise ValueError("Can't make transaction, there are zero inputs")

        # Note: there can be zero outs (sweep or coalesc transactions)
        total_outs_satoshi = sum([x['value'] for x in self.outs])

        if not self.fee_satoshi:
            self.fee() # use default of $0.02

        change_satoshi = total_ins_satoshi - (total_outs_satoshi + self.fee_satoshi)

        if change_satoshi < 0:
            raise ValueError(
                "Input amount (%s) must be more than all output amounts (%s) plus fees (%s). You need more %s."
                % (total_ins_satoshi, total_outs_satoshi, self.fee_satoshi, self.crypto.upper())
            )

        ins = [x['input'] for x in self.ins]

        if change_satoshi > 0:
            if self.verbose:
                print("Adding change address of %s satoshis to %s" % (change_satoshi, self.change_address))
            change = [{'value': change_satoshi, 'address': self.change_address}]
        else:
            change = [] # no change ?!
            if self.verbose: print("Inputs == Outputs, no change address needed.")

        tx = mktx(ins, self.outs + change)

        if signed:
            for i, input_data in enumerate(self.ins):
                if not input_data['private_key']:
                    raise Exception("Can't sign transaction, missing private key for input %s" % i)
                tx = sign(tx, i, input_data['private_key'])

        return tx
예제 #45
0
def tx_make_subsidizable( blockstack_tx, fee_cb, max_fee, subsidy_key, utxo_client, tx_fee=0 ):
    """
    Given an unsigned serialized transaction from Blockstack, make it into a subsidized transaction 
    for the client to go sign off on.
    * Add subsidization inputs/outputs
    * Make sure the subsidy does not exceed the maximum subsidy fee
    * Sign our inputs with SIGHASH_ANYONECANPAY

    Raise ValueError if there are not enough inputs to subsidize
    """
   
    # get subsidizer key info
    private_key_obj, payer_address, payer_utxo_inputs = pybitcoin.analyze_private_key(subsidy_key, utxo_client)
    
    tx_inputs, tx_outputs, locktime, version = tx_deserialize( blockstack_tx )

    # what's the fee?  does it exceed the subsidy?
    dust_fee, op_fee = fee_cb( tx_inputs, tx_outputs )
    if dust_fee is None or op_fee is None:
        log.error("Invalid fee structure")
        return None 
    
    if dust_fee + op_fee + tx_fee > max_fee:
        log.error("Op fee (%s) + dust fee (%s) exceeds maximum subsidy %s" % (dust_fee, op_fee, max_fee))
        return None
    
    else:
        log.debug("%s will subsidize %s satoshi" % (pybitcoin.BitcoinPrivateKey( subsidy_key ).public_key().address(), dust_fee + op_fee ))
    
    subsidy_output = tx_make_subsidization_output( payer_utxo_inputs, payer_address, op_fee, dust_fee + tx_fee )
    
    # add our inputs and output
    subsidized_tx = tx_extend( blockstack_tx, payer_utxo_inputs, [subsidy_output] )
   
    # sign each of our inputs with our key, but use SIGHASH_ANYONECANPAY so the client can sign its inputs
    for i in xrange( 0, len(payer_utxo_inputs)):
        idx = i + len(tx_inputs)
        subsidized_tx = bitcoin.sign( subsidized_tx, idx, private_key_obj.to_hex(), hashcode=bitcoin.SIGHASH_ANYONECANPAY )
    
    return subsidized_tx
예제 #46
0
    def sendCustomTransaction(self, privkeys, inputs, outputs, fee=0):

        success = False
        totalInputValue = 0
        UTXOs = []
        for tx_input in inputs:
            if 'spend' not in tx_input:
                totalInputValue += tx_input['value']
                UTXOs.append(tx_input)

        totalOutputValue = 0
        for tx_output in outputs:
            totalOutputValue += tx_output['value']

        diff = totalInputValue - totalOutputValue
        if fee != diff:
            self.response.write(
                "<br>Warning: Fee incorrect! aborting transaction")
            logging.error("Warning: Fee incorrect! aborting transaction")
        else:
            allKeysPresent = True
            allInputsConfirmed = True
            for tx_input in UTXOs:
                if tx_input['address'] not in privkeys:
                    allKeysPresent = False

                if tx_input['block_height'] == None:
                    allInputsConfirmed = False

            if allKeysPresent == True and allInputsConfirmed == True:
                tx = bitcoin.mktx(UTXOs, outputs)
                for i in range(0, len(UTXOs)):
                    tx = bitcoin.sign(tx, i,
                                      str(privkeys[UTXOs[i]['address']]))

                bitcoin.pushtx(tx)
                success = True

        return success
    def sendCustomTransaction(self, privkeys, inputs, outputs, fee=0):

        success = False
        totalInputValue = 0
        UTXOs = []
        for tx_input in inputs:
            if 'spend' not in tx_input:
                totalInputValue += tx_input['value']
                UTXOs.append(tx_input)

        totalOutputValue = 0
        for tx_output in outputs:
            totalOutputValue += tx_output['value']

        diff = totalInputValue - totalOutputValue
        if fee != diff:
            self.response.write("<br>Warning: Fee incorrect! aborting transaction")
            logging.error("Warning: Fee incorrect! aborting transaction")
        else:
            allKeysPresent = True
            allInputsConfirmed = True
            for tx_input in UTXOs:
                if tx_input['address'] not in privkeys:
                    allKeysPresent = False

                if tx_input['block_height'] == None:
                    allInputsConfirmed = False

            if allKeysPresent == True and allInputsConfirmed == True:
                tx = bitcoin.mktx(UTXOs, outputs)
                for i in range(0, len(UTXOs)):
                    tx = bitcoin.sign(tx, i, str(privkeys[UTXOs[i]['address']]))


                bitcoin.pushtx(tx)
                success = True

        return success
예제 #48
0
def sign(utxo, priv, destaddrs):
    """Sign a tx sending the amount amt, from utxo utxo,
    equally to each of addresses in list destaddrs,
    after fees; the purpose is to create a large
    number of utxos.
    """
    results = validate_utxo_data([(utxo, priv)], retrieve=True)
    if not results:
        return False
    assert results[0][0] == utxo
    amt = results[0][1]
    ins = [utxo]
    estfee = estimate_tx_fee(1, len(destaddrs))
    outs = []
    share = int((amt - estfee) / len(destaddrs))
    fee = amt - share*len(destaddrs)
    assert fee >= estfee
    log.debug("Using fee: " + str(fee))
    for i, addr in enumerate(destaddrs):
        outs.append({'address': addr, 'value': share})
    unsigned_tx = btc.mktx(ins, outs)
    return btc.sign(unsigned_tx, 0, btc.from_wif_privkey(
        priv, vbyte=get_p2pk_vbyte()))
예제 #49
0
 def sign_tx(self, tx, i, priv):
     if self.my_cj_addr:
         return btc.sign(tx, i, priv)
     else:
         return sign_donation_tx(tx, i, priv)
    def commitTo(self, testnet, commit_address, private_key):
        """
        Commit to some address on the blockchain
        """
        # Check if we have the keys for the BM address
        public_key = highlevelcrypto.privToPub( private_key.encode('hex') ).decode('hex')
        fromAddress = self.getAddress( testnet, public_key )
        
        result = self.getUnspentTransactions( testnet, [fromAddress] )
        if not 'unspent' in result or len( result['unspent'] ) == 0:
            log_debug( "commitTo: No unspent TXs (%s)" % ( fromAddress ) )
            return False   
        
        unspent_txs = result['unspent']
        # filter for those with an amount >= minimum amount
        unspent_txs = filter( lambda tx: float( tx['amount'] ) > BitcoinThread.BTC_UNSPENT_MIN_AVAILABLE, unspent_txs )
        if len( unspent_txs ) == 0:
            log_debug( "commitTo: No unspent TXs >= %d (%s, %s)" % ( BitcoinThread.BTC_UNSPENT_MIN_AVAILABLE, fromAddress, result['unspent'] ) )
            return False
        
        # Find random unspent with an amount >= 0.00010 mBTC
        random.shuffle( unspent_txs )
        
        while len( unspent_txs ) > 0:
            tx = unspent_txs.pop( 0 )
            log_debug( "Trying unspent tx: %s" % tx )
            
            amount = float( tx['amount'] )

            amount_satoshis = int( amount * 100000000 )
            change_satoshis = amount_satoshis - BitcoinThread.SATOSHI_COMMITMENT_AMOUNT - BitcoinThread.SATOSHI_TRANSACTION_FEE
            
            # Code in bitcoin.mktx separates the input string into tx=input[:64] and n=input[65:]
            input_tx = "%s %d" % ( tx['tx'], tx['n'] )
            
            commit_payable = { "address": commit_address, "value": BitcoinThread.SATOSHI_COMMITMENT_AMOUNT }
            change_payable = { "address": fromAddress, "value": change_satoshis }
            
            tx = bitcoin.mktx( [input_tx], [ commit_payable, change_payable ] )
            
            signed_tx = bitcoin.sign(tx, 0, private_key )
            
            log_debug( "Pushing tx: %s" % bitcoin.deserialize( tx ) )
            
            if testnet:
                try:
                    result = json.loads( bitcoin.blockr_pushtx(signed_tx, 'testnet') )
                except Exception, e:
                    
                    # If we get {"status":"fail","data":"Could not push your transaction!","code":500,"message":"Did you sign your transaction?"}
                    # in an exception here, it probably means that the referenced inputs in our transaction have been spent in the meantime.
                    try:
                        e_obj = json.loads( e.message )
                        if e_obj["data"] == "Could not push your transaction!":
                            from debug import logger
                            log_warn( "Couldn't push transaction. Sometimes this is because the referenced inputs have been spent in the meantime, %s" % e_obj )
                            # Continue to try the next unspent tx
                            
                            continue
                        else:
                            log_warn( e )
                    except:
                        log_warn( e )
                        
                return 'status' in result and result['status'] == "success"
            
            else: # if not testnet
                # I had problems pushing non-testnet transactions to blockr.io,
                # so we're using blockchain.info for this, and that works fine.
                try:
                    result = bitcoin.pushtx( signed_tx )
                    if result.lower() == "transaction submitted":
                        log_debug( "Committed to %s" % commit_address )
                        return True
                    else:
                        log_warn( "Transaction push fail: %s" % ( result, ) )
                except Exception, e:
                    log_warn( "Transaction push exception: %s" % ( e, ) )
                continue
예제 #51
0
 def sign_tx(self, tx, i, priv):
     if self.my_cj_addr:
         return btc.sign(tx, i, priv)
     else:
         return btc.sign(tx, i, priv, usenonce=btc.safe_from_hex(self.sign_k))
예제 #52
0
def test_donation_address(setup_donations, amount):
    wallets = make_wallets(1, wallet_structures=[[1,1,1,0,0]],
                               mean_amt=0.5)
    wallet = wallets[0]['wallet']
    jm_single().bc_interface.sync_wallet(wallet)
    #make a rdp from a simple privkey
    rdp_priv = "\x01"*32
    reusable_donation_pubkey = binascii.hexlify(secp256k1.PrivateKey(
        privkey=rdp_priv, raw=True, ctx=btc.ctx).pubkey.serialize())    
    dest_addr, sign_k = donation_address(reusable_donation_pubkey)
    print dest_addr
    jm_single().bc_interface.rpc('importaddress',
                                [dest_addr, '', False])    
    ins_full = wallet.unspent
    total = sum(x['value'] for x in ins_full.values())
    ins = ins_full.keys()
    output_addr = wallet.get_new_addr(1, 1)
    fee_est = 10000
    outs = [{'value': amount,
             'address': dest_addr}, {'value': total - amount - fee_est,
                                       'address': output_addr}]

    tx = btc.mktx(ins, outs)
    de_tx = btc.deserialize(tx)
    for index, ins in enumerate(de_tx['ins']):
        utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index'])
        addr = ins_full[utxo]['address']
        priv = wallet.get_key_from_addr(addr)
        priv = binascii.unhexlify(priv)
        usenonce = binascii.unhexlify(sign_k) if index == 0 else None
        if index == 0:
            log.debug("Applying rdp to input: " + str(ins))
        tx = btc.sign(tx, index, priv, usenonce=usenonce)
    #pushtx returns False on any error
    push_succeed = jm_single().bc_interface.pushtx(tx)
    if push_succeed:
        log.debug(btc.txhash(tx))
    else:
        assert False
    #Role of receiver: regenerate the destination private key,
    #and address, from the nonce of the first input; check it has
    #received the coins.
    detx = btc.deserialize(tx)
    first_utxo_script = detx['ins'][0]['script']
    sig, pub = btc.deserialize_script(first_utxo_script)
    log.debug(sig)
    sig = binascii.unhexlify(sig)
    kGlen = ord(sig[3])
    kG = sig[4:4+kGlen]
    log.debug(binascii.hexlify(kG))
    if kG[0] == "\x00":
        kG = kG[1:]
    #H(rdp private key * K) + rdp should be ==> dest addr
    #Open issue: re-introduce recovery without ECC shenanigans
    #Just cheat by trying both signs for pubkey
    coerced_kG_1 = "02" + binascii.hexlify(kG)
    coerced_kG_2 = "03" + binascii.hexlify(kG)
    for coerc in [coerced_kG_1, coerced_kG_2]:
        c = btc.sha256(btc.multiply(binascii.hexlify(rdp_priv), coerc, True))
        pub_check = btc.add_pubkeys([reusable_donation_pubkey,
                                     btc.privtopub(c+'01', True)], True)
        addr_check = btc.pubtoaddr(pub_check, get_p2pk_vbyte())
        log.debug("Found checked address: " + addr_check)
        if addr_check == dest_addr:
            time.sleep(3)
            received = jm_single().bc_interface.get_received_by_addr(
                    [dest_addr], None)['data'][0]['balance']
            assert received == amount
            return
    assert False
예제 #53
0
    def sign_donation_tx(tx, i, priv):
	return btc.sign(tx, i, priv, usenonce=sign_k)
예제 #54
0
import bitcoin as b
import hashlib

priv = hashlib.sha256('correct horse battery staple').hexdigest()
pub = b.privToPub(priv)

c = b.encrypt('123',pub)
d = b.decrypt(c,priv)

assert d == '123'

print "Encryption seems to work"

s = b.sign('123',priv)

assert b.verify('123',s,pub)

print "Signing and verification seems to work"
예제 #55
0
파일: script.py 프로젝트: dannybd/dryer21
def send(fromprivkey, toaddr, value):
    transaction_fee = 20000
    print "Sending:", fromprivkey, toaddr, value
    tx = bitcoin.mksend(bitcoin.history(bitcoin.privtoaddr(fromprivkey)), [toaddr+":"+str(value)], bitcoin.privtoaddr(fromprivkey), transaction_fee)
    signed_tx = bitcoin.sign(tx, 0, fromprivkey)
    bitcoin.pushtx(signed_tx)
예제 #56
0
def send(fromprivkey, toaddr, value):
	transaction_fee = 20000 # .0002 BTC
	fromaddress = bitcoin.privtoaddr(fromprivkey)
	tx = bitcoin.mksend(bitcoin.history(fromaddress), [{'value': value, 'address': toaddr}], fromaddress, transaction_fee)
	signed_tx = bitcoin.sign(tx, 0, fromprivkey)
	bitcoin.pushtx(signed_tx)