Skip to content

Commit 5399f27

Browse files
committed
Test for correctness of the supplied script
This is to avoid users accidentally adding script inputs with the wrong script and then get cryptic errors from ogmios.
1 parent efbc2d2 commit 5399f27

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

pycardano/txbuilder.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
RedeemerTag,
4545
ScriptType,
4646
datum_hash,
47-
script_hash,
47+
script_hash, plutus_script_hash,
4848
)
4949
from pycardano.transaction import (
5050
Asset,
@@ -250,24 +250,45 @@ def add_script_input(
250250
self._consolidate_redeemer(redeemer)
251251
self._inputs_to_redeemers[utxo] = redeemer
252252

253+
input_script_hash = utxo.output.address.payment_part
254+
if not isinstance(input_script_hash, ScriptHash):
255+
raise InvalidArgumentException(
256+
f"Expect the payment part of the address to be of a script (type ScriptHash), "
257+
f"but got {type(input_script_hash)} instead."
258+
)
259+
260+
# collect potential scripts to fulfill the input
261+
candidate_scripts = []
253262
if utxo.output.script:
254-
self._inputs_to_scripts[utxo] = utxo.output.script
255-
self.reference_inputs.add(utxo)
256-
self._reference_scripts.append(utxo.output.script)
263+
candidate_scripts.append((utxo.output.script, utxo))
257264
elif not script:
258265
for i in self.context.utxos(utxo.output.address):
259266
if i.output.script:
260-
self._inputs_to_scripts[utxo] = i.output.script
261-
self.reference_inputs.add(i)
262-
self._reference_scripts.append(i.output.script)
263-
break
267+
candidate_scripts.append((i.output.script, i))
264268
elif isinstance(script, UTxO):
265-
assert script.output.script is not None
266-
self._inputs_to_scripts[utxo] = script.output.script
267-
self.reference_inputs.add(script)
268-
self._reference_scripts.append(script.output.script)
269+
if script.output.script is None:
270+
raise InvalidArgumentException(
271+
f"Expect the output of the UTxO to have a script, "
272+
f"but got None instead."
273+
)
274+
candidate_scripts.append((script.output.script, script))
269275
else:
270-
self._inputs_to_scripts[utxo] = script
276+
candidate_scripts.append((script, None))
277+
278+
found_valid_script = False
279+
for candidate_script, candidate_utxo in candidate_scripts:
280+
if script_hash(candidate_script) != input_script_hash:
281+
continue
282+
found_valid_script = True
283+
self._inputs_to_scripts[utxo] = candidate_script
284+
if candidate_utxo is not None:
285+
self.reference_inputs.add(candidate_utxo)
286+
self._reference_scripts.append(candidate_script)
287+
if not found_valid_script:
288+
raise InvalidArgumentException(
289+
f"Cannot find a valid script to fulfill the input UTxO: {utxo}."
290+
"Supplied scripts do not match the payment part of the input address."
291+
)
271292

272293
self.inputs.append(utxo)
273294
return self

0 commit comments

Comments
 (0)