def test_from_public_key(self):
     public_key = "0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A" \
                  "04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38" \
                  "855ED6F2EE187E9C582BA6"
     hex_pk = a2b_hex(public_key)
     address = Address.from_public_key(hex_pk)
     self.assertEqual(address.address, "16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM")
     address_hash = "010966776006953D5567439E5E39F86A0D273BEE"
     self.assertEqual(address.hash, a2b_hex(address_hash))
 def test_from_ripemd160(self):
     ripemd160 = "010966776006953D5567439E5E39F86A0D273BEE"
     address = Address.from_ripemd160(a2b_hex(ripemd160))
     self.assertEqual(address.address, "16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM")
Example #3
0
def extract(block, tx):
    inputs = []
    outputs = []

    if not tx.is_coinbase():
        for input_index, item in enumerate(tx.inputs):
            xput = {"i": input_index}

            for chunk_index, chunk in enumerate(item.script.operations):
                if isinstance(chunk, bytes):
                    op_b = base64.b64encode(chunk).decode("utf-8")

                    if op_b == '':  # TODO: special case to match bitd (investigate bitcoinlib)
                        xput["b" + str(chunk_index)] = {"op": 0}
                    else:
                        xput["b" + str(chunk_index)] = op_b
                        xput["h" + str(chunk_index)] = chunk.hex()
                elif isinstance(chunk, CScriptOp):
                    xput["b" + str(chunk_index)] = {"op": int(chunk)}
                else:
                    if chunk == 1:  # TODO: special case to match bitd (investigate bitcoinlib)
                        xput["b" + str(chunk_index)] = {"op": 81}
                    else:
                        xput["b" + str(chunk_index)] = chunk

            xput["str"] = item.script.value
            sender = {
                "h": item.transaction_hash,
                "i": item.transaction_index,
            }

            addr = None

            if len(item.script.operations) == 2:  # p2pk / p2pkh
                try:
                    a = item.script.operations[1]
                    if isinstance(a, str) or isinstance(
                            a, bytes):  # could be CScriptOp in rare case
                        if len(a) == 33 or len(a) == 65:
                            addr = Address.from_public_key(a).address
                except:
                    addr = None

            if addr is None:  # p2sh
                try:
                    version = b'\x05'
                    hash160 = btc_ripemd160(item.script.operations[-1])
                    checksum = double_sha256(version + hash160)
                    addr = base58.encode(version + hash160 + checksum[:4])
                except:
                    addr = None

            if addr is not None:
                try:
                    sender['a'] = to_cash_addr(addr)
                except:
                    pass

            xput["e"] = sender
            inputs.append(xput)

    for output_index, item in enumerate(tx.outputs):
        xput = {"i": output_index}

        for chunk_index, chunk in enumerate(item.script.operations):
            if isinstance(chunk, bytes):
                xput["b" + str(chunk_index)] = base64.b64encode(chunk).decode(
                    "utf-8")
                try:
                    xput["s" + str(chunk_index)] = chunk.decode("utf-8")
                except UnicodeDecodeError:
                    pass
                xput["h" + str(chunk_index)] = chunk.hex()
            elif isinstance(chunk, CScriptOp):
                xput["b" + str(chunk_index)] = {"op": int(chunk)}
            else:
                xput["b" + str(chunk_index)] = chunk

        xput["str"] = item.script.value

        receiver = {"v": item.value, "i": output_index}
        # bitdb only supports single address, so we will too
        addresses = [str(m.address) for m in item.addresses]
        if len(addresses) == 1:
            receiver["a"] = to_cash_addr(addresses[0])
        xput["e"] = receiver

        outputs.append(xput)

    d = {
        "tx": {
            "h": tx.hash
        },
        "in": inputs,
        "out": outputs,
    }

    if block is not None:
        d['blk'] = {
            "i":
            block.height,
            "h":
            block.hash,
            "t":
            int(
                block.header.timestamp.replace(
                    tzinfo=timezone.utc).timestamp())
        }
    return d