Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
malik672 committed Dec 15, 2024
1 parent 453604b commit 29ce663
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 19 deletions.
74 changes: 59 additions & 15 deletions examples/revert.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,77 @@
//! Example of revert
#![cfg_attr(target_arch = "wasm32", no_std)]
#![cfg_attr(target_arch = "wasm32", no_main)]

use zink::{
primitives::{Address, U256},
Error,
};

extern crate zink;

// Define custom errors
#[derive(Error)]
pub enum ContractError {
Unauthorized,
InsufficientBalance(U256, U256),
InvalidAddress(Address),
}

#[cfg(not(target_arch = "wasm32"))]
fn main() {}

/// check if the passing address is owner
#[zink::external]
pub fn revert() {
zink::revert!("revert works")
pub fn simple_revert() {
zink::revert!("simple revert message");
}

#[zink::external]
pub fn assert_example() {
zink::assert!(false, "assertion failed");
}

#[zink::external]
pub fn custom_error() {
ContractError::Unauthorized;
}

#[zink::external]
pub fn insufficient_balance(amount: U256) {
let balance = U256::empty();
ContractError::InsufficientBalance(balance, amount);
}

/// check if the passing address is owner
#[zink::external]
pub fn assert() {
zink::assert!(false, "assert works");
pub fn check_address(addr: Address) {
ContractError::InvalidAddress(addr);
}

#[test]
fn test_revert() -> anyhow::Result<()> {
#[cfg(test)]
mod tests {
use super::*;
use zint::Contract;
let mut contract = Contract::search("revert")?.compile()?;

let info = contract.execute(["revert()".as_bytes()])?;
assert_eq!(info.revert, Some("revert works".into()));
// #[test]
// fn test_errors() -> anyhow::Result<()> {
// let mut contract = Contract::search("errors")?.compile()?;

// // Test string revert
// let info = contract.execute(["simple_revert()".as_bytes()])?;
// assert_eq!(info.revert, Some("simple revert message".into()));

// // Test assertion
// let info = contract.execute(["assert_example()".as_bytes()])?;
// assert_eq!(info.revert, Some("assertion failed".into()));

// // Test custom error
// let info = contract.execute(["custom_error()".as_bytes()])?;
// assert!(info.revert.is_some());
// // In practice, you'd decode the custom error from the revert data

// // Test custom error with data
// let info = contract.execute(["insufficient_balance(uint256)".as_bytes(), &[100u8; 32]])?;
// assert!(info.revert.is_some());
// // You'd decode the balance values from the revert data

let info = contract.execute(["assert()".as_bytes()])?;
assert_eq!(info.revert, Some("assert works".into()));
Ok(())
// Ok(())
// }
}
9 changes: 8 additions & 1 deletion zink/codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ mod utils;
/// Revert with the input message
///
/// Only raw string is supported, formatter currently doesn't work.
#[proc_macro_derive(Error)]
pub fn error(input: TokenStream) -> TokenStream {
revert::derive_error(input)
}

#[proc_macro]
pub fn revert(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as LitStr);
let input = parse_macro_input!(input);
revert::parse(input)
}

Expand All @@ -33,6 +38,8 @@ pub fn assert(input: TokenStream) -> TokenStream {
revert::parse_assert(input)
}



/// Event logging interface
///
/// ```ignore
Expand Down
64 changes: 62 additions & 2 deletions zink/codegen/src/revert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,69 @@ use proc_macro::TokenStream;
use proc_macro2::{Literal, Span};
use quote::{quote, ToTokens};
use syn::{
parse::{Parse, ParseStream},
parse2, Expr, Ident, LitStr, Token,
parse::{Parse, ParseStream}, parse2, parse_macro_input, Data, DeriveInput, Expr, Fields, Ident, LitStr, Token, Type
};
use super::selector;

pub fn derive_error(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;

let error_variants = match input.data {
Data::Enum(enum_data) => enum_data.variants,
_ => panic!("Error derive macro only works on enums"),
};

let mut error_matches = vec![];
let mut error_names = vec![];
let mut error_signatures = vec![];

for variant in error_variants {
let variant_name = variant.ident;
let signature = match variant.fields {
Fields::Unnamed(fields) => {
let types: Vec<Type> = fields.unnamed.iter()
.map(|f| f.ty.clone())
.collect();
quote! { (#(#types),*) }
},
Fields::Unit => quote! {},
Fields::Named(_) => panic!("Named fields are not supported in error variants"),
};

let selector = generate_error_selector(&variant_name.to_string());
error_matches.push(quote! {
#name::#variant_name #signature => #selector
});
error_names.push(variant_name.to_string());
error_signatures.push(signature);
}

quote! {
impl #name {
pub fn selector(&self) -> [u8; 4] {
match self {
#(#error_matches,)*
}
}

pub fn get_abi() -> Vec<zink::abi::Error> {
vec![
// #(zink::abi::Error {
// name: #error_names.into(),
// inputs: #error_signatures,
// },)*
]
}
}
}.into()
}

fn generate_error_selector(name: &str) -> proc_macro2::TokenStream {
quote! {

}
}

/// Revert with message
pub fn parse(input: LitStr) -> TokenStream {
Expand Down
2 changes: 1 addition & 1 deletion zink/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod primitives;
pub mod storage;
pub use self::{asm::Asm, event::Event};
pub use storage::{DoubleKeyMapping, Mapping, Storage, TransientStorage};
pub use zink_codegen::{assert, external, revert, storage, transient_storage, Event};
pub use zink_codegen::{assert, external, storage, transient_storage, Event, revert, Error};

/// Generate a keccak hash of the input (sha3)
#[cfg(not(target_family = "wasm"))]
Expand Down

0 comments on commit 29ce663

Please sign in to comment.