Exemplo n.º 1
0
def test_p2pk():
    pubkey = "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"
    signature = "304402200A5C6163F07B8D3B013C4D1D6DBA25E780B39658D79BA37AF7057A3B7F15FFA102201FD9B4EAA9943F734928B99A83592C2E7BF342EA2680F6A2BB705167966B742001"
    script_pubkey = script.serialize([pubkey, "OP_CHECKSIG"])
    script_sig = script.serialize([signature])

    founding_tx_script = script.serialize([0, 0])
    founding_tx = Tx(
        1,
        0,
        vin=[
            TxIn(OutPoint(b"\x00" * 32, 0xFFFFFFFF), founding_tx_script,
                 0xFFFFFFFF, [])
        ],
        vout=[TxOut(0, script_pubkey)],
    )
    receiving_tx = Tx(
        1,
        0,
        vin=[TxIn(OutPoint(founding_tx.txid, 0), script_sig, 0xFFFFFFFF, [])],
        vout=[TxOut(0, b"")],
    )
    sighash = get_sighash(receiving_tx, founding_tx.vout[0], 0, 0x01)
    assert dsa._verify(sighash, bytes.fromhex(pubkey),
                       bytes.fromhex(signature)[:-1])
Exemplo n.º 2
0
def test_p2pk_anyonecanpay():
    pubkey = "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf"
    signature = "304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790281"
    script_pubkey = script.serialize([pubkey, "OP_CHECKSIG"])
    script_sig = script.serialize([signature])

    founding_tx_script = script.serialize([0, 0])
    founding_tx = Tx(
        1,
        0,
        vin=[
            TxIn(OutPoint(b"\x00" * 32, 0xFFFFFFFF), founding_tx_script,
                 0xFFFFFFFF, [])
        ],
        vout=[TxOut(0, script_pubkey)],
    )
    receiving_tx = Tx(
        1,
        0,
        vin=[TxIn(OutPoint(founding_tx.txid, 0), script_sig, 0xFFFFFFFF, [])],
        vout=[TxOut(0, b"")],
    )
    sighash = get_sighash(receiving_tx, founding_tx.vout[0], 0, 0x81)
    assert dsa._verify(sighash, bytes.fromhex(pubkey),
                       bytes.fromhex(signature)[:-1])
Exemplo n.º 3
0
def test_p2pkh():
    pubkey = "038282263212C609D9EA2A6E3E172DE238D8C39CABD5AC1CA10646E23FD5F51508"
    signature = "304402206E05A6FE23C59196FFE176C9DDC31E73A9885638F9D1328D47C0C703863B8876022076FEB53811AA5B04E0E79F938EB19906CC5E67548BC555A8E8B8B0FC603D840C01"
    script_pubkey = script.serialize([
        "OP_DUP",
        "OP_HASH160",
        "1018853670F9F3B0582C5B9EE8CE93764AC32B93",
        "OP_EQUALVERIFY",
        "OP_CHECKSIG",
    ])
    script_sig = script.serialize([signature, pubkey])

    founding_tx_script = script.serialize([0, 0])
    founding_tx = Tx(
        1,
        0,
        vin=[
            TxIn(OutPoint(b"\x00" * 32, 0xFFFFFFFF), founding_tx_script,
                 0xFFFFFFFF, [])
        ],
        vout=[TxOut(0, script_pubkey)],
    )
    receiving_tx = Tx(
        1,
        0,
        vin=[TxIn(OutPoint(founding_tx.txid, 0), script_sig, 0xFFFFFFFF, [])],
        vout=[TxOut(0, b"")],
    )
    sighash = get_sighash(receiving_tx, founding_tx.vout[0], 0, 0x01)
    assert dsa._verify(sighash, bytes.fromhex(pubkey),
                       bytes.fromhex(signature)[:-1])
Exemplo n.º 4
0
def test_block():
    transactions = []
    for x in range(10):
        tx_in = TxIn(
            prevout=OutPoint(),
            scriptSig=script.serialize([f"{x}{x}"]),
            sequence=0xFFFFFFFF,
            txinwitness=[],
        )
        tx_out = TxOut(
            value=50 * 10**8,
            scriptPubKey=script.serialize([f"{x}{x}"]),
        )
        tx = TxData(
            version=1,
            locktime=0,
            vin=[tx_in],
            vout=[tx_out],
        )
        transactions.append(tx)
    header = BlockHeader(
        version=1,
        previousblockhash="00" * 32,
        merkleroot="00" * 32,
        time=1,
        bits=b"\x23\x00\x00\x01",
        nonce=1,
    )
    header.merkleroot = _generate_merkle_root(transactions)
    msg = Block(BlockData(header, transactions))
    msg_bytes = bytes.fromhex("00" * 4) + msg.serialize()
    assert msg == Block.deserialize(get_payload(msg_bytes)[1])
