@@ -3,6 +3,8 @@ use core::fmt;
33use sha2:: { Digest , Sha256 } ;
44use thiserror:: Error ;
55
6+ use crate :: { StdError , StdResult } ;
7+
68/// A SHA-256 checksum of a Wasm blob, used to identify a Wasm code.
79/// This must remain stable since this checksum is stored in the blockchain state.
810///
@@ -16,6 +18,15 @@ impl Checksum {
1618 Checksum ( Sha256 :: digest ( wasm) . into ( ) )
1719 }
1820
21+ /// Tries to parse the given hex string into a checksum.
22+ /// Errors if the string contains non-hex characters or does not contain 32 bytes.
23+ pub fn from_hex ( input : & str ) -> StdResult < Self > {
24+ let mut binary = [ 0u8 ; 32 ] ;
25+ hex:: decode_to_slice ( input, & mut binary) . map_err ( StdError :: invalid_hex) ?;
26+
27+ Ok ( Self ( binary) )
28+ }
29+
1930 /// Creates a lowercase hex encoded copy of this checksum.
2031 ///
2132 /// This takes an owned `self` instead of a reference because `Checksum` is cheap to `Copy`.
@@ -96,6 +107,24 @@ mod tests {
96107 ) ;
97108 }
98109
110+ #[ test]
111+ fn from_hex_works ( ) {
112+ // echo -n "hij" | sha256sum
113+ let checksum = "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104" ;
114+ let parsed = Checksum :: from_hex ( checksum) . unwrap ( ) ;
115+ assert_eq ! ( parsed, Checksum :: generate( b"hij" ) ) ;
116+ // should be inverse of `to_hex`
117+ assert_eq ! ( parsed. to_hex( ) , checksum) ;
118+
119+ // invalid hex
120+ let too_short = "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a1428842271" ;
121+ assert ! ( Checksum :: from_hex( too_short) . is_err( ) ) ;
122+ let invalid_char = "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a1428842271g4" ;
123+ assert ! ( Checksum :: from_hex( invalid_char) . is_err( ) ) ;
124+ let too_long = "722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a14288422710400" ;
125+ assert ! ( Checksum :: from_hex( too_long) . is_err( ) ) ;
126+ }
127+
99128 #[ test]
100129 fn to_hex_works ( ) {
101130 let wasm = vec ! [ 0x68 , 0x69 , 0x6a ] ;
0 commit comments