コード例 #1
0
    def getrawtransaction(self, txid, verbose=False):
        """Return transaction with hash txid

        Raises IndexError if transaction not found.

        verbse - If true a dict is returned instead with additional information
                 on the transaction.

        Note that if all txouts are spent and the transaction index is not
        enabled the transaction may not be available.
        """
        try:
            r = self._call('getrawtransaction', b2lx(txid), 1 if verbose else 0)
        except JSONRPCException as ex:
            raise IndexError('%s.getrawtransaction(): %s (%d)' %
                    (self.__class__.__name__, ex.error['message'], ex.error['code']))
        if verbose:
            r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
            del r['hex']
            del r['txid']
            del r['version']
            del r['locktime']
            del r['vin']
            del r['vout']
            r['blockhash'] = lx(r['blockhash']) if 'blockhash' in r else None
        else:
            r = CTransaction.deserialize(unhexlify(r))

        return r
コード例 #2
0
def calculate_tx_fees(coins, currency, tx_hex):
    #Process source TX.
    rpc = coins[currency]["rpc"]["sock"]
    tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))

    #Tally input coins.
    input_total = decimal.Decimal(0)
    for vin in tx.vin:
        txid = b2lx(vin.prevout.hash)
        vin_tx_hex = rpc.getrawtransaction(txid)
        vin_tx = CTransaction.deserialize(binascii.unhexlify(vin_tx_hex))
        input_value = vin_tx.vout[vin.prevout.n].nValue
        input_total += decimal.Decimal(str_money_value(input_value))

    #Tally output coins.
    output_total = decimal.Decimal(0)
    for vout in tx.vout:
        output_value = decimal.Decimal(str_money_value(vout.nValue))
        output_total += output_value

    #TX fees are the difference between the source and
    fees = input_total - output_total

    #Return totals and fees.
    return [input_total, output_total, fees]
コード例 #3
0
ファイル: rpc.py プロジェクト: sdaftuar/replace-by-fee-tools
    def getrawtransaction(self, txid, verbose=False):
        """Return transaction with hash txid

        Raises IndexError if transaction not found.

        verbose - If true a dict is returned instead with additional
        information on the transaction.

        Note that if all txouts are spent and the transaction index is not
        enabled the transaction may not be available.
        """
        try:
            r = self._call("getrawtransaction", b2lx(txid), 1 if verbose else 0)
        except JSONRPCError as ex:
            raise IndexError(
                "%s.getrawtransaction(): %s (%d)" % (self.__class__.__name__, ex.error["message"], ex.error["code"])
            )
        if verbose:
            r["tx"] = CTransaction.deserialize(unhexlify(r["hex"]))
            del r["hex"]
            del r["txid"]
            del r["version"]
            del r["locktime"]
            del r["vin"]
            del r["vout"]
            r["blockhash"] = lx(r["blockhash"]) if "blockhash" in r else None
        else:
            r = CTransaction.deserialize(unhexlify(r))

        return r
コード例 #4
0
ファイル: coinlib.py プロジェクト: robertsdotpm/coinbend
def calculate_tx_fees(coins, currency, tx_hex):
    #Process source TX.
    rpc = coins[currency]["rpc"]["sock"]
    tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))

    #Tally input coins.
    input_total = decimal.Decimal(0)
    for vin in tx.vin:
        txid = b2lx(vin.prevout.hash) 
        vin_tx_hex = rpc.getrawtransaction(txid)
        vin_tx = CTransaction.deserialize(binascii.unhexlify(vin_tx_hex))
        input_value = vin_tx.vout[vin.prevout.n].nValue
        input_total += decimal.Decimal(str_money_value(input_value))

    #Tally output coins.
    output_total = decimal.Decimal(0)
    for vout in tx.vout:
        output_value = decimal.Decimal(str_money_value(vout.nValue))
        output_total += output_value

    #TX fees are the difference between the source and 
    fees = input_total - output_total
    
    #Return totals and fees.
    return [input_total, output_total, fees]
コード例 #5
0
ファイル: funding.py プロジェクト: rustyrussell/lnprototest
    def add_input(self,
                  serial_id: int,
                  prevtx: str,
                  prevtx_vout: int,
                  script_sig: str,
                  sequence: int,
                  privkey: str = None) -> None:
        # the dummy runner sends empty info, skip
        if len(prevtx) == 0:
            return

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

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

        self.inputs.append({'input': txin,
                            'serial_id': serial_id,
                            'sats': prev_vout.nValue,
                            'prev_outscript': prev_vout.scriptPubKey.hex(),
                            'redeemscript': script_sig,
                            'privkey': privkey,
                            })
コード例 #6
0
ファイル: tx.py プロジェクト: mbaniasad/ahunavar
    def refund_tx(self, payer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction refunding the funder of
            the P2SH address.
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([payer_sig + '\x01', OP_FALSE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("refund_tx: TXID is %s", txid)
        self.logger.info("refund_tx: RAW TX is %s", b2x(serial_tx))

        return serial_tx
コード例 #7
0
    def check_refund_works(self, tx_hex, owner_first_sig, owner_second_sig, recipient_sig, actor):
        global error_log_path

        try:
            tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))
            redeem_script = bond_redeem_script(self.ecdsa_us, self.ecdsa_them, self.factory.ecdsa_arbiters[0], actor)
            redeem_script_hash160 = hash160_script(redeem_script)

            print(tx_hex)
            print(redeem_script)

            tx.vin[0].scriptSig = CScript([OP_0, owner_first_sig, owner_second_sig, recipient_sig, redeem_script["bin"]])
            p2sh_script_pub_key = CScript([OP_HASH160, redeem_script_hash160["bin"], OP_EQUAL])
            print(redeem_script_hash160)

            VerifyScript(tx.vin[0].scriptSig, p2sh_script_pub_key, tx, 0, (SCRIPT_VERIFY_P2SH,))
            signed_tx_hex = b2x(tx.serialize())
            return {
                "tx_hex": signed_tx_hex,
                "txid": calculate_txid(signed_tx_hex)
            }
        except Exception as e:
            error = parse_exception(e)
            log_exception(error_log_path, error)
            print(error)
            print("Check refund failed.")
            return None
コード例 #8
0
	def provide_transaction(self, transaction_data):
		self.send_lock.acquire()

		if self.send_transaction_cache.contains(transaction_data):
			self.send_lock.release()
			return
		if len(transaction_data) > self.MAX_RELAY_TRANSACTION_BYTES and (len(transaction_data) > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES or self.send_transaction_cache.get_flag_count() >= MAX_EXTRA_OVERSIZE_TRANSACTIONS):
			self.send_lock.release()
			return

		try:
			relay_data = pack('>3I', self.MAGIC_BYTES, self.TRANSACTION_TYPE, len(transaction_data))
			relay_data += transaction_data
			self.relay_sock.sendall(relay_data)
			self.send_transaction_cache.add(transaction_data, len(transaction_data) > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES)

			if deserialize_utils:
				transaction = CTransaction.deserialize(transaction_data)
				print("Sent transaction " + str(b2lx(transaction.GetHash())) + " of size " + str(len(transaction_data)))
			else:
				print("Sent transaction of size " + str(len(transaction_data)))
		except (OSError, socket.error) as err:
			print("Failed to send to relay node: ", err)

		self.send_lock.release()
コード例 #9
0
ファイル: tx.py プロジェクト: miklobit/TumbleBit
def spend_escrow(serial_tx, redeem_script, payer_sig, redeemer_sig):
    '''
        Sends a transaction fulfilling the redeem script of escrow tx
    '''
    # Read in transaction
    temp_tx = CTransaction.deserialize(serial_tx)
    tx = CMutableTransaction.from_tx(temp_tx)

    txin = tx.vin[0]

    # Set script sig
    txin.scriptSig = CScript([OP_0,
                             payer_sig + '\x01',
                             redeemer_sig + '\x01',
                             redeem_script])

    # Verify script
    redeem_script = CScript(redeem_script)
    serial_tx = tx.serialize()
    VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(),
                 tx, 0, [SCRIPT_VERIFY_P2SH])

    serial_tx = tx.serialize()
    txid = b2lx(Hash(serial_tx))

    print("spend_escrow: TXID is %s" % txid)
    print("spend_escrow: RAW TX is %s" % b2x(serial_tx))

    return serial_tx
