3
3
from __future__ import annotations
4
4
5
5
from dataclasses import dataclass , field
6
- from typing import List , Union
6
+ from typing import ClassVar , List , Union
7
7
8
8
from nacl .encoding import RawEncoder
9
9
from nacl .hash import blake2b
@@ -52,16 +52,80 @@ def hash(self) -> ScriptHash:
52
52
)
53
53
)
54
54
55
+ @classmethod
56
+ def from_dict (
57
+ cls : NativeScript , script : dict , top_level : bool = True
58
+ ) -> Union [
59
+ ScriptPubkey , ScriptAll , ScriptAny , ScriptNofK , InvalidBefore , InvalidHereAfter
60
+ ]:
61
+ """Parse a standard native script dictionary (potentially parsed from a JSON file)."""
62
+
63
+ types = {
64
+ p .json_tag : p
65
+ for p in [
66
+ ScriptPubkey ,
67
+ ScriptAll ,
68
+ ScriptAny ,
69
+ ScriptNofK ,
70
+ InvalidBefore ,
71
+ InvalidHereAfter ,
72
+ ]
73
+ }
74
+
75
+ if isinstance (script , dict ):
76
+ native_script = []
77
+
78
+ for key , value in script .items ():
79
+ if key == "type" :
80
+ native_script .insert (0 , list (types .keys ()).index (value ))
81
+ elif key == "scripts" :
82
+ native_script .append (cls .from_dict (value , top_level = False ))
83
+ else :
84
+ native_script .append (value )
85
+
86
+ elif isinstance (script , list ): # list
87
+ native_script = [cls .from_dict (i , top_level = False ) for i in script ]
88
+
89
+ if not top_level :
90
+ return native_script
91
+ else :
92
+ return super (NativeScript , types [script ["type" ]]).from_primitive (
93
+ native_script [1 :]
94
+ )
95
+
96
+ def to_dict (self ) -> dict :
97
+ """Export to standard native script dictionary (potentially to dump to a JSON file)."""
98
+
99
+ script = {}
100
+
101
+ for value in self .__dict__ .values ():
102
+ script ["type" ] = self .json_tag
103
+
104
+ if isinstance (value , list ):
105
+ script ["scripts" ] = [i .to_dict () for i in value ]
106
+
107
+ else :
108
+ if isinstance (value , int ):
109
+ script [self .json_field ] = value
110
+ else :
111
+ script [self .json_field ] = str (value )
112
+
113
+ return script
114
+
55
115
56
116
@dataclass
57
117
class ScriptPubkey (NativeScript ):
118
+ json_tag : ClassVar [str ] = "sig"
119
+ json_field : ClassVar [str ] = "keyHash"
58
120
_TYPE : int = field (default = 0 , init = False )
59
121
60
122
key_hash : VerificationKeyHash
61
123
62
124
63
125
@dataclass
64
126
class ScriptAll (NativeScript ):
127
+ json_tag : ClassVar [str ] = "all"
128
+ json_field : ClassVar [str ] = "scripts"
65
129
_TYPE : int = field (default = 1 , init = False )
66
130
67
131
native_scripts : List [
@@ -78,6 +142,8 @@ class ScriptAll(NativeScript):
78
142
79
143
@dataclass
80
144
class ScriptAny (NativeScript ):
145
+ json_tag : ClassVar [str ] = "any"
146
+ json_field : ClassVar [str ] = "scripts"
81
147
_TYPE : int = field (default = 2 , init = False )
82
148
83
149
native_scripts : List [
@@ -94,6 +160,8 @@ class ScriptAny(NativeScript):
94
160
95
161
@dataclass
96
162
class ScriptNofK (NativeScript ):
163
+ json_tag : ClassVar [str ] = "atLeast"
164
+ json_field : ClassVar [str ] = "required"
97
165
_TYPE : int = field (default = 3 , init = False )
98
166
99
167
n : int
@@ -112,13 +180,17 @@ class ScriptNofK(NativeScript):
112
180
113
181
@dataclass
114
182
class InvalidBefore (NativeScript ):
183
+ json_tag : ClassVar [str ] = "after"
184
+ json_field : ClassVar [str ] = "slot"
115
185
_TYPE : int = field (default = 4 , init = False )
116
186
117
187
before : int = None
118
188
119
189
120
190
@dataclass
121
191
class InvalidHereAfter (NativeScript ):
192
+ json_tag : ClassVar [str ] = "before"
193
+ json_field : ClassVar [str ] = "slot"
122
194
_TYPE : int = field (default = 5 , init = False )
123
195
124
196
after : int = None
0 commit comments