33from __future__ import annotations
44
55from dataclasses import dataclass , field
6- from typing import ClassVar , List , Type , Union
6+ from typing import ClassVar , List , Type , Union , cast
77
88from nacl .encoding import RawEncoder
99from nacl .hash import blake2b
@@ -35,25 +35,37 @@ def from_primitive(
3535 ) -> Union [
3636 ScriptPubkey , ScriptAll , ScriptAny , ScriptNofK , InvalidBefore , InvalidHereAfter
3737 ]:
38- script_type = value [0 ]
39- for t in [
40- ScriptPubkey ,
41- ScriptAll ,
42- ScriptAny ,
43- ScriptNofK ,
44- InvalidBefore ,
45- InvalidHereAfter ,
46- ]:
47- if t ._TYPE == script_type :
48- return super (NativeScript , t ).from_primitive (value [1 :])
38+ if not isinstance (
39+ value ,
40+ (
41+ list ,
42+ tuple ,
43+ ),
44+ ):
45+ raise DeserializeException (
46+ f"A list or a tuple is required for deserialization: { str (value )} "
47+ )
48+
49+ script_type : int = value [0 ]
50+ if script_type == ScriptPubkey ._TYPE :
51+ return super (NativeScript , ScriptPubkey ).from_primitive (value [1 :])
52+ elif script_type == ScriptAll ._TYPE :
53+ return super (NativeScript , ScriptAll ).from_primitive (value [1 :])
54+ elif script_type == ScriptAny ._TYPE :
55+ return super (NativeScript , ScriptAny ).from_primitive (value [1 :])
56+ elif script_type == ScriptNofK ._TYPE :
57+ return super (NativeScript , ScriptNofK ).from_primitive (value [1 :])
58+ elif script_type == InvalidBefore ._TYPE :
59+ return super (NativeScript , InvalidBefore ).from_primitive (value [1 :])
60+ elif script_type == InvalidHereAfter ._TYPE :
61+ return super (NativeScript , InvalidHereAfter ).from_primitive (value [1 :])
4962 else :
5063 raise DeserializeException (f"Unknown script type indicator: { script_type } " )
5164
5265 def hash (self ) -> ScriptHash :
66+ cbor_bytes = cast (bytes , self .to_cbor ("bytes" ))
5367 return ScriptHash (
54- blake2b (
55- bytes (1 ) + self .to_cbor ("bytes" ), SCRIPT_HASH_SIZE , encoder = RawEncoder
56- )
68+ blake2b (bytes (1 ) + cbor_bytes , SCRIPT_HASH_SIZE , encoder = RawEncoder )
5769 )
5870
5971 @classmethod
@@ -63,43 +75,16 @@ def from_dict(
6375 ScriptPubkey , ScriptAll , ScriptAny , ScriptNofK , InvalidBefore , InvalidHereAfter
6476 ]:
6577 """Parse a standard native script dictionary (potentially parsed from a JSON file)."""
66-
67- types = {
68- p .json_tag : p
69- for p in [
70- ScriptPubkey ,
71- ScriptAll ,
72- ScriptAny ,
73- ScriptNofK ,
74- InvalidBefore ,
75- InvalidHereAfter ,
76- ]
77- }
78- script_type = script_json ["type" ]
79- target_class = types [script_type ]
8078 script_primitive = cls ._script_json_to_primitive (script_json )
81- return super ( NativeScript , target_class ) .from_primitive (script_primitive [ 1 :] )
79+ return cls .from_primitive (script_primitive )
8280
8381 @classmethod
8482 def _script_json_to_primitive (
8583 cls : Type [NativeScript ], script_json : JsonDict
8684 ) -> List [Primitive ]:
8785 """Serialize a standard JSON native script into a primitive array"""
88-
89- types = {
90- p .json_tag : p
91- for p in [
92- ScriptPubkey ,
93- ScriptAll ,
94- ScriptAny ,
95- ScriptNofK ,
96- InvalidBefore ,
97- InvalidHereAfter ,
98- ]
99- }
100-
10186 script_type : str = script_json ["type" ]
102- native_script = [types [script_type ]. _TYPE ]
87+ native_script : List [ Primitive ] = [JSON_TAG_TO_INT [script_type ]]
10388
10489 for key , value in script_json .items ():
10590 if key == "type" :
@@ -118,22 +103,18 @@ def _script_jsons_to_primitive(
118103 native_script = [cls ._script_json_to_primitive (i ) for i in script_jsons ]
119104 return native_script
120105
121- def to_dict (self ) -> dict :
106+ def to_dict (self ) -> JsonDict :
122107 """Export to standard native script dictionary (potentially to dump to a JSON file)."""
123-
124- script = {}
125-
108+ script : JsonDict = {}
126109 for value in self .__dict__ .values ():
127110 script ["type" ] = self .json_tag
128111
129112 if isinstance (value , list ):
130113 script ["scripts" ] = [i .to_dict () for i in value ]
131-
114+ elif isinstance (value , int ):
115+ script [self .json_field ] = value
132116 else :
133- if isinstance (value , int ):
134- script [self .json_field ] = value
135- else :
136- script [self .json_field ] = str (value )
117+ script [self .json_field ] = str (value )
137118
138119 return script
139120
@@ -209,7 +190,7 @@ class InvalidBefore(NativeScript):
209190 json_field : ClassVar [str ] = "slot"
210191 _TYPE : int = field (default = 4 , init = False )
211192
212- before : int = None
193+ before : int
213194
214195
215196@dataclass
@@ -218,4 +199,14 @@ class InvalidHereAfter(NativeScript):
218199 json_field : ClassVar [str ] = "slot"
219200 _TYPE : int = field (default = 5 , init = False )
220201
221- after : int = None
202+ after : int
203+
204+
205+ JSON_TAG_TO_INT = {
206+ ScriptPubkey .json_tag : ScriptPubkey ._TYPE ,
207+ ScriptAll .json_tag : ScriptAll ._TYPE ,
208+ ScriptAny .json_tag : ScriptAny ._TYPE ,
209+ ScriptNofK .json_tag : ScriptNofK ._TYPE ,
210+ InvalidBefore .json_tag : InvalidBefore ._TYPE ,
211+ InvalidHereAfter .json_tag : InvalidHereAfter ._TYPE ,
212+ }
0 commit comments