3
3
from __future__ import annotations
4
4
5
5
from dataclasses import dataclass , field
6
- from typing import ClassVar , List , Type , Union
6
+ from typing import ClassVar , List , Type , Union , cast
7
7
8
8
from nacl .encoding import RawEncoder
9
9
from nacl .hash import blake2b
@@ -35,25 +35,37 @@ def from_primitive(
35
35
) -> Union [
36
36
ScriptPubkey , ScriptAll , ScriptAny , ScriptNofK , InvalidBefore , InvalidHereAfter
37
37
]:
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 :])
49
62
else :
50
63
raise DeserializeException (f"Unknown script type indicator: { script_type } " )
51
64
52
65
def hash (self ) -> ScriptHash :
66
+ cbor_bytes = cast (bytes , self .to_cbor ("bytes" ))
53
67
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 )
57
69
)
58
70
59
71
@classmethod
@@ -63,43 +75,16 @@ def from_dict(
63
75
ScriptPubkey , ScriptAll , ScriptAny , ScriptNofK , InvalidBefore , InvalidHereAfter
64
76
]:
65
77
"""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 ]
80
78
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 )
82
80
83
81
@classmethod
84
82
def _script_json_to_primitive (
85
83
cls : Type [NativeScript ], script_json : JsonDict
86
84
) -> List [Primitive ]:
87
85
"""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
-
101
86
script_type : str = script_json ["type" ]
102
- native_script = [types [script_type ]. _TYPE ]
87
+ native_script : List [ Primitive ] = [JSON_TAG_TO_INT [script_type ]]
103
88
104
89
for key , value in script_json .items ():
105
90
if key == "type" :
@@ -118,22 +103,18 @@ def _script_jsons_to_primitive(
118
103
native_script = [cls ._script_json_to_primitive (i ) for i in script_jsons ]
119
104
return native_script
120
105
121
- def to_dict (self ) -> dict :
106
+ def to_dict (self ) -> JsonDict :
122
107
"""Export to standard native script dictionary (potentially to dump to a JSON file)."""
123
-
124
- script = {}
125
-
108
+ script : JsonDict = {}
126
109
for value in self .__dict__ .values ():
127
110
script ["type" ] = self .json_tag
128
111
129
112
if isinstance (value , list ):
130
113
script ["scripts" ] = [i .to_dict () for i in value ]
131
-
114
+ elif isinstance (value , int ):
115
+ script [self .json_field ] = value
132
116
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 )
137
118
138
119
return script
139
120
@@ -209,7 +190,7 @@ class InvalidBefore(NativeScript):
209
190
json_field : ClassVar [str ] = "slot"
210
191
_TYPE : int = field (default = 4 , init = False )
211
192
212
- before : int = None
193
+ before : int
213
194
214
195
215
196
@dataclass
@@ -218,4 +199,14 @@ class InvalidHereAfter(NativeScript):
218
199
json_field : ClassVar [str ] = "slot"
219
200
_TYPE : int = field (default = 5 , init = False )
220
201
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