コード例 #10
0
def adjust_transaction(tx_hex):
    # if you don't want change you wallet signature code
    # you can use this to adjust high S signature to a canonical signature
    tx = CTransaction.deserialize(x(tx_hex))
    for vin in tx.vin:
        script_lst = list(vin.scriptSig)
        sig = script_lst[0]
        # normal signature format <sig> <pubkey>
        if len(script_lst) == 2 and not IsLowDERSignature(sig):
            low_s_sig = signature_to_low_s(sig)#.encode('hex')
            #print sig.encode('hex'), low_s_sig.encode('hex')
            script_lst[0] = low_s_sig
            vin.scriptSig = CScript(script_lst)
        # 2/2 or 2/3 multisig format <0> <signature> <signature> <redeemscript>
        elif len(script_lst) == 4:
            script_lst_new = []
            for idx, sig in enumerate(script_lst[1:3]):
                if not IsLowDERSignature(sig):
                    low_s_sig = signature_to_low_s(sig)#.encode('hex')
                    #print sig.encode('hex'), low_s_sig.encode('hex')
                    script_lst_new.append(low_s_sig)
                else:
                    script_lst_new.append(sig)
            script_lst_new.append(script_lst[3])
            vin.scriptSig = "\x00" + CScript(script_lst_new)
    return b2x(tx.serialize())
コード例 #11
0
ファイル: signtx.py プロジェクト: trezor/trezor-firmware
def assert_tx_matches(serialized_tx: bytes,
                      hash_link: str,
                      tx_hex: str = None) -> None:
    """Verifies if a transaction is correctly formed."""
    tx_id = hash_link.split("/")[-1]

    parsed_tx = CTransaction.deserialize(serialized_tx)
    assert tx_id == parsed_tx.GetTxid()[::-1].hex()
    if tx_hex:
        assert serialized_tx.hex() == tx_hex

    # TODO: we could probably do better than os.environ, this was the easiest solution
    # (we could create a pytest option (and use config.getoption("check-on-chain")),
    # but then each test would need to have access to config via function argument)
    if int(os.environ.get("CHECK_ON_CHAIN", 0)):

        def get_tx_hex(hash_link: str) -> str:
            tx_data = requests.get(hash_link,
                                   headers={
                                       "User-Agent": "BTC transactions test"
                                   }).json(parse_float=Decimal)

            return tx_data["hex"]

        assert serialized_tx.hex() == get_tx_hex(hash_link)
コード例 #12
0
ファイル: funding.py プロジェクト: cdecker/lnprototest
    def add_input(self,
                  serial_id: int,
                  prevtx: str,
                  prevtx_vout: int,
                  max_witness_len: int,
                  script: str,
                  sequence: int,
                  privkey: str = None) -> None:
        # Find the txid of the transaction
        prev_tx = CTransaction.deserialize(bytes.fromhex(prevtx))
        txin = CTxIn(COutPoint(prev_tx.GetTxid(), prevtx_vout),
                     nSequence=sequence)

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

        self.inputs.append({
            'input': txin,
            'serial_id': serial_id,
            'sats': prev_vout.nValue,
            'prev_outscript': prev_vout.scriptPubKey.hex(),
            'redeemscript': script,
            'max_witness_len': max_witness_len,
            'privkey': privkey,
        })
コード例 #13
0
def cmd_mkwitness(args):
    tx = None
    if args.tx is not None:
        serialized_tx = args.tx
        tx = CTransaction.deserialize(serialized_tx)

    else:
        tx = args.proxy.getrawtransaction(args.txid)

    txproof = TxProof(tx=tx)

    for seal_fd in args.seal_fds:
        seal = BitcoinSingleUseSeal.deserialize(seal_fd.read())

        txinproof = None
        txoutproof = None
        for i, txin in enumerate(txproof.tx.vin):
            if txin.prevout == seal.outpoint:
                txinproof = TxInProof(i=i, txproof=txproof)
                txoutproof = TxOutProof(i=0, txproof=txproof)
                break

        else:
            args.parser.error("Seal '%s' not closed by this transaction" % seal_fd.name)

        witness = BitcoinSealWitness(seal=seal, txinproof=txinproof, txoutproof=txoutproof)

        witness_filename = seal_fd.name + '.witness'
        logging.info("Creating witness file '%s'" % witness_filename)
        with open(seal_fd.name + '.witness', 'xb') as witness_fd:
            witness_fd.write(witness.serialize())
