Ejemplo n.º 1
0
def get_public_key_hex_from_tx(inputs, address):
    """
    Given a list of inputs and outputs and the address of one of the inputs,
    find the public key.
    """

    ret = None

    for inp in inputs:

        input_scriptsig = inp.get('scriptSig', None)
        if input_scriptsig is None:
            continue

        input_asm = input_scriptsig.get("asm")

        if len(input_asm.split(" ")) >= 2:

            # public key is the second hex string.  verify it matches the address
            pubkey_hex = input_asm.split(" ")[1]
            pubkey = None

            try:
                pubkey = pybitcoin.BitcoinPublicKey(str(pubkey_hex))
            except Exception, e:
                traceback.print_exc()
                log.warning("Invalid public key '%s'" % pubkey_hex)
                continue

            if address != pubkey.address():
                continue

            ret = pubkey_hex
            break
Ejemplo n.º 2
0
def btc_decoderawtransaction_get_pubkey_from_script( script ):
    """
    Given a pay-to-public-key script, get the public key.
    Returns a hex string on success.
    Returns None on error.
    """

    # format: [1-byte length] [pubkey] OP_CHECKSIG
    pubkey_len = int( script[0:1], 16 )
    if len(script[:-2]) == pubkey_len * 2 and script[-2:].lower() == 'ac':

        # the rest of the script is a public key
        bin_pubkey = binascii.unhexlify( script[2:2*pubkey_len] )
        try:
            pk = pybitcoin.BitcoinPublicKey( bin_pubkey )
            return pk.to_hex()

        except:
            return None 

    else:
        return None
Ejemplo n.º 3
0
def parse_nameop(opcode,
                 payload,
                 fake_pubkey,
                 recipient=None,
                 recipient_address=None,
                 import_update_hash=None):

    opcode_name = OPCODE_NAMES[opcode]
    pubk = pybitcoin.BitcoinPublicKey(fake_pubkey)
    address = pubk.address()
    script_pubkey = pybitcoin.make_pay_to_address_script(address)
    senders = [{
        "script_pubkey": script_pubkey,
        "script_type": "pubkeyhash",
        "addresses": [address]
    }]

    # just enough to get the public key
    inputs = [{
        "scriptSig": {
            "asm": "ignored %s" % fake_pubkey,
        }
    }]

    script = "OP_RETURN %s" % payload

    try:
        scripthex = pybitcoin.make_op_return_script(payload)
    except:
        if len(payload) == 0:
            scripthex = "6a"
        else:
            raise

    outputs = [{
        "scriptPubKey": {
            "asm": script,
            "hex": scripthex,
            "addresses": []
        }
    }]

    if recipient_address is not None:
        script = "OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG" % binascii.hexlify(
            pybitcoin.bin_double_sha256(fake_pubkey))
        scripthex = pybitcoin.make_pay_to_address_script(recipient_address)
        outputs.append({
            "scriptPubKey": {
                "asm": script,
                "hex": scripthex,
                "addresses": [recipient_address]
            }
        })

    if import_update_hash is not None:
        script = "OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG" % import_update_hash
        scripthex = pybitcoin.make_pay_to_address_script(
            pybitcoin.hex_hash160_to_address(import_update_hash))
        outputs.append({
            "scriptPubKey": {
                "asm": script,
                "hex": scripthex,
                "addresses":
                [pybitcoin.hex_hash160_to_address(import_update_hash)]
            }
        })

    try:
        op = op_extract(opcode_name, payload, senders, inputs, outputs, 373601,
                        0, "00" * 64)
    except AssertionError, ae:
        # failed to parse
        return None
Ejemplo n.º 4
0
def btc_decoderawtransaction_compat( tx_hex ):
    """
    Implementation of bitcoind's decoderawtransaction
    JSONRPC method.  Tries to be faithful enough to
    bitcoind for virtualchain's sake.

    Does NOT handle coinbase transactions
    """

    inputs, outputs, locktime, version = tx_deserialize( tx_hex )
    txid = make_txid( tx_hex )

    vin = []
    vout = []

    for inp in inputs:
        vin_inp = {
            "txid": inp['transaction_hash'],
            "vout": inp['output_index'],
        }

        if inp.has_key("script_sig"):
            scriptsig_hex = inp['script_sig']
            scriptsig_asm = btc_decoderawtransaction_script_hex_to_asm( scriptsig_hex )

            vin_inp['scriptSig'] = {
                'asm': scriptsig_asm,
                'hex': scriptsig_hex
            }

        if inp.has_key("sequence"):

            vin_inp['sequence'] = inp['sequence']

        vin.append( vin_inp )

    for i in xrange( 0, len(outputs) ):

        out = outputs[i]
        script_type = btc_decoderawtransaction_get_script_type( out['script_hex'] )
        addresses = []

        if script_type == "pubkeyhash":
            addresses.append( pybitcoin.script_hex_to_address( out['script_hex'] ) )

        elif script_type == "pubkey":
            pubkey = btc_decoderawtransaction_get_pubkey_from_script( out['script_hex'] )
            addr = pybitcoin.BitcoinPublicKey( pubkey ).address()
            addresses.append( addr )

        elif script_type == "scripthash":
            script_hash = btc_decoderawtransaction_get_script_hash_from_script( out['script_hex'] ) 
            addr = pybitcoin.b58check_encode( binascii.unhexlify( script_hash ), version_byte=5 )
            addresses.append( addr )

        vout_out = {
            "value": float(out['value']) / 10e7,
            "mock_bitcoind_value_satoshi": out['value'],  # NOTE: extra
            "n": i,
            "scriptPubKey": {
                'asm': btc_decoderawtransaction_script_hex_to_asm( out['script_hex'] ),
                'hex': out['script_hex'],
                "type": script_type
            },
        }

        if script_type in ["pubkeyhash", "pubkey", "scripthash"]:
            vout_out['scriptPubKey']['reqSigs'] = 1

        if len(addresses) > 0:
            vout_out['scriptPubKey']['addresses'] = addresses

        vout.append( vout_out )

    tx_decoded = {
        "txid": txid,
        "version": version,
        "locktime": locktime,
        "vin": vin,
        "vout": vout
    }

    return tx_decoded