Exemple #1
1
	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)
Exemple #2
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
Exemple #3
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
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
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
Exemple #6
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
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
Exemple #8
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)
Exemple #9
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")
Exemple #10
0
def get_input_and_output_scriptpubkeys(rpc, txid):
    gettx = rpc.call("gettransaction", [txid])
    txd = btc.deserialize(gettx["hex"])
    output_scriptpubkeys = [sc['script'] for sc in txd['outs']]
    input_scriptpubkeys = []
    for ins in txd["ins"]:
        try:
            wallet_tx = rpc.call("gettransaction", [ins["outpoint"]["hash"]])
        except JsonRpcError:
            #wallet doesnt know about this tx, so the input isnt ours
            continue
        script = btc.deserialize(str(
            wallet_tx["hex"]))["outs"][ins["outpoint"]["index"]]["script"]
        input_scriptpubkeys.append(script)
    return output_scriptpubkeys, input_scriptpubkeys, txd
 def test_decode_nonstandard_transaction_1(self):
     """
     txid: e411dbebd2f7d64dafeef9b14b5c59ec60c36779d43f850e5e347abee1e1a455
     """
     rawtransaction = (
         "010000000127d57276f1026a95b4af3b03b6aba859a001861682342af19825e8a2408ae008010000008c49304"
         "6022100cd92b992d4bde3b44471677081c5ece6735d6936480ff74659ac1824d8a1958e022100b08839f16753"
         "2aea10acecc9d5f7044ddd9793ef2989d090127a6e626dc7c9ce014104cac6999d6c3feaba7cdd6c62bce1743"
         "39190435cffd15af7cb70c33b82027deba06e6d5441eb401c0f8f92d4ffe6038d283d2b2dd59c4384b66b7b8f"
         "038a7cf5ffffffff0200093d0000000000434104636d69f81d685f6f58054e17ac34d16db869bba8b3562aabc"
         "38c35b065158d360f087ef7bd8b0bcbd1be9a846a8ed339bf0131cdb354074244b0a9736beeb2b9ac40420f00"
         "00000000fdba0f76a9144838a081d73cf134e8ff9cfd4015406c73beceb388" + ("ac" * 4002) + "00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 0.01000000,
         "n": 1,
         "scriptPubKey": {
             "asm": "OP_DUP OP_HASH160 4838a081d73cf134e8ff9cfd4015406c73beceb3 OP_EQUALVERIFY"
             + (" OP_CHECKSIG" * 4002),
             "hex": "76a9144838a081d73cf134e8ff9cfd4015406c73beceb388" + ("ac" * 4002),
             "type": "nonstandard",
         },
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][1], 1, "main")
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(sut, vout)
 def test_decode_nonstandard_transaction_2(self):
     """
     5492a05f1edfbd29c525a3dbf45f654d0fc45a805ccd620d0a4dff47de63f90b
     :return:
     """
     rawtransaction = (
         "0100000001d488bf79a92feb869c984de9fc6be7cb5c5ac2e408d608e25460501c2aff2dac010000008a47304402200f"
         "185ac16694f3f3902fb058f1a3d96f2549db4311b038742fc315685c9e6a1f022018e6c2c8e0559d87988b48ba80d214"
         "d95ed3f06795e549d4568702cc2a9e2af301410463cd01a8f2b56fff4e9357ccedf014ca119d64c1dff8b576e2785f60"
         "3b3fd1a04e7ab451929ef5e4e2449a7999a1365db7bc08fccc19cdad16c4ce26d6ba9bf4ffffffff03008aa411000000"
         "001a76a91469d28eb9a311256338d281025a7437096149472c88ac610065cd1d000000001976a9145f8b65a4064ef5c0"
         "71c382d594b55d94bd31ec3a88ac00100000000000001976a9146300bf4c5c2a724c280b893807afb976ec78a92b88ac"
         "00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 2.95995904,
         "n": 0,
         "scriptPubKey": {
             "asm": "OP_DUP OP_HASH160 69d28eb9a311256338d281025a7437096149472c OP_EQUALVERIFY OP_CHECKSIG OP_NOP",
             "hex": "76a91469d28eb9a311256338d281025a7437096149472c88ac61",
             "type": "nonstandard",
         },
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(sut, vout)
Exemple #13
0
def sign(tx, i, priv, t="default", script="", hashcode=SIGHASH_ALL):
    i = int(i)
    #if (not is_python2 and isinstance(re, bytes)) or not re.match('^[0-9a-fA-F]*$', tx):
    if not re.match('^[0-9a-fA-F]*$', tx):
        return binascii.unhexlify(
            custom_sign(safe_hexlify(tx), i, priv, hashcode))
    if len(priv) <= 33:
        priv = b.safe_hexlify(priv)
    pub = b.privkey_to_pubkey(priv)
    address = b.pubkey_to_address(pub)
    if t not in ["atomic_1", "atomic_2"]:
        script = b.mk_pubkey_script(address)
    if script == "": error()
    signing_tx = b.signature_form(
        tx, i, script,
        hashcode)  #mk_pubkey_scrip needs to be our custom scriptn
    sig = b.ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = b.deserialize(tx)
    if t == "atomic_1":
        txobj["ins"][i]["script"] = b.serialize_script([sig])
    if t == "atomic_2":
        old_sig = txobj["ins"][i]["script"]
        txobj["ins"][i]["script"] = b.serialize_script([old_sig, sig, 1])
    else:
        txobj["ins"][i]["script"] = b.serialize_script([sig, pub])
    return b.serialize(txobj)
Exemple #14
0
    def test_native_P2WSH_SIGHASH_SINGLE_ANYONECANPAY(self):
        tx = TEST_CASES[2]
        deserialized = deserialize(tx['unsigned'])
        serialized = serialize(deserialized)
        self.assertEqual(serialized, tx['unsigned'])
        self.assertEqual(deserialized['locktime'], tx['locktime'])
        ins = self.get_pybtc_vins(tx)
        outs = self.get_pybtc_outs(tx)
        generated_tx = mktx(ins, outs)
        stripped_tx = strip_witness_data(generated_tx)
        self.assertEqual(stripped_tx, serialized)
        priv0 = self.append_compressed_flag_to_privkey(tx['ins'][1]['privkey'])
        partially_signed = segwit_sign(generated_tx,
                                       0,
                                       priv0,
                                       int(0.16777215 * 10**8),
                                       hashcode=SIGHASH_SINGLE|SIGHASH_ANYONECANPAY,
                                       script=tx['ins'][0]['txinwitness'][1])

        signed = segwit_sign(partially_signed,
                             1,
                             priv0,
                             int(0.16777215 * 10 ** 8),
                             hashcode=SIGHASH_SINGLE|SIGHASH_ANYONECANPAY,
                             script=tx['ins'][1]['txinwitness'][1],
                             separator_index=tx['ins'][1]['separator'])
        self.assertEqual(signed, tx['signed'])
        print('[Native P2WSH] SIGHASH_SINGLE OK')
Exemple #15
0
def list_purchases(obj):
    txs, heights = obj['txs'], obj['heights']
    o = []
    for h in txs:
        txhex = str(txs[h])
        # print txhex
        txouts = b.deserialize(txhex)['outs']
        if len(txouts) >= 2 and txouts[0]['value'] >= minimum - 30000:
            addr = b.script_to_address(txouts[0]['script'])
            if addr == exodus:
                v = txouts[0]['value'] + 30000
                ht = heights[h]
                # We care about the timestamp of the previous
                # confirmed block before a transaction
                t = get_block_header_data(ht - 1)['timestamp']
                o.append({
                    "tx": h,
                    "addr": b.b58check_to_hex(b.script_to_address(
                                              txouts[1]['script'])),
                    "value": v,
                    "time": t
                })
                if len(o) % 50 == 0:
                    sys.stderr.write('Gathered outputs: %d\n' % len(o))
    return o
 def test_decode_nonstandard_transaction_4(self):
     """
     b728387a3cf1dfcff1eef13706816327907f79f9366a7098ee48fc0c00ad2726
     """
     rawtransaction = (
         "0100000001658d363400dac6f939da9065c853a77d07d7e62e60a3bb8c1063437fc0018cff000000008b483045"
         "022100e84437d13d6f316ee69e3328c77dba344a0da973fb40b4974a753e65cf8fae0c02205f3de940ad995e3f"
         "960523e9afa5f5cec71ed91ef16cb3dbd7a69a43fb8898a6014104e4411b8275776b110b3b06a7ac0d5927f08f"
         "95a476a97ab091436fe423de660fb9606ab64749ea360b7d624c9698d26d9965732017acd3da7e9ffc13daca0f"
         "26ffffffff02ee4d8a050000000043410467b7944809e4b3748d2cac0c388dad7ee3555b408a7892a8bf929e85"
         "6afa2da4d329a39cf2c28f85438ae8d98a4d0bfb107b914933168eb9b31fae845fe8f614ac0100000000000000"
         "4240f816b480f87144ec4de5862adf028ff66cc6964250325d53fd22bf8922824b6f1e1f2c881ae0608ec77ebf"
         "88a75c66d3099113a7343238f2f7a0ebb91a4ed335ac00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout1 = {
         "value": 0.00000001,
         "n": 1,
         "scriptPubKey": {
             "asm": "f816b480f87144ec4de5862adf028ff66cc6964250325d53fd22bf8922824b6f1e1f2c881ae0608ec77ebf88a75c66d3099113a7343238f2f7a0ebb91a4ed335 OP_CHECKSIG",
             "hex": "40f816b480f87144ec4de5862adf028ff66cc6964250325d53fd22bf8922824b6f1e1f2c881ae0608ec77ebf88a75c66d3099113a7343238f2f7a0ebb91a4ed335ac",
             "type": "pubkey",
         },
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][1], 1, "main")
     vout = json.loads(json.dumps(bitcoind_json_vout1), parse_float=Decimal)
     self.assertEqual(sut, vout)
    def test_Vin(self):
        rawtransaction = (
            "01000000031091bb34c19754b689685bd5f84078b437653d08377d2d03d256b34f80eb219e010000008a4730440"
            "220476c26cdcecccf46fdd96fb87814661cb1044e103d1bcd5be339b9cbaceca47902201b2caafe5b36913ef475"
            "d4d33b9d62aa3316ece6f1ac3371a506906e61afd4510141048c632401521a105db6b62db0a2c393181b5538f2c"
            "56d461057611252baebc9c7794378c252c45b7393fc93ea3b8bc6d6db1c9b5506744d51d1ddd7a9acd27d81ffff"
            "ffffcc72f7a8acf77c1b1313d4ba229bff7db4f40e0a1b525a9b8a4dbc8ecc80b070000000008b4830450221009"
            "97b74ef85d3be61a96a4d8ecebfeb588979364276f54fa77571ff8fb7906e4202204390f9935695194362fbc221"
            "b00436b4811d01f645715105f9d081ad65977e2b014104fd579aa4983cece29365038ddbaf479af86bdf25afdca"
            "e67bbe8b30c268aecdac6cd8f923ef3f23ab694783f9243522f67886a46a43499e3fb3ed49623869d6fffffffff"
            "8ecdae566b8e8d709a32054175ce61fc2a9323e60023f62b23c342a7186beeea000000008b48304502200f95d4c"
            "d51bb5b867563700979ea23bf69921b1a0262ff5de3d7330bb992a713022100de58fa5822e7e62c8e6e4edbdece"
            "7913cb21f5a7b5a39d85fa9291874ce81a710141045f7f6eed56863bf527b8fd30cbe78038db311370da6c7054b"
            "eced527d60f47a65d6f1ce62278ba496f5da4a3d738eac0e2cb0f4ac38b113cbeabef59b685b16cffffffff0280"
            "c51b11010000000576a90088ac4cbdd397a90000001976a914d1121a58483d135c953e0f4e2cc6d126b5c6b0638"
            "8ac00000000"
        )
        pybtcd_deserialized_transaction = deserialize(rawtransaction)
        bitcoind_json_vin0 = {
            "txid": "9e21eb804fb356d2032d7d37083d6537b47840f8d55b6889b65497c134bb9110",
            "vout": 1,
            "scriptSig": {
                "asm": "30440220476c26cdcecccf46fdd96fb87814661cb1044e103d1bcd5be339b9cbaceca47902201b2caafe5b36913ef475d4d33b9d62aa3316ece6f1ac3371a506906e61afd45101 048c632401521a105db6b62db0a2c393181b5538f2c56d461057611252baebc9c7794378c252c45b7393fc93ea3b8bc6d6db1c9b5506744d51d1ddd7a9acd27d81",
                "hex": "4730440220476c26cdcecccf46fdd96fb87814661cb1044e103d1bcd5be339b9cbaceca47902201b2caafe5b36913ef475d4d33b9d62aa3316ece6f1ac3371a506906e61afd4510141048c632401521a105db6b62db0a2c393181b5538f2c56d461057611252baebc9c7794378c252c45b7393fc93ea3b8bc6d6db1c9b5506744d51d1ddd7a9acd27d81",
            },
            "sequence": 4294967295,
        }
        sut = VINDecoder.decode(pybtcd_deserialized_transaction["ins"][0])
        vin = json.loads(json.dumps(bitcoind_json_vin0), parse_float=Decimal)

        self.assertEqual(vin, sut)
 def test_decode_nonostandard_9(self):
     """
     0f20c8dab4a8dfb50dd5cf4c276ba1fab1c79cae5b6641be2f67faaca838c1e6
     """
     rawtransaction = (
         "0100000002919ce962176f35c28531389b386f98ea9ca418bfe50b2791bc680424638b6079010000006b48304"
         "5022100f1165ece65fc48f7b72e274b874924cece0f943ce5bc041bdcce23f7346218f0022079cf10cde06355"
         "11f465d18d16edab9321eac9055f5a66c320fc8ef364bb6c72012102b20dafdbe1f0da03bbe07eae16e07fe6a"
         "29cf3e3e564525ce4d5a9b687a1bd22ffffffffe109088d7f9ffeae98d356c535ca4d6e5893b561a299f71dfd"
         "2e6af1fdff7abf010000006c493046022100e058b2e7fd16e73841dcfbc58eb644d1ee84d055913e2858855e8"
         "2df35496598022100bc56a9b63f547d451b3d7a02a5e8d6fa94777c29dc84d1f2ecd5590da8f00c9e012102e3"
         "5cd7a41926b636db064133926c1834139dd58cb5fd968258d01b1b696c2da3ffffffff01e03cc80100000000a"
         "a512102953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213623441048da561da64584f"
         "b1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf410c7b6d6fd39acf9d870cb9726578eaf8ba430"
         "bb296eac24957f3fb3395b8b042060466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764"
         "bcdffb6a9740de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e3953ae00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 0.29900000,
         "n": 0,
         "scriptPubKey": {
             "asm": "1 02953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf221162136234 048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b0 060466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcdffb6a9740de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e39 3 OP_CHECKMULTISIG",
             "hex": "512102953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213623441048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b042060466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcdffb6a9740de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e3953ae",
             "type": "nonstandard",
         },
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(sut, vout)
    def test__decode_PayToPubKeyHash(self):
        """
        OP_DUP OP_HASH160 OP_DATA_20 OP_EQUALVERIFY OP_CHECKSIG
        """
        rawtransaction = (
            "0100000002bc2ea135edf7fe4cbf907601a6dddcaa093c502791b476ebb756a2f63c72ae24000000"
            "008c4930460221009d4aa20d971b7c90143750227c905608e9dfe3546a02b25411b3005045e2ba60"
            "0221008c52ef6fe58ea64492ee1cde059bb22e0d7eeea2d7130f522c5dc02d598f7b2c0141040277"
            "a8116d60b32ddd8fe5e6215e10c39880888a7c7f125fa6815b06a0b51d934cc2b30a3c22e06ff179"
            "bca23c54652f233f7665cc54f8b7b1971e894482ea45ffffffffbc2ea135edf7fe4cbf907601a6dd"
            "dcaa093c502791b476ebb756a2f63c72ae24010000008c493046022100d4c00f143da46e733e5afe"
            "5f8babe61884d6b42250346f9e26f12d5821d70a7d022100b93ae61ab3792b4d2290c793b128a326"
            "c96234ac662793821063d887044e49f1014104f6e8c8581ee3dba51288e68386475fba780710c964"
            "dfb1aaabea06afb4fb0cd10282adf8bfed9fb94d959a089fcd19f691a0cc7b14b1f5aae5e132b39c"
            "c63efaffffffff0280d87407030000001976a914f5118746a4dce6ac146077f73fea49e10b1e908e"
            "88ac401c59c0020000001976a914c2a7a8f990252e6e048476b6a7a4433be10e9c3588ac00000000"
        )

        pybtcd_deserialized_transaction = deserialize(rawtransaction)
        bitcoind_json_vout0 = {
            "value": 130.10000000,
            "n": 0,
            "scriptPubKey": {
                "asm": "OP_DUP OP_HASH160 f5118746a4dce6ac146077f73fea49e10b1e908e OP_EQUALVERIFY OP_CHECKSIG",
                "hex": "76a914f5118746a4dce6ac146077f73fea49e10b1e908e88ac",
                "reqSigs": 1,
                "type": "pubkeyhash",
                "addresses": ["1PLoYttF6YdytJRzdnyubpEethhn5B8836"],
            },
        }

        sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
        vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
        self.assertEqual(vout, sut)
 def test_decode_nonstandard_8(self):
     rawtransaction = (
         "0100000001b409333c7daee2ecb95e860ce7dc3376eff8aae437cad727cf9b624cf3354c00010000008a47304"
         "40220b5afdf9e538c59fd0604d43c7053cefeff20bbe434f7c0d71b8800c31e88c34b02209e0d55cc3bae16f8"
         "ba347213d0b565b915f25e401351c2d405edcec69af0508f01410441a99c4157ed26924cd410a1cd3d7524e3f"
         "4a1a5d4e764755b73abbd0c479d8a3e9c4b916e62d5603ac4514fffccaa4a27aa7d2cac403a6b872981e71acb"
         "9528ffffffff0400ca9a3b000000001976a9140cbc34efb7e6cde16940cc0283a5770c6627616c88ace0b85a0"
         "2000000001976a91403f024eb71ceafb36c67bc7ebdcfbd0e6b2a70d488ac00000000000000007b4c784d6573"
         "736167653a2057656c6c204920677565737320746861742773206f6e652077617920746f20646f2069742e205"
         "768792063616e27742074686520717420636c69656e742062652074686973206e6963653f20466f7220616e79"
         "6f6e6520737472696e67732d696e672074686520626c6f636b636861ac000000000000000023214120656c656"
         "374696f6e7320736f6f6e2e00000000000000000000000000000000ac00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vouts = [
         {
             "value": 10.00000000,
             "n": 0,
             "scriptPubKey": {
                 "asm": "OP_DUP OP_HASH160 0cbc34efb7e6cde16940cc0283a5770c6627616c OP_EQUALVERIFY OP_CHECKSIG",
                 "hex": "76a9140cbc34efb7e6cde16940cc0283a5770c6627616c88ac",
                 "reqSigs": 1,
                 "type": "pubkeyhash",
                 "addresses": ["12ALa92sWLrXy5DSwL6Qs53AY4GP5e4GrX"],
             },
         },
         {
             "value": 0.39500000,
             "n": 1,
             "scriptPubKey": {
                 "asm": "OP_DUP OP_HASH160 03f024eb71ceafb36c67bc7ebdcfbd0e6b2a70d4 OP_EQUALVERIFY OP_CHECKSIG",
                 "hex": "76a91403f024eb71ceafb36c67bc7ebdcfbd0e6b2a70d488ac",
                 "reqSigs": 1,
                 "type": "pubkeyhash",
                 "addresses": ["1Mpi67rzcwzmkcrzTAakUwtYnRcERSbhs"],
             },
         },
         {
             "value": 0.00000000,
             "n": 2,
             "scriptPubKey": {
                 "asm": "4d6573736167653a2057656c6c204920677565737320746861742773206f6e652077617920746f20646f2069742e205768792063616e27742074686520717420636c69656e742062652074686973206e6963653f20466f7220616e796f6e6520737472696e67732d696e672074686520626c6f636b636861 OP_CHECKSIG",
                 "hex": "4c784d6573736167653a2057656c6c204920677565737320746861742773206f6e652077617920746f20646f2069742e205768792063616e27742074686520717420636c69656e742062652074686973206e6963653f20466f7220616e796f6e6520737472696e67732d696e672074686520626c6f636b636861ac",
                 "type": "nonstandard",
             },
         },
         {
             "value": 0.00000000,
             "n": 3,
             "scriptPubKey": {
                 "asm": "4120656c656374696f6e7320736f6f6e2e00000000000000000000000000000000 OP_CHECKSIG",
                 "hex": "214120656c656374696f6e7320736f6f6e2e00000000000000000000000000000000ac",
                 "type": "pubkey",
             },
         },
     ]
     for x in bitcoind_json_vouts:
         sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][x["n"]], x["n"], "main")
         vout = json.loads(json.dumps(x), parse_float=Decimal)
         self.assertEqual(sut, vout)
