From e80019a4131cfd9aef617f165aa7ef7d4852856e Mon Sep 17 00:00:00 2001 From: Jerry Date: Tue, 18 Apr 2023 21:17:39 -0700 Subject: [PATCH] Fix _get_script in blockfrost context Sometimes script cbor returned from blockfrost needs to be reloaded by cbor again, sometimes not. This fix will handle both cases. --- pycardano/backend/blockfrost.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/pycardano/backend/blockfrost.py b/pycardano/backend/blockfrost.py index 60abb11e..5e2225c5 100644 --- a/pycardano/backend/blockfrost.py +++ b/pycardano/backend/blockfrost.py @@ -4,6 +4,7 @@ import warnings from typing import Dict, List, Optional, Union +import cbor2 from blockfrost import ApiError, ApiUrls, BlockFrostApi from blockfrost.utils import Namespace @@ -18,7 +19,7 @@ from pycardano.hash import SCRIPT_HASH_SIZE, DatumHash, ScriptHash from pycardano.nativescript import NativeScript from pycardano.network import Network -from pycardano.plutus import ExecutionUnits, PlutusV1Script, PlutusV2Script +from pycardano.plutus import ExecutionUnits, PlutusV1Script, PlutusV2Script, script_hash from pycardano.serialization import RawCBOR from pycardano.transaction import ( Asset, @@ -34,6 +35,19 @@ __all__ = ["BlockFrostChainContext"] +def _try_fix_script( + scripth: str, script: Union[PlutusV1Script, PlutusV2Script] +) -> Union[PlutusV1Script, PlutusV2Script]: + if str(script_hash(script)) == scripth: + return script + else: + new_script = script.__class__(cbor2.loads(script)) + if str(script_hash(new_script)) == scripth: + return new_script + else: + raise ValueError("Cannot recover script from hash.") + + class BlockFrostChainContext(ChainContext): """A `BlockFrost `_ API wrapper for the client code to interact with. @@ -151,9 +165,15 @@ def _get_script( ) -> Union[PlutusV1Script, PlutusV2Script, NativeScript]: script_type = self.api.script(script_hash).type if script_type == "plutusV1": - return PlutusV1Script(bytes.fromhex(self.api.script_cbor(script_hash).cbor)) + v1script = PlutusV1Script( + bytes.fromhex(self.api.script_cbor(script_hash).cbor) + ) + return _try_fix_script(script_hash, v1script) elif script_type == "plutusV2": - return PlutusV2Script(bytes.fromhex(self.api.script_cbor(script_hash).cbor)) + v2script = PlutusV2Script( + bytes.fromhex(self.api.script_cbor(script_hash).cbor) + ) + return _try_fix_script(script_hash, v2script) else: script_json: JsonDict = self.api.script_json( script_hash, return_type="json"