def test_creation() -> None: psbt_str = "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAAAAAA=" psbt = Psbt.b64decode(psbt_str) assert psbt.b64encode() == psbt_str output_1 = TxOut( 149990000, ScriptPubKey("0014d85c2b71d0060b09c9886aeb815e50991dda124d")) output_2 = TxOut( 100000000, ScriptPubKey("001400aea9a2e5f0f876a588df5546e8742d1d87008f")) input_1 = TxIn( OutPoint( "75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858", 0), b"", 0xFFFFFFFF, ) input_2 = TxIn( OutPoint( "1dea7cd05979072a3578cab271c02244ea8a090bbb46aa680a65ecd027048d83", 1), b"", 0xFFFFFFFF, ) transaction = Tx(2, 0, [input_1, input_2], [output_1, output_2]) psbt_from_tx_ = Psbt.from_tx(transaction) assert psbt_from_tx_ == psbt
def test_p2pk() -> None: pub_key = "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" signature = "304402200A5C6163F07B8D3B013C4D1D6DBA25E780B39658D79BA37AF7057A3B7F15FFA102201FD9B4EAA9943F734928B99A83592C2E7BF342EA2680F6A2BB705167966B742001" script_pub_key = serialize([pub_key, "OP_CHECKSIG"]) script_sig = serialize([signature]) founding_tx_script = serialize(["OP_0", "OP_0"]) tx_in = TxIn(OutPoint(b"\x00" * 32, 0xFFFFFFFF), founding_tx_script, 0xFFFFFFFF) funding_tx = Tx(1, 0, [tx_in], [TxOut(0, script_pub_key)]) tx_in = TxIn(OutPoint(funding_tx.id, 0), script_sig, 0xFFFFFFFF) receiving_tx = Tx(1, 0, [tx_in], [TxOut(0, b"")]) hash_ = sig_hash.from_tx(funding_tx.vout, receiving_tx, 0, sig_hash.ALL) assert dsa.verify_(hash_, pub_key, bytes.fromhex(signature)[:-1])
def test_p2pk_anyonecanpay() -> None: pub_key = "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf" signature = "304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790281" script_pub_key = serialize([pub_key, "OP_CHECKSIG"]) script_sig = serialize([signature]) founding_tx_script = serialize(["OP_0", "OP_0"]) tx_in = TxIn(OutPoint(b"\x00" * 32, 0xFFFFFFFF), founding_tx_script, 0xFFFFFFFF) funding_tx = Tx(1, 0, [tx_in], [TxOut(0, script_pub_key)]) tx_in = TxIn(OutPoint(funding_tx.id, 0), script_sig, 0xFFFFFFFF) receiving_tx = Tx(1, 0, [tx_in], [TxOut(0, b"")]) hash_ = sig_hash.from_tx(funding_tx.vout, receiving_tx, 0, sig_hash.ANYONECANPAY | sig_hash.ALL) assert dsa.verify_(hash_, pub_key, bytes.fromhex(signature)[:-1])
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)
def test_legacy_p2pkh() -> None: pub_key = "04280c8f66bf2ccaeb3f60a19ad4a06365f8bd6178aab0e709df2173df8f553366549aec336aae8742a84702b6c7c3052d89f5d76d535ec3716e72187956351613" signature = "3045022100ea43c4800d1a860ec89b5273898a146cfb01d34ff4c364d24a110c480d0e3f7502201c82735577f932f1ca8e1c54bf653e0f8e74e408fe83666bc85cac4472ec950801" script_sig = serialize([signature, pub_key]) out_point = OutPoint( "d8343a35ba951684f2969eafe833d9e6fe436557b9707ae76802875952e860fc", 1) tx_in = TxIn(out_point, script_sig, 0xFFFFFFFF) tx_out1 = TxOut( 2017682, bytes.fromhex("76a91413bd20236d0da56492c325dce289b4da35b4b5bd88ac")) tx_out2 = TxOut( 1049154982, bytes.fromhex("76a914da169b45781ca210f8c11617ba66bd843da76b1688ac")) tx = Tx(1, 0, [tx_in], [tx_out1, tx_out2]) script_pub_key = serialize([ "OP_DUP", "OP_HASH160", "82ac30f58baf99ec9d14e6181eee076f4e27f69c", "OP_EQUALVERIFY", "OP_CHECKSIG", ]) utxo = TxOut(1051173696, script_pub_key) hash_ = sig_hash.from_tx([utxo], tx, 0, sig_hash.ALL) assert dsa.verify_(hash_, pub_key, bytes.fromhex(signature)[:-1])
def test_dataclasses_json_dict() -> None: fname = "d4f3c2c3c218be868c77ae31bedb497e2f908d6ee5bbbe91e4933e6da680c970.bin" filename = path.join(path.dirname(__file__), "_data", fname) with open(filename, "rb") as binary_file_: temp = Tx.parse(binary_file_.read()) tx_in = temp.vin[0] # TxIn dataclass assert isinstance(tx_in, TxIn) # TxIn dataclass to dict tx_in_dict = tx_in.to_dict() assert isinstance(tx_in_dict, dict) # TxIn dataclass dict to file datadir = path.join(path.dirname(__file__), "_generated_files") filename = path.join(datadir, "tx_in.json") with open(filename, "w") as file_: json.dump(tx_in_dict, file_, indent=4) # TxIn dataclass dict from file with open(filename, "r") as file_: tx_dict2 = json.load(file_) assert isinstance(tx_dict2, dict) assert tx_in_dict == tx_dict2 # TxIn dataclass from dict tx_in2 = TxIn.from_dict(tx_in_dict) assert isinstance(tx_in2, TxIn) assert tx_in == tx_in2
def test_output_scripts_serialization() -> None: input_1 = TxIn( OutPoint( "75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858", 0), b"", 0xFFFFFFFF, ) output_1 = TxOut( 149990000, bytes.fromhex("a914256b3a9ae8145e5094329537dd4d7a25dbc9452087")) output_2 = TxOut( 100000000, bytes.fromhex("001400aea9a2e5f0f876a588df5546e8742d1d87008f")) tx = Tx(2, 0, [input_1], [output_1, output_2]) psbt = Psbt.from_tx(tx) # p2sh-p2wsh psbt.outputs[0].redeem_script = bytes.fromhex( "003BD89EE628E6EB745F99DF1E4AEF64A0DAA814850DAA509F30C0F472E0563C7A") psbt.outputs[0].witness_script = bytes.fromhex( "522103dcea327ff7b2b4449413d9dc24cef0cc9e7864bad9d6291f3f1a04b639422c312103a2c5199b333adfaed4fea7ab65485b9e23a6cb317ddae7e8c1f2bd673414bdd352ae" ) assert Psbt.b64decode(psbt.b64encode()) == psbt
def from_dict(cls: Type["Tx"], dict_: Mapping[str, Any], check_validity: bool = True) -> "Tx": return cls( dict_["version"], dict_["locktime"], [TxIn.from_dict(tx_in, False) for tx_in in dict_["vin"]], [TxOut.from_dict(tx_out, False) for tx_out in dict_["vout"]], check_validity, )
def test_p2pkh() -> None: pub_key = "038282263212C609D9EA2A6E3E172DE238D8C39CABD5AC1CA10646E23FD5F51508" signature = "304402206E05A6FE23C59196FFE176C9DDC31E73A9885638F9D1328D47C0C703863B8876022076FEB53811AA5B04E0E79F938EB19906CC5E67548BC555A8E8B8B0FC603D840C01" script_pub_key = serialize([ "OP_DUP", "OP_HASH160", "1018853670F9F3B0582C5B9EE8CE93764AC32B93", "OP_EQUALVERIFY", "OP_CHECKSIG", ]) script_sig = serialize([signature, pub_key]) founding_tx_script = serialize(["OP_0", "OP_0"]) tx_in = TxIn(OutPoint(b"\x00" * 32, 0xFFFFFFFF), founding_tx_script, 0xFFFFFFFF) funding_tx = Tx(1, 0, [tx_in], [TxOut(0, script_pub_key)]) tx_in = TxIn(OutPoint(funding_tx.id, 0), script_sig, 0xFFFFFFFF) receiving_tx = Tx(1, 0, [tx_in], [TxOut(0, b"")]) hash_ = sig_hash.from_tx(funding_tx.vout, receiving_tx, 0, sig_hash.ALL) assert dsa.verify_(hash_, pub_key, bytes.fromhex(signature)[:-1])
def test_empty_stack() -> None: utxo = TxOut( 100000000, serialize([ "OP_1", "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf" ]), ) tx_in = TxIn(OutPoint(), "", 1, Witness([])) tx = Tx(vin=[tx_in], vout=[TxOut(100000000, "")]) err_msg = "Empty stack" with pytest.raises(BTClibValueError, match=err_msg): sig_hash.from_tx([utxo], tx, 0, 0)
def test_wrapped_p2tr() -> None: script = [ "OP_1", "cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaf", ] utxo = TxOut( 100000000, serialize(["OP_HASH160", hash160(serialize(script)), "OP_EQUAL"])) tx_in = TxIn(OutPoint(), serialize(script), 1, Witness(["0A" * 32])) tx = Tx(vin=[tx_in], vout=[TxOut(100000000, "")]) err_msg = "Taproot scripts cannot be wrapped in p2sh" with pytest.raises(BTClibValueError, match=err_msg): sig_hash.from_tx([utxo], tx, 0, 0)
def test_psbt() -> None: prev_out = OutPoint( "9dcfdb5836ecfe146bdaa896605ba21222f83cd014dd47adde14fab2aba7de9b", 1) script_sig = b"" sequence = 0xFFFFFFFF tx_in = TxIn(prev_out, script_sig, sequence) tx_out1 = TxOut(2500000, "a914f987c321394968be164053d352fc49763b2be55c87") tx_out2 = TxOut( 6381891, "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d") version = 1 lock_time = 0 tx = Tx(version, lock_time, [tx_in], [tx_out1, tx_out2]) psbt = Psbt.from_tx(tx) assert psbt == Psbt.parse(psbt.serialize()) assert psbt == Psbt.from_dict(psbt.to_dict())
def test_valid_sign_2() -> None: psbt_str = "cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQEEIgAgdx/RitRZZm3Unz1WTj28QvTIR3TjYK2haBao7UiNVoEBBUdSIQOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RiED3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg71SriIGA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GELSmumcAAACAAAAAgAQAAIAiBgPeVdHh2sgF4/iljB+/m5TALz26r+En/vykmV8m+CCDvRC0prpnAAAAgAAAAIAFAACAAAA=" psbt = Psbt.b64decode(psbt_str) assert psbt.b64encode() == psbt_str transaction_input = TxIn( OutPoint( "75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858", 0), b"", 0xFFFFFFFF, ) assert psbt.inputs[0].witness_utxo is not None # pylance cannot grok the following line, even considering the above line transaction = Tx(1, 2, [transaction_input], [psbt.inputs[0].witness_utxo]) # type: ignore psbt.tx.vin[0].prev_out.tx_id = transaction.id psbt.inputs[0].non_witness_utxo = transaction psbt.assert_signable()
def test_coinbase_block_1() -> None: coinbase_out = "00f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac" tx_out = TxOut.parse(coinbase_out) assert tx_out.serialize().hex() == coinbase_out coinbase_inp = ( # prev_out "0000000000000000000000000000000000000000000000000000000000000000ffffffff" "0704ffff001d0104" # script_sig "ffffffff" # sequence ) tx_in = TxIn.parse(coinbase_inp) assert tx_in.serialize().hex() == coinbase_inp assert tx_in.prev_out.is_coinbase coinbase = "01000000" "01" + coinbase_inp + "01" + coinbase_out + "00000000" tx = Tx.parse(coinbase) assert tx.serialize(include_witness=True).hex() == coinbase assert tx == Tx.from_dict(tx.to_dict()) assert tx.version == 1 assert tx.lock_time == 0 assert len(tx.vin) == 1 assert len(tx.vout) == 1 assert tx.vin[0].script_sig == tx_in.script_sig assert tx.vout[0].script_pub_key == tx_out.script_pub_key tx_id = "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098" assert tx.id.hex() == tx_id assert tx.id == tx.hash assert tx.size == 134 assert tx.vsize == tx.size assert tx.weight == tx.size * 4 assert not tx.is_segwit() assert not any(bool(w) for w in tx.vwitness) assert not any(bool(tx_in.script_witness) for tx_in in tx.vin) assert tx.is_coinbase()
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)
def test_tx() -> None: # default constructor tx = Tx() assert not tx.is_segwit() assert not any(bool(w) for w in tx.vwitness) assert not any(bool(tx_in.script_witness) for tx_in in tx.vin) assert not tx.is_coinbase() assert tx.version == 1 assert tx.lock_time == 0 assert not tx.vin assert not tx.vout assert tx.nVersion == tx.version assert tx.nLockTime == tx.lock_time tx_id = "d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43" assert tx.id.hex() == tx_id assert tx.hash == tx.id assert tx.size == 10 assert tx.vsize == tx.size assert tx.weight == tx.size * 4 tx_2 = Tx.from_dict(tx.to_dict()) assert tx_2.is_segwit() == tx.is_segwit() assert tx_2 == tx tx_2 = Tx.parse(tx.serialize(include_witness=True)) assert tx_2.is_segwit() == tx.is_segwit() assert tx_2 == tx tx_2 = Tx.parse(tx.serialize(include_witness=False)) assert not tx_2.is_segwit() assert tx_2 == tx # non-default constructor, no segwit prev_out = OutPoint( "9dcfdb5836ecfe146bdaa896605ba21222f83cd014dd47adde14fab2aba7de9b", 1) script_sig = b"" sequence = 0xFFFFFFFF tx_in = TxIn(prev_out, script_sig, sequence) tx_out1 = TxOut(2500000, "a914f987c321394968be164053d352fc49763b2be55c87") tx_out2 = TxOut( 6381891, "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d") version = 1 lock_time = 0 tx = Tx(version, lock_time, [tx_in], [tx_out1, tx_out2]) assert not tx.is_segwit() assert not any(bool(w) for w in tx.vwitness) assert not any(bool(tx_in.script_witness) for tx_in in tx.vin) assert not tx.is_coinbase() assert tx.version == 1 assert tx.lock_time == 0 assert len(tx.vin) == 1 assert len(tx.vout) == 2 assert tx.nVersion == tx.version assert tx.nLockTime == tx.lock_time tx_id = "4e52f7848dab7dd89ef7ba477939574198a170bfcb2fb34355c69f5e0169f63c" assert tx.id.hex() == tx_id assert tx.hash == tx.id assert tx.size == 126 assert tx.vsize == tx.size assert tx.weight == tx.size * 4 tx_2 = Tx.from_dict(tx.to_dict()) assert tx_2.is_segwit() == tx.is_segwit() assert tx_2 == tx tx_2 = Tx.parse(tx.serialize(include_witness=True)) assert tx_2.is_segwit() == tx.is_segwit() assert tx_2 == tx tx_2 = Tx.parse(tx.serialize(include_witness=False)) assert not tx_2.is_segwit() assert tx_2 == tx # non-default constructor, with segwit version = 1 lock_time = 0 tx = Tx(version, lock_time, [tx_in], [tx_out1, tx_out2]) stack = [ "", "30440220421fbbedf2ee096d6289b99973509809d5e09589040d5e0d453133dd11b2f78a02205686dbdb57e0c44e49421e9400dd4e931f1655332e8d078260c9295ba959e05d01", "30440220398f141917e4525d3e9e0d1c6482cb19ca3188dc5516a3a5ac29a0f4017212d902204ea405fae3a58b1fc30c5ad8ac70a76ab4f4d876e8af706a6a7b4cd6fa100f4401", "52210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae", ] tx.vin[0].script_witness = Witness(stack) assert tx.is_segwit() assert any(bool(w) for w in tx.vwitness) assert any(bool(tx_in.script_witness) for tx_in in tx.vin) assert not tx.is_coinbase() assert tx.version == 1 assert tx.lock_time == 0 assert len(tx.vin) == 1 assert len(tx.vout) == 2 assert tx.nVersion == tx.version assert tx.nLockTime == tx.lock_time tx_id = "4e52f7848dab7dd89ef7ba477939574198a170bfcb2fb34355c69f5e0169f63c" assert tx.id.hex() == tx_id hash_ = "d39eb3e3954be4bdc0b3be2d980124b1e1e11fb414b886b52939b07d95a58a8f" assert tx.hash.hex() == hash_ assert tx.size == 380 assert tx.vsize == 190 assert tx.weight == 758 tx_2 = Tx.from_dict(tx.to_dict()) assert tx_2.is_segwit() == tx.is_segwit() assert tx_2 == tx tx_2 = Tx.parse(tx.serialize(include_witness=True)) assert tx_2.is_segwit() == tx.is_segwit() assert tx_2 == tx tx_2 = Tx.parse(tx.serialize(include_witness=False)) assert not tx_2.is_segwit() assert tx_2 != tx
def test_tx_in() -> None: tx_in = TxIn() assert tx_in.prev_out == OutPoint() assert tx_in.script_sig == b"" assert tx_in.sequence == 0 assert tx_in.outpoint == tx_in.prev_out assert tx_in.scriptSig == tx_in.script_sig assert tx_in.nSequence == tx_in.nSequence assert tx_in.is_coinbase() assert not tx_in.is_segwit() tx_in2 = TxIn.parse(tx_in.serialize()) assert not tx_in2.is_segwit() assert tx_in == tx_in2 tx_in2 = TxIn.from_dict(tx_in.to_dict()) assert not tx_in2.is_segwit() assert tx_in == tx_in2 tx_id = "d5b5982254eebca64e4b42a3092a10bfb76ab430455b2bf0cf7c4f7f32db1c2e" vout = 0 prev_out = OutPoint(tx_id, vout) script_sig = b"" sequence = 0 tx_in = TxIn(prev_out, script_sig, sequence) assert tx_in.prev_out == prev_out assert tx_in.script_sig == script_sig assert tx_in.sequence == sequence assert tx_in.outpoint == tx_in.prev_out assert tx_in.scriptSig == tx_in.script_sig assert tx_in.nSequence == tx_in.nSequence assert not tx_in.is_coinbase() assert not tx_in.is_segwit() tx_in2 = TxIn.parse(tx_in.serialize()) assert not tx_in2.is_segwit() assert tx_in == tx_in2 tx_in2 = TxIn.from_dict(tx_in.to_dict()) assert not tx_in2.is_segwit() assert tx_in == tx_in2 prev_out = OutPoint( "9dcfdb5836ecfe146bdaa896605ba21222f83cd014dd47adde14fab2aba7de9b", 1 ) script_sig = b"" sequence = 0xFFFFFFFF tx_in = TxIn(prev_out, script_sig, sequence) stack = [ "", "30440220421fbbedf2ee096d6289b99973509809d5e09589040d5e0d453133dd11b2f78a02205686dbdb57e0c44e49421e9400dd4e931f1655332e8d078260c9295ba959e05d01", "30440220398f141917e4525d3e9e0d1c6482cb19ca3188dc5516a3a5ac29a0f4017212d902204ea405fae3a58b1fc30c5ad8ac70a76ab4f4d876e8af706a6a7b4cd6fa100f4401", "52210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae", ] tx_in.script_witness = Witness(stack) assert tx_in.prev_out == prev_out assert tx_in.script_sig == script_sig assert tx_in.sequence == sequence assert tx_in.outpoint == tx_in.prev_out assert tx_in.scriptSig == tx_in.script_sig assert tx_in.nSequence == tx_in.nSequence assert not tx_in.is_coinbase() assert tx_in.is_segwit() tx_in2 = TxIn.parse(tx_in.serialize()) assert not tx_in2.is_segwit() assert tx_in == tx_in2 or TX_IN_COMPARES_WITNESS tx_in2 = TxIn.from_dict(tx_in.to_dict()) assert tx_in2.is_segwit() assert tx_in == tx_in2 assert tx_in != OutPoint() tx_in.sequence = 0xFFFFFFFF + 1 with pytest.raises(BTClibValueError, match="invalid sequence: "): tx_in.assert_valid()