Exemplo n.º 5
0
def generate_random_chain(length, start):
    # random.seed(42)
    chain = []
    for x in range(length):
        previous_block_hash = chain[-1].header.hash if chain else start
        coinbase_in = TxIn(
            prevout=OutPoint(),
            scriptSig=script.serialize(
                [random.randrange(256**32).to_bytes(32, "big").hex()]),
            sequence=0xFFFFFFFF,
            txinwitness=[],
        )
        coinbase_out = TxOut(
            value=50 * 10**8,
            scriptPubKey=script.serialize(
                [random.randrange(256**32).to_bytes(32, "big").hex()]),
        )
        coinbase = Tx(
            version=1,
            locktime=0,
            vin=[coinbase_in],
            vout=[coinbase_out],
        )
        transactions = [coinbase]
        if chain:
            tx_in = TxIn(
                prevout=OutPoint(chain[x - 1].transactions[0].txid, 0),
                scriptSig=script.serialize(
                    [random.randrange(256**32).to_bytes(32, "big").hex()]),
                sequence=0xFFFFFFFF,
                txinwitness=[],
            )
            tx_out = TxOut(
                value=50 * 10**8,
                scriptPubKey=script.serialize(
                    [random.randrange(256**32).to_bytes(32, "big").hex()]),
            )
            tx = Tx(
                version=1,
                locktime=0,
                vin=[tx_in],
                vout=[tx_out],
            )
            transactions.append(tx)
        header = BlockHeader(
            version=70015,
            previousblockhash=previous_block_hash,
            merkleroot=_generate_merkle_root(transactions),
            time=1,
            bits=b"\x23\x00\x00\x01",
            nonce=1,
        )
        block = Block(header, transactions)
        chain.append(block)
    return chain
Exemplo n.º 6
0
def test_nulldata() -> None:

    scripts: List[List[Token]] = [["OP_RETURN", "11" * 79],
                                  ["OP_RETURN", "00" * 79]]
    for scriptPubKey in scripts:
        assert scriptPubKey == script.decode(script.encode(scriptPubKey))
        assert scriptPubKey == script.decode(script.encode(scriptPubKey).hex())
        assert scriptPubKey == script.deserialize(
            script.serialize(scriptPubKey))
        assert scriptPubKey == script.deserialize(
            script.serialize(scriptPubKey).hex())
Exemplo n.º 7
0
def test_nulldata() -> None:

    scripts: List[List[ScriptToken]] = [
        ["OP_RETURN", "11" * 79],
        ["OP_RETURN", "00" * 79],
    ]
    for script_pubkey in scripts:
        assert script_pubkey == script.deserialize(
            script.serialize(script_pubkey))
        assert script_pubkey == script.deserialize(
            script.serialize(script_pubkey).hex())
Exemplo n.º 8
0
def test_p2pk() -> None:

    # self-consistency
    pubkey = "02 cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
    scriptPubKey = script.serialize([pubkey, "OP_CHECKSIG"])
    assert scriptPubKey == p2pk(pubkey)

    # to the scriptPubKey in two steps (through payload)
    script_type = "p2pk"
    assert scriptPubKey == scriptPubKey_from_payload(script_type, pubkey)

    # back from the scriptPubKey to the payload
    assert (script_type, bytes.fromhex(pubkey),
            0) == payload_from_scriptPubKey(scriptPubKey)

    err_msg = "no address for p2pk scriptPubKey"
    with pytest.raises(ValueError, match=err_msg):
        address_from_scriptPubKey(scriptPubKey)

    # documented test case: https://learnmeabitcoin.com/guide/p2pk
    pubkey = (
        "04"
        "ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414"
        "e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c")
    scriptPubKey = "41" + pubkey + "ac"
    assert scriptPubKey == p2pk(pubkey).hex()

    # invalid size: 34 bytes instead of (33, 65)
    pubkey = (  # fmt: off
        "03"
        "ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414"
        "14")  # fmt: on
    err_msg = "not a private or public key: "
    with pytest.raises(ValueError, match=err_msg):
        p2pk(pubkey)
