Example #1
0
def insight_tx(url):
    try:
        f = urllib2.urlopen(url)
    except:
        raise Exception('URL error: %s' % url)
    data = json.load(f)

    t = proto_types.TransactionType()
    t.version = data['version']
    t.lock_time = data['locktime']

    for vin in data['vin']:
        i = t.inputs.add()
        if 'coinbase' in vin.keys():
            i.prev_hash = "\0" * 32
            i.prev_index = 0xffffffff  # signed int -1
            i.script_sig = binascii.unhexlify(vin['coinbase'])
            i.sequence = vin['sequence']

        else:
            i.prev_hash = binascii.unhexlify(vin['txid'])
            i.prev_index = vin['vout']
            asm = vin['scriptSig']['asm'].split(' ')
            asm = [opcode_serialize(x) for x in asm]
            i.script_sig = ''.join(asm)
            i.sequence = vin['sequence']

    for vout in data['vout']:
        o = t.bin_outputs.add()
        o.amount = int(Decimal(vout['value']) * 100000000)
        asm = vout['scriptPubKey']['asm'].split(' ')
        asm = [opcode_serialize(x) for x in asm]
        o.script_pubkey = ''.join(asm)

    return t
Example #2
0
def insight_tx(url, rawdata=False):
    if not rawdata:
        try:
            f = urllib2.urlopen(url)
            data = json.load(f)
        except:
            raise Exception('URL error: %s' % url)
    else:
        data = url

    t = proto_types.TransactionType()
    t.version = data['version']
    t.lock_time = data['locktime']

    for vin in data['vin']:
        i = t.inputs.add()
        if 'coinbase' in vin.keys():
            i.prev_hash = "\0" * 32
            i.prev_index = 0xffffffff  # signed int -1
            i.script_sig = binascii.unhexlify(vin['coinbase'])
            i.sequence = vin['sequence']

        else:
            i.prev_hash = binascii.unhexlify(vin['txid'])
            i.prev_index = vin['vout']
            i.script_sig = binascii.unhexlify(vin['scriptSig']['hex'])
            i.sequence = vin['sequence']

    for vout in data['vout']:
        o = t.bin_outputs.add()
        o.amount = int(Decimal(str(vout['value'])) * 100000000)
        o.script_pubkey = binascii.unhexlify(vout['scriptPubKey']['hex'])

    return t
Example #3
0
    def _prepare_sign_tx(self, coin_name, inputs, outputs):
        tx = types.TransactionType()
        tx.inputs.extend(inputs)
        tx.outputs.extend(outputs)

        txes = {}
        txes[''] = tx

        known_hashes = []
        for inp in inputs:
            if inp.prev_hash in known_hashes:
                continue

            txes[inp.prev_hash] = self.tx_api.get_tx(
                binascii.hexlify(inp.prev_hash))
            known_hashes.append(inp.prev_hash)

        return txes
Example #4
0
    def sign_tx(self, coin_name, inputs, outputs, debug_processor=None):

        start = time.time()
        txes = self._prepare_sign_tx(coin_name, inputs, outputs)

        try:
            self.transport.session_begin()

            # Prepare and send initial message
            tx = proto.SignTx()
            tx.inputs_count = len(inputs)
            tx.outputs_count = len(outputs)
            tx.coin_name = coin_name
            res = self.call(tx)

            # Prepare structure for signatures
            signatures = [None] * len(inputs)
            serialized_tx = ''

            counter = 0
            while True:
                counter += 1

                if isinstance(res, proto.Failure):
                    raise CallException("Signing failed")

                if not isinstance(res, proto.TxRequest):
                    raise CallException("Unexpected message")

                # If there's some part of signed transaction, let's add it
                if res.HasField('serialized') and res.serialized.HasField(
                        'serialized_tx'):
                    log("RECEIVED PART OF SERIALIZED TX (%d BYTES)" %
                        len(res.serialized.serialized_tx))
                    serialized_tx += res.serialized.serialized_tx

                if res.HasField('serialized') and res.serialized.HasField(
                        'signature_index'):
                    if signatures[res.serialized.signature_index] != None:
                        raise Exception(
                            "Signature for index %d already filled" %
                            res.serialized.signature_index)
                    signatures[res.serialized.
                               signature_index] = res.serialized.signature

                if res.request_type == types.TXFINISHED:
                    # Device didn't ask for more information, finish workflow
                    break

                # Device asked for one more information, let's process it.
                current_tx = txes[res.details.tx_hash]

                if res.request_type == types.TXMETA:
                    msg = types.TransactionType()
                    msg.version = current_tx.version
                    msg.lock_time = current_tx.lock_time
                    msg.inputs_cnt = len(current_tx.inputs)
                    if res.details.tx_hash:
                        msg.outputs_cnt = len(current_tx.bin_outputs)
                    else:
                        msg.outputs_cnt = len(current_tx.outputs)
                    res = self.call(proto.TxAck(tx=msg))
                    continue

                elif res.request_type == types.TXINPUT:
                    msg = types.TransactionType()
                    msg.inputs.extend([
                        current_tx.inputs[res.details.request_index],
                    ])
                    res = self.call(proto.TxAck(tx=msg))
                    continue

                elif res.request_type == types.TXOUTPUT:
                    msg = types.TransactionType()
                    if res.details.tx_hash:
                        msg.bin_outputs.extend([
                            current_tx.bin_outputs[res.details.request_index],
                        ])
                    else:
                        msg.outputs.extend([
                            current_tx.outputs[res.details.request_index],
                        ])

                    if debug_processor != None:
                        # If debug_processor function is provided,
                        # pass thru it the request and prepared response.
                        # This is useful for unit tests, see test_msg_signtx
                        msg = debug_processor(res, msg)

                    res = self.call(proto.TxAck(tx=msg))
                    continue

        finally:
            self.transport.session_end()

        if None in signatures:
            raise Exception("Some signatures are missing!")

        log("SIGNED IN %.03f SECONDS, CALLED %d MESSAGES, %d BYTES" % \
                (time.time() - start, counter, len(serialized_tx)))

        return (signatures, serialized_tx)