コード例 #14
0
ファイル: tx.py プロジェクト: mbaniasad/ahunavar
    def spend_escrow(self, payer_sig, redeemer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction fulfilling the redeem script of escrow tx
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([
            OP_FALSE, payer_sig + '\x01', redeemer_sig + '\x01', OP_TRUE,
            redeem_script
        ])

        # Verify script
        redeem_script = CScript(redeem_script)
        serial_tx = tx.serialize()
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_escrow: TXID is %s", txid)
        self.logger.info("spend_escrow: RAW TX is %s", b2x(serial_tx))

        return serial_tx
コード例 #15
0
ファイル: rpc.py プロジェクト: bloomark/python-bitcoinlib
    def createrawtransaction(self, *args):
        """Get rawtransactions when provided vin and vout

        FIXME: Implement options and accept outpoints instead of user args
        """
        r = self._call('createrawtransaction', *args)
        r = str(r)
        tx = CTransaction.deserialize(unhexlify(r))
        return tx
コード例 #16
0
def analyze_tx(tx_hex_string):
    output = {}

    # get op_return from transaction
    hex = unhexlify(tx_hex_string)
    deserializedTransaction = CTransaction.deserialize(hex)
    op_return_vout = deserializedTransaction.vout[1].scriptPubKey

    # get redeem script
    redeem_script = ''
    for i in op_return_vout:
        script = bytes(i).decode('utf8')
        if 'REDEEM' in script:
            redeem_script_string = script.replace('REDEEM SCRIPT ', '')
    output['redeemScript'] = redeem_script_string

    # convert redeem script into list
    redeemScript = CScript(unhexlify(redeem_script_string))
    redeem_script_array = []
    for i in redeemScript:
        redeem_script_array.append(i)

    # get redeem script hash (hodl address)
    p2sh_address = P2SHBitcoinAddress.from_redeemScript(redeemScript)
    output['hodlAddress'] = str(p2sh_address)

    # get nlocktime from redeem script
    nlocktime_hex = b2lx(redeem_script_array[0])
    nlocktime = int(nlocktime_hex, 16)
    output['nLockTime'] = nlocktime

    # get authorized key from redeem script
    pubkey = b2x(redeem_script_array[3])

    # get address from authorized key
    pubkey = unhexlify(pubkey)
    P2PKHBitcoinAddress = bitcoin.wallet.P2PKHBitcoinAddress
    addr = P2PKHBitcoinAddress.from_pubkey(pubkey)
    output['authorizedAddress'] = str(addr)

    # get total sent to hodl address
    locked_satoshis = 0
    for i in deserializedTransaction.vout:
        if i.nValue > 0:
            sPK = i.scriptPubKey
            amount = i.nValue
            try:
                vout_p2sh_addr = P2SHBitcoinAddress.from_scriptPubKey(sPK)
                # rewards only paid to really locked funds
                if str(p2sh_address) == str(vout_p2sh_addr):
                    locked_satoshis += amount
            except:
                pass
    output["lockedSatoshis"] = locked_satoshis

    return (output)
コード例 #17
0
    def signrawtransaction(self, tx, *args):
        """Sign inputs for transaction

        FIXME: implement options
        """
        hextx = hexlify(tx.serialize())
        r = self._call('signrawtransaction', hextx, *args)
        r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
        del r['hex']
        return r
コード例 #18
0
 def sign_refund_tx(self, tx_hex, key_no=1, actor="us"):
     key_no -= 1
     if key_no == 0:
         ecdsa = self.ecdsa_us[0]
     if key_no == 1:
         ecdsa = self.ecdsa_us[1]
     tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))
     sighash = SignatureHash(bond_redeem_script(self.ecdsa_us, self.ecdsa_them, self.factory.ecdsa_arbiters[0], actor)["bin"], tx, 0, SIGHASH_ALL)
     seckey = CBitcoinSecret.from_secret_bytes(ecdsa.get_private_key("bin"), compressed=True)
     sig = seckey.sign(sighash) + bytes([SIGHASH_ALL])
     return sig
コード例 #19
0
    def signrawtransactionwithwallet(self, tx, *args):
        """Sign inputs for transaction
            bicoincore >= 0.17.x

        FIXME: implement options
        """
        hextx = hexlify(tx.serialize())
        r = self._call('signrawtransactionwithwallet', hextx, *args)
        r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
        del r['hex']
        return r
コード例 #20
0
def mutate_tx(tx_hex):
    """
    Mutates a raw transaction using TX malleability in the scriptSig (specifically, the OP codes.) This function shouldn't be used beyond testing as it uses an ugly eval() hack.

    https://en.bitcoin.it/wiki/Transaction_Malleability
    """
    tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))
    script_sig = repr(tx.vin[0].scriptSig)[9:]
    script_sig = eval("CScript([OP_1, OP_DROP, " + script_sig)
    tx.vin[0].scriptSig = script_sig
    return b2x(tx.serialize())
コード例 #21
0
ファイル: coinlib.py プロジェクト: robertsdotpm/coinbend
def mutate_tx(tx_hex):
    """
    Mutates a raw transaction using TX malleability in the scriptSig (specifically, the OP codes.) This function shouldn't be used beyond testing as it uses an ugly eval() hack.

    https://en.bitcoin.it/wiki/Transaction_Malleability
    """
    tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))
    script_sig = repr(tx.vin[0].scriptSig)[9:]
    script_sig = eval("CScript([OP_1, OP_DROP, " + script_sig)
    tx.vin[0].scriptSig = script_sig
    return b2x(tx.serialize())
コード例 #22
0
ファイル: stack.py プロジェクト: kryptoc/hashmal
 def set_tx(self):
     """Set the spending transaction and (en|dis)able the input index box."""
     txt = str(self.tx_edit.toPlainText())
     if not txt:
         self.tx = None
         self.input_idx.setEnabled(False)
         self.tx_edit.setToolTip('')
         return
     self.tx = CTransaction.deserialize(txt.decode('hex'))
     self.tx_edit.setToolTip(''.join(['Tx ID: ', bitcoin.core.b2lx(self.tx.GetHash())]))
     self.input_idx.setRange(0, len(self.tx.vin) - 1)
     self.input_idx.setEnabled(True)
コード例 #23
0
    def __init__(self, tx_hex, targetScriptPubkey: CScript):
        self.tx = CTransaction.deserialize(x(tx_hex))
        self.txid = b2lx(self.tx.GetTxid())

        # TODO: assuming there is only one output with targetScriptPubkey
        self.nout = None
        for i, out in enumerate(self.tx.vout):
            if out.scriptPubKey == targetScriptPubkey:
                self.nout = i
                break

        assert self.nout is not None
        self.outpoint = COutPoint(lx(self.txid), self.nout)
コード例 #24
0
 def set_transaction(self, name, tx_hex):
     self.transactions[name]["hex"] = tx_hex
     if tx_hex == None:
         self.transactions[name]["CTransaction"] = None
         self.transactions[name]["txid_hex"] = None
     else:
         self.transactions[name]["CTransaction"] = CTransaction.deserialize(
             binascii.unhexlify(self.transactions[name]["hex"]))
         self.transactions[name]["txid_hex"] = self.calculate_txid(
             self.transactions[name]["hex"])
     self.transactions[name]["is_broadcast"] = 0
     self.transactions[name]["confirmations"] = 0
     self.transactions[name]["malleability_occured"] = 0
コード例 #25
0
    def signrawtransaction(self, tx, *args):
        """Sign inputs for transaction

        FIXME: implement options
        """
        if getattr(tx, "serialize", None) is not None:
            hextx = hexlify(tx.serialize())
        else:
            # then assume we got a raw string already
            hextx = tx
        r = self._call('signrawtransaction', hextx, *args)
        r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
        del r['hex']
        return r
コード例 #26
0
ファイル: rpc.py プロジェクト: skeebuzz/python-bitcoinlib
    def signrawtransaction(self, tx, *args):
        """Sign inputs for transaction

        FIXME: implement options
        """
        if getattr(tx, "serialize", None) is not None:
            hextx = hexlify(tx.serialize())
        else:
            # then assume we got a raw string already
            hextx = tx
        r = self._call('signrawtransaction', hextx, *args)
        r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
        del r['hex']
        return r
コード例 #27
0
    def action(self, runner: 'Runner') -> bool:
        super().action(runner)
        utxo_tx = self.resolve_arg('utxo_tx', runner, self.utxo_tx)
        txid = CTransaction.deserialize(
            bytes.fromhex(utxo_tx)).GetTxid()[::-1].hex()

        runner.init_rbf(
            self, self.find_conn(runner),
            self.resolve_arg('channel_id', runner, self.channel_id),
            self.resolve_arg('amount', runner, self.amount), txid,
            self.resolve_arg('utxo_outnum', runner, self.utxo_outnum),
            self.feerate)

        return True
