Exemple #1
0
def _deserialize_final_script_witness(k: bytes, v: bytes) -> Witness:
    "Return the dataclass element from its binary representation."

    if len(k) != 1:
        err_msg = f"invalid final script witness key length: {len(k)}"
        raise BTClibValueError(err_msg)
    return Witness.parse(v)
Exemple #2
0
    def parse(cls: Type[_Tx],
              data: BinaryData,
              check_validity: bool = True) -> _Tx:
        "Return a Tx by parsing binary data."

        stream = bytesio_from_binarydata(data)

        # version is a signed int (int32_t, not uint32_t)
        version = int.from_bytes(stream.read(4),
                                 byteorder="little",
                                 signed=True)

        segwit = stream.read(2) == _SEGWIT_MARKER
        if not segwit:
            # Change stream position: seek to byte offset relative to position
            stream.seek(-2, SEEK_CUR)  # current position

        n = var_int.parse(stream)
        vin = [TxIn.parse(stream) for _ in range(n)]

        n = var_int.parse(stream)
        vout = [TxOut.parse(stream) for _ in range(n)]

        if segwit:
            for tx_in in vin:
                tx_in.script_witness = Witness.parse(stream, check_validity)

        lock_time = int.from_bytes(stream.read(4),
                                   byteorder="little",
                                   signed=False)

        return cls(version, lock_time, vin, vout, check_validity)
Exemple #3
0
def test_witness() -> None:
    witness = Witness()
    assert not witness.stack
    assert len(witness) == 0
    witness.assert_valid()
    assert witness == Witness.parse(witness.serialize())
    assert witness == Witness.from_dict(witness.to_dict())

    stack = [
        "",
        "3044022077ecafa04bc23f87057bd54b572a473cf5cc6a945c167fcefe561618b86d097002200eb7c62a855295c8c288ff972c58905861a98260dafb6f8b7587cfda3091e00d01",
        "3045022100f20ba32865985e66985ba2d7ad11950309e253788b2edb27ccf5899e806f43ef02202899d98360f6476fcefbbf1dc1813595f4d0807d13237218de5ffaaeaa85640101",
        "304402206f7f5b0723d61f5d9f2ecbae448646d4cf0cf3ecade5ab50867fdfe8e131ce8f02207f0c260620e41dbdecd6ce574bf2773de248178d33f24aee71627843560137cd01",
        "01",
        "635321024713c6e66da107644c64ab84189840e78310b247cc7fa563d6f98f2a46900a0d21026cb4cc5bbde0e59806657b1780a9a3b333a8acb6fcac48ade7d52e2b34aa30042102b6615b55426b7362cd82897db26b1423e3732f98eaea5cd2c150c49a46003c6521033557edc1a6aec5a28648f6e22deb542e9ee8c9219d5bb5e81d0fe23c8f955ad221039d7f91444b2d4c4e89a1f550fa7d32c5d9b75a49b14c54f10109d95f637bb7de2103d9cdf5c6da8b2fd66fa918916cc93d831f16781c01ca759c9cf60acf94268bbd56ae67029000b275522102d02570ed9db9ee6abd13a6c269758debcfaa1aa6d0857553e5b6a5cf764ffe0a21030968209ccaaae1c0f8ee7a4a3594b3504fd3f89db1c259aedbdce3aba29f219321036069299a8a990474eb34786bf446e724088896a54bf848650c9543f18af602dc53ae68",
    ]
    witness = Witness(stack)
    assert len(witness) == 6
    witness.assert_valid()
    assert witness == Witness.parse(witness.serialize())
    assert witness == Witness.from_dict(witness.to_dict())
