@@ -7,7 +7,9 @@ use starknet_api::deprecated_contract_class::EntryPoint;
77pub use starknet_contract_class:: to_cairo_runner_program;
88use starknet_contract_class:: AbiType ;
99use starknet_contract_class:: { ContractEntryPoint , EntryPointType } ;
10- use std:: { collections:: HashMap , fs:: File , io:: BufReader , path:: PathBuf } ;
10+ use std:: collections:: HashMap ;
11+ use std:: io:: { BufReader , Read } ;
12+ use std:: path:: { Path , PathBuf } ;
1113
1214// -------------------------------
1315// Contract Class
@@ -33,12 +35,10 @@ impl ContractClass {
3335 abi : Option < AbiType > ,
3436 ) -> Result < Self , ContractClassError > {
3537 for entry_points in entry_points_by_type. values ( ) {
36- let mut index = 1 ;
37- while let Some ( entry_point) = entry_points. get ( index) {
38- if entry_point. selector ( ) > entry_points[ index - 1 ] . selector ( ) {
38+ for i in 1 ..entry_points. len ( ) {
39+ if entry_points[ i - 1 ] . selector ( ) > entry_points[ i] . selector ( ) {
3940 return Err ( ContractClassError :: EntrypointError ( entry_points. clone ( ) ) ) ;
4041 }
41- index += 1 ;
4242 }
4343 }
4444
@@ -49,21 +49,29 @@ impl ContractClass {
4949 abi,
5050 } )
5151 }
52+
53+ pub fn new_from_path < F > ( path : F ) -> Result < Self , ProgramError >
54+ where
55+ F : AsRef < Path > ,
56+ {
57+ Self :: try_from ( std:: fs:: read_to_string ( path) ?. as_str ( ) )
58+ }
5259}
5360
5461// -------------------------------
5562// From traits
5663// -------------------------------
57- impl TryFrom < starknet_api:: deprecated_contract_class:: ContractClass > for ContractClass {
64+
65+ impl TryFrom < & str > for ContractClass {
5866 type Error = ProgramError ;
5967
60- fn try_from (
61- contract_class : starknet_api:: deprecated_contract_class:: ContractClass ,
62- ) -> Result < Self , Self :: Error > {
68+ fn try_from ( s : & str ) -> Result < Self , ProgramError > {
69+ let contract_class: starknet_api:: deprecated_contract_class:: ContractClass =
70+ serde_json :: from_str ( s ) ? ;
6371 let program = to_cairo_runner_program ( & contract_class. program ) ?;
6472 let entry_points_by_type =
6573 convert_entry_points ( contract_class. clone ( ) . entry_points_by_type ) ;
66- let program_json = serde_json:: to_value ( & contract_class ) ?;
74+ let program_json = serde_json:: from_str ( s ) ?;
6775 Ok ( ContractClass {
6876 program_json,
6977 program,
@@ -73,58 +81,52 @@ impl TryFrom<starknet_api::deprecated_contract_class::ContractClass> for Contrac
7381 }
7482}
7583
76- // -------------------
77- // Helper Functions
78- // -------------------
79-
80- impl TryFrom < & str > for ContractClass {
84+ impl TryFrom < & Path > for ContractClass {
8185 type Error = ProgramError ;
8286
83- fn try_from ( s : & str ) -> Result < Self , ProgramError > {
84- let raw_contract_class: starknet_api:: deprecated_contract_class:: ContractClass =
85- serde_json:: from_str ( s) ?;
86- ContractClass :: try_from ( raw_contract_class)
87+ fn try_from ( path : & Path ) -> Result < Self , Self :: Error > {
88+ Self :: new_from_path ( path)
8789 }
8890}
8991
9092impl TryFrom < PathBuf > for ContractClass {
9193 type Error = ProgramError ;
9294
9395 fn try_from ( path : PathBuf ) -> Result < Self , Self :: Error > {
94- ContractClass :: try_from ( & path)
96+ Self :: new_from_path ( path)
9597 }
9698}
9799
98100impl TryFrom < & PathBuf > for ContractClass {
99101 type Error = ProgramError ;
100102
101103 fn try_from ( path : & PathBuf ) -> Result < Self , Self :: Error > {
102- let file = File :: open ( path) ?;
103- let reader = BufReader :: new ( file) ;
104- let raw_contract_class: starknet_api:: deprecated_contract_class:: ContractClass =
105- serde_json:: from_reader ( reader) ?;
106- ContractClass :: try_from ( raw_contract_class)
104+ Self :: new_from_path ( path)
107105 }
108106}
109107
110108impl < T : std:: io:: Read > TryFrom < BufReader < T > > for ContractClass {
111109 type Error = ProgramError ;
112110
113- fn try_from ( reader : BufReader < T > ) -> Result < Self , Self :: Error > {
114- let raw_contract_class : starknet_api :: deprecated_contract_class :: ContractClass =
115- serde_json :: from_reader ( reader) ?;
116- ContractClass :: try_from ( raw_contract_class )
111+ fn try_from ( mut reader : BufReader < T > ) -> Result < Self , Self :: Error > {
112+ let mut s = String :: new ( ) ;
113+ reader. read_to_string ( & mut s ) ?;
114+ Self :: try_from ( s . as_str ( ) )
117115 }
118116}
119117
118+ // -------------------
119+ // Helper Functions
120+ // -------------------
121+
120122fn convert_entry_points (
121123 entry_points : HashMap < starknet_api:: deprecated_contract_class:: EntryPointType , Vec < EntryPoint > > ,
122124) -> HashMap < EntryPointType , Vec < ContractEntryPoint > > {
123125 let mut converted_entries: HashMap < EntryPointType , Vec < ContractEntryPoint > > = HashMap :: new ( ) ;
124- for ( entry_type, vec ) in entry_points {
126+ for ( entry_type, entry_points ) in entry_points {
125127 let en_type = entry_type. into ( ) ;
126128
127- let contracts_entry_points = vec
129+ let contracts_entry_points = entry_points
128130 . into_iter ( )
129131 . map ( |e| {
130132 let selector = Felt252 :: from_bytes_be ( e. selector . 0 . bytes ( ) ) ;
@@ -141,20 +143,20 @@ fn convert_entry_points(
141143
142144#[ cfg( test) ]
143145mod tests {
146+ use crate :: core:: contract_address:: compute_deprecated_class_hash;
147+
144148 use super :: * ;
145149 use cairo_vm:: {
146150 felt:: { felt_str, PRIME_STR } ,
147151 serde:: deserialize_program:: BuiltinName ,
148152 } ;
149- use std:: io:: Read ;
153+ use starknet_contract_class:: ParsedContractClass ;
154+ use std:: { fs, str:: FromStr } ;
150155
151156 #[ test]
152157 fn deserialize_contract_class ( ) {
153- let mut serialized = String :: new ( ) ;
154-
155158 // This specific contract compiles with --no_debug_info
156- File :: open ( PathBuf :: from ( "starknet_programs/AccountPreset.json" ) )
157- . and_then ( |mut f| f. read_to_string ( & mut serialized) )
159+ let serialized = fs:: read_to_string ( "starknet_programs/AccountPreset.json" )
158160 . expect ( "should be able to read file" ) ;
159161
160162 let res = ContractClass :: try_from ( serialized. as_str ( ) ) ;
@@ -201,4 +203,112 @@ mod tests {
201203 ) ]
202204 ) ;
203205 }
206+
207+ #[ test]
208+ fn test_contract_class_new_equals_raw_instantiation ( ) {
209+ let contract_str = fs:: read_to_string ( "starknet_programs/raw_contract_classes/0x4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad.json" ) . unwrap ( ) ;
210+
211+ let parsed_contract_class = ParsedContractClass :: try_from ( contract_str. as_str ( ) ) . unwrap ( ) ;
212+ let contract_class = ContractClass {
213+ program_json : serde_json:: Value :: from_str ( & contract_str) . unwrap ( ) ,
214+ program : parsed_contract_class. program . clone ( ) ,
215+ entry_points_by_type : parsed_contract_class. entry_points_by_type . clone ( ) ,
216+ abi : parsed_contract_class. abi . clone ( ) ,
217+ } ;
218+
219+ let contract_class_new = ContractClass :: new (
220+ serde_json:: Value :: from_str ( & contract_str) . unwrap ( ) ,
221+ parsed_contract_class. program ,
222+ parsed_contract_class. entry_points_by_type ,
223+ parsed_contract_class. abi ,
224+ )
225+ . unwrap ( ) ;
226+
227+ assert_eq ! ( contract_class, contract_class_new) ;
228+ }
229+
230+ #[ test]
231+ fn test_compute_class_hash_0x4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad_try_from (
232+ ) {
233+ let contract_str = fs:: read_to_string ( "starknet_programs/raw_contract_classes/0x4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad.json" ) . unwrap ( ) ;
234+
235+ let contract_class = ContractClass :: try_from ( contract_str. as_str ( ) ) . unwrap ( ) ;
236+
237+ assert_eq ! (
238+ compute_deprecated_class_hash( & contract_class) . unwrap( ) ,
239+ felt_str!(
240+ "4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad" ,
241+ 16
242+ )
243+ ) ;
244+ }
245+
246+ #[ test]
247+ fn test_new_equals_try_from ( ) {
248+ let contract_str = fs:: read_to_string ( "starknet_programs/raw_contract_classes/0x4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad.json" ) . unwrap ( ) ;
249+
250+ let parsed_contract_class = ParsedContractClass :: try_from ( contract_str. as_str ( ) ) . unwrap ( ) ;
251+
252+ let contract_class_new = ContractClass :: new (
253+ serde_json:: Value :: from_str ( & contract_str) . unwrap ( ) ,
254+ parsed_contract_class. program ,
255+ parsed_contract_class. entry_points_by_type ,
256+ parsed_contract_class. abi ,
257+ )
258+ . unwrap ( ) ;
259+
260+ let contract_class = ContractClass :: try_from ( contract_str. as_str ( ) ) . unwrap ( ) ;
261+
262+ assert_eq ! ( contract_class. abi, contract_class_new. abi) ;
263+ assert_eq ! ( contract_class. program, contract_class_new. program) ;
264+ assert_eq ! ( contract_class. program_json, contract_class_new. program_json) ;
265+ assert_eq ! (
266+ contract_class. entry_points_by_type,
267+ contract_class_new. entry_points_by_type
268+ ) ;
269+ }
270+
271+ #[ test]
272+ fn test_compute_class_hash_0x4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad_new (
273+ ) {
274+ let contract_str = fs:: read_to_string ( "starknet_programs/raw_contract_classes/0x4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad.json" ) . unwrap ( ) ;
275+
276+ let parsed_contract_class = ParsedContractClass :: try_from ( contract_str. as_str ( ) ) . unwrap ( ) ;
277+ let contract_class = ContractClass :: new (
278+ serde_json:: Value :: from_str ( & contract_str) . unwrap ( ) ,
279+ parsed_contract_class. program ,
280+ parsed_contract_class. entry_points_by_type ,
281+ parsed_contract_class. abi ,
282+ )
283+ . unwrap ( ) ;
284+
285+ assert_eq ! (
286+ compute_deprecated_class_hash( & contract_class) . unwrap( ) ,
287+ felt_str!(
288+ "4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad" ,
289+ 16
290+ )
291+ ) ;
292+ }
293+
294+ #[ test]
295+ fn test_compute_class_hash_0x4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad ( ) {
296+ let contract_str = fs:: read_to_string ( "starknet_programs/raw_contract_classes/0x4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad.json" ) . unwrap ( ) ;
297+
298+ let parsed_contract_class = ParsedContractClass :: try_from ( contract_str. as_str ( ) ) . unwrap ( ) ;
299+ let contract_class = ContractClass {
300+ program_json : serde_json:: Value :: from_str ( & contract_str) . unwrap ( ) ,
301+ program : parsed_contract_class. program ,
302+ entry_points_by_type : parsed_contract_class. entry_points_by_type ,
303+ abi : parsed_contract_class. abi ,
304+ } ;
305+
306+ assert_eq ! (
307+ compute_deprecated_class_hash( & contract_class) . unwrap( ) ,
308+ felt_str!(
309+ "4479c3b883b34f1eafa5065418225d78a11ee7957c371e1b285e4b77afc6dad" ,
310+ 16
311+ )
312+ ) ;
313+ }
204314}
0 commit comments