Exemple #21
0
    def test_native_P2WSH_SIGHASH_SINGLE_ANYONECANPAY(self):
        tx = TEST_CASES[2]
        deserialized = deserialize(tx['unsigned'])
        serialized = serialize(deserialized)
        self.assertEqual(serialized, tx['unsigned'])
        self.assertEqual(deserialized['locktime'], tx['locktime'])
        ins = self.get_pybtc_vins(tx)
        outs = self.get_pybtc_outs(tx)
        generated_tx = mktx(ins, outs)
        stripped_tx = strip_witness_data(generated_tx)
        self.assertEqual(stripped_tx, serialized)
        priv0 = self.append_compressed_flag_to_privkey(tx['ins'][1]['privkey'])
        partially_signed = segwit_sign(generated_tx,
                                       0,
                                       priv0,
                                       int(0.16777215 * 10**8),
                                       hashcode=SIGHASH_SINGLE
                                       | SIGHASH_ANYONECANPAY,
                                       script=tx['ins'][0]['txinwitness'][1])

        signed = segwit_sign(partially_signed,
                             1,
                             priv0,
                             int(0.16777215 * 10**8),
                             hashcode=SIGHASH_SINGLE | SIGHASH_ANYONECANPAY,
                             script=tx['ins'][1]['txinwitness'][1],
                             separator_index=tx['ins'][1]['separator'])
        self.assertEqual(signed, tx['signed'])
        print('[Native P2WSH] SIGHASH_SINGLE OK')
 def test_decode_standard_pubkeyhash_op_drop_vin(self):
     """
     51874c4b26a92dacb256f0e60303daabf60a63681111c4c1948f0bba25d8df96
     """
     rawtransaction = (
         "010000000135ae0d99ffc1aea8fe97944e01b7842cbcbb5e186ab993438def514a2153b5cd0000000003010075f"
         "fffffff01b01df505000000001976a914d994aabea310efb308baa96c044aeae1fe1c413188ac00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 0.99950000,
         "n": 0,
         "scriptPubKey": {
             "asm": "OP_DUP OP_HASH160 d994aabea310efb308baa96c044aeae1fe1c4131 OP_EQUALVERIFY OP_CHECKSIG",
             "hex": "76a914d994aabea310efb308baa96c044aeae1fe1c413188ac",
             "reqSigs": 1,
             "type": "pubkeyhash",
             "addresses": ["1LqTjBzMRdXQqXpRQo1zDYRiUobAVS55Lo"],
         },
     }
     bitcoind_json_vin0 = {
         "txid": "cdb553214a51ef8d4393b96a185ebbbc2c84b7014e9497fea8aec1ff990dae35",
         "vout": 0,
         "scriptSig": {"asm": "0 OP_DROP", "hex": "010075"},
         "sequence": 4294967295,
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
     sut_in = VINDecoder.decode(pybtcd_deserialized_transaction["ins"][0])
     vin = json.loads(json.dumps(bitcoind_json_vin0), parse_float=Decimal)
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(sut, vout)
     self.assertEqual(sut_in, vin)
 def test__decode_PayToPubKey_33_bytes(self):
     """
     OP_DATA_33 OP_CHECKSIG
     """
     rawtransaction = (
         "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3c049"
         "93c1c4f02b0002c4d4d3d3d7df37de04d7764c9945027b3d19e66a03ef56bdd230f36648ad8b4b0ce9e2a81"
         "0100000000000000062f503253482fffffffff0100f2052a010000002321024d57123256b2a84e6618bc12b"
         "08f81cd54ec79fcd7a55a129eee9402bac8d5f7ac00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 50.00000000,
         "n": 0,
         "scriptPubKey": {
             "asm": "024d57123256b2a84e6618bc12b08f81cd54ec79fcd7a55a129eee9402bac8d5f7 OP_CHECKSIG",
             "hex": "21024d57123256b2a84e6618bc12b08f81cd54ec79fcd7a55a129eee9402bac8d5f7ac",
             "reqSigs": 1,
             "type": "pubkey",
             "addresses": ["1PLDXZPhFEfGGxdXr54FxvWUvWcRCrjHEG"],
         },
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(vout, sut)
 def test_decode_nonstandard_transaction_9(self):
     """
     91c8b08f305d895d6bc8f43bbdd36dcbc7f1d998e3df5e8f13dd9cdeebf15cb5
     """
     rawtransaction = (
         "0100000001a30562a1cd9e907a90d7367ceaf55e859417a53ffda6190086110b7f8a4b4d2201000000020151ffff"
         "ffff0130d397000000000017a91469d98314fbc4dbee037f86f51392a14c4c1d41da8700000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 0.09950000,
         "n": 0,
         "scriptPubKey": {
             "asm": "OP_HASH160 69d98314fbc4dbee037f86f51392a14c4c1d41da OP_EQUAL",
             "hex": "a91469d98314fbc4dbee037f86f51392a14c4c1d41da87",
             "reqSigs": 1,
             "type": "scripthash",
             "addresses": ["3BLhSgpY9xCFJv9Y6AyA9eSRZT6k3z6w4s"],
         },
     }
     bitcoind_json_vin1 = {
         "txid": "224d4b8a7f0b11860019a6fd3fa51794855ef5ea7c36d7907a909ecda16205a3",
         "vout": 1,
         "scriptSig": {"asm": "81", "hex": "0151"},
         "sequence": 4294967295,
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
     sut_in = VINDecoder.decode(pybtcd_deserialized_transaction["ins"][0])
     vin = json.loads(json.dumps(bitcoind_json_vin1), parse_float=Decimal)
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(sut, vout)
     self.assertEqual(sut_in, vin)
    def test__decode_OPRETURN_data(self):
        """
        OP_RETURN OP_DATA
        """
        rawtransaction = (
            "0100000001c858ba5f607d762fe5be1dfe97ddc121827895c2562c4348d69d02b91dbb408e0100000"
            "08b4830450220446df4e6b875af246800c8c976de7cd6d7d95016c4a8f7bcdbba81679cbda2420221"
            "00c1ccfacfeb5e83087894aa8d9e37b11f5c054a75d030d5bfd94d17c5bc953d4a0141045901f6367"
            "ea950a5665335065342b952c5d5d60607b3cdc6c69a03df1a6b915aa02eb5e07095a2548a98dcdd84"
            "d875c6a3e130bafadfd45e694a3474e71405a4ffffffff020000000000000000156a13636861726c6"
            "579206c6f766573206865696469400d0300000000001976a914b8268ce4d481413c4e848ff353cd16"
            "104291c45b88ac00000000"
        )

        pybtcd_deserialized_transaction = deserialize(rawtransaction)
        bitcoind_json_vout0 = {
            "value": 0.00000000,
            "n": 0,
            "scriptPubKey": {
                "asm": "OP_RETURN 636861726c6579206c6f766573206865696469",
                "hex": "6a13636861726c6579206c6f766573206865696469",
                "type": "nulldata",
            },
        }
        sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
        vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
        self.assertEqual(vout, sut)
 def test__decode_PayToPubKey_65_bytes(self):
     """
     OP_DATA_65 OP_CHECKSIG
     """
     rawtransaction = (
         "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704f"
         "fff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a62"
         "7c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac0"
         "0000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 50.00000000,
         "n": 0,
         "scriptPubKey": {
             "asm": "0496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858ee OP_CHECKSIG",
             "hex": "410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac",
             "reqSigs": 1,
             "type": "pubkey",
             "addresses": ["12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX"],
         },
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(vout, sut)
    def test__decode_P2SH(self):
        """
        OP_HASH160 OP_DATA_20 OP_EQUAL
        """
        rawtransaction = (
            "0100000001323fcde8eb922407811af73ace8a621587f0e3756d9daa0306f43e9ee806701401000000fc"
            "004730440220385b914def508fe2e19e4db04eb3a242f9f2052ca4850e4d4ef47086c2ff0ca20220323c"
            "67b383d34731c3adcc231b3efbbd385a1ac1f9edbb03794361b0f8c39775014730440220663eb7920041"
            "7e448da1acfbf16543045ff42a8e2c64121589062f0e5311e879022010cb0965a9aa96bab8824778c2ae"
            "790ec14ed3bfaf4905478021152cbf78517f014c69522102d125ff449e4de303919ef232dafa0bc7528b"
            "266a576da91f6fd25a4709f98337210290418ccfa7e5ca60c01d5525be826dc791009e698519b4c090b4"
            "5e75ec8887d4210329ff00450d9756ecc26fc5446aebce88d4053f30cb08768e7cce3d172983d58f53ae"
            "ffffffff020b7e32000000000017a9146af7caf9b09224af8a171318f69d254c1756e54e87db8f0f2c00"
            "00000017a914fe9840ab09de0fa3d2f4c73da1d1fc49f0c0bb508700000000"
        )

        pybtcd_deserialized_transaction = deserialize(rawtransaction)
        bitcoind_json_vout0 = {
            "value": 0.03309067,
            "n": 0,
            "scriptPubKey": {
                "asm": "OP_HASH160 6af7caf9b09224af8a171318f69d254c1756e54e OP_EQUAL",
                "hex": "a9146af7caf9b09224af8a171318f69d254c1756e54e87",
                "reqSigs": 1,
                "type": "scripthash",
                "addresses": ["3BScPpzxa8LErVDWg7zfHC5wcGHQf8F5pi"],
            },
        }
        sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
        vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
        self.assertEqual(vout, sut)
def list_purchases(obj):
    txs, heights = obj['txs'], obj['heights']
    o = []
    for h in txs:
        txhex = str(txs[h])
        # print txhex
        txouts = b.deserialize(txhex)['outs']
        if len(txouts) >= 2:
            addr = b.script_to_address(txouts[0]['script'])
            if addr == exodus:
                v = txouts[0][
                    'value'] + 10000  # add 0.1 millibit for the fees paid transfering from koinify wallet to Factom multisig
                ht = heights[h]
                # We care about the timestamp of the previous
                # confirmed block before a transaction
                t = get_block_header_data(ht - 1)['timestamp']
                o.append({
                    "tx": h,
                    "addr": extract_pubkey(txouts[1]['script']),
                    "value": v,
                    "time": t
                })
                if len(o) % 50 == 0:
                    sys.stderr.write('Gathered outputs: %d\n' % len(o))
    return o
    def test__decode_CHECKMULTISIG_1_of_2(self):
        rawtransaction = (
            "010000000123ba84a7ce8ab2785a838fa9ca50ad395bee25aba38dda28336cc337d08a599e000000006a4730"
            "440220320a58bf09ce578dd2ddf5381a34d80c3b659e2748c8fd8aa1b7ecc5b8c87665022019905d76a7bbc8"
            "3cbc3fb6d33e7e8aae903716206e9cf1fcb75518ce37baf69a01210312c50bdc21e06827c0bdd3ef1ff849e2"
            "4b17147f9a6f240c4af45bd235eb5819ffffffff0102000000000000004751210351efb6e91a31221652105d"
            "032a2508275f374cea63939ad72f1b1e02f477da782100f2b7816db49d55d24df7bdffdbc1e203b424e8cd39"
            "f5651ab938e5e4a193569e52ae00000000"
        )

        pybtcd_deserialized_transaction = deserialize(rawtransaction)
        bitcoind_json_vout0 = {
            "value": 0.00000002,
            "n": 0,
            "scriptPubKey": {
                "asm": "1 0351efb6e91a31221652105d032a2508275f374cea63939ad72f1b1e02f477da78 00f2b7816db49d55d24df7bdffdbc1e203b424e8cd39f5651ab938e5e4a193569e 2 OP_CHECKMULTISIG",
                "hex": "51210351efb6e91a31221652105d032a2508275f374cea63939ad72f1b1e02f477da782100f2b7816db49d55d24df7bdffdbc1e203b424e8cd39f5651ab938e5e4a193569e52ae",
                "reqSigs": 1,
                "type": "multisig",
                "addresses": ["1NdB761LmTmrJixxp93nz7pEiCx5cKPW44"],
            },
        }
        sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
        vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
        self.assertEqual(sut, vout)
    def import_json( self, json_text ):
        try:
            importTxInfo = json.loads( json_text )
        except:
            raise RuntimeError( "Invalid Input", "The input doesn't parse to valid json." )

        try: 
            if 'tx' not in importTxInfo:
                raise ValueError( "No transaction found in json" )

            redeemScriptCanidate = None
    
            try: 
		self.tx = bitcoin.deserialize( importTxInfo['tx'] )
                sigScript = self.tx['ins'][0]['script']
                if sigScript != "":
                    sigScript = bitcoin.deserialize_script( sigScript )
                    redeemScriptCanidate = sigScript[-1]
            except Exception as e:
                raise ValueError( "tx could not be deserialized:" + str( e ) )

            if 'input' in importTxInfo and 'redeemScript' in importTxInfo['input']:
                if redeemScriptCanidate is not None and redeemScriptCanidate.lower() != importTxInfo['input']['redeemScript'].lower():
                    raise ValueError( "redeemScript given in info doesn't match redeemScript from partial signature" )
                redeemScriptCanidate = importTxInfo['input']['redeemScript']

            if redeemScriptCanidate is not None:
                self.pubs, self.neededSigs = KeyHelper.parse_redeem_script( redeemScriptCanidate )
                self.redeemScript = redeemScriptCanidate
            else:
                raise ValueError( "No redeemScript can be located." )

        except ValueError as e:
            raise RuntimeError( "Invalid Input", str( e ) )
 def test__decode_OPDATA_nonstandard(self):
     """
     OP_DATA_32
     OP_DATA_36
     """
     rawtransaction = (
         "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2cfabe6d"
         "6dc4a1165ea4f5b251a55d0a5826282b4a9b3551a28d9ff0d9343a1bc942fa895e0100000000000000ffffffff"
         "0e00000000000000002120b7837f89bd7d3b262037ed0e31063c00d8e5f785b742ac467cef4e69d98a19bd5f71"
         "2300000000001976a91404b61d237655b3ceb6329ac474cd4eb16fa7318f88accf057b00000000001976a9147f"
         "92bc474f4d80ac06c8f02d57915bf550c8447b88aca16f850100000000434104ffd03de44a6e11b9917f3a29f9"
         "443283d9871c9d743ef30d5eddcd37094b64d1b3d8090496b53256786bf5c82932ec23c3b74d9f05a6f95a8b55"
         "29352656664bacb17fe203000000001976a9149fdc63fd4c87de443b5984d00b159a8340f64eb388acd88f4d04"
         "000000001976a91491ce910c7ca125114f2e38bf9a17f1130185ca7f88ac2fae2d0b000000001976a91426bad6"
         "b6f1079452cd954471d58a641dcd20abb888ac6ee2f50e000000001976a914761331627d4769d4e551762caa58"
         "f54fb65822a188ace92add0f000000001976a914984f8de73e491543c52a7cb23537706887247f8688acb1fc8f"
         "1f000000001976a9147522e01f331ef160bf609ddc321033a87529ccb688ac02767426000000001976a914bcf8"
         "2a713a320942ce47e073787b48e73ed21bc388ac3333752d000000001976a914155b7de88446ba2fb671df7e3e"
         "68def8646e1cda88ac331f893f0000000043410461c9f86eb47bda456cedc2e4bc45a51026b244db1f3fd4c2d2"
         "5713f517062b6c832f2e9231eba78e92eb77ce122498d99cea3007bdba9bed715e4525b92e8cc9ac79dfb64200"
         "0000001976a914af1ffe62761b0c8b83d96f06621eda34b1b0683288ac00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 0.00000000,
         "n": 0,
         "scriptPubKey": {
             "asm": "b7837f89bd7d3b262037ed0e31063c00d8e5f785b742ac467cef4e69d98a19bd",
             "hex": "20b7837f89bd7d3b262037ed0e31063c00d8e5f785b742ac467cef4e69d98a19bd",
             "type": "nonstandard",
         },
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(sut, vout)
 def test__decode_nonstandard_transaction(self):
     rawtransaction = (
         "01000000031091bb34c19754b689685bd5f84078b437653d08377d2d03d256b34f80eb219e010000008a473044"
         "0220476c26cdcecccf46fdd96fb87814661cb1044e103d1bcd5be339b9cbaceca47902201b2caafe5b36913ef4"
         "75d4d33b9d62aa3316ece6f1ac3371a506906e61afd4510141048c632401521a105db6b62db0a2c393181b5538"
         "f2c56d461057611252baebc9c7794378c252c45b7393fc93ea3b8bc6d6db1c9b5506744d51d1ddd7a9acd27d81"
         "ffffffffcc72f7a8acf77c1b1313d4ba229bff7db4f40e0a1b525a9b8a4dbc8ecc80b070000000008b48304502"
         "2100997b74ef85d3be61a96a4d8ecebfeb588979364276f54fa77571ff8fb7906e4202204390f9935695194362"
         "fbc221b00436b4811d01f645715105f9d081ad65977e2b014104fd579aa4983cece29365038ddbaf479af86bdf"
         "25afdcae67bbe8b30c268aecdac6cd8f923ef3f23ab694783f9243522f67886a46a43499e3fb3ed49623869d6f"
         "ffffffff8ecdae566b8e8d709a32054175ce61fc2a9323e60023f62b23c342a7186beeea000000008b48304502"
         "200f95d4cd51bb5b867563700979ea23bf69921b1a0262ff5de3d7330bb992a713022100de58fa5822e7e62c8e"
         "6e4edbdece7913cb21f5a7b5a39d85fa9291874ce81a710141045f7f6eed56863bf527b8fd30cbe78038db3113"
         "70da6c7054beced527d60f47a65d6f1ce62278ba496f5da4a3d738eac0e2cb0f4ac38b113cbeabef59b685b16c"
         "ffffffff0280c51b11010000000576a90088ac4cbdd397a90000001976a914d1121a58483d135c953e0f4e2cc6"
         "d126b5c6b06388ac00000000"
     )
     pybtcd_deserialized_transaction = deserialize(rawtransaction)
     bitcoind_json_vout0 = {
         "value": 45.82000000,
         "n": 0,
         "scriptPubKey": {
             "asm": "OP_DUP OP_HASH160 0 OP_EQUALVERIFY OP_CHECKSIG",
             "hex": "76a90088ac",
             "type": "nonstandard",
         },
     }
     sut = VOUTDecoder.decode(pybtcd_deserialized_transaction["outs"][0], 0, "main")
     vout = json.loads(json.dumps(bitcoind_json_vout0), parse_float=Decimal)
     self.assertEqual(sut, vout)
Exemple #33
0
def sign_donation_tx(tx, i, priv):
    from bitcoin.main import fast_multiply, decode_privkey, G, inv, N
    from bitcoin.transaction import der_encode_sig
    k = sign_k
    hashcode = btc.SIGHASH_ALL
    i = int(i)
    if len(priv) <= 33:
        priv = btc.safe_hexlify(priv)
    pub = btc.privkey_to_pubkey(priv)
    address = btc.pubkey_to_address(pub)
    signing_tx = btc.signature_form(tx, i, btc.mk_pubkey_script(address),
                                    hashcode)

    msghash = btc.bin_txhash(signing_tx, hashcode)
    z = btc.hash_to_int(msghash)
    # k = deterministic_generate_k(msghash, priv)
    r, y = fast_multiply(G, k)
    s = inv(k, N) * (z + r * decode_privkey(priv)) % N
    rawsig = 27 + (y % 2), r, s

    sig = der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2)
    # sig = ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = btc.deserialize(tx)
    txobj["ins"][i]["script"] = btc.serialize_script([sig, pub])
    return btc.serialize(txobj)
Exemple #34
0
def segwit_signature_form(tx, i, script, amount, hashcode=SIGHASH_ALL):
    d = deserialize(tx)

    def parse_vout(o):
        return b''.join([struct.pack('<Q', o['value']),
                         struct.pack('B', len(o['script']) // 2),
                         binascii.unhexlify(o['script'])])
    def parse_vin(inp):
        return b''.join([binascii.unhexlify(inp['outpoint']['hash'])[::-1],
                         struct.pack('<I', (inp['outpoint']['index']))])

    vin_outpoint = [binascii.unhexlify(d['ins'][i]['outpoint']['hash'])[::-1],
                    struct.pack('<I', (d['ins'][i]['outpoint']['index']))]
    hashcode_strategy = get_hashcode_strategy(hashcode)
    outpoints = [parse_vin(inp) for inp in hashcode_strategy.get_inputs_for_sequences(d, i)]
    sequences = hashcode_strategy.get_sequences(d, i)
    outputs_to_sign = hashcode_strategy.get_outputs(d, i)
    outputs = [parse_vout(out) for out in outputs_to_sign]

    hash_outputs = hashlib.sha256(hashlib.sha256(b''.join(outputs)).digest()).digest() if outputs_to_sign else b'\x00'*32
    hash_sequences = hashlib.sha256(hashlib.sha256(b''.join(sequences)).digest()).digest() if sequences else b'\x00'*32
    hash_outpoints = hashlib.sha256(hashlib.sha256(b''.join(outpoints)).digest()).digest() if outpoints else b'\x00'*32

    preimage = [struct.pack('<I', d['version']),
                hash_outpoints,
                hash_sequences,
                b''.join(vin_outpoint),
                struct.pack('B', len(script) // 2),
                binascii.unhexlify(script),
                struct.pack('<Q', amount),
                struct.pack('<I', d['ins'][i]['sequence']),
                hash_outputs,
                struct.pack('<I', d['locktime']),
                struct.pack('<I', hashcode)]
    return binascii.hexlify(b''.join(preimage)).decode('ascii')
Exemple #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)
Exemple #36
0
def normalize_transaction(tx):
    _tx = deserialize(tx)
    _tx['segwit'] = True
    for i, vin in enumerate(_tx['ins']):
        if vin.get('txinwitness', '0' * 64) == '0' * 64:
            _tx['ins'][i]['txinwitness'] = ''
    return serialize(_tx)
Exemple #37
0
def sign_donation_tx(tx, i, priv):
    from bitcoin.main import fast_multiply, decode_privkey, G, inv, N
    from bitcoin.transaction import der_encode_sig
    k = sign_k
    hashcode = btc.SIGHASH_ALL
    i = int(i)
    if len(priv) <= 33:
        priv = btc.safe_hexlify(priv)
    pub = btc.privkey_to_pubkey(priv)
    address = btc.pubkey_to_address(pub)
    signing_tx = btc.signature_form(
            tx, i, btc.mk_pubkey_script(address), hashcode)

    msghash = btc.bin_txhash(signing_tx, hashcode)
    z = btc.hash_to_int(msghash)
    # k = deterministic_generate_k(msghash, priv)
    r, y = fast_multiply(G, k)
    s = inv(k, N) * (z + r * decode_privkey(priv)) % N
    rawsig = 27 + (y % 2), r, s

    sig = der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2)
    # sig = ecdsa_tx_sign(signing_tx, priv, hashcode)
    txobj = btc.deserialize(tx)
    txobj["ins"][i]["script"] = btc.serialize_script([sig, pub])
    return btc.serialize(txobj)
Exemple #38
0
def main():
    parser = OptionParser(
        usage=
        'usage: %prog [options] utxo destaddr1 destaddr2 ..',
        description="For creating multiple utxos from one (for commitments in JM)."
                    "Provide a utxo in form txid:N that has some unspent coins;"
                    "Specify a list of destination addresses and the coins will"
                    "be split equally between them (after bitcoin fees)."

                    "You'll be prompted to enter the private key for the utxo"
                    "during the run; it must be in WIF compressed format."
                    "After the transaction is completed, the utxo strings for"

                    "the new outputs will be shown."
                    "Note that these utxos will not be ready for use as external"

                    "commitments in Joinmarket until 5 confirmations have passed."
                    " BE CAREFUL about handling private keys!"
                    " Don't do this in insecure environments."
                    " Also note this ONLY works for standard (p2pkh) utxos."
    )
    parser.add_option(
        '-v',
        '--validate-utxos',
        action='store_true',
        dest='validate',
        help='validate the utxos and pubkeys provided against the blockchain',
        default=False
    )
    parser.add_option(
        '-o',
        '--validate-only',
        action='store_true',
        dest='vonly',
        help='only validate the provided utxos (file or command line), not add',
        default=False
    )
    (options, args) = parser.parse_args()
    load_program_config()
    if len(args) < 2:
        quit(parser, 'Invalid syntax')
    u = args[0]
    priv = raw_input(
        'input private key for ' + u + ', in WIF compressed format : ')
    u, priv = get_utxo_info(','.join([u, priv]))
    if not u:
        quit(parser, "Failed to parse utxo info: " + u)
    destaddrs = args[1:]
    for d in destaddrs:
        if not validate_address(d):
            quit(parser, "Address was not valid; wrong network?: " + d)
    txsigned = sign(u, priv, destaddrs)
    log.debug("Got signed transaction:\n" + txsigned)
    log.debug("Deserialized:")
    log.debug(pformat(btc.deserialize(txsigned)))
    if raw_input('Would you like to push to the network? (y/n):')[0] != 'y':
        log.debug("You chose not to broadcast the transaction, quitting.")
        return
    jm_single().bc_interface.pushtx(txsigned)
Exemple #39
0
def main():
    locktime = args.locktime
    privkey = args.privkey
    address = args.address

    script = getRedeemScript(locktime, privkey)
    ins, balance = getBalance(scriptaddr(script, 50))
    len_inputs = len(ins)

    tx = ''

    if balance > 0 and check_addr(address) and is_privkey(privkey):
        # Fee
        fee = round(base_fee + fee_per_input * len_inputs, 8)

        # Outputs
        out_value = int((balance - fee) * COIN)
        outs = [{'address' : address, 'value' : out_value}]

        # Make unsigned transaction
        tx = mktx(ins, outs)

        # Append nLockTime and reset nSequence
        unpacked = deserialize(tx)
        unpacked['locktime'] = locktime
        for i in range(len_inputs):
            unpacked['ins'][i]['sequence'] = 0
        tx = serialize(unpacked)

        # get all signatures
        sigs = []
        for i in range(len_inputs):
            sigs.append(multisign(tx, i, script, privkey))

        # sign inputs
        unpacked = deserialize(tx)
        for i in range(len_inputs):
            unpacked['ins'][i]['script'] = getLen(sigs[i]) + sigs[i]
            unpacked['ins'][i]['script'] += getLen(script) + script
        tx = serialize(unpacked)

    print('> BALANCE (%s): %f' % (scriptaddr(script, 50), balance))

    if len(tx) > 0:
        txid = broadcast(tx)
        print('> RESPONSE: %s' % txid.text)
    def do_HEAD(self):
        pages = ('/walletnotify?', '/alertnotify?')

        if self.path.startswith('/walletnotify?'):
            txid = self.path[len(pages[0]):]
            if not re.match('^[0-9a-fA-F]*$', txid):
                log.debug('not a txid')
                return
            tx = self.btcinterface.rpc('getrawtransaction', [txid])
            if not re.match('^[0-9a-fA-F]*$', tx):
                log.debug('not a txhex')
                return
            txd = btc.deserialize(tx)
            tx_output_set = set([(sv['script'], sv['value']) for sv in txd[
                'outs']])

            unconfirmfun, confirmfun = None, None
            for tx_out, ucfun, cfun in self.btcinterface.txnotify_fun:
                if tx_out == tx_output_set:
                    unconfirmfun = ucfun
                    confirmfun = cfun
                    break
            if unconfirmfun is None:
                log.debug('txid=' + txid + ' not being listened for')
            else:
                # on rare occasions people spend their output without waiting
                #  for a confirm
                txdata = None
                for n in range(len(txd['outs'])):
                    txdata = self.btcinterface.rpc('gettxout', [txid, n, True])
                    if txdata is not None:
                        break
                assert txdata is not None
                if txdata['confirmations'] == 0:
                    unconfirmfun(txd, txid)
                    # TODO pass the total transfered amount value here somehow
                    # wallet_name = self.get_wallet_name()
                    # amount =
                    # bitcoin-cli move wallet_name "" amount
                    log.debug('ran unconfirmfun')
                else:
                    confirmfun(txd, txid, txdata['confirmations'])
                    self.btcinterface.txnotify_fun.remove(
                            (tx_out, unconfirmfun, confirmfun))
                    log.debug('ran confirmfun')

        elif self.path.startswith('/alertnotify?'):
            jm_single().core_alert[0] = urllib.unquote(self.path[len(pages[1]):])
            log.debug('Got an alert!\nMessage=' + jm_single().core_alert[0])

        else:
            log.debug('ERROR: This is not a handled URL path.  You may want to check your notify URL for typos.')

        os.system('curl -sI --connect-timeout 1 http://localhost:' + str(
                self.base_server.server_address[1] + 1) + self.path)
        self.send_response(200)
        # self.send_header('Connection', 'close')
        self.end_headers()
    def do_HEAD(self):
        pages = ('/walletnotify?', '/alertnotify?')

        if self.path.startswith('/walletnotify?'):
            txid = self.path[len(pages[0]):]
            if not re.match('^[0-9a-fA-F]*$', txid):
                log.debug('not a txid')
                return
            tx = self.btcinterface.rpc('getrawtransaction', [txid])
            if not re.match('^[0-9a-fA-F]*$', tx):
                log.debug('not a txhex')
                return
            txd = btc.deserialize(tx)
            tx_output_set = set([(sv['script'], sv['value']) for sv in txd[
                'outs']])

            unconfirmfun, confirmfun = None, None
            for tx_out, ucfun, cfun in self.btcinterface.txnotify_fun:
                if tx_out == tx_output_set:
                    unconfirmfun = ucfun
                    confirmfun = cfun
                    break
            if unconfirmfun is None:
                log.debug('txid=' + txid + ' not being listened for')
            else:
                # on rare occasions people spend their output without waiting
                #  for a confirm
                txdata = None
                for n in range(len(txd['outs'])):
                    txdata = self.btcinterface.rpc('gettxout', [txid, n, True])
                    if txdata is not None:
                        break
                assert txdata is not None
                if txdata['confirmations'] == 0:
                    unconfirmfun(txd, txid)
                    # TODO pass the total transfered amount value here somehow
                    # wallet_name = self.get_wallet_name()
                    # amount =
                    # bitcoin-cli move wallet_name "" amount
                    log.debug('ran unconfirmfun')
                else:
                    confirmfun(txd, txid, txdata['confirmations'])
                    self.btcinterface.txnotify_fun.remove(
                            (tx_out, unconfirmfun, confirmfun))
                    log.debug('ran confirmfun')

        elif self.path.startswith('/alertnotify?'):
            jm_single().core_alert[0] = urllib.unquote(self.path[len(pages[1]):])
            log.debug('Got an alert!\nMessage=' + jm_single().core_alert[0])

        else:
            log.debug('ERROR: This is not a handled URL path.  You may want to check your notify URL for typos.')

        os.system('curl -sI --connect-timeout 1 http://localhost:' + str(
                self.base_server.server_address[1] + 1) + self.path)
        self.send_response(200)
        # self.send_header('Connection', 'close')
        self.end_headers()
Exemple #42
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 = self.sign_tx(tx, index, self.wallet.get_key_from_addr(addr))
		self.latest_tx = btc.deserialize(tx)
Exemple #43
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
Exemple #44
0
def get_postings():
    """
    Retrive all books for sale in the mempool

    Returns:
        current_postings (list): list of current postings
            each element is tuple of (poster, isbn, price, quality)
    """
    postings = []
    canceled_postings = []
    current_postings = []
    txs = bitcoin.history(settings.MARKET_ADDRESS)
    for tx in txs:
        poster, isbn, price = None, None, None
        fetched = bitcoin.fetchtx(tx['output'].split(':')[0])
        tx_outputs = bitcoin.deserialize(fetched)['outs']
        tx_inputs = bitcoin.deserialize(
            bitcoin.fetchtx(
                bitcoin.deserialize(fetched)['ins'][0]['outpoint']
                ['hash']))['outs']
        for input in tx_inputs:
            if input['script'].startswith('76a914'):
                try:
                    text = input['script'].lstrip('76a914').rstrip('88ac')
                    poster = bitcoin.hex_to_b58check(text)
                except:
                    pass
        for output in tx_outputs:
            if output['script'].startswith('6a'):
                text = str(binascii.unhexlify(output['script'][2:]))
                components = text.split('-')
        if len(components) == 3:
            isbn, price, quality = components
            isbn = isbn[-10:]
        if poster and isbn and price and quality:
            if price == '0':
                canceled_postings.append((poster, isbn))
            else:
                postings.append((poster, isbn, price, quality))
    for posting in postings:
        if (posting[0], posting[1]) not in canceled_postings:
            current_postings.append(posting)
    return list(set(current_postings))
def create_testing_cjtx(counterparty_list):
    msgchan_pushtx_count[0] = dict(zip(counterparty_list, [0]*
        len(counterparty_list)))
    self_pushtx_count[0] = 0
    orders = zip(counterparty_list, [[]]*len(counterparty_list))
    input_utxos = {'utxo-hex-here': {'value': 0, 'address': '1addr'}}

    cjtx = CoinJoinTX(DummyMessageChannel(), None, None, 0, orders, input_utxos
        , '1cjaddr', '1changeaddr', 0, None, None, dummy_commitment_creator)
    cjtx.latest_tx = btc.deserialize(sample_tx_hex)
    return cjtx
Exemple #46
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 = self.sign_tx(tx, index, self.wallet.get_key_from_addr(addr))
     self.latest_tx = btc.deserialize(tx)
Exemple #47
0
def create_testing_cjtx(counterparty_list):
    msgchan_pushtx_count[0] = dict(zip(counterparty_list, [0]*
        len(counterparty_list)))
    self_pushtx_count[0] = 0
    orders = zip(counterparty_list, [[]]*len(counterparty_list))
    input_utxos = {'utxo-hex-here': {'value': 0, 'address': '1addr'}}

    cjtx = CoinJoinTX(DummyMessageChannel(), None, None, 0, orders, input_utxos
        , '1cjaddr', '1changeaddr', 0, None, None, None)
    cjtx.latest_tx = btc.deserialize(sample_tx_hex)
    return cjtx
Exemple #48
0
def get_txn_outputs(raw_tx_hex, output_addr_list, coin_symbol):
    '''
    Used to verify a transaction hex does what's expected of it.

    Must supply a list of output addresses so that the library can try to
    convert from script to address using both pubkey and script.

    Returns a list of the following form:
        [{'value': 12345, 'address': '1abc...'}, ...]

    Uses @vbuterin's decoding methods.
    '''
    # Defensive checks:
    err_msg = 'Library not able to parse %s transactions' % coin_symbol
    assert lib_can_deserialize_cs(coin_symbol), err_msg
    assert isinstance(output_addr_list, (list, tuple))
    for output_addr in output_addr_list:
        assert is_valid_address_for_coinsymbol(output_addr,
                                               coin_symbol), output_addr

    output_addr_set = set(output_addr_list)  # speed optimization

    outputs = []
    deserialized_tx = deserialize(str(raw_tx_hex))
    for out in deserialized_tx.get('outs', []):
        output = {'value': out['value']}

        # determine if the address is a pubkey address, script address, or op_return
        pubkey_addr = script_to_address(
            out['script'],
            vbyte=COIN_SYMBOL_MAPPINGS[coin_symbol]['vbyte_pubkey'])
        script_addr = script_to_address(
            out['script'],
            vbyte=COIN_SYMBOL_MAPPINGS[coin_symbol]['vbyte_script'])
        nulldata = out['script'] if out['script'][0:2] == '6a' else None
        if pubkey_addr in output_addr_set:
            address = pubkey_addr
            output['address'] = address
        elif script_addr in output_addr_set:
            address = script_addr
            output['address'] = address
        elif nulldata:
            output['script'] = nulldata
            output['script_type'] = 'null-data'
        else:
            raise Exception(
                'Script %s Does Not Contain a Valid Output Address: %s' % (
                    out['script'],
                    output_addr_set,
                ))

        outputs.append(output)
    return outputs
Exemple #49
0
 def test_native_P2WSH_SIGHASH_SINGLE(self):
     tx = TEST_CASES[1]
     deserialized = deserialize(tx['unsigned'])
     serialized = serialize(deserialized)
     self.assertEqual(serialized, tx['unsigned'])
     self.assertEqual(deserialized['locktime'], tx['locktime'])
     ins = self.get_pybtc_vins(tx)
     outs = self.get_pybtc_outs(tx)
     generated_tx = mktx(ins, outs)
     stripped_tx = strip_witness_data(generated_tx)
     self.assertEqual(stripped_tx, serialized)
     partially_signed = p2pk_sign(stripped_tx,
                                  0,
                                  self.append_compressed_flag_to_privkey(
                                      tx['ins'][0]['privkey']),
                                  hashcode=SIGHASH_ALL)
     priv0 = self.append_compressed_flag_to_privkey(
         tx['ins'][1]['privkeys'][0])
     priv1 = self.append_compressed_flag_to_privkey(
         tx['ins'][1]['privkeys'][1])
     pub0 = privtopub(priv0)
     pub1 = privtopub(priv1)
     REDEEM_SCRIPT_STRUCTURE = {
         'keys': [pub0, pub1],
         'schema': [{
             'reqs': 1,
             'keys': [0],
         }, {
             'reqs': 1,
             'keys': [1],
         }]
     }
     witness_script = mk_OPCS_multisig_script(REDEEM_SCRIPT_STRUCTURE)
     sign1 = segwit_multisign(partially_signed,
                              1,
                              witness_script,
                              priv0,
                              49 * 10**8,
                              hashcode=SIGHASH_SINGLE)
     sign2 = segwit_multisign(partially_signed,
                              1,
                              witness_script,
                              priv1,
                              49 * 10**8,
                              hashcode=SIGHASH_SINGLE,
                              separator_index=1)
     signed = apply_segwit_multisignatures(partially_signed,
                                           1,
                                           witness_script, [sign2, sign1],
                                           dummy=False)
     self.assertEqual(signed, tx['signed'])
     print('[Native P2WSH] SIGHASH_SINGLE OK')
Exemple #50
0
def checkTransaction(transactiontext):
    try:
        transactiontext.strip()
        deserialized = bitcoin.deserialize(transactiontext)
        for item in deserialized['outs']:
            out = item['script']
            subString = out[6:len(out) - 4]
            add = bitcoin.hex_to_b58check(subString, 111)
            if add == bitcoinAddress:
                return True
        return False
    except:
        return False
Exemple #51
0
def segwit_signature_form(tx, i, script, amount, hashcode=SIGHASH_ALL):
    d = deserialize(tx)

    def parse_vout(o):
        return b''.join([
            struct.pack('<Q', o['value']),
            struct.pack('B',
                        len(o['script']) // 2),
            binascii.unhexlify(o['script'])
        ])

    def parse_vin(inp):
        return b''.join([
            binascii.unhexlify(inp['outpoint']['hash'])[::-1],
            struct.pack('<I', (inp['outpoint']['index']))
        ])

    vin_outpoint = [
        binascii.unhexlify(d['ins'][i]['outpoint']['hash'])[::-1],
        struct.pack('<I', (d['ins'][i]['outpoint']['index']))
    ]
    hashcode_strategy = get_hashcode_strategy(hashcode)
    outpoints = [
        parse_vin(inp)
        for inp in hashcode_strategy.get_inputs_for_sequences(d, i)
    ]
    sequences = hashcode_strategy.get_sequences(d, i)
    outputs_to_sign = hashcode_strategy.get_outputs(d, i)
    outputs = [parse_vout(out) for out in outputs_to_sign]

    hash_outputs = hashlib.sha256(hashlib.sha256(b''.join(
        outputs)).digest()).digest() if outputs_to_sign else b'\x00' * 32
    hash_sequences = hashlib.sha256(
        hashlib.sha256(b''.join(
            sequences)).digest()).digest() if sequences else b'\x00' * 32
    hash_outpoints = hashlib.sha256(
        hashlib.sha256(b''.join(
            outpoints)).digest()).digest() if outpoints else b'\x00' * 32

    preimage = [
        struct.pack('<I', d['version']), hash_outpoints, hash_sequences,
        b''.join(vin_outpoint),
        struct.pack('B',
                    len(script) // 2),
        binascii.unhexlify(script),
        struct.pack('<Q', amount),
        struct.pack('<I', d['ins'][i]['sequence']), hash_outputs,
        struct.pack('<I', d['locktime']),
        struct.pack('<I', hashcode)
    ]
    return binascii.hexlify(b''.join(preimage)).decode('ascii')
Exemple #52
0
def get_messages():
    """
    Gets inbox messages from the mempool

    Returns:
        messages (dict): dict of messages
            {sender: {message_num: {submessage_num: message}}}
    """
    messages = defaultdict(dict)
    priv, pub, addr = books.read_wallet()
    txs = bitcoin.history(addr)
    for tx in txs:
        sender, message_num, submessage_num, message = None, None, None, None
        fetched = bitcoin.fetchtx(tx['output'].split(':')[0])
        tx_outputs = bitcoin.deserialize(fetched)['outs']
        tx_inputs = bitcoin.deserialize(
            bitcoin.fetchtx(
                bitcoin.deserialize(fetched)['ins'][0]['outpoint']
                ['hash']))['outs']
        for output in tx_outputs:
            if output['script'].startswith('6a'):
                text = str(binascii.unhexlify(output['script'].lstrip('6a')))
                message_num = text[1]
                submessage_num = text[2]
                message = text[3:]
        for input in tx_inputs:
            try:
                if input['script'].startswith('76a914'):
                    text = input['script'].lstrip('76a914').rstrip('88ac')
                    sender = bitcoin.hex_to_b58check(text)
            except:
                pass
        if sender and message:
            if sender != addr:
                if sender not in messages:
                    messages[sender] = defaultdict(dict)
                messages[sender][message_num].update({submessage_num: message})
    return messages
Exemple #53
0
def apply_segwit_multisignatures(tx,
                                 i,
                                 witness_program,
                                 signatures,
                                 dummy=True,
                                 nested=False):
    txobj = deserialize(tx)
    signed = apply_segwit_multisignatures_deserialized_data(txobj,
                                                            i,
                                                            witness_program,
                                                            signatures,
                                                            dummy=dummy,
                                                            nested=nested)
    return serialize(signed)
Exemple #54
0
def apply_segwit_multisignatures(tx,
                                 i,
                                 witness_program,
                                 signatures,
                                 dummy=True,
                                 nested=False):
    o = [""] + signatures + [witness_program
                             ] if dummy else signatures + [witness_program]
    txobj = deserialize(tx)
    txobj['ins'][i]['txinwitness'] = o
    if nested:
        redeem_script = hashlib.sha256(
            binascii.unhexlify(witness_program)).hexdigest()
        length = len(redeem_script) // 2
        redeem_script = serialize_script([length + 2, None, redeem_script])
        txobj["ins"][i]["script"] = redeem_script
    return serialize(txobj)
def list_purchases(obj):
    txs, heights = obj['txs'], obj['heights']
    process_queue = []
    for h in txs:
        txhex = str(txs[h])
        txouts = b.deserialize(txhex)['outs']
        if len(txouts) >= 2 and txouts[0]['value'] >= minimum - 30000:
            addr = b.script_to_address(txouts[0]['script'])
            if addr == exodus:
                v = txouts[0]['value'] + 30000
                process_queue.append({
                    "tx":
                    h,
                    "addr":
                    b.b58check_to_hex(b.script_to_address(
                        txouts[1]['script'])),
                    "value":
                    v,
                    "height":
                    heights[h]
                })
            else:
                sys.stderr.write(
                    "Non-purchase tx found (not to exodus): %s\n" % h)
        elif len(txouts) == 1:
            sys.stderr.write("Non-purchase tx found (single output): %s\n" % h)
        else:
            sys.stderr.write(
                "Non-purchase tx found (insufficient value): %s\n" % h)
    sys.stderr.write('Gathered outputs, collecting block timestamps\n')
    # Determine the timestamp for every block height. We care about
    # the timestamp of the previous confirmed block before a transaction.
    # Save the results as a dictionary of transaction data
    o = []
    for i in range(0, len(process_queue), 20):
        subpq = process_queue[i:i + 20]
        t = get_block_timestamp([x['height'] - 1 for x in subpq])
        assert len(t) == len(subpq), [x['height'] - 1 for x in subpq]
        o.extend([{
            "tx": _a["tx"],
            "addr": _a["addr"],
            "value": _a["value"],
            "time": _b
        } for _a, _b in zip(subpq, t)])
        sys.stderr.write('Collected timestamps: %d\n' % len(o))
    return o
    def test_encode_decode(self):
        transaction = "010000000001019fa7fad392a29f74d124a8770d24e23f0fcc3e3007e756e4114e4b950a5cf37a0200000000f" \
                      "fffffff02402d0e20000000001976a914c0123fd352e7f53a9c4c0e512c490e1a6817dffa88acb19066000000" \
                      "0000220020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d040048304502210" \
                      "0f227d07b7ca8bef3b9d591fc46803b1fc6b41290b3b229064726eee5c3d6fc8b02206450b248d4d035a121e6" \
                      "92d7a0e1b720801e1fd30255f5d1f099dbca61eb92dc01483045022100966181ecf84d9a75be1c7654a29ce2a" \
                      "1cba32b2bfb9988d6564ae3bc7358420702200a5e54430e1a9c4537c84d9159243cbfe020fbac2fa7e09b8cd6" \
                      "efb08c984432016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c210" \
                      "3a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3" \
                      "e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000"

        expected_address = "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej"
        decoded_expected_address = bech32decode(expected_address)
        deserialized = deserialize(transaction)
        assert decoded_expected_address == deserialized['outs'][1]['script']
        re_encoded_address = bech32encode(deserialized['outs'][1]['script'])
        assert re_encoded_address == expected_address