Exemple #4
0
    def parse(cls: Type["Tx"],
              data: BinaryData,
              check_validity: bool = True) -> "Tx":
        "Return a Tx by parsing binary data."

        stream = bytesio_from_binarydata(data)

        # version is a signed int (int32_t) in bitcoin_core
        # However there are at least two transactions:
        # 35e79ee733fad376e76d16d1f10088273c2f4c2eaba1374a837378a88e530005
        # c659729a7fea5071361c2c1a68551ca2bf77679b27086cc415adeeb03852e369
        # where the version number is negative if it is considered as a signed
        # integer. As such in btclib the version is an UNSIGNED integer.
        # This has been discussed in: https://github.com/bitcoin/bitcoin/pull/16525
        version = int.from_bytes(stream.read(4),
                                 byteorder="little",
                                 signed=False)

        segwit = stream.read(2) == _SEGWIT_MARKER
        if not segwit:
            # Change stream position: seek to byte offset relative to position
            stream.seek(-2, SEEK_CUR)  # current position

        n = var_int.parse(stream)
        vin = [TxIn.parse(stream) for _ in range(n)]

        n = var_int.parse(stream)
        vout = [TxOut.parse(stream) for _ in range(n)]

        if segwit:
            for tx_in in vin:
                tx_in.script_witness = Witness.parse(stream, check_validity)

        lock_time = int.from_bytes(stream.read(4),
                                   byteorder="little",
                                   signed=False)

        return cls(version, lock_time, vin, vout, check_validity)
Exemple #5
0
def test_dataclasses_json_dict() -> None:
    witness_bytes = "0600483045022100a2c452a28dc58984d809e445bc9429d2e5023eafc6b070e64655928034409b7e022071de7f967b0f2e3e99d636b6e5497197cd2d4dbea81c8b42f8f0a9a8709987b701483045022100cace5cc666336fd9b620f5853d0e344da3bf2face0ac28c968240a635efe71ea022000c8bf8aafeab9c62a0815efcbc11890a742d0baee9be652b316060be54dde750147304402202ed13a2a660020e030c40a49378c507e86ec73d05c59b045b8502126630a03e3022051b6160547ac9604cc30ecfbdab66545783182b8ea30ceac657366ccea08575b010101fd1e0163532102ccb438a1d9fae7aaff5c058949f0768d4fa24671f1c43643f194098316a854752102f3448accdbf6e648ff8c9c591797b57ebfbd7bab0e2a4fcaeba686f9a9df58e121033a1229e67ad80e37234edafda3fc9dc02a2e5d70e7d861c11c94515d178edaf52103519b8d8f86813e07852728d31338f1d1d772865bf4792aa87d6f1ceb1e348fcd2103cd36dabe3dfd4e473a5a62a97a40b2e6bb47bb502bcf13163c91262f0604a06855ae67029000b27552210219d79d15338a4596b2a5dc88d191e0ae85fbfdd30802a18b3c3ff0d1c1c7c6f121025dedb64d7e5046f62b506ae9ec391ab15e70acb8d3d98c5527a481526a25d4f62103cee6fe19333a1b2e11e424bb106dfe4bc61daa273badb1de86c19dbc9037cdcd53ae68"
    witness = Witness.parse(witness_bytes)

    # Witness dataclass
    assert isinstance(witness, Witness)
    assert witness.stack
    assert len(witness.stack) > 0

    # Witness dataclass to dict
    witness_dict = witness.to_dict()
    assert isinstance(witness_dict, dict)
    assert witness_dict["stack"]
    assert len(witness_dict["stack"]) > 0  # type: ignore

    # Witness dataclass dict to file
    datadir = path.join(path.dirname(__file__), "_generated_files")
    filename = path.join(datadir, "witness.json")
    with open(filename, "w", encoding="ascii") as file_:
        json.dump(witness_dict, file_, indent=4)

    # Witness dataclass dict from file
    with open(filename, "r", encoding="ascii") as file_:
        witness_dict2 = json.load(file_)
    assert isinstance(witness_dict2, dict)
    assert witness_dict2["stack"]
    assert len(witness_dict2["stack"]) > 0  # type: ignore

    assert witness_dict == witness_dict2

    # Witness dataclass from dict
    witness2 = Witness.from_dict(witness_dict)
    assert isinstance(witness2, Witness)
    assert witness2.stack
    assert len(witness2.stack) > 0

    assert witness == witness2