コード例 #28
0
def sign_setup_tx(tx_hex, redeem_script, ecdsa):
    tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))
    sighash = SignatureHash(redeem_script["bin"], tx, 0, SIGHASH_ALL)

    print(b"Signing = " + sighash)
    
    print(ecdsa.get_public_key())

    seckey = CBitcoinSecret.from_secret_bytes(ecdsa.get_private_key("bin"), compressed=True)
    sig = seckey.sign(sighash) + bytes([SIGHASH_ALL])
    print(b"Pub key = " + ecdsa.get_public_key("bin"))

    print(b"Sig = " + sig)
    print()
    return sig
コード例 #29
0
ファイル: electrum.py プロジェクト: petertodd/ngcccbase
 def get_utxo(self, address):
     """Gets all the Unspent Transaction Outs from a given <address>
     """
     script_pubkey = CBitcoinAddress(address).to_scriptPubKey()
     txs = self.get_response("blockchain.address.get_history", [address])
     spent = {}
     utxos = []
     for tx in txs:
         raw = self.get_raw_transaction(tx["tx_hash"], tx["height"])
         data = CTransaction.deserialize(to_binary(raw))
         for vin in data.vin:
             spent[(to_little_endian_hex(vin.prevout.hash), vin.prevout.n)] = 1
         for outindex, vout in enumerate(data.vout):
             if vout.scriptPubKey == script_pubkey:
                 utxos += [(tx["tx_hash"], outindex, vout.nValue, to_hex(vout.scriptPubKey))]
     return [u for u in utxos if not u[0:2] in spent]
コード例 #30
0
 def get_utxo(self, address):
     script_pubkey = CBitcoinAddress(address).to_scriptPubKey()
     txs = self.get_response('blockchain.address.get_history', [address])
     spent = {}
     utxos = []
     for tx in txs:
         print tx
         raw = self.get_raw_transaction(tx['tx_hash'], tx['height'])
         data = CTransaction.deserialize(to_binary(raw))
         for vin in data.vin:
             spent[(to_little_endian_hex(vin.prevout.hash),
                    vin.prevout.n)] = 1
         for outindex, vout in enumerate(data.vout):
             if vout.scriptPubKey == script_pubkey:
                 utxos += [(tx['tx_hash'], outindex, vout.nValue,
                            to_hex(vout.scriptPubKey))]
     return [u for u in utxos if not u[0:2] in spent]
コード例 #31
0
def spend_preimage(redeem_script, preimages, redeemer_sig, serial_tx):
    """
    Creates a transaction fulfilling the redeem script of the preimage P2SH.

    Arguements:
        redeem_script (bytes): The script that specifies the conditions that a tx has
                        to fulfill to transfer funds from the `funding_tx`
        preimages (list): The preimages that hash into the hash values
                          specified in the `redeem_script`
        redeemer_sig (bytes): The signature of the redeemer on the `serial_tx`
        serial_tx (bytes): The serial transaction

    Returns:
        The serial raw transaction that passes the script verification
    """
    # Read in transaction
    temp_tx = CTransaction.deserialize(serial_tx)
    tx = CMutableTransaction.from_tx(temp_tx)

    txin = tx.vin[0]

    # Setup preimages in reverse order
    script = []
    for p in reversed(preimages):
        script += [p]

    # Create script sig
    txin.scriptSig = CScript([redeemer_sig + '\x01'] + script +
                             [redeem_script])

    # Verify script
    redeem_script = CScript(redeem_script)
    try:
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])
    except ValidationError:
        print("spend_preimage: Script failed to verify")
        return None

    serial_tx = tx.serialize()
    txid = b2lx(Hash(serial_tx))

    print("spend_preimage: TXID is %s" % txid)
    print("spend_preimage: RAW TX is %s" % b2x(serial_tx))

    return serial_tx
コード例 #32
0
ファイル: tx_deserializer.py プロジェクト: kryptoc/hashmal
    def deserialize(self):
        self.clear()
        txt = str(self.raw_tx_edit.toPlainText())
        try:
            txt = txt.decode('hex')
        except Exception:
            self.status_message('Raw transaction must be hex.', True)
            return
        try:
            self.tx = tx = CTransaction.deserialize(txt)
        except Exception:
            self.status_message('Cannot deserialize transaction.', True)
            return

        self.tx_widget.set_tx(tx)

        self.status_message('Deserialized transaction {}'.format(bitcoin.core.b2lx(tx.GetHash())))
コード例 #33
0
    def test_path_from_msg_to_txid(self):
        def T(msg, tx):
            path = path_from_msg_to_txid(msg, tx)
            self.assertEqual(path(msg), tx.GetHash())

        tx = CTransaction.deserialize(x('0100000001e853c9e0c133547fd9e162b1d3860dd0f27d5b9b8a7430d28896c00fbb3f1bc7000000008c49304602210095bcd54ebd0caa7cee75f0f89de472a765e6ef4b98c5fd4b32c7f9d4905db9ae022100ebd3f668e3a1a36d56e30184c27531dbb9fc136c84b1282be562064d86997d1e014104727eb4fdcc90658cd26abe7dcb0ae7297810b15b9e27c32bcf8e3edd934901968806dc18b1276d7273cc4c223feee0070361ed947888a3cef422bebfede96e08ffffffff020065cd1d000000001976a91468c6c2b3c0bc4a8eeb10d16a300d627a31a3b58588ac0008af2f000000001976a9141d87f0a54a1d704ffc70eae83b025698bc0fdcfc88ac00000000'))

        # txid in vin
        T(lx('c71b3fbb0fc09688d230748a9b5b7df2d00d86d3b162e1d97f5433c1e0c953e8'), tx)

        # part of a script
        T(x('1d87f0a54a1d704ffc70eae83b025698bc0fdcfc'), tx)

        # beginning of the tx
        T(x('0100000001e853c9e0c133547fd9'), tx)

        # end of the tx
        T(x('98bc0fdcfc88ac00000000'), tx)
コード例 #34
0
def spend_escrow(redeem_script, payer_sig, redeemer_sig, serial_tx):
    """
    Creates a transaction fulfilling the redeem script of the escrow P2SH.

    Arguements:
        redeem_script (bytes): The script that specifies the conditions that a tx has
                        to fulfill to transfer funds from the `funding_tx`
        payer_sig (bytes): The signature of the payer on the `serial_tx`
        redeemer_sig (bytes): The signature of the redeemer on the `serial_tx`
        serial_tx (bytes): The serial transaction

    Returns:
        The serial raw transaction that passes the script verification
    """
    # Read in transaction
    temp_tx = CTransaction.deserialize(serial_tx)
    tx = CMutableTransaction.from_tx(temp_tx)

    txin = tx.vin[0]

    # Set script sig
    txin.scriptSig = CScript(
        [OP_0, payer_sig + '\x01', redeemer_sig + '\x01', redeem_script])

    # Verify script
    redeem_script = CScript(redeem_script)
    serial_tx = tx.serialize()

    try:
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])
    except ValidationError:
        print("spend_escrow: Script failed to verify")
        return None

    serial_tx = tx.serialize()
    txid = b2lx(Hash(serial_tx))

    print("spend_escrow: TXID is %s" % txid)
    print("spend_escrow: RAW TX is %s" % b2x(serial_tx))

    return serial_tx
