Skip to content

Commit

Permalink
Implement ewasm_call_only_by macro
Browse files Browse the repository at this point in the history
  • Loading branch information
yanganto committed Oct 8, 2021
1 parent fe7a2b4 commit 7bb6f11
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
2 changes: 0 additions & 2 deletions examples/ballot-contract/src/errors.rs
Expand Up @@ -2,8 +2,6 @@ use thiserror::Error;

#[derive(Error, Debug, PartialEq)]
pub enum Error {
#[error("This handler is for chairman only")]
ChairmanOnly,
#[error("Voter `{0}` already exist")]
VoterExist(String),
#[error("Voter `{0}` address is incorrect")]
Expand Down
14 changes: 6 additions & 8 deletions examples/ballot-contract/src/lib.rs
Expand Up @@ -11,7 +11,8 @@ use std::convert::TryInto;
use serde_derive::{Deserialize, Serialize};
use sewup::types::{Address, Raw};
use sewup_derive::{
ewasm_constructor, ewasm_fn, ewasm_fn_sig, ewasm_main, ewasm_test, SizedString, Value,
ewasm_call_only_by, ewasm_constructor, ewasm_fn, ewasm_fn_sig, ewasm_main, ewasm_test,
SizedString, Value,
};

mod errors;
Expand Down Expand Up @@ -71,12 +72,9 @@ fn constructor() {

#[ewasm_fn]
fn give_right_to_vote(voter: String) -> anyhow::Result<sewup::primitives::EwasmAny> {
let caller = sewup::utils::caller();
let charman_address = Address::from_str(CHAIRMAN)?;

if caller != charman_address {
return Err(errors::Error::ChairmanOnly.into());
}
ewasm_call_only_by!(CHAIRMAN);
// or
// ewasm_call_only_by!("8663DBF0cC68AaF37fC8BA262F2df4c666a41993");

let mut storage = sewup::kv::Store::load(None)?;
let mut voters_bucket = storage.bucket::<Address, Voter>("voters")?;
Expand Down Expand Up @@ -173,7 +171,7 @@ mod tests {
fn test_give_right_to_vote() {
ewasm_assert_eq!(
give_right_to_vote("1cCA28600d7491365520B31b466f88647B9839eC"),
ewasm_err_output!(errors::Error::ChairmanOnly)
ewasm_err_output!(sewup::errors::HandlerError::Unauthorized)
);

// TODO: handle input with primitive types, ex: usize
Expand Down
32 changes: 32 additions & 0 deletions sewup-derive/src/lib.rs
Expand Up @@ -228,6 +228,11 @@ pub fn ewasm_main(attr: TokenStream, item: TokenStream) -> TokenStream {
/// `ewasm_fn_sig!` macro to get your function signature;
///
/// ```compile_fail
/// #[ewasm_fn]
/// fn check_input_object(s: SimpleStruct) -> anyhow::Result<()> {
/// Ok(())
/// }
///
/// #[ewasm_main]
/// fn main() -> Result<()> {
/// let contract = Contract::new()?;
Expand All @@ -238,6 +243,7 @@ pub fn ewasm_main(attr: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(())
/// }
/// ```
///
#[proc_macro_error]
#[proc_macro_attribute]
pub fn ewasm_fn(attr: TokenStream, item: TokenStream) -> TokenStream {
Expand Down Expand Up @@ -1414,3 +1420,29 @@ pub fn SizedString(item: TokenStream) -> TokenStream {
}
panic!("The input of SizedString! should be a greator than zero integer")
}

/// helps you return handler when caller is not in access control list
/// ```compile_fail
/// ewasm_call_only_by!("8663..1993")
/// ```
#[proc_macro]
pub fn ewasm_call_only_by(item: TokenStream) -> TokenStream {
let input = item.to_string().replace(" ", "");
let output = if input.starts_with("\"") {
let addr = format!("{}", input.replace("\"", ""));
quote! {
if sewup::utils::caller() != sewup::types::Address::from_str(#addr)? {
return Err(sewup::errors::HandlerError::Unauthorized.into())
}
}
} else {
let addr = Ident::new(&format!("{}", input), Span::call_site());
quote! {
if sewup::utils::caller() != sewup::types::Address::from_str(#addr)? {
return Err(sewup::errors::HandlerError::Unauthorized.into())
}
}
};

output.into()
}
9 changes: 9 additions & 0 deletions sewup/src/errors.rs
Expand Up @@ -12,3 +12,12 @@ pub enum ContractError {
#[error("contract address and call data are both absent")]
InsufficientContractInfoError,
}

#[remain::sorted]
#[derive(Error, Debug)]
pub enum HandlerError {
#[error("Resource not found")]
NotFound,
#[error("Authorization has been refused for current caller's credential")]
Unauthorized,
}

0 comments on commit 7bb6f11

Please sign in to comment.