Example #1
0
def test_exceptions() -> None:

    # invalid size: 11 bytes instead of 20
    err_msg = "invalid size: "
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload("p2wpkh", "00" * 11)

    # invalid size: 33 bytes instead of 32
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload("p2wsh", "00" * 33)

    err_msg = "unknown scriptPubKey type: "
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload("p2unkn", "00" * 32)

    err_msg = "unknown scriptPubKey: "
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey = [16, 20 * b"\x00"]
        address_from_scriptPubKey(scriptPubKey)

    # Unhandled witness version (16)
    err_msg = "unmanaged witness version: "
    address = b32address_from_witness(16, 20 * b"\x00")
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_address(address)
Example #2
0
def test_p2pk() -> None:

    # self-consistency
    pubkey = "02 cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
    scriptPubKey = script.encode([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)
Example #3
0
def test_nulldata() -> None:

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

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

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

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

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

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

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

    # documented test cases: https://learnmeabitcoin.com/guide/nulldata
    string = "家族も友達もみんなが笑顔の毎日がほしい"
    payload = string.encode()
    assert (
        payload.hex()  # pylint: disable=no-member
        ==
        "e5aeb6e6978fe38282e58f8be98194e38282e381bfe38293e381aae3818ce7ac91e9a194e381aee6af8ee697a5e3818ce381bbe38197e38184"
    )
    scriptPubKey = b"\x6a\x39" + payload
    assert scriptPubKey == nulldata(string)
    assert scriptPubKey == scriptPubKey_from_payload(script_type, payload)
    assert (script_type, payload, 0) == payload_from_scriptPubKey(scriptPubKey)
Example #4
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.encode([
        "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)
Example #5
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.encode([0, payload])
    assert scriptPubKey == p2wsh(script.decode(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)
Example #6
0
def test_p2pkh() -> None:

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

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

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

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

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

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

    # invalid size: 11 bytes instead of 20
    err_msg = "invalid size: "
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload(script_type, "00" * 11)
Example #7
0
def test_p2sh() -> None:

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

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

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

    # base58 address
    network = "mainnet"
    address = base58address.p2sh(script.decode(redeem_script), network)
    assert address == address_from_scriptPubKey(scriptPubKey, network)
    prefix = NETWORKS[network]["p2sh"]
    assert address == b58address_from_h160(prefix, payload, network)

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

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

    # invalid size: 21 bytes instead of 20
    err_msg = "invalid size: "
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload(script_type, "00" * 21)
Example #8
0
def test_p2ms() -> None:

    script_type = "p2ms"

    # self-consistency
    pubkey1 = (
        "04"
        "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf"
        "f7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4")
    pubkey2 = (
        "04"
        "61cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d765"
        "19aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af")
    pubkeys = [bytes.fromhex(pubkey1), bytes.fromhex(pubkey2)]
    m = 1

    # straight to the scriptPubKey
    payload = sorted(pubkeys)
    n = len(pubkeys)
    scriptPubKey = script.encode([m] + payload + [n, "OP_CHECKMULTISIG"])
    assert scriptPubKey == p2ms(pubkeys, m)

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

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

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

    # documented test case: https://learnmeabitcoin.com/guide/p2ms
    pubkeys = [bytes.fromhex(pubkey1), bytes.fromhex(pubkey2)]
    m = 1
    n = 2
    scriptPubKey = (  # fmt: off
        "51"  # OP_1
        "41"  # canonical 65-bytes push
        + pubkey1 + "41"  # noqa E148  # canonical 65-bytes push
        + pubkey2 + "52"  # noqa E148  # OP_2
        "ae"  # OP_CHECKMULTISIG
    )  # fmt: on
    assert scriptPubKey == p2ms(pubkeys, 1, lexicographic_sort=False).hex()

    err_msg = "number-of-pubkeys < m in "
    with pytest.raises(ValueError, match=err_msg):
        p2ms(pubkeys, 3)

    err_msg = "invalid m for p2ms scriptPubKey: "
    with pytest.raises(ValueError, match=err_msg):
        p2ms(pubkeys, 0)

    err_msg = "not a private or public key: "
    with pytest.raises(ValueError, match=err_msg):
        p2ms([pubkey1 + "00", pubkey2], 1)

    err_msg = "too many pubkeys in m-of-n multisignature: "
    with pytest.raises(ValueError, match=err_msg):
        p2ms([pubkey1] * 17, 3)

    err_msg = "invalid size: "
    badpubkeys = sorted(pubkeys)
    badpubkeys[0] = badpubkeys[0] + b"\x00"
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload(script_type, badpubkeys, m)

    scriptPubKey = script.encode([m] + sorted(badpubkeys) +
                                 [n, "OP_CHECKMULTISIG"])
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    err_msg = "invalid key in p2ms"
    scriptPubKey = script.encode([m] + [0, pubkeys[1]] +
                                 [n, "OP_CHECKMULTISIG"])
    with pytest.raises(ValueError, match=err_msg):
        payload_from_scriptPubKey(scriptPubKey)

    err_msg = "invalid m in m-of-n multisignature: "
    with pytest.raises(ValueError, match=err_msg):
        scriptPubKey_from_payload(script_type, pubkeys, 17)