コード例 #35
0
def load_test_vectors(name):
    with open(os.path.dirname(__file__) + '/data/' + name, 'r') as fd:
        for test_case in json.load(fd):
            # Comments designated by single length strings
            if len(test_case) == 1:
                continue
            assert len(test_case) == 3

            prevouts = {}
            for json_prevout in test_case[0]:
                assert len(json_prevout) == 3
                n = json_prevout[1]
                if n == -1:
                    n = 0xffffffff
                prevout = COutPoint(lx(json_prevout[0]), n)
                prevouts[prevout] = parse_script(json_prevout[2])

            tx = CTransaction.deserialize(x(test_case[1]))
            enforceP2SH = test_case[2]

            yield (prevouts, tx, enforceP2SH)
コード例 #36
0
    def fundrawtransaction(self, tx, include_watching=False):
        """Add inputs to a transaction until it has enough in value to meet its out value.

        include_watching - Also select inputs which are watch only

        Returns dict:

        {'tx':        Resulting tx,
         'fee':       Fee the resulting transaction pays,
         'changepos': Position of added change output, or -1,
        }
        """
        hextx = hexlify(tx.serialize())
        r = self._call('fundrawtransaction', hextx, include_watching)

        r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
        del r['hex']

        r['fee'] = int(r['fee'] * COIN)

        return r
コード例 #37
0
ファイル: rpc.py プロジェクト: petertodd/replace-by-fee-tools
    def fundrawtransaction(self, tx, include_watching=False):
        """Add inputs to a transaction until it has enough in value to meet its out value.

        include_watching - Also select inputs which are watch only

        Returns dict:

        {'tx':        Resulting tx,
         'fee':       Fee the resulting transaction pays,
         'changepos': Position of added change output, or -1,
        }
        """
        hextx = hexlify(tx.serialize())
        r = self._call('fundrawtransaction', hextx, include_watching)

        r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
        del r['hex']

        r['fee'] = int(r['fee'] * COIN)

        return r
コード例 #38
0
def load_test_vectors(name):
    with open(os.path.dirname(__file__) + '/data/' + name, 'r') as fd:
        for test_case in json.load(fd):
            # Comments designated by single length strings
            if len(test_case) == 1:
                continue
            assert len(test_case) == 3

            prevouts = {}
            for json_prevout in test_case[0]:
                assert len(json_prevout) == 3
                n = json_prevout[1]
                if n == -1:
                    n = 0xffffffff
                prevout = COutPoint(lx(json_prevout[0]), n)
                prevouts[prevout] = parse_script(json_prevout[2])

            tx = CTransaction.deserialize(x(test_case[1]))
            enforceP2SH = test_case[2]

            yield (prevouts, tx, enforceP2SH)
コード例 #39
0
ファイル: tx.py プロジェクト: mbaniasad/ahunavar
    def get_keys_from_tx(self, serial_tx, n_keys=15):
        '''Extracts n_keys from tx in serial form'''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        # Keys are in txin.scriptSig
        txin = tx.vin[0]
        script = txin.scriptSig

        # Extract keys from script
        keys = []
        for i, op in enumerate(script):
            if i in range(1, n_keys + 1):
                keys += [op]

        # Serialize keys in correct order
        serial_keys = ""
        for op in reversed(keys):
            serial_keys += op

        return serial_keys
コード例 #40
0
def check_setup_works(tx_hex, redeem_script, owner_first_sig, owner_second_sig, third_party_sig):
    try:
        tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))
        redeem_script_hash160 = hash160_script(redeem_script)

        if owner_first_sig != None and owner_second_sig != None and third_party_sig != None:
            tx.vin[0].scriptSig = CScript([OP_0, owner_first_sig, owner_second_sig, third_party_sig, redeem_script["bin"]])
        p2sh_script_pub_key = CScript([OP_HASH160, redeem_script_hash160["bin"], OP_EQUAL])

        VerifyScript(tx.vin[0].scriptSig, p2sh_script_pub_key, tx, 0, (SCRIPT_VERIFY_P2SH,))
        signed_tx_hex = b2x(tx.serialize())
        return {
            "tx_hex": signed_tx_hex,
            "txid": calculate_txid(signed_tx_hex)
        }
    except Exception as e:
        error = parse_exception(e)
        log_exception(error_log_path, error)
        print(error)
        print("Check setup works failed.")
        print(e)
        return None
コード例 #41
0
    def deserialize_raw_transaction(raw_transaction: str) -> CTransaction:
        '''
        Checking if transaction can be deserialized (is not corrupted).

        Args:
            raw_transaction (str): transaction to check

        Returns:
            CTransaction: transaction object

        Raises:
            ImpossibleDeserialization: when transaction is corrupted

        Example:
            >>> from clove.network import Litecoin
            >>> network = Litecoin()
            >>> network.deserialize_raw_transaction('0100000001aa25fd5f63cb41d6ee7dd495256046b4c3f17d4540a1b258a06bfefac30da60900000000fdff0047304402201c8869d359b5599ecffd51a96f0a8799392c98c4e15242762ba455e37b1f5d6302203f2974e9afc8d641f9363167df48e5a845a8deba1381bf5a1b549ac04718a1ac01410459cdb91eb7298bc2578dc4e7ac2109ac3cfd9dc9818795c5583e720d2114d540724bf26b4541f683ff51968db627a04eecd1f5cff615b6350dad5fb595f8adf420c480afb333623864901c968022a07dd93fe3c06f5684ea728b8113e17fa91bd9514c5163a61450314a793bf317665ecdc54c2e843bb106aeee158876a91485c0522f6e23beb11cc3d066cd20ed732648a4e66704926db75bb17576a914621f617c765c3caa5ce1bb67f6a3e51382b8da296888ac00000000015a7b0100000000001976a91485c0522f6e23beb11cc3d066cd20ed732648a4e688ac00000000')  # noqa: E501
            CTransaction((CTxIn(COutPoint(lx('09a60dc3fafe6ba058b2a140457df1c3b446602595d47deed641cb635ffd25aa'), 0), CScript([x('304402201c8869d359b5599ecffd51a96f0a8799392c98c4e15242762ba455e37b1f5d6302203f2974e9afc8d641f9363167df48e5a845a8deba1381bf5a1b549ac04718a1ac01'), x('0459cdb91eb7298bc2578dc4e7ac2109ac3cfd9dc9818795c5583e720d2114d540724bf26b4541f683ff51968db627a04eecd1f5cff615b6350dad5fb595f8adf4'), x('c480afb333623864901c968022a07dd93fe3c06f5684ea728b8113e17fa91bd9'), 1, x('63a61450314a793bf317665ecdc54c2e843bb106aeee158876a91485c0522f6e23beb11cc3d066cd20ed732648a4e66704926db75bb17576a914621f617c765c3caa5ce1bb67f6a3e51382b8da296888ac')]), 0x0),), (CTxOut(0.00097114*COIN, CScript([OP_DUP, OP_HASH160, x('85c0522f6e23beb11cc3d066cd20ed732648a4e6'), OP_EQUALVERIFY, OP_CHECKSIG])),), 0, 1, CTxWitness())  # noqa: E501
        '''
        try:
            return CTransaction.deserialize(x(raw_transaction))
        except Exception:
            raise ImpossibleDeserialization()
