Skip to content

Commit

Permalink
feat(zint): introduce caller for address
Browse files Browse the repository at this point in the history
  • Loading branch information
clearloop committed Nov 13, 2024
1 parent bc72c9c commit 595e0f6
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 33 deletions.
2 changes: 0 additions & 2 deletions codegen/src/codegen/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ impl Function {
// Record the offset for validation.
while let Ok((count, val)) = locals.read() {
for _ in 0..count {
// TODO: the below here is outdated, sp is not required anymore after #245

// Define locals.
self.locals
.push(LocalSlot::new(val, LocalSlotType::Variable, sp));
Expand Down
9 changes: 4 additions & 5 deletions codegen/src/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,10 @@ impl Locals {
let offset = if local.ty() == &LocalSlotType::Parameter {
self.inner[..index].iter().fold(0, |acc, x| acc + x.align())
} else {
panic!("This should never be reached");
// self.inner[..index]
// .iter()
// .filter(|x| x.ty() == &LocalSlotType::Variable)
// .fold(0, |acc, x| acc + x.align())
self.inner[..index]
.iter()
.filter(|x| x.ty() == &LocalSlotType::Variable)
.fold(0, |acc, x| acc + x.align())
}
.to_ls_bytes()
.to_vec()
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/visitor/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl Function {

/// Local get for variables.
fn _local_get_var(&mut self, local_index: usize) -> Result<()> {
tracing::trace!("Local get variable: {local_index}");
tracing::debug!("Local get variable: {local_index}");
if local_index + 1 > self.locals.len() {
// The local we want is not from function arguments
return Err(Error::InvalidLocalIndex(local_index));
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ impl Env {
/// Allocate memory slots from local index
pub fn alloc(&self, index: u32) -> SmallVec<[u8; 4]> {
let slots = index + self.reserved();
tracing::trace!(
tracing::debug!(
"allocating memory for local {index} of function {:?}, slot: {slots}",
self.index
);
Expand Down
46 changes: 24 additions & 22 deletions examples/approval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,24 @@ pub struct Allowance;

#[zink::external]
pub fn approve(spender: Address, value: U256) -> bool {
let owner = unsafe { zink::ffi::evm::caller() };
let owner = Address::caller();
_approve(owner, spender, value);
true
}

// NOTE:
//
// #[no_mangle] here is required otherwise the inner functions could
// not get the passing variables correctly.
#[no_mangle]
fn _approve(owner: Address, spender: Address, value: U256) {
// if owner.eq(Address::empty()) {
// zink::revert!("ERC20 Invalid approval");
// }
if owner.eq(Address::empty()) {
zink::revert!("ERC20 Invalid approval");
}

// if spender.eq(Address::empty()) {
// zink::revert!("ERC20 Invalid spender");
// }
if spender.eq(Address::empty()) {
zink::revert!("ERC20 Invalid spender");
}

Allowance::set(owner, spender, value);
}
Expand All @@ -37,29 +42,26 @@ fn main() {}
fn test_approval() -> anyhow::Result<()> {
use zint::{Bytes32, Contract, EVM};

let mut evm = EVM::default(); //.commit(true);
let mut evm = EVM::default().commit(true);
let contract = Contract::search("approval")?.compile()?;
let info = evm.deploy(&contract.bytecode()?)?;
let address = info.address;

println!("contract address: 0x{}", hex::encode(address));
let value = 42;
let spender = [42; 20];
let info = evm
.calldata(&contract.encode(&[
b"approve(address,uint256)".to_vec(),
[0; 20].to_bytes32().to_vec(),
42.to_bytes32().to_vec(),
spender.to_bytes32().to_vec(),
value.to_bytes32().to_vec(),
])?)
.call(address)?;
println!("{info:?}");
// assert_eq!(info.ret, true.to_bytes32());
//
// let info = evm
// .calldata(&contract.encode(&[
// b"allowance(address,address)".to_vec(),
// [0; 20].to_bytes32().to_vec(),
// [0; 20].to_bytes32().to_vec(),
// ])?)
// .call(address)?;
// println!("{info:?}");
assert_eq!(info.ret, true.to_bytes32());

let stored_value = evm.storage(
address,
Allowance::storage_key(Address(evm.caller), Address(spender)),
)?;
assert_eq!(value.to_bytes32(), stored_value);
Ok(())
}
6 changes: 6 additions & 0 deletions zink/src/primitives/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@ impl Address {
Address(0)
}

/// Returns empty address
pub fn caller() -> Self {
unsafe { ffi::evm::caller() }
}

/// if self equal to another
///
/// NOTE: not using core::cmp because it uses registers in wasm
#[allow(clippy::should_implement_trait)]
#[inline(always)]
pub fn eq(self, other: Self) -> bool {
unsafe { ffi::address_eq(self, other) }
}
Expand Down
2 changes: 1 addition & 1 deletion zink/src/primitives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
mod address;
mod u256;

pub use address::Address;
pub use address::{Address, Caller};
pub use u256::U256;

pub type Bytes20 = Address;
Expand Down
1 change: 1 addition & 0 deletions zink/src/storage/dkmapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub trait DoubleKeyMapping {
}

/// Set key and value
#[inline(always)]
fn set(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
value.push();
load_double_key(key1, key2, Self::STORAGE_SLOT);
Expand Down
11 changes: 10 additions & 1 deletion zint/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub const CONTRACT: [u8; 20] = [1; 20];
/// Wrapper of full REVM
pub struct EVM<'e> {
inner: Revm<'e, (), InMemoryDB>,
/// Caller for the execution
pub caller: [u8; 20],
/// If commit changes
commit: bool,
}
Expand All @@ -35,6 +37,7 @@ impl<'e> Default for EVM<'e> {
let evm = Revm::<'e, (), EmptyDB>::builder().with_db(db).build();
Self {
inner: evm,
caller: [1; 20],
commit: false,
}
}
Expand Down Expand Up @@ -63,12 +66,18 @@ impl<'e> EVM<'e> {
self
}

/// Set caller for the execution
pub fn caller(mut self, caller: [u8; 20]) -> Self {
self.caller = caller;
self
}

/// Send transaction to the provided address.
pub fn call(&mut self, to: [u8; 20]) -> Result<Info> {
let to = TransactTo::Call(to.into());
self.inner.tx_mut().gas_limit = GAS_LIMIT;
self.inner.tx_mut().transact_to = to;
println!("caller: {:?}", self.inner.tx().caller);
self.inner.tx_mut().caller = self.caller.into();

if self.commit {
self.inner.transact_commit()?.try_into()
Expand Down

0 comments on commit 595e0f6

Please sign in to comment.