1- def decode (bstream : bytes , typedef : object ) -> object :
1+ import typing
2+
3+ from pycspr .crypto import KeyAlgorithm
4+ from pycspr .factory import create_public_key
5+ from pycspr .serialisation .cl_type_from_bytes import decode as cl_type_from_bytes
6+ from pycspr .serialisation .cl_value_from_bytes import decode as cl_value_from_bytes
7+ from pycspr .types import Timestamp
8+ from pycspr .types import cl_types
9+ from pycspr .types import Deploy
10+ from pycspr .types import DeployApproval
11+ from pycspr .types import DeployArgument
12+ from pycspr .types import DeployBody
13+ from pycspr .types import DeployExecutableItem
14+ from pycspr .types import DeployHeader
15+ from pycspr .types import DeployTimeToLive
16+ from pycspr .types import ModuleBytes
17+ from pycspr .types import StoredContractByHash
18+ from pycspr .types import StoredContractByHashVersioned
19+ from pycspr .types import StoredContractByName
20+ from pycspr .types import StoredContractByNameVersioned
21+ from pycspr .types import Transfer
22+
23+
24+ def decode (bstream : bytes , typedef : object ) -> typing .Tuple [bytes , object ]:
225 """Decodes a deploy from a byte array.
326
427 :param bstream: An array of bytes being decoded.
528 :param typedef: Deploy related type definition.
629 :returns: A deploy related type.
730
831 """
9- raise NotImplementedError (typedef , bstream )
32+ try :
33+ decoder = _DECODERS [typedef ]
34+ except KeyError :
35+ raise ValueError (f"Cannot decode { typedef } from bytes" )
36+ else :
37+ return decoder (bstream )
38+
39+
40+ def _decode_deploy (bstream : bytes ) -> typing .Tuple [bytes , Deploy ]:
41+ bstream , header = decode (bstream , DeployHeader )
42+ bstream , deploy_hash = cl_value_from_bytes (bstream , cl_types .CL_Type_ByteArray (32 ))
43+ bstream , payment = decode (bstream , DeployExecutableItem )
44+ bstream , session = decode (bstream , DeployExecutableItem )
45+ bstream , approvals = _decode_deploy_approval_set (bstream )
46+
47+ return bstream , Deploy (
48+ approvals = approvals ,
49+ hash = deploy_hash .value ,
50+ header = header ,
51+ payment = payment ,
52+ session = session
53+ )
54+
55+
56+ def _decode_deploy_approval (bstream : bytes ) -> typing .Tuple [bytes , DeployApproval ]:
57+ algo = KeyAlgorithm (bstream [0 ])
58+ if algo == KeyAlgorithm .ED25519 :
59+ key_length = 32
60+ elif algo == KeyAlgorithm .SECP256K1 :
61+ key_length = 33
62+ else :
63+ raise ValueError ("Invalid Key Algorithm" )
64+ pbk = bstream [1 :key_length + 1 ]
65+ sig = bstream [key_length + 1 :key_length + 66 ]
66+ bstream = bstream [1 + key_length + 66 :]
67+
68+ return bstream , DeployApproval (
69+ signer = create_public_key (algo , pbk ),
70+ signature = sig
71+ )
72+
73+
74+ def _decode_deploy_approval_set (bstream : bytes ) -> typing .Tuple [bytes , typing .List [DeployApproval ]]:
75+ approvals = []
76+ bstream , args_length = cl_value_from_bytes (bstream , cl_types .CL_Type_U32 ())
77+ for _ in range (args_length .value ):
78+ bstream , approval = decode (bstream , DeployApproval )
79+ approvals .append (approval )
80+
81+ return bstream , approvals
82+
83+
84+ def _decode_deploy_argument (bstream : bytes ) -> typing .Tuple [bytes , DeployArgument ]:
85+ bstream , name = cl_value_from_bytes (bstream , cl_types .CL_Type_String ())
86+ bstream , val_bytes_length = cl_value_from_bytes (bstream , cl_types .CL_Type_U32 ())
87+ bstream_rem , arg_cl_type = cl_type_from_bytes (bstream [val_bytes_length .value :])
88+ _ , arg_cl_value = cl_value_from_bytes (bstream , arg_cl_type )
89+
90+ return bstream_rem , DeployArgument (name .value , arg_cl_value )
91+
92+
93+ def _decode_deploy_argument_set (bstream : bytes ) -> typing .Tuple [bytes , typing .List [DeployArgument ]]:
94+ args = []
95+ bstream , args_length = cl_value_from_bytes (bstream , cl_types .CL_Type_U32 ())
96+ for _ in range (args_length .value ):
97+ bstream , arg = decode (bstream , DeployArgument )
98+ args .append (arg )
99+
100+ return bstream , args
101+
102+
103+ def _decode_deploy_body (bstream : bytes ) -> typing .Tuple [bytes , DeployBody ]:
104+ bstream , payment = _decode_deploy_executable_item (bstream )
105+ bstream , session = _decode_deploy_executable_item (bstream )
106+ bstream , body_hash = cl_value_from_bytes (bstream , cl_types .CL_Type_ByteArray (32 ))
107+
108+ return bstream , DeployBody (payment , session , body_hash .value )
109+
110+
111+ def _decode_deploy_executable_item (bstream : bytes ) -> DeployExecutableItem :
112+ if bstream [0 ] == 0 :
113+ return decode (bstream , ModuleBytes )
114+ elif bstream [0 ] == 1 :
115+ return decode (bstream , StoredContractByHash )
116+ elif bstream [0 ] == 2 :
117+ return decode (bstream , StoredContractByHashVersioned )
118+ elif bstream [0 ] == 3 :
119+ return decode (bstream , StoredContractByName )
120+ elif bstream [0 ] == 4 :
121+ return decode (bstream , StoredContractByNameVersioned )
122+ elif bstream [0 ] == 5 :
123+ return decode (bstream , Transfer )
124+
125+ raise ValueError ("Invalid deploy executable item type tag" )
126+
127+
128+ def _decode_deploy_header (bstream : bytes ) -> typing .Tuple [bytes , DeployHeader ]:
129+ bstream , account_public_key = cl_value_from_bytes (
130+ bstream , cl_types .CL_Type_PublicKey ()
131+ )
132+ bstream , timestamp = cl_value_from_bytes (
133+ bstream , cl_types .CL_Type_U64 ()
134+ )
135+ bstream , ttl = cl_value_from_bytes (
136+ bstream , cl_types .CL_Type_U64 ()
137+ )
138+ bstream , gas_price = cl_value_from_bytes (
139+ bstream , cl_types .CL_Type_U64 ()
140+ )
141+ bstream , body_hash = cl_value_from_bytes (
142+ bstream , cl_types .CL_Type_ByteArray (32 )
143+ )
144+ bstream , dependencies = cl_value_from_bytes (
145+ bstream , cl_types .CL_Type_List (cl_types .CL_Type_ByteArray (32 ))
146+ )
147+ bstream , chain_name = cl_value_from_bytes (
148+ bstream , cl_types .CL_Type_String ()
149+ )
150+
151+ return bstream , DeployHeader (
152+ account_public_key = account_public_key ,
153+ body_hash = body_hash .value ,
154+ chain_name = chain_name .value ,
155+ dependencies = dependencies .vector ,
156+ gas_price = gas_price .value ,
157+ timestamp = Timestamp (timestamp .value / 1000 ),
158+ ttl = DeployTimeToLive .from_milliseconds (ttl .value )
159+ )
160+
161+
162+ def _decode_module_bytes (bstream : bytes ) -> typing .Tuple [bytes , ModuleBytes ]:
163+ bstream = bstream [1 :]
164+ bstream , length = cl_value_from_bytes (bstream , cl_types .CL_Type_U32 ())
165+ if length .value > 0 :
166+ module_bytes = bstream [:length .value ]
167+ bstream = bstream [length .value :]
168+ else :
169+ module_bytes = bytes ([])
170+ bstream , args = _decode_deploy_argument_set (bstream )
171+
172+ return bstream , ModuleBytes (args , module_bytes )
173+
174+
175+ def _decode_stored_contract_by_hash (bstream : bytes ) -> typing .Tuple [bytes , StoredContractByHash ]:
176+ bstream = bstream [1 :]
177+ bstream , contract_hash = cl_value_from_bytes (bstream , cl_types .CL_Type_ByteArray (32 ))
178+ bstream , entry_point = cl_value_from_bytes (bstream , cl_types .CL_Type_String ())
179+ bstream , args = _decode_deploy_argument_set (bstream )
180+
181+ return bstream , StoredContractByHash (
182+ args = args ,
183+ entry_point = entry_point .value ,
184+ hash = contract_hash .value
185+ )
186+
187+
188+ def _decode_stored_contract_by_hash_versioned (bstream : bytes ) -> typing .Tuple [bytes , StoredContractByHashVersioned ]:
189+ bstream = bstream [1 :]
190+ bstream , contract_hash = cl_value_from_bytes (bstream , cl_types .CL_Type_ByteArray (32 ))
191+ bstream , contract_version = cl_value_from_bytes (bstream , cl_types .CL_Type_U32 ())
192+ bstream , entry_point = cl_value_from_bytes (bstream , cl_types .CL_Type_String ())
193+ bstream , args = _decode_deploy_argument_set (bstream )
194+
195+ return bstream , StoredContractByHashVersioned (
196+ args = args ,
197+ entry_point = entry_point .value ,
198+ hash = contract_hash .value ,
199+ version = contract_version .value
200+ )
201+
202+
203+ def _decode_stored_contract_by_name (bstream : bytes ) -> typing .Tuple [bytes , StoredContractByName ]:
204+ bstream = bstream [1 :]
205+ bstream , contract_name = cl_value_from_bytes (bstream , cl_types .CL_Type_String ())
206+ bstream , entry_point = cl_value_from_bytes (bstream , cl_types .CL_Type_String ())
207+ bstream , args = _decode_deploy_argument_set (bstream )
208+
209+ return bstream , StoredContractByName (
210+ args = args ,
211+ entry_point = entry_point .value ,
212+ name = contract_name .value
213+ )
214+
215+
216+ def _decode_stored_contract_by_name_versioned (bstream : bytes ) -> typing .Tuple [bytes , StoredContractByNameVersioned ]:
217+ bstream = bstream [1 :]
218+ bstream , contract_name = cl_value_from_bytes (bstream , cl_types .CL_Type_String ())
219+ bstream , contract_version = cl_value_from_bytes (bstream , cl_types .CL_Type_U32 ())
220+ bstream , entry_point = cl_value_from_bytes (bstream , cl_types .CL_Type_String ())
221+ bstream , args = _decode_deploy_argument_set (bstream )
222+
223+ return bstream , StoredContractByNameVersioned (
224+ args = args ,
225+ entry_point = entry_point .value ,
226+ name = contract_name .value ,
227+ version = contract_version .value
228+ )
229+
230+
231+ def _decode_transfer (bstream : bytes ) -> typing .Tuple [bytes , Transfer ]:
232+ bstream = bstream [1 :]
233+ bstream , args = _decode_deploy_argument_set (bstream )
234+
235+ return bstream , Transfer (args )
236+
237+
238+ _DECODERS = {
239+ Deploy : _decode_deploy ,
240+ DeployApproval : _decode_deploy_approval ,
241+ DeployArgument : _decode_deploy_argument ,
242+ DeployBody : _decode_deploy_body ,
243+ DeployExecutableItem : _decode_deploy_executable_item ,
244+ DeployHeader : _decode_deploy_header ,
245+ ModuleBytes : _decode_module_bytes ,
246+ StoredContractByHash : _decode_stored_contract_by_hash ,
247+ StoredContractByHashVersioned : _decode_stored_contract_by_hash_versioned ,
248+ StoredContractByName : _decode_stored_contract_by_name ,
249+ StoredContractByNameVersioned : _decode_stored_contract_by_name_versioned ,
250+ Transfer : _decode_transfer
251+ }
0 commit comments