Exemplo n.º 9
0
def test_simple():
    script_list = [
        [2, 3, "OP_ADD", 5, "OP_EQUAL"],
        ["1ADD", "OP_1ADD", "1ADE", "OP_EQUAL"],
        [hex(26)[2:].upper(), -1, "OP_ADD",
         hex(26)[2:].upper(), "OP_EQUAL"],
        [
            hex(0xFFFFFFFF)[2:].upper(),
            -1,
            "OP_ADD",
            hex(0xFFFFFFFF)[2:].upper(),
            "OP_EQUAL",
        ],
        ["1F" * 250, "OP_DROP"],
        ["1F" * 520, "OP_DROP"],
    ]
    for script in script_list:
        script_bytes = encode(script)
        script2 = decode(script_bytes)
        assert script == script2
        script_bytes2 = encode(script2)
        assert script_bytes == script_bytes2
        script_serialized = serialize(script)
        script3 = deserialize(script_serialized)
        assert script == script3
        script4 = deserialize(script_serialized.hex())
        assert script == script4
Exemplo n.º 10
0
def test_p2wsh() -> None:

    # self-consistency
    pubkey = "02 cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
    pubkey_hash = hash160(pubkey)
    redeem_script = scriptPubKey_from_payload("p2pkh", pubkey_hash)
    payload = sha256(redeem_script)
    scriptPubKey = script.serialize([0, payload])
    assert scriptPubKey == p2wsh(script.deserialize(redeem_script))

    # to the scriptPubKey in two steps (through payload)
    script_type = "p2wsh"
    assert scriptPubKey == scriptPubKey_from_payload(script_type, payload)

    # back from the scriptPubKey to the payload
    assert (script_type, payload, 0) == payload_from_scriptPubKey(scriptPubKey)

    # bech32 address
    network = "mainnet"
    address = bech32address.p2wsh(redeem_script, network)
    assert address == address_from_scriptPubKey(scriptPubKey, network)
    wit_ver = 0
    assert address == b32address_from_witness(wit_ver, payload, network)

    # back from the address to the scriptPubKey
    assert (scriptPubKey, network) == scriptPubKey_from_address(address)

    # p2sh-wrapped base58 address
    address = base58address.p2wsh_p2sh(redeem_script, network)
    assert address == b58address_from_witness(payload, network)
Exemplo n.º 11
0
def test_CLT() -> None:

    network = "mainnet"

    fed_pubkeys = [b"\x00" * 33, b"\x11" * 33, b"\x22" * 33]
    rec_pubkeys = [b"\x77" * 33, b"\x88" * 33, b"\x99" * 33]
    # fmt: off
    redeem_script = script.serialize([
        "OP_IF",
        2,
        *fed_pubkeys,
        3,
        "OP_CHECKMULTISIG",  # noqa E131
        "OP_ELSE",
        500,
        "OP_CHECKLOCKTIMEVERIFY",
        "OP_DROP",  # noqa E131
        2,
        *rec_pubkeys,
        3,
        "OP_CHECKMULTISIG",  # noqa E131
        "OP_ENDIF",
    ])
    # fmt: on
    payload = sha256(redeem_script)
    scriptPubKey = (
        "00207b5310339c6001f75614daa5083839fa54d46165f6c56025cc54d397a85a5708")
    assert scriptPubKey == p2wsh(redeem_script).hex()
    assert scriptPubKey == scriptPubKey_from_payload("p2wsh", payload).hex()

    address = b"bc1q0df3qvuuvqqlw4s5m2jsswpelf2dgct97mzkqfwv2nfe02z62uyq7n4zjj"
    assert address == address_from_scriptPubKey(scriptPubKey, network)
    assert address == b32address_from_witness(0, payload, network)
Exemplo n.º 12
0
def test_p2wsh_p2sh() -> None:

    # leading/trailing spaces should be tolerated
    pub = " 02 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
    script_pubkey: List[ScriptToken] = [pub, "OP_CHECKSIG"]
    witness_script_bytes = script.serialize(script_pubkey)
    p2wsh_p2sh(witness_script_bytes)
    p2wsh_p2sh(witness_script_bytes, "testnet")
Exemplo n.º 13
0
    def test_simple(self):
        script_list = [2, 3, 'OP_ADD', 5, 'OP_EQUAL']
        script_bytes = encode(script_list)
        script_list2 = decode(script_bytes)
        self.assertEqual(script_list, script_list2)

        script_serialized = serialize(script_list)
        script_list2 = parse(script_serialized)
        self.assertEqual(script_list, script_list2)

        script_list = [26, -1, 'OP_ADD', 25, 'OP_EQUAL']
        script_bytes = encode(script_list)
        script_list2 = decode(script_bytes)
        self.assertEqual(script_list, script_list2)

        script_serialized = serialize(script_list)
        script_list2 = parse(script_serialized)
        self.assertEqual(script_list, script_list2)

        script_list = [0xffffffff, -1, 'OP_ADD', 0xfffffffe, 'OP_EQUAL']
        script_bytes = encode(script_list)
        script_list2 = decode(script_bytes)
        self.assertEqual(script_list, script_list2)

        script_serialized = serialize(script_list)
        script_list2 = parse(script_serialized)
        self.assertEqual(script_list, script_list2)

        script_list = ["1f" * 250, 'OP_DROP']
        script_bytes = encode(script_list)
        script_list2 = decode(script_bytes)
        self.assertEqual(script_list, script_list2)

        script_serialized = serialize(script_list)
        script_list2 = parse(script_serialized)
        self.assertEqual(script_list, script_list2)

        script_list = ["1f" * 520, 'OP_DROP']
        script_bytes = encode(script_list)
        script_list2 = decode(script_bytes.hex())
        self.assertEqual(script_list, script_list2)

        script_serialized = serialize(script_list)
        script_list2 = parse(script_serialized.hex())
        self.assertEqual(script_list, script_list2)