コード例 #42
0
ファイル: tx.py プロジェクト: mbaniasad/ahunavar
    def spend_preimage(self, preimages, redeemer_sig, serial_tx,
                       redeem_script):
        '''
            Sends a transaction fulfilling the redeem script
            of the preimage P2SH
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Setup preimages in reverse order
        script = []
        for p in reversed(preimages):
            script += [p]

        # Create script sig
        txin.scriptSig = CScript([redeemer_sig + '\x01'] + script +
                                 [OP_TRUE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_preimage: TXID is %s", txid)
        self.logger.info("spend_preimage: RAW TX is %s", b2x(serial_tx))

        return serial_tx
コード例 #43
0
ファイル: connectors.py プロジェクト: tonypius/cert-issuer
 def broadcast_tx(self, transaction):
     as_hex = transaction.as_hex()
     transaction = CTransaction.deserialize(unhexlify(as_hex))
     tx_id = bitcoin.rpc.Proxy().sendrawtransaction(transaction)
     # reverse endianness for bitcoind
     return hexlify(bytearray(tx_id)[::-1])
コード例 #44
0
ファイル: electrum.py プロジェクト: amidvidy/ngcccbase
 def get_tx(self, txhash):
     """Get the transaction object given a transaction hash.
     """
     txhex = self.get_raw_transaction(txhash)
     tx = CTransaction.deserialize(to_binary(txhex))
     return blockchain.CTransaction.from_bitcoincore(txhash, tx, self)
コード例 #45
0
 def get_tx(self, txhash):
     """Get the transaction object given a transaction hash.
     """
     txhex = self.get_raw_transaction(txhash)
     tx = CTransaction.deserialize(to_binary(txhex))
     return blockchain.CTransaction.from_bitcoincore(txhash, tx, self)
コード例 #46
0
    def str_tree(self, indent=0, verbosity=0):
        """Convert to tree (for debugging)"""

        class bcolors:
            HEADER = '\033[95m'
            OKBLUE = '\033[94m'
            OKGREEN = '\033[92m'
            WARNING = '\033[93m'
            FAIL = '\033[91m'
            ENDC = '\033[0m'
            BOLD = '\033[1m'
            UNDERLINE = '\033[4m'

        def str_result(verb, parameter, result):
            rr = ""
            if verb > 0 and result is not None:
                rr += " == "
                result_hex = b2x(result)
                if parameter is not None:
                    parameter_hex = b2x(parameter)
                    try:
                        index = result_hex.index(parameter_hex)
                        parameter_hex_highlight = bcolors.BOLD + parameter_hex + bcolors.ENDC
                        if index == 0:
                            rr += parameter_hex_highlight + result_hex[index+len(parameter_hex):]
                        else:
                            rr += result_hex[0:index] + parameter_hex_highlight
                    except ValueError:
                        rr += result_hex
                else:
                    rr += result_hex

            return rr

        r = ""
        if len(self.attestations) > 0:
            for attestation in sorted(self.attestations):
                r += " "*indent + "verify %s" % str(attestation) + str_result(verbosity, self.msg, None) + "\n"
                if attestation.__class__ == BitcoinBlockHeaderAttestation:
                    r += " "*indent + "# Bitcoin block merkle root " + b2lx(self.msg) + "\n"

        if len(self.ops) > 1:
            for op, timestamp in sorted(self.ops.items()):
                try:
                    CTransaction.deserialize(self.msg)
                    r += " " * indent + "* Bitcoin transaction id " + b2lx(
                        OpSHA256()(OpSHA256()(self.msg))) + "\n"
                except SerializationError:
                    pass
                cur_res = op(self.msg)
                cur_par = op[0]
                r += " " * indent + " -> " + "%s" % str(op) + str_result(verbosity, cur_par, cur_res) + "\n"
                r += timestamp.str_tree(indent+4, verbosity=verbosity)
        elif len(self.ops) > 0:
            try:
                CTransaction.deserialize(self.msg)
                r += " " * indent + "# Bitcoin transaction id " + \
                     b2lx(OpSHA256()(OpSHA256()(self.msg))) + "\n"
            except SerializationError:
                pass
            op = tuple(self.ops.keys())[0]
            cur_res = op(self.msg)
            cur_par = op[0] if len(op) > 0 else None
            r += " " * indent + "%s" % str(op) + str_result(verbosity, cur_par, cur_res) + "\n"
            r += tuple(self.ops.values())[0].str_tree(indent, verbosity=verbosity)

        return r
コード例 #47
0
 def broadcast_tx(self, transaction):
     as_hex = transaction.as_hex()
     transaction = CTransaction.deserialize(h2b(as_hex))
     tx_id = bitcoin.rpc.Proxy().sendrawtransaction(transaction)
     # reverse endianness for bitcoind
     return b2h_rev(tx_id)
コード例 #48
0
ファイル: connectors.py プロジェクト: Akiiki/cert-issuer
def bitcoind_broadcast(hextx):
    tx = CTransaction.deserialize(unhexlify(hextx))
    txid = bitcoin.rpc.Proxy().sendrawtransaction(tx)
    return hexlify(txid)
コード例 #49
0
ファイル: coinlib.py プロジェクト: robertsdotpm/coinbend
def compare_transactions(tx_hex1, tx_hex2):
    """
    This function compares two transactions. It is required
    because attackers can change serialized transactions without
    invalidating the transaction by modifying a scriptSig or
    by changing a signature which would change the transaction
    ID. This function considers transactions equivalent if
    they share the same inputs and outputs. The scriptSig
    doesn't matter for the purposes of this function. The
    risk of replacing a valid transaction with an invalid
    one with false scriptSigs doesn't occur as subsequent
    code [in this module] only replaces transactions if
    they have at least 1 confirmation. I'm sure Bitcoind
    also wouldn't allow invalid transactions into the
    mempool, disk, etc.
    """
    try:
        if tx_hex1 == tx_hex2:
            #Well, that was easy. Now for the hard part.
            return 1
        
        tx1 = CTransaction.deserialize(binascii.unhexlify(tx_hex1))
        tx2 = CTransaction.deserialize(binascii.unhexlify(tx_hex2))
        
        #Compare number of inputs.
        if len(tx1.vin) != len(tx2.vin):
            return 0
        
        #Compare number of outputs.
        if len(tx1.vout) != len(tx2.vout):
            return 0
            
        #Compare nVersion.
        if tx1.nVersion != tx2.nVersion:
            return 0
            
        #Compare nLockTime.
        if tx1.nLockTime != tx2.nLockTime:
            return 0
            
        #Compare inputs.
        for i in range(0, len(tx1.vin)):
            #Compare sequences.
            #To keep it simple: tx replacement isn't supported.
            if tx1.vin[i].nSequence != tx2.vin[i].nSequence:
                return 0
            
            #Compare outpoints.
            if tx1.vin[i].prevout.hash != tx2.vin[i].prevout.hash:
                return 0
            if tx1.vin[i].nSequence != tx2.vin[i].nSequence:
                return 0

        #Compare outputs.
        for i in range(0, len(tx2.vout)):
            if tx1.vout[i] != tx2.vout[i]:
                return 0

        #Sighash and sigs aren't checked as this code is run on TXs returned from *coind.
        
        return 1
    except:
        return 0
コード例 #50
0
    def adjust_refund_tx(self, our_setup_txid, their_setup_tx_hex, their_refund_tx_hex, received_tx_hex=None, their_first_sig=None, their_second_sig=None):
        #Calculate chunk sizes.
        remaining = self.upload_amount - self.trade.sent
        send_chunk_size = self.our_chunk_size
        if send_chunk_size > remaining:
            send_chunk_size = remaining
        remaining = self.download_amount - self.trade.recv
        recv_chunk_size = self.their_chunk_size
        if recv_chunk_size > remaining:
            recv_chunk_size = remaining

        #Validate transactions.
        if received_tx_hex != None and their_first_sig != None and their_second_sig != None:
            #Check their refund spends the output of the bond.
            their_refund_tx = CTransaction.deserialize(binascii.unhexlify(their_refund_tx_hex))
            their_setup_txid = calculate_txid(their_setup_tx_hex)
            if reverse_hex(binascii.hexlify(their_refund_tx.vin[0].prevout.hash).decode("utf-8")) != their_setup_txid:
                print("11111")
                return None
            else:
                """
                try:
                    #Ensure the bond transaction has been broadcast.
                    self.recv_coin_rpc.sendrawtransaction(their_bond_tx_hex)

                    #(Subsequent code will fail since bond has only just been broadcast.)
                    #return None
                except Exception as e:
                    #Transaction already in block chain.
                    pass
                """

            #Check our received payment is as expected.
            unsigned_tx = CTransaction.deserialize(binascii.unhexlify(received_tx_hex))
            expected = self.trade.recv + recv_chunk_size

            #Check transaction input.
            their_alleged_setup_txid = reverse_hex(binascii.hexlify(unsigned_tx.vin[0].prevout.hash).decode("utf-8"))
            if their_alleged_setup_txid != their_setup_txid:
                #Give them the benefit of the doubt - look for tx malluability.
                alleged_setup_tx_hex = recv_coin_rpc.getrawtransaction(their_alleged_setup_txid)
                if not compare_transactions(alleged_setup_tx_hex, their_setup_tx_hex):
                    print("22222222@")
                    return None

            #This is what our output -should- look like.
            our_address = deconstruct_address(self.our_address)["hash"]
            our_pub_key = CScript([OP_DUP, OP_HASH160, our_address, OP_EQUALVERIFY, OP_CHECKSIG])

            #Check an output goes to us with expected amount.
            amount_found = 0
            for output in unsigned_tx.vout:
                print(output.scriptPubKey)
                print(our_pub_key)
                if output.scriptPubKey == our_pub_key:
                    amount_found = Decimal(str_money_value(output.nValue))
                    break
            if not amount_found:
                print(our_pub_key)
                print(unsigned_tx.vout)
                print("333333333333")
                return None
            else:
                #Check amount.
                if amount_found < expected.as_decimal:
                    print("43535345346")
                    print(amount_found)
                    print(expected.as_decimal)
                    return None

            #Check transaction isn't time locked.
            if unsigned_tx.nLockTime:
                print("4444444444")
                return None

            #Check sequences are final.
            for input in unsigned_tx.vin:
                if input.nSequence != 0xffffffff:
                    print("55555555555")
                    return None

            #Check transaction can be spent.
            our_first_sig = self.sign_refund_tx(received_tx_hex, 1, "them")
            ret = self.check_refund_works(received_tx_hex, their_first_sig, their_second_sig, our_first_sig, "them")
            if ret == None:
                print("6666666666666")
                return None
            self.details["our_download"] = ret
        else:
            #The first call to this function has nothing to evaluate -- you are receiving nothing.
            recv_chunk_size = 0

        #Adjust refund.
        refund_amount = self.trade.sent + send_chunk_size
        print("sdfsdfsdf--------")
        print(refund_amount)
        refund_tx_hex = self.build_refund_tx(our_setup_txid, refund_amount)["tx_hex"]
        self.trade.sent += send_chunk_size
        self.trade.recv += recv_chunk_size

        #Save details.
        self.update()

        #Is transfer complete? I.e. no change = transfer complete.
        if send_chunk_size == C(0) and recv_chunk_size == C(0):
            #I liek chocolate milk.
            return 1
        
        #Return result.
        our_first_sig = self.sign_refund_tx(refund_tx_hex, 1)
        our_second_sig = self.sign_refund_tx(refund_tx_hex, 2)
        return {
            "tx_hex": refund_tx_hex,
            "first_sig": our_first_sig,
            "second_sig": our_second_sig
        }
コード例 #51
0
 def ctx_deserialize(cls, ctx):
     serialized_tx = ctx.read_bytes('tx')
     return CTransaction.deserialize(serialized_tx)
コード例 #52
0
    def str_tree(self, indent=0, verbosity=0):
        """Convert to tree (for debugging)"""
        class bcolors:
            HEADER = '\033[95m'
            OKBLUE = '\033[94m'
            OKGREEN = '\033[92m'
            WARNING = '\033[93m'
            FAIL = '\033[91m'
            ENDC = '\033[0m'
            BOLD = '\033[1m'
            UNDERLINE = '\033[4m'

        def str_result(verb, parameter, result):
            rr = ""
            if verb > 0 and result is not None:
                rr += " == "
                result_hex = b2x(result)
                if parameter is not None:
                    parameter_hex = b2x(parameter)
                    try:
                        index = result_hex.index(parameter_hex)
                        parameter_hex_highlight = bcolors.BOLD + parameter_hex + bcolors.ENDC
                        if index == 0:
                            rr += parameter_hex_highlight + result_hex[
                                index + len(parameter_hex):]
                        else:
                            rr += result_hex[0:index] + parameter_hex_highlight
                    except ValueError:
                        rr += result_hex
                else:
                    rr += result_hex

            return rr

        r = ""
        if len(self.attestations) > 0:
            for attestation in sorted(self.attestations):
                r += " " * indent + "verify %s" % str(
                    attestation) + str_result(verbosity, self.msg, None) + "\n"
                if attestation.__class__ == BitcoinBlockHeaderAttestation:
                    r += " " * indent + "# Bitcoin block merkle root " + b2lx(
                        self.msg) + "\n"

        if len(self.ops) > 1:
            for op, timestamp in sorted(self.ops.items()):
                try:
                    CTransaction.deserialize(self.msg)
                    r += " " * indent + "* Bitcoin transaction id " + b2lx(
                        OpSHA256()(OpSHA256()(self.msg))) + "\n"
                except SerializationError:
                    pass
                cur_res = op(self.msg)
                cur_par = op[0]
                r += " " * indent + " -> " + "%s" % str(op) + str_result(
                    verbosity, cur_par, cur_res) + "\n"
                r += timestamp.str_tree(indent + 4, verbosity=verbosity)
        elif len(self.ops) > 0:
            try:
                CTransaction.deserialize(self.msg)
                r += " " * indent + "# Bitcoin transaction id " + \
                     b2lx(OpSHA256()(OpSHA256()(self.msg))) + "\n"
            except SerializationError:
                pass
            op = tuple(self.ops.keys())[0]
            cur_res = op(self.msg)
            cur_par = op[0] if len(op) > 0 else None
            r += " " * indent + "%s" % str(op) + str_result(
                verbosity, cur_par, cur_res) + "\n"
            r += tuple(self.ops.values())[0].str_tree(indent,
                                                      verbosity=verbosity)

        return r
コード例 #53
0
 def broadcast_tx(self, transaction):
     as_hex = transaction.as_hex()
     transaction = CTransaction.deserialize(unhexlify(as_hex))
     tx_id = bitcoin.rpc.Proxy().sendrawtransaction(transaction)
     # reverse endianness for bitcoind
     return hexlify(bytearray(tx_id)[::-1])
コード例 #54
0
if args.testnet:
    bitcoin.SelectParams('testnet')

proxy = bitcoin.rpc.Proxy()

txins = []
prevouts = set()
sum_value_in = 0
line = -1
for l in sys.stdin.readlines():
    line += 1

    l = l.strip()

    try:
        tx = CTransaction.deserialize(x(l))
    except Exception:
        continue


    for txin in tx.vin:
        try:
            txout_info = proxy.gettxout(txin.prevout)
        except IndexError:
            print('Already spent! line %d, txid %s %d' % \
                    (line, b2lx(txin.prevout.hash), txin.prevout.n),
                    file=sys.stderr)
            continue

        print('line %d: %s %d: %s' % \
                (line, b2lx(txin.prevout.hash), txin.prevout.n,
コード例 #55
0
 def __init__(self, txid, rawhex):
     self.ct = CTransaction.deserialize(x(rawhex))
     self.txid = txid
コード例 #56
0
 def deserialize_raw_transaction(raw_transaction: str) -> CTransaction:
     try:
         return CTransaction.deserialize(x(raw_transaction))
     except Exception:
         raise ImpossibleDeserialization()
コード例 #57
0
	def connect(self):
		self.send_lock.acquire()
		self.recv_transaction_cache = FlaggedArraySet(1000)
		self.send_transaction_cache = FlaggedArraySet(1000)
		self.relay_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.relay_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
		try:
			try:
				self.relay_sock.connect((self.server, 8336))
				self.relay_sock.sendall(pack('>3I', self.MAGIC_BYTES, self.VERSION_TYPE, len(self.VERSION_STRING)))
				self.relay_sock.sendall(self.VERSION_STRING)
			finally:
				self.send_lock.release()

			while True:
				msg_header = unpack('>3I', self.relay_sock.recv(3 * 4, socket.MSG_WAITALL))
				if msg_header[0] != self.MAGIC_BYTES:
					raise ProtocolError("Invalid magic bytes: " + str(msg_header[0]) + " != " +  str(self.MAGIC_BYTES))
				if msg_header[2] > 1000000:
					raise ProtocolError("Got message too large: " + str(msg_header[2]))

				if msg_header[1] == self.VERSION_TYPE:
					version = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL)
					if version != self.VERSION_STRING:
						raise ProtocolError("Got back unknown version type " + str(version))
					print("Connected to relay node with protocol version " + str(version))
				elif msg_header[1] == self.BLOCK_TYPE:
					if msg_header[2] > 10000:
						raise ProtocolError("Got a BLOCK message with far too many transactions: " + str(msg_header[2]))

					wire_bytes = 3 * 4

					header_data = self.relay_sock.recv(80, socket.MSG_WAITALL)
					wire_bytes += 80
					self.data_recipient.provide_block_header(header_data)
					if deserialize_utils:
						header = CBlockHeader.deserialize(header_data)
						print("Got block header: " + str(b2lx(header.GetHash())))

					if msg_header[2] < 0xfd:
						block_data = header_data + pack('B', msg_header[2])
					elif msg_header[2] < 0xffff:
						block_data = header_data + b'\xfd' + pack('<H', msg_header[2])
					elif msg_header[2] < 0xffffffff:
						block_data = header_data + b'\xfe' + pack('<I', msg_header[2])
					else:
						raise ProtocolError("WTF?????")

					for i in range(0, msg_header[2]):
						index = unpack('>H', self.relay_sock.recv(2, socket.MSG_WAITALL))[0]
						wire_bytes += 2
						if index == 0xffff:
							data_length = unpack('>HB', self.relay_sock.recv(3, socket.MSG_WAITALL))
							wire_bytes += 3
							data_length = data_length[0] << 8 | data_length[1]
							if data_length > 1000000:
								raise ProtocolError("Got in-block transaction of size > MAX_BLOCK_SIZE: " + str(dat_length))
							transaction_data = self.relay_sock.recv(data_length, socket.MSG_WAITALL)
							wire_bytes += data_length
							if deserialize_utils:
								transaction = CTransaction.deserialize(transaction_data)
								print("Got in-block full transaction: " + str(b2lx(transaction.GetHash())) + " of length " + str(data_length))
							else:
								print("Got in-block full transaction of length " + str(data_length))
							block_data += transaction_data
						else:
							transaction_data = self.recv_transaction_cache.get_by_index(index)
							if transaction_data is None:
								raise ProtocolError("Got index for a transaction we didn't have")
							self.recv_transaction_cache.remove(transaction_data)
							block_data += transaction_data

					self.data_recipient.provide_block(block_data)

					if deserialize_utils:
						print("Got full block " + str(b2lx(header.GetHash())) + " with " + str(msg_header[2]) + " transactions in " + str(wire_bytes) + " wire bytes")
						block = CBlock.deserialize(block_data)
						print("Deserialized full block " + str(b2lx(block.GetHash())))
					else:
						print("Got full block with " + str(msg_header[2]) + " transactions in " + str(wire_bytes) + " wire bytes")

					if unpack('>3I', self.relay_sock.recv(3 * 4, socket.MSG_WAITALL)) != (self.MAGIC_BYTES, self.END_BLOCK_TYPE, 0):
						raise ProtocolError("Invalid END_BLOCK message after block")

				elif msg_header[1] == self.TRANSACTION_TYPE:
					if msg_header[2] > self.MAX_RELAY_TRANSACTION_BYTES and (self.recv_transaction_cache.get_flag_count() >= self.MAX_EXTRA_OVERSIZE_TRANSACTIONS or msg_header[2] > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES):
						raise ProtocolError("Got a freely relayed transaction too large (" + str(msg_header[2]) + ") bytes")
					transaction_data = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL)
					self.recv_transaction_cache.add(transaction_data, msg_header[2] > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES)

					self.data_recipient.provide_transaction(transaction_data)

					if deserialize_utils:
						transaction = CTransaction.deserialize(transaction_data)
						print("Got transaction: " + str(b2lx(transaction.GetHash())))
					else:
						print("Got transaction of length " + str(msg_header[2]))

				elif msg_header[1] == self.MAX_VERSION_TYPE:
					version = self.relay_sock.recv(msg_header[2], socket.MSG_WAITALL)
					print("Relay network now uses version " + str(version) + " (PLEASE UPGRADE)")

				else:
					raise ProtocolError("Unknown message type: " + str(msg_header[1]))

		except (OSError, socket.error) as err:
			print("Lost connect to relay node:", err)
			self.reconnect()
		except ProtocolError as err:
			print("Error processing data from relay node:", err)
			self.reconnect()
		except Exception as err:
			print("Unknown error processing data from relay node:", err)
			self.reconnect()