From f2220cd65b18f2c21bed2aadf517dcf052c69f23 Mon Sep 17 00:00:00 2001 From: g4titanx Date: Tue, 1 Apr 2025 13:59:36 +0100 Subject: [PATCH] fix(zink): debug erc20 contract example --- evm/abi/src/lib.rs | 2 +- examples/erc20.rs | 60 +++++++++++++++++++++++++++++----- zink/src/primitives/address.rs | 4 +-- zink/src/primitives/u256.rs | 2 +- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/evm/abi/src/lib.rs b/evm/abi/src/lib.rs index fd346e3aa..dae22bc95 100644 --- a/evm/abi/src/lib.rs +++ b/evm/abi/src/lib.rs @@ -1,6 +1,6 @@ //! Solidity ABI implementation //! -//! https://docs.soliditylang.org/en/latest/abi-spec.html#json +//! #![deny(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] diff --git a/examples/erc20.rs b/examples/erc20.rs index 3b21fcaf3..857837869 100644 --- a/examples/erc20.rs +++ b/examples/erc20.rs @@ -6,8 +6,23 @@ extern crate zink; use zink::{ primitives::{Address, String32, U256}, - DoubleKeyMapping, Mapping, Storage, + DoubleKeyMapping, Event, Mapping, Storage, }; +use crate::zink::Asm; + +#[derive(Event)] +pub enum DebugEvent { + Caller(Address), + FromAddr(Address), + Balance(U256), + Insufficient(U256, U256), + TestLog(U256), +} + +#[zink::external] +pub fn test_log(value: U256) { + DebugEvent::TestLog(value).emit(); +} #[zink::storage(String32)] pub struct Name; @@ -40,6 +55,8 @@ pub fn decimals() -> u32 { #[zink::external] pub fn transfer(to: Address, value: U256) -> bool { let owner = Address::caller(); + DebugEvent::Caller(owner).emit(); + DebugEvent::TestLog(value).emit(); _transfer(owner, to, value); true } @@ -78,18 +95,22 @@ fn _update(from: Address, to: Address, value: U256) { TotalSupply::set(TotalSupply::get().add(value)); } else { let from_balance = Balances::get(from); - + DebugEvent::FromAddr(from).emit(); + DebugEvent::Balance(from_balance).emit(); if from_balance.lt(value) { + DebugEvent::Insufficient(from_balance, value).emit(); zink::revert!("Insufficient balance"); } - + Balances::set(from, from_balance.sub(value)); + DebugEvent::TestLog(from_balance).emit(); } if to.eq(Address::empty()) { TotalSupply::set(TotalSupply::get().sub(value)); } else { - TotalSupply::set(TotalSupply::get().add(value)); + let to_balance = Balances::get(to); + Balances::set(to, to_balance.add(value)); } } @@ -153,7 +174,7 @@ fn deploy() -> anyhow::Result<()> { let name = "The Zink Language"; let symbol = "zink"; let value = 42; - //let half_value = 21; + let half_value = 21; // 1. deploy let info = evm.deploy( @@ -241,6 +262,13 @@ fn deploy() -> anyhow::Result<()> { assert_eq!(info.ret, allowance); } + // Test log emission + let info = contract.execute(&[ + b"test_log(uint256)".to_vec(), + U256::from(42).0.bytes32().to_vec(), + ])?; + println!("Test log result: {info:?}"); + // 4. check transfer { // 4.1. verify balance of the caller @@ -252,9 +280,24 @@ fn deploy() -> anyhow::Result<()> { .call(address)?; assert_eq!(info.ret, value.to_bytes32(), "{info:?}"); + // Debug: Check balance immediately before transfer + let balance_before = evm.storage(address, Balances::storage_key(Address::from(caller)))?; + println!("Balance in storage before transfer: {:?}", balance_before); + let info = evm + .calldata(&contract.encode(&[ + b"balances(address)".to_vec(), + evm.caller.to_bytes32().to_vec(), + ])?) + .call(address)?; + println!("Balance via balances() before transfer: {:?}", info.ret); + // TODO: see br_balance.rs (#287) // 4.2. check transfer - /* evm = evm.commit(false); + evm = evm.commit(false); + println!( + "EVM storage after commit(false): {:?}", + evm.storage(address, Balances::storage_key(Address::from(caller)))? + ); let info = evm .calldata(&contract.encode(&[ b"transfer(address,uint256)".to_vec(), @@ -262,8 +305,9 @@ fn deploy() -> anyhow::Result<()> { half_value.to_bytes32().to_vec(), ])?) .call(address)?; - println!("{info:?}"); - assert_eq!(info.ret, true.to_bytes32(), "{info:?}"); */ + println!("Transfer result: {info:?}"); + println!("Logs: {:?}", info.logs); + assert_eq!(info.ret, true.to_bytes32(), "{info:?}"); } Ok(()) diff --git a/zink/src/primitives/address.rs b/zink/src/primitives/address.rs index 1f105b75d..9f1ab6ba3 100644 --- a/zink/src/primitives/address.rs +++ b/zink/src/primitives/address.rs @@ -7,8 +7,8 @@ use crate::{ /// Account address #[repr(C)] -#[derive(Clone, Copy)] -pub struct Address(Bytes20); +#[derive(Clone, Copy, Debug)] +pub struct Address(pub Bytes20); impl Address { /// Returns empty address diff --git a/zink/src/primitives/u256.rs b/zink/src/primitives/u256.rs index 624e1975e..dbd0221f6 100644 --- a/zink/src/primitives/u256.rs +++ b/zink/src/primitives/u256.rs @@ -11,7 +11,7 @@ use core::ops::Sub; /// Account address #[repr(C)] #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] -pub struct U256(Bytes32); +pub struct U256(pub Bytes32); impl U256 { /// Returns empty value