Exemplo n.º 14
0
def test_nulldata() -> None:

    # self-consistency
    string = "time-stamped data"
    payload = string.encode()
    script_pubkey = script.serialize(["OP_RETURN", payload])
    assert script_pubkey == nulldata(string)

    # to the script_pubkey in two steps (through payload)
    script_type = "nulldata"
    assert script_pubkey == script_pubkey_from_payload(script_type, payload)

    # back from the script_pubkey to the payload
    assert (script_type, payload,
            0) == payload_from_script_pubkey(script_pubkey)

    # data -> payload in this case is invertible (no hash functions)
    assert payload.decode("ascii") == string

    err_msg = "no address for null data script"
    with pytest.raises(BTClibValueError, match=err_msg):
        address_from_script_pubkey(script_pubkey)

    # documented test cases: https://learnmeabitcoin.com/guide/nulldata
    string = "hello world"
    payload = string.encode()
    assert payload.hex() == "68656c6c6f20776f726c64"  # pylint: disable=no-member
    script_pubkey = b"\x6a\x0b" + payload
    assert script_pubkey == nulldata(string)
    assert script_pubkey == script_pubkey_from_payload(script_type, payload)
    assert (script_type, payload,
            0) == payload_from_script_pubkey(script_pubkey)

    # documented test cases: https://learnmeabitcoin.com/guide/nulldata
    string = "charley loves heidi"
    payload = string.encode()
    assert (payload.hex()  # pylint: disable=no-member
            == "636861726c6579206c6f766573206865696469")
    script_pubkey = b"\x6a\x13" + payload
    assert script_pubkey == nulldata(string)
    assert script_pubkey == script_pubkey_from_payload(script_type, payload)
    assert (script_type, payload,
            0) == payload_from_script_pubkey(script_pubkey)

    # documented test cases: https://learnmeabitcoin.com/guide/nulldata
    string = "家族も友達もみんなが笑顔の毎日がほしい"
    payload = string.encode()
    assert (
        payload.hex()  # pylint: disable=no-member
        ==
        "e5aeb6e6978fe38282e58f8be98194e38282e381bfe38293e381aae3818ce7ac91e9a194e381aee6af8ee697a5e3818ce381bbe38197e38184"
    )
    script_pubkey = b"\x6a\x39" + payload
    assert script_pubkey == nulldata(string)
    assert script_pubkey == script_pubkey_from_payload(script_type, payload)
    assert (script_type, payload,
            0) == payload_from_script_pubkey(script_pubkey)
Exemplo n.º 15
0
def test_tx():
    tx_in = TxIn(
        prevout=OutPoint(),
        scriptSig=script.serialize(["00"]),
        sequence=0xFFFFFFFF,
        txinwitness=[],
    )
    tx_out = TxOut(
        value=50 * 10**8,
        scriptPubKey=script.serialize(["00"]),
    )
    tx = TxData(
        version=1,
        locktime=0,
        vin=[tx_in],
        vout=[tx_out],
    )
    msg = Tx(tx)
    msg_bytes = bytes.fromhex("00" * 4) + msg.serialize()
    assert msg == Tx.deserialize(get_payload(msg_bytes)[1])
Exemplo n.º 16
0
def test_simple() -> None:
    script_list: List[List[ScriptToken]] = [
        [2, 3, "OP_ADD", 5, "OP_EQUAL"],
        ["1ADD", "OP_1ADD", "1ADE", "OP_EQUAL"],
        [hex(26)[2:].upper(), -1, "OP_ADD",
         hex(26)[2:].upper(), "OP_EQUAL"],
        [
            hex(0xFFFFFFFF)[2:].upper(),
            -1,
            "OP_ADD",
            hex(0xFFFFFFFF)[2:].upper(),
            "OP_EQUAL",
        ],
        ["1F" * 250, "OP_DROP"],
        ["1F" * 520, "OP_DROP"],
    ]
    for script_pubkey in script_list:
        assert script_pubkey == script.deserialize(
            script.serialize(script_pubkey))
        assert script_pubkey == script.deserialize(
            script.serialize(script_pubkey).hex())
