Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions integration-test/test/test_plutus.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,45 @@ def test_plutus_v2_ref_script(self):

self.assert_output(taker_address, take_output)

@retry(tries=TEST_RETRIES, backoff=1.3, delay=2, jitter=(0, 10))
@pytest.mark.post_alonzo
def test_plutus_v2_spend_ref_script(self):
# ----------- Create a reference script ---------------
with open("./plutus_scripts/fortytwoV2.plutus", "r") as f:
script_hex = f.read()
forty_two_script = PlutusV2Script(cbor2.loads(bytes.fromhex(script_hex)))

giver_address = Address(self.payment_vkey.hash(), network=self.NETWORK)

builder = TransactionBuilder(self.chain_context)
builder.add_input_address(giver_address)
builder.add_output(
TransactionOutput(giver_address, 50000000, script=forty_two_script)
)

signed_tx = builder.build_and_sign([self.payment_skey], giver_address)

print("############### Transaction created ###############")
print(signed_tx)
print(signed_tx.to_cbor_hex())
print("############### Submitting transaction ###############")
self.chain_context.submit_tx(signed_tx)
time.sleep(6)

# ----------- Spend script utxo ---------------
utxo_to_spend = UTxO(
TransactionInput(signed_tx.id, 0), signed_tx.transaction_body.outputs[0]
)

builder = TransactionBuilder(self.chain_context)
builder.add_input(utxo_to_spend)
signed_tx = builder.build_and_sign([self.payment_skey], giver_address)
print("############### Transaction created ###############")
print(signed_tx)
print(signed_tx.to_cbor_hex())
print("############### Submitting transaction ###############")
self.chain_context.submit_tx(signed_tx)

@retry(tries=TEST_RETRIES, backoff=1.3, delay=2, jitter=(0, 10))
@pytest.mark.post_alonzo
def test_transaction_chaining(self):
Expand Down
8 changes: 7 additions & 1 deletion pycardano/txbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ def add_input(self, utxo: UTxO) -> TransactionBuilder:
TransactionBuilder: Current transaction builder.
"""
self.inputs.append(utxo)
if utxo.output.script:
self._reference_scripts.append(utxo.output.script)
return self

def _consolidate_redeemer(self, redeemer):
Expand Down Expand Up @@ -1403,7 +1405,11 @@ def build(

for address in self.input_addresses:
for utxo in self.context.utxos(address):
if utxo not in seen_utxos and utxo not in self.excluded_inputs:
if (
utxo not in seen_utxos
and utxo not in self.excluded_inputs
and utxo.output.script is None
):
additional_utxo_pool.append(utxo)
additional_amount += utxo.output.amount
seen_utxos.add(utxo)
Expand Down
57 changes: 51 additions & 6 deletions test/pycardano/test_txbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2041,12 +2041,6 @@ def test_build_witness_set_mixed_scripts(chain_context):
assert witness_set.plutus_v2_script is None
assert witness_set.plutus_v3_script is None

# Test with remove_dup_script=False
witness_set = builder.build_witness_set(remove_dup_script=False)
assert len(witness_set.plutus_v1_script) == 2
assert len(witness_set.plutus_v2_script) == 1
assert len(witness_set.plutus_v3_script) == 1


def test_add_script_input_post_chang(chain_context):
tx_builder = TransactionBuilder(chain_context)
Expand Down Expand Up @@ -2421,3 +2415,54 @@ def test_token_transfer_with_change(chain_context):
change_output.amount.multi_asset[token_policy_id][token_name]
== 1876083 - 382
)


def test_spend_utxo_with_script(chain_context):
"""Test that UTxOs with scripts are added as reference scripts when added directly."""
utxo = UTxO(
TransactionInput.from_primitive(
[
"a6cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef",
0,
]
),
TransactionOutput(
Address.from_primitive(
"addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x"
),
Value(10000000),
script=PlutusV2Script(b"dummy test script"),
),
)

tx_builder = TransactionBuilder(chain_context)
tx_builder.add_input(utxo)
assert len(tx_builder._reference_scripts) == 1


def test_skip_utxo_with_script(chain_context):
"""Test that UTxOs with scripts are skipped when selecting UTxOs by address."""
addr = Address.from_primitive(
"addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x"
)

utxo = UTxO(
TransactionInput.from_primitive(
[
"a6cbe6cadecd3f89b60e08e68e5e6c7d72d730aaa1ad21431590f7e6643438ef",
0,
]
),
TransactionOutput(
addr,
Value(10000000),
script=PlutusV2Script(b"dummy test script"),
),
)

with patch.object(chain_context, "utxos") as mock_utxos:
mock_utxos.return_value = [utxo]
tx_builder = TransactionBuilder(chain_context)
tx_builder.add_input_address(addr)
with pytest.raises(UTxOSelectionException):
tx_builder.build()