diff --git a/examples/plutus/forty_two/forty_two.py b/examples/plutus/forty_two/forty_two.py index 70f3b365..dbaa55bb 100644 --- a/examples/plutus/forty_two/forty_two.py +++ b/examples/plutus/forty_two/forty_two.py @@ -94,7 +94,7 @@ def create_collateral(target_address, skey): # Notice that transaction builder will automatically estimate execution units (num steps & memory) for a redeemer if # no execution units are provided in the constructor of Redeemer. # Put integer 42 (the secret that unlocks the fund) in the redeemer. -redeemer = Redeemer(RedeemerTag.SPEND, 42) +redeemer = Redeemer(42) utxo_to_spend = None for utxo in chain_context.utxos(str(script_address)): diff --git a/integration-test/test/test_min_utxo.py b/integration-test/test/test_min_utxo.py index da431e5a..f54bb00c 100644 --- a/integration-test/test/test_min_utxo.py +++ b/integration-test/test/test_min_utxo.py @@ -66,7 +66,7 @@ class MyPlutusData(PlutusData): # Add minting script with an empty datum and a minting redeemer builder.add_minting_script( - anymint_script, redeemer=Redeemer(RedeemerTag.MINT, MyPlutusData(a=42)) + anymint_script, redeemer=Redeemer(MyPlutusData(a=42)) ) # Set nft we want to mint diff --git a/integration-test/test/test_mint.py b/integration-test/test/test_mint.py index 7cda39a7..3d16fba9 100644 --- a/integration-test/test/test_mint.py +++ b/integration-test/test/test_mint.py @@ -214,9 +214,7 @@ def test_mint_nft_with_script(self): builder.add_input_address(address) # Add minting script with an empty datum and a minting redeemer - builder.add_minting_script( - forty_two_script, redeemer=Redeemer(RedeemerTag.MINT, 42) - ) + builder.add_minting_script(forty_two_script, redeemer=Redeemer(42)) # Set nft we want to mint builder.mint = my_nft @@ -311,7 +309,7 @@ class MyPlutusData(PlutusData): # Add minting script with an empty datum and a minting redeemer builder.add_minting_script( - anymint_script, redeemer=Redeemer(RedeemerTag.MINT, MyPlutusData(a=42)) + anymint_script, redeemer=Redeemer(MyPlutusData(a=42)) ) # Set nft we want to mint diff --git a/integration-test/test/test_plutus.py b/integration-test/test/test_plutus.py index c1dd9eb8..9d702a3d 100644 --- a/integration-test/test/test_plutus.py +++ b/integration-test/test/test_plutus.py @@ -61,7 +61,7 @@ def test_plutus_v1(self): # ----------- Taker take --------------- - redeemer = Redeemer(RedeemerTag.SPEND, 42) + redeemer = Redeemer(42) utxo_to_spend = self.chain_context.utxos(str(script_address))[0] @@ -128,7 +128,7 @@ def test_plutus_v2_datum_hash(self): # ----------- Taker take --------------- - redeemer = Redeemer(RedeemerTag.SPEND, 42) + redeemer = Redeemer(42) utxo_to_spend = None @@ -206,7 +206,7 @@ def test_plutus_v2_inline_script_inline_datum(self): # ----------- Taker take --------------- - redeemer = Redeemer(RedeemerTag.SPEND, 42) + redeemer = Redeemer(42) utxo_to_spend = None @@ -285,7 +285,7 @@ def test_plutus_v2_ref_script(self): # ----------- Taker take --------------- - redeemer = Redeemer(RedeemerTag.SPEND, 42) + redeemer = Redeemer(42) utxo_to_spend = None diff --git a/pycardano/plutus.py b/pycardano/plutus.py index 3906344e..d0feed08 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -697,7 +697,7 @@ def __add__(self, other: ExecutionUnits) -> ExecutionUnits: @dataclass(repr=False) class Redeemer(ArrayCBORSerializable): - tag: RedeemerTag + tag: Optional[RedeemerTag] = field(default=None, init=False) index: int = field(default=0, init=False) @@ -710,9 +710,8 @@ class Redeemer(ArrayCBORSerializable): def from_primitive(cls: Type[Redeemer], values: list) -> Redeemer: if isinstance(values[2], CBORTag) and cls is Redeemer: values[2] = RawPlutusData.from_primitive(values[2]) - redeemer = super(Redeemer, cls).from_primitive( - [values[0], values[2], values[3]] - ) + redeemer = super(Redeemer, cls).from_primitive([values[2], values[3]]) + redeemer.tag = RedeemerTag.from_primitive(values[0]) redeemer.index = values[1] return redeemer diff --git a/pycardano/txbuilder.py b/pycardano/txbuilder.py index 0ebd7ff9..673c1981 100644 --- a/pycardano/txbuilder.py +++ b/pycardano/txbuilder.py @@ -226,6 +226,12 @@ def add_script_input( self.datums[datum_hash(datum)] = datum if redeemer: + if redeemer.tag is not None and redeemer.tag != RedeemerTag.SPEND: + raise InvalidArgumentException( + f"Expect the redeemer tag's type to be {RedeemerTag.SPEND}, " + f"but got {redeemer.tag} instead." + ) + redeemer.tag = RedeemerTag.SPEND self._consolidate_redeemer(redeemer) self._inputs_to_redeemers[utxo] = redeemer @@ -266,11 +272,12 @@ def add_minting_script( TransactionBuilder: Current transaction builder. """ if redeemer: - if redeemer.tag != RedeemerTag.MINT: + if redeemer.tag is not None and redeemer.tag != RedeemerTag.MINT: raise InvalidArgumentException( f"Expect the redeemer tag's type to be {RedeemerTag.MINT}, " f"but got {redeemer.tag} instead." ) + redeemer.tag = RedeemerTag.MINT self._consolidate_redeemer(redeemer) if isinstance(script, UTxO): @@ -1119,6 +1126,9 @@ def _update_execution_units( change_address, merge_change, collateral_change_address ) for r in self.redeemers: + assert ( + r.tag is not None + ), "Expected tag of redeemer to be set, but found None" key = f"{r.tag.name.lower()}:{r.index}" if ( key not in estimated_execution_units diff --git a/test/pycardano/test_plutus.py b/test/pycardano/test_plutus.py index 5fd7147e..8e0fdcf1 100644 --- a/test/pycardano/test_plutus.py +++ b/test/pycardano/test_plutus.py @@ -1,6 +1,6 @@ -from dataclasses import dataclass +from dataclasses import dataclass, field from test.pycardano.util import check_two_way_cbor -from typing import Union +from typing import Union, Optional import pytest @@ -152,7 +152,8 @@ def test_plutus_data_hash(): def test_redeemer(): data = MyTest(123, b"234", IndefiniteList([4, 5, 6]), {1: b"1", 2: b"2"}) - redeemer = MyRedeemer(RedeemerTag.SPEND, data, ExecutionUnits(1000000, 1000000)) + redeemer = MyRedeemer(data, ExecutionUnits(1000000, 1000000)) + redeemer.tag = RedeemerTag.SPEND assert ( "840000d8668218829f187b433233349f040506ffa2014131024132ff821a000f42401a000f4240" == redeemer.to_cbor() @@ -162,7 +163,8 @@ def test_redeemer(): def test_redeemer_empty_datum(): data = MyTest(123, b"234", IndefiniteList([]), {1: b"1", 2: b"2"}) - redeemer = MyRedeemer(RedeemerTag.SPEND, data, ExecutionUnits(1000000, 1000000)) + redeemer = MyRedeemer(data, ExecutionUnits(1000000, 1000000)) + redeemer.tag = RedeemerTag.SPEND assert ( "840000d8668218829f187b433233349fffa2014131024132ff821a000f42401a000f4240" == redeemer.to_cbor() diff --git a/test/pycardano/test_txbuilder.py b/test/pycardano/test_txbuilder.py index 0d2957a5..74696492 100644 --- a/test/pycardano/test_txbuilder.py +++ b/test/pycardano/test_txbuilder.py @@ -455,15 +455,11 @@ def test_add_script_input(chain_context): script_address, Value(10000000, mint), datum_hash=datum.hash() ), ) - redeemer1 = Redeemer( - RedeemerTag.SPEND, PlutusData(), ExecutionUnits(1000000, 1000000) - ) - redeemer2 = Redeemer( - RedeemerTag.MINT, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer1 = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) + redeemer2 = Redeemer(PlutusData(), ExecutionUnits(5000000, 1000000)) tx_builder.mint = mint tx_builder.add_script_input(utxo1, plutus_script, datum, redeemer1) - tx_builder.add_script_input(utxo2, plutus_script, datum, redeemer2) + tx_builder.add_minting_script(plutus_script, redeemer2) receiver = Address.from_primitive( "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x" ) @@ -490,9 +486,7 @@ def test_add_script_input_no_script(chain_context): script_address, 10000000, datum_hash=datum.hash(), script=plutus_script ), ) - redeemer = Redeemer( - RedeemerTag.SPEND, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) tx_builder.add_script_input(utxo1, datum=datum, redeemer=redeemer) receiver = Address.from_primitive( "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x" @@ -534,9 +528,7 @@ def test_add_script_input_find_script(chain_context): mock_utxos.return_value = original_utxos + [existing_script_utxo] - redeemer = Redeemer( - RedeemerTag.SPEND, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) tx_builder.add_script_input(utxo1, datum=datum, redeemer=redeemer) receiver = Address.from_primitive( "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x" @@ -573,9 +565,7 @@ def test_add_script_input_with_script_from_specified_utxo(chain_context): TransactionOutput(script_address, 1234567, script=plutus_script), ) - redeemer = Redeemer( - RedeemerTag.SPEND, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) tx_builder.add_script_input( utxo1, script=existing_script_utxo, datum=datum, redeemer=redeemer ) @@ -609,9 +599,7 @@ def test_add_minting_script_from_specified_utxo(chain_context): mint = MultiAsset.from_primitive({script_hash.payload: {b"TestToken": 1}}) - redeemer = Redeemer( - RedeemerTag.MINT, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) tx_builder.add_minting_script(existing_script_utxo, redeemer=redeemer) receiver = Address.from_primitive( "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x" @@ -662,9 +650,7 @@ def test_collateral_return(chain_context): mock_utxos.return_value = original_utxos + [existing_script_utxo] - redeemer = Redeemer( - RedeemerTag.SPEND, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) tx_builder.add_script_input(utxo1, datum=datum, redeemer=redeemer) receiver = Address.from_primitive( "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x" @@ -700,16 +686,14 @@ def test_wrong_redeemer_execution_units(chain_context): script_address, Value(10000000, mint), datum_hash=datum.hash() ), ) - redeemer1 = Redeemer(RedeemerTag.SPEND, PlutusData()) - redeemer2 = Redeemer(RedeemerTag.MINT, PlutusData()) - redeemer3 = Redeemer( - RedeemerTag.MINT, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer1 = Redeemer(PlutusData()) + redeemer2 = Redeemer(PlutusData()) + redeemer3 = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) tx_builder.mint = mint tx_builder.add_script_input(utxo1, plutus_script, datum, redeemer1) - tx_builder.add_script_input(utxo1, plutus_script, datum, redeemer2) + tx_builder.add_minting_script(plutus_script, redeemer2) with pytest.raises(InvalidArgumentException): - tx_builder.add_script_input(utxo2, plutus_script, datum, redeemer3) + tx_builder.add_minting_script(plutus_script, redeemer3) def test_all_redeemer_should_provide_execution_units(chain_context): @@ -728,10 +712,8 @@ def test_all_redeemer_should_provide_execution_units(chain_context): tx_in1, TransactionOutput(script_address, 10000000, datum_hash=datum.hash()) ) mint = MultiAsset.from_primitive({script_hash.payload: {b"TestToken": 1}}) - redeemer1 = Redeemer( - RedeemerTag.SPEND, PlutusData(), ExecutionUnits(1000000, 1000000) - ) - redeemer2 = Redeemer(RedeemerTag.MINT, PlutusData()) + redeemer1 = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) + redeemer2 = Redeemer(PlutusData()) tx_builder.mint = mint tx_builder.add_script_input(utxo1, plutus_script, datum, redeemer1) with pytest.raises(InvalidArgumentException): @@ -748,9 +730,7 @@ def test_add_minting_script(chain_context): script_address = Address(script_hash) utxo1 = UTxO(tx_in1, TransactionOutput(script_address, 10000000)) mint = MultiAsset.from_primitive({script_hash.payload: {b"TestToken": 1}}) - redeemer1 = Redeemer( - RedeemerTag.MINT, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer1 = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) tx_builder.mint = mint tx_builder.add_input(utxo1) tx_builder.add_minting_script(plutus_script, redeemer1) @@ -766,9 +746,8 @@ def test_add_minting_script(chain_context): def test_add_minting_script_wrong_redeemer_type(chain_context): tx_builder = TransactionBuilder(chain_context) plutus_script = PlutusV1Script(b"dummy test script") - redeemer1 = Redeemer( - RedeemerTag.SPEND, PlutusData(), ExecutionUnits(1000000, 1000000) - ) + redeemer1 = Redeemer(PlutusData(), ExecutionUnits(1000000, 1000000)) + redeemer1.tag = RedeemerTag.SPEND with pytest.raises(InvalidArgumentException): tx_builder.add_minting_script(plutus_script, redeemer1) @@ -853,7 +832,7 @@ def test_estimate_execution_unit(chain_context): tx_in1, TransactionOutput(script_address, 10000000, datum_hash=datum.hash()) ) mint = MultiAsset.from_primitive({script_hash.payload: {b"TestToken": 1}}) - redeemer1 = Redeemer(RedeemerTag.SPEND, PlutusData()) + redeemer1 = Redeemer(PlutusData()) tx_builder.mint = mint tx_builder.add_script_input(utxo1, plutus_script, datum, redeemer1) receiver = Address.from_primitive( diff --git a/test/pycardano/test_util.py b/test/pycardano/test_util.py index b965f9cd..3732db2c 100644 --- a/test/pycardano/test_util.py +++ b/test/pycardano/test_util.py @@ -147,7 +147,8 @@ def test_min_lovelace_multi_asset_9(self, chain_context): def test_script_data_hash(): unit = PlutusData() - redeemers = [Redeemer(RedeemerTag.SPEND, unit, ExecutionUnits(1000000, 1000000))] + redeemers = [Redeemer(unit, ExecutionUnits(1000000, 1000000))] + redeemers[0].tag = RedeemerTag.SPEND assert ScriptDataHash.from_primitive( "032d812ee0731af78fe4ec67e4d30d16313c09e6fb675af28f825797e8b5621d" ) == script_data_hash(redeemers=redeemers, datums=[unit])