Exemplo n.º 17
0
def create_genesis(time, nonce, difficulty, version, reward):
    script_sig = script.serialize(
        [
            "FFFF001D",
            b"\x04",
            "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks".encode(),
        ]
    )
    script_pub_key = script.serialize(
        [
            "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f",
            "OP_CHECKSIG",
        ]
    )
    tx_in = TxIn(
        prevout=OutPoint(),
        scriptSig=script_sig,
        sequence=0xFFFFFFFF,
        txinwitness=[],
    )
    tx_out = TxOut(
        value=reward,
        scriptPubKey=script_pub_key,
    )
    tx = Tx(
        version=1,
        locktime=0,
        vin=[tx_in],
        vout=[tx_out],
    )
    header = BlockHeader(
        version=version,
        previousblockhash="00" * 32,
        merkleroot="00" * 32,
        time=time,
        bits=difficulty.to_bytes(4, "big"),
        nonce=nonce,
    )
    header.merkleroot = _generate_merkle_root([tx])
    return header
Exemplo n.º 18
0
def test_p2sh() -> None:
    # https://medium.com/@darosior/bitcoin-raw-transactions-part-2-p2sh-94df206fee8d
    scriptPubKey: List[ScriptToken] = [
        "OP_2DUP",
        "OP_EQUAL",
        "OP_NOT",
        "OP_VERIFY",
        "OP_SHA1",
        "OP_SWAP",
        "OP_SHA1",
        "OP_EQUAL",
    ]
    assert script.serialize(scriptPubKey).hex() == "6e879169a77ca787"

    network = "mainnet"
    addr = p2sh(scriptPubKey, network)
    assert addr == b"37k7toV1Nv4DfmQbmZ8KuZDQCYK9x5KpzP"

    _, redeem_script_hash, network2, is_script_hash = h160_from_b58address(
        addr)
    assert network == network2
    assert is_script_hash
    assert redeem_script_hash == hash160(script.serialize(scriptPubKey))

    assert redeem_script_hash.hex(
    ) == "4266fc6f2c2861d7fe229b279a79803afca7ba34"
    output_script: List[ScriptToken] = [
        "OP_HASH160",
        redeem_script_hash.hex(),
        "OP_EQUAL",
    ]
    script.serialize(output_script)

    # address with trailing/leading spaces
    _, h160, network2, is_script_hash = h160_from_b58address(
        " 37k7toV1Nv4DfmQbmZ8KuZDQCYK9x5KpzP ")
    assert network == network2
    assert is_script_hash
    assert redeem_script_hash == h160
Exemplo n.º 19
0
def test_blocktxn():
    transactions = []
    for x in range(10):
        tx_in = TxIn(
            prevout=OutPoint(),
            scriptSig=script.serialize([f"{x}{x}"]),
            sequence=0xFFFFFFFF,
            txinwitness=[],
        )
        tx_out = TxOut(
            value=50 * 10**8,
            scriptPubKey=script.serialize([f"{x}{x}"]),
        )
        tx = TxData(
            version=1,
            locktime=0,
            vin=[tx_in],
            vout=[tx_out],
        )
        transactions.append(tx)
    msg = Blocktxn("00" * 32, transactions)
    msg_bytes = bytes.fromhex("00" * 4) + msg.serialize()
    assert msg == Blocktxn.deserialize(get_payload(msg_bytes)[1])
Exemplo n.º 20
0
def test_nulldata2() -> None:

    script_type = "nulldata"

    # max length case
    byte = b"\x00"
    for length in (0, 1, 16, 17, 74, 75, 76, 77, 78, 79, 80):
        payload = byte * length
        scriptPubKey = script.serialize(["OP_RETURN", payload])
        assert scriptPubKey == scriptPubKey_from_payload(script_type, payload)

        # back from the scriptPubKey to the payload
        assert (script_type, payload,
                0) == payload_from_scriptPubKey(scriptPubKey)
        assert (script_type, payload, 0) == payload_from_scriptPubKey(
            script.deserialize(scriptPubKey))
