diff --git a/abi/src/codec.rs b/abi/src/codec.rs new file mode 100644 index 000000000..041793da8 --- /dev/null +++ b/abi/src/codec.rs @@ -0,0 +1,46 @@ +//! Serialization and Deserialization for Zink ABI. + +use crate::{Abi, Error, Result}; + +/// Implement encoding and decoding for Zink ABI. +macro_rules! impl_codec { + ($ty:ident) => { + impl $ty { + /// Convert self to bytes. + pub fn to_bytes(&self) -> Result> { + postcard::to_stdvec(self).map_err(Into::into) + } + + /// Convert self to hex string. + pub fn to_hex(&self) -> Result { + Ok(hex::encode(self.to_bytes()?)) + } + + /// Convert bytes to self. + pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { + postcard::from_bytes(bytes.as_ref()).map_err(Into::into) + } + + /// Convert hex string to self. + pub fn from_hex(hex: impl AsRef) -> Result { + Self::from_bytes(&hex::decode(hex.as_ref().trim_start_matches("0x"))?) + } + } + + impl ToString for $ty { + fn to_string(&self) -> String { + self.to_hex().unwrap_or_default() + } + } + + impl core::str::FromStr for $ty { + type Err = Error; + + fn from_str(hex: &str) -> Result { + Self::from_hex(hex) + } + } + }; +} + +impl_codec!(Abi); diff --git a/abi/src/lib.rs b/abi/src/lib.rs index bbbc48521..4c7443dee 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -1,24 +1,10 @@ //! Utils for generating of zink ABI pub use self::result::{Error, Result}; use serde::{Deserialize, Serialize}; -use sha3::{Digest, Keccak256}; +mod codec; mod result; - -/// Generate a keccak hash of the input (sha3) -pub fn keccak256(input: &[u8]) -> [u8; 32] { - let mut hasher = Keccak256::new(); - hasher.update(input); - hasher.finalize().into() -} - -/// Get function selector from function signature. -pub fn selector(input: &[u8]) -> [u8; 4] { - let mut selector = [0u8; 4]; - selector.copy_from_slice(&keccak256(input)[..4]); - - selector -} +pub mod util; /// Function ABI. #[derive(Debug, Clone, Serialize, Deserialize)] @@ -38,34 +24,6 @@ impl Abi { /// Get function selector. pub fn selector(&self) -> [u8; 4] { let sig = self.signature(); - let mut selector = [0u8; 4]; - selector.copy_from_slice(&keccak256(sig.as_bytes())[..4]); - - selector - } - - /// Parse ABI from bytes. - pub fn from_bytes(bytes: &[u8]) -> Result { - postcard::from_bytes(bytes).map_err(Into::into) - } - - /// Decode ABI form hex string. - pub fn from_hex(hex: &str) -> Result { - Self::from_bytes(&hex::decode(hex)?) - } - - /// Decode ABI form hex string. - pub fn from_hex_bytes(bytes: &[u8]) -> Result { - Self::from_hex(&String::from_utf8_lossy(bytes)) - } - - /// Convert ABI to hex string. - pub fn to_hex(&self) -> Result { - self.to_bytes().map(hex::encode) - } - - /// Convert ABI to bytes. - pub fn to_bytes(&self) -> Result> { - postcard::to_stdvec(&self).map_err(Into::into) + util::selector(&sig.as_bytes()) } } diff --git a/abi/src/util.rs b/abi/src/util.rs new file mode 100644 index 000000000..4f35a4293 --- /dev/null +++ b/abi/src/util.rs @@ -0,0 +1,17 @@ +//! Zink ABI utils +use sha3::{Digest, Keccak256}; + +/// Generate a keccak hash of the input (sha3) +pub fn keccak256(input: &[u8]) -> [u8; 32] { + let mut hasher = Keccak256::new(); + hasher.update(input); + hasher.finalize().into() +} + +/// Get function selector from function signature. +pub fn selector(input: &[u8]) -> [u8; 4] { + let mut selector = [0u8; 4]; + selector.copy_from_slice(&keccak256(input)[..4]); + + selector +} diff --git a/codegen/src/dispatcher.rs b/codegen/src/dispatcher.rs index 4d9a24331..decae0696 100644 --- a/codegen/src/dispatcher.rs +++ b/codegen/src/dispatcher.rs @@ -88,7 +88,8 @@ impl<'d> Dispatcher<'d> { return Err(Error::FuncNotImported("emit_abi".into())); } - Abi::from_hex_bytes(&self.data.load(offset, length as usize)?).map_err(Into::into) + let abi = self.data.load(offset, length as usize)?; + Abi::from_hex(String::from_utf8_lossy(&abi)).map_err(Into::into) } /// Emit return of ext function. diff --git a/zint/src/contract.rs b/zint/src/contract.rs index 7ce04c5fe..2269a39d5 100644 --- a/zint/src/contract.rs +++ b/zint/src/contract.rs @@ -148,7 +148,7 @@ impl Contract { return Err(anyhow!("no selector provided")); } - calldata.extend_from_slice(&zabi::selector(&inputs[0].to_vec())); + calldata.extend_from_slice(&zabi::util::selector(&inputs[0].to_vec())); inputs = &inputs[1..]; }