Skip to content

Commit

Permalink
Test for correctness of the supplied script
Browse files Browse the repository at this point in the history
This is to avoid users accidentally adding script inputs with the wrong
script and then get cryptic errors from ogmios.
  • Loading branch information
nielstron committed Mar 1, 2024
1 parent efbc2d2 commit 5399f27
Showing 1 changed file with 34 additions and 13 deletions.
47 changes: 34 additions & 13 deletions pycardano/txbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
RedeemerTag,
ScriptType,
datum_hash,
script_hash,
script_hash, plutus_script_hash,
)
from pycardano.transaction import (
Asset,
Expand Down Expand Up @@ -250,24 +250,45 @@ def add_script_input(
self._consolidate_redeemer(redeemer)
self._inputs_to_redeemers[utxo] = redeemer

input_script_hash = utxo.output.address.payment_part
if not isinstance(input_script_hash, ScriptHash):
raise InvalidArgumentException(
f"Expect the payment part of the address to be of a script (type ScriptHash), "
f"but got {type(input_script_hash)} instead."
)

# collect potential scripts to fulfill the input
candidate_scripts = []
if utxo.output.script:
self._inputs_to_scripts[utxo] = utxo.output.script
self.reference_inputs.add(utxo)
self._reference_scripts.append(utxo.output.script)
candidate_scripts.append((utxo.output.script, utxo))
elif not script:
for i in self.context.utxos(utxo.output.address):
if i.output.script:
self._inputs_to_scripts[utxo] = i.output.script
self.reference_inputs.add(i)
self._reference_scripts.append(i.output.script)
break
candidate_scripts.append((i.output.script, i))
elif isinstance(script, UTxO):
assert script.output.script is not None
self._inputs_to_scripts[utxo] = script.output.script
self.reference_inputs.add(script)
self._reference_scripts.append(script.output.script)
if script.output.script is None:
raise InvalidArgumentException(
f"Expect the output of the UTxO to have a script, "
f"but got None instead."
)
candidate_scripts.append((script.output.script, script))
else:
self._inputs_to_scripts[utxo] = script
candidate_scripts.append((script, None))

found_valid_script = False
for candidate_script, candidate_utxo in candidate_scripts:
if script_hash(candidate_script) != input_script_hash:
continue
found_valid_script = True
self._inputs_to_scripts[utxo] = candidate_script
if candidate_utxo is not None:
self.reference_inputs.add(candidate_utxo)
self._reference_scripts.append(candidate_script)
if not found_valid_script:
raise InvalidArgumentException(
f"Cannot find a valid script to fulfill the input UTxO: {utxo}."
"Supplied scripts do not match the payment part of the input address."
)

self.inputs.append(utxo)
return self
Expand Down

0 comments on commit 5399f27

Please sign in to comment.