Exemplo n.º 21
0
def test_legacy_p2pkh():
    pubkey = "04280c8f66bf2ccaeb3f60a19ad4a06365f8bd6178aab0e709df2173df8f553366549aec336aae8742a84702b6c7c3052d89f5d76d535ec3716e72187956351613"
    signature = "3045022100ea43c4800d1a860ec89b5273898a146cfb01d34ff4c364d24a110c480d0e3f7502201c82735577f932f1ca8e1c54bf653e0f8e74e408fe83666bc85cac4472ec950801"
    script_sig = [signature, pubkey]
    previous_txout = TxOut(
        value=1051173696,
        script_pubkey=script.serialize([
            "OP_DUP",
            "OP_HASH160",
            "82ac30f58baf99ec9d14e6181eee076f4e27f69c",
            "OP_EQUALVERIFY",
            "OP_CHECKSIG",
        ]),
    )
    tx = Tx(
        1,
        0,
        vin=[
            TxIn(
                OutPoint(
                    bytes.fromhex(
                        "d8343a35ba951684f2969eafe833d9e6fe436557b9707ae76802875952e860fc"
                    ),
                    1,
                ),
                script_sig,
                0xFFFFFFFF,
                [],
            )
        ],
        vout=[
            TxOut(
                2017682,
                bytes.fromhex(
                    "76a91413bd20236d0da56492c325dce289b4da35b4b5bd88ac"),
            ),
            TxOut(
                1049154982,
                bytes.fromhex(
                    "76a914da169b45781ca210f8c11617ba66bd843da76b1688ac"),
            ),
        ],
    )
    sighash = get_sighash(tx, previous_txout, 0, 0x01)
    assert dsa._verify(sighash, bytes.fromhex(pubkey),
                       bytes.fromhex(signature)[:-1])
Exemplo n.º 22
0
def test_p2pkh() -> None:

    # self-consistency
    pubkey = (
        "04 "
        "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
        "f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4")
    payload = hash160(pubkey)
    script_pubkey = script.serialize(
        ["OP_DUP", "OP_HASH160", payload, "OP_EQUALVERIFY", "OP_CHECKSIG"])
    assert script_pubkey == p2pkh(pubkey)

    # to the script_pubkey in two steps (through payload)
    script_type = "p2pkh"
    assert script_pubkey == script_pubkey_from_payload(script_type, payload)

    # back from the script_pubkey to the payload
    assert (script_type, payload,
            0) == payload_from_script_pubkey(script_pubkey)

    # base58 address
    network = "mainnet"
    address = base58address.p2pkh(pubkey, network)
    assert address == address_from_script_pubkey(script_pubkey, network)
    prefix = NETWORKS[network].p2pkh
    assert address == b58address_from_h160(prefix, payload, network)

    # back from the address to the script_pubkey
    assert (script_pubkey, network) == script_pubkey_from_address(address)

    # documented test case: https://learnmeabitcoin.com/guide/p2pkh
    payload = "12ab8dc588ca9d5787dde7eb29569da63c3a238c"
    script_pubkey = "76a914" + payload + "88ac"
    assert script_pubkey == script_pubkey_from_payload(script_type,
                                                       payload).hex()
    address = b"12higDjoCCNXSA95xZMWUdPvXNmkAduhWv"
    assert address == address_from_script_pubkey(script_pubkey, network)
    assert (bytes.fromhex(script_pubkey),
            network) == script_pubkey_from_address(address)

    # invalid size: 11 bytes instead of 20
    err_msg = "invalid size: "
    with pytest.raises(BTClibValueError, match=err_msg):
        script_pubkey_from_payload(script_type, "00" * 11)
Exemplo n.º 23
0
def test_sighashsingle_bug():
    pubkey = "02D5C25ADB51B61339D2B05315791E21BBE80EA470A49DB0135720983C905AACE0"
    signature = "3045022100C9CDD08798A28AF9D1BAF44A6C77BCC7E279F47DC487C8C899911BC48FEAFFCC0220503C5C50AE3998A733263C5C0F7061B483E2B56C4C41B456E7D2F5A78A74C07703"
    script_pubkey = script.serialize([
        "OP_DUP",
        "OP_HASH160",
        "5b6462475454710f3c22f5fdf0b40704c92f25c3",
        "OP_EQUALVERIFY",
        "OP_CHECKSIGVERIFY",
        1,
    ])

    previous_txout = TxOut(0, script_pubkey)
    tx = Tx.deserialize(
        "01000000020002000000000000000000000000000000000000000000000000000000000000000000000151ffffffff0001000000000000000000000000000000000000000000000000000000000000000000006b483045022100c9cdd08798a28af9d1baf44a6c77bcc7e279f47dc487c8c899911bc48feaffcc0220503c5c50ae3998a733263c5c0f7061b483e2b56c4c41b456e7d2f5a78a74c077032102d5c25adb51b61339d2b05315791e21bbe80ea470a49db0135720983c905aace0ffffffff010000000000000000015100000000"
    )
    sighash = get_sighash(tx, previous_txout, 1, 0x03)
    assert dsa._verify(sighash, bytes.fromhex(pubkey),
                       bytes.fromhex(signature)[:-1])
Exemplo n.º 24
0
def test_p2sh() -> None:

    # self-consistency
    pubkey = "02 cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
    pubkey_hash = hash160(pubkey)
    redeem_script = script_pubkey_from_payload("p2pkh", pubkey_hash)
    payload = hash160(redeem_script)
    script_pubkey = script.serialize(["OP_HASH160", payload, "OP_EQUAL"])
    assert script_pubkey == p2sh(redeem_script)

    # to the script_pubkey in two steps (through payload)
    script_type = "p2sh"
    assert script_pubkey == script_pubkey_from_payload(script_type, payload)

    # back from the script_pubkey to the payload
    assert (script_type, payload,
            0) == payload_from_script_pubkey(script_pubkey)

    # base58 address
    network = "mainnet"
    address = base58address.p2sh(script.deserialize(redeem_script), network)
    assert address == address_from_script_pubkey(script_pubkey, network)
    prefix = NETWORKS[network].p2sh
    assert address == b58address_from_h160(prefix, payload, network)

    # back from the address to the script_pubkey
    assert (script_pubkey, network) == script_pubkey_from_address(address)

    # documented test case: https://learnmeabitcoin.com/guide/p2sh
    payload = "748284390f9e263a4b766a75d0633c50426eb875"
    script_pubkey = "a914" + payload + "87"
    assert script_pubkey == script_pubkey_from_payload(script_type,
                                                       payload).hex()
    address = b"3CK4fEwbMP7heJarmU4eqA3sMbVJyEnU3V"
    assert address == address_from_script_pubkey(script_pubkey, network)
    assert (bytes.fromhex(script_pubkey),
            network) == script_pubkey_from_address(address)

    # invalid size: 21 bytes instead of 20
    err_msg = "invalid size: "
    with pytest.raises(BTClibValueError, match=err_msg):
        script_pubkey_from_payload(script_type, "00" * 21)
Exemplo n.º 25
0
def test_p2ms_2() -> None:

    pubkey1 = "04 cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4"
    pubkey2 = "04 61cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d765 19aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af"
    pubkey3 = "04 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"
    pubkeys = [pubkey1, pubkey2, pubkey3]
    m = 1
    n = len(pubkeys)
    scriptPubKey = [m] + pubkeys + [n, "OP_CHECKMULTISIG"]
    payload_from_scriptPubKey(scriptPubKey)
    scriptPubKey_from_payload("p2ms", pubkeys, m)

    err_msg = "invalid list of Octets for p2sh scriptPubKey"
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload("p2sh", pubkeys, 0)

    err_msg = "invalid number of pubkeys in "
    scriptPubKey = [1, 3, "OP_CHECKMULTISIG"]
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    err_msg = "wrong number of pubkeys in "
    scriptPubKey = [1, pubkey1, pubkey2, 3, "OP_CHECKMULTISIG"]
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    err_msg = "invalid number of pubkeys in "
    scriptPubKey = [3, pubkey1, pubkey2, 2, "OP_CHECKMULTISIG"]
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    err_msg = "invalid m in m-of-n multisignature: "
    scriptPubKey = [0, pubkey1, pubkey2, 2, "OP_CHECKMULTISIG"]
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    scriptPubKey = script.serialize(
        [1, pubkey1, pubkey2, pubkey3, 3, "OP_CHECKMULTISIG"])
    scriptPubKey = scriptPubKey[:133] + b"\x40" + scriptPubKey[134:]
    err_msg = "wrong number of pubkeys in "
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)
Exemplo n.º 26
0
def test_p2ms_3() -> None:

    # mixed compressed / uncompressed public keys
    pubkey1 = "04 cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4"
    pubkey2 = "03 61cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d765"
    pubkey3 = "02 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
    pubkeys = [
        bytes.fromhex(pubkey1),
        bytes.fromhex(pubkey2),
        bytes.fromhex(pubkey3),
    ]
    m = 1
    n = len(pubkeys)
    scriptPubKey = scriptPubKey_from_payload("p2ms", pubkeys, m)
    pubkeys.sort()
    exp_script = script.serialize([m] + pubkeys + [n, "OP_CHECKMULTISIG"])
    assert scriptPubKey.hex() == exp_script.hex()
    script_type, payload, m2 = payload_from_scriptPubKey(scriptPubKey)
    assert script_type == "p2ms"
    assert m == m2
    assert pubkeys == payload
Exemplo n.º 27
0
def test_exceptions() -> None:

    script_pubkey: List[ScriptToken] = [2, 3, "OP_ADD", 5, "OP_RETURN_244"]
    err_msg = "invalid string token: OP_RETURN_244"
    with pytest.raises(BTClibValueError, match=err_msg):
        script.serialize(script_pubkey)

    err_msg = "Unmanaged <class 'function'> token type"
    with pytest.raises(BTClibValueError, match=err_msg):
        script.serialize([2, 3, "OP_ADD", 5, script.serialize])  # type: ignore

    script_pubkey = ["1f" * 521, "OP_DROP"]
    err_msg = "Too many bytes for OP_PUSHDATA: "
    with pytest.raises(BTClibValueError, match=err_msg):
        script.serialize(script_pubkey)

    # A script_pubkey with OP_PUSHDATA4 can be decoded
    script_bytes = "4e09020000" + "00" * 521 + "75"  # ['00'*521, 'OP_DROP']
    script_pubkey = script.deserialize(script_bytes)
    # but it cannot be encoded
    err_msg = "Too many bytes for OP_PUSHDATA: "
    with pytest.raises(BTClibValueError, match=err_msg):
        script.serialize(script_pubkey)
Exemplo n.º 28
0
def test_valid_address() -> None:
    """Test whether valid addresses decode to the correct output"""

    valid_bc_addresses: List[Tuple[str, str]] = [
        (
            "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4",
            "0014751e76e8199196d454941c45d1b3a323f1433bd6",
        ),
        (
            "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
            "5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6",
        ),
        ("BC1SW50QA3JX3S", "6002751e"),
        (
            "bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
            "5210751e76e8199196d454941c45d1b3a323",
        ),
        (
            " bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",  # extra leading space
            "5210751e76e8199196d454941c45d1b3a323",
        ),
    ]
    valid_tb_addresses: List[Tuple[str, str]] = [
        (
            "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
            "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262",
        ),
        (
            "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy",
            "0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433",
        ),
    ]

    for address, hexscript in valid_bc_addresses + valid_tb_addresses:
        witvers, witprog, network, _ = witness_from_b32address(address)
        script_pubkey: List[ScriptToken] = [witvers, witprog]
        assert script.serialize(script_pubkey).hex() == hexscript
        addr = b32address_from_witness(witvers, witprog, network)
        assert address.lower().strip() == addr.decode("ascii")
Exemplo n.º 29
0
def test_p2wsh() -> None:

    # https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
    pub = "02 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
    script_pubkey: List[ScriptToken] = [pub, "OP_CHECKSIG"]
    witness_script_bytes = script.serialize(script_pubkey)

    addr = b"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7"
    assert addr == p2wsh(witness_script_bytes, "testnet")
    _, wp, _, _ = witness_from_b32address(addr)
    assert bytes(wp) == sha256(witness_script_bytes)

    addr = b"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"
    assert addr == p2wsh(witness_script_bytes)
    _, wp, _, _ = witness_from_b32address(addr)
    assert bytes(wp) == sha256(witness_script_bytes)

    assert witness_from_b32address(addr)[1] == sha256(witness_script_bytes)

    err_msg = "invalid witness program length for witness v0: "
    with pytest.raises(BTClibValueError, match=err_msg):
        b32address_from_witness(0, witness_script_bytes)
Exemplo n.º 30
0
def test_nulldata3() -> None:

    err_msg = "invalid nulldata script length: "
    with pytest.raises(ValueError, match=err_msg):
        payload = "00" * 81
        scriptPubKey_from_payload("nulldata", payload)

    # wrong data length: 32 in 35-bytes nulldata script;
    # it should have been 33
    scriptPubKey = script.serialize(["OP_RETURN", b"\x00" * 33])
    scriptPubKey = scriptPubKey[:1] + b"\x20" + scriptPubKey[2:]
    err_msg = "wrong data length: "
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    # wrong data length: 32 in 83-bytes nulldata script;
    # it should have been 80
    scriptPubKey = script.serialize(["OP_RETURN", b"\x00" * 80])
    scriptPubKey = scriptPubKey[:2] + b"\x20" + scriptPubKey[3:]
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    # missing OP_PUSHDATA1 (0x4c) in 83-bytes nulldata script,
    # got 0x20 instead
    scriptPubKey = script.serialize(["OP_RETURN", b"\x00" * 80])
    scriptPubKey = scriptPubKey[:1] + b"\x20" + scriptPubKey[2:]
    err_msg = "missing OP_PUSHDATA1 "
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    assert len(script.serialize(["OP_RETURN", b"\x00" * 75])) == 77
    assert len(script.serialize(["OP_RETURN", b"\x00" * 76])) == 79
    scriptPubKey = script.serialize(["OP_RETURN", b"\x00" * 76])[:-1]
    err_msg = "invalid 78 bytes nulldata script length"
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)