feat(zink): introduce derive macro contract - #314
Conversation
clearloop
left a comment
There was a problem hiding this comment.
the struct of the contract looks neat!
seems like the contract creating logic works however the dispatcher got problems, I'm not pretty sure about the root case of it, but I'd suggest create another example with simple logic for debugging it, e.g. a getter,
- make sure the getter functions work
- apply this macro to other examples and see if there will be new bugs introduced
- add TODOs for the calls like
_transferbecause we haven't solved it yet
dispatcher bug in relation to unified structs still persist |
yeah, sure, i can open a new issue for this right? |
|
opened #315 to track runtime dispatch issues with multi-field structs |
resolves #288
i made some choices i think you should be aware of
storage type choice:
Bytes32OverString32i opted for
Bytes32for fields likenameandsymbolinstead ofString32(aliased toU256) due to API constraints inzink::primitives::U256. initially, I attempted to useString32to align with the original ERC20 intent:this failed because:
Bytes32::from_slice_uncheckedis not available inzink::primitives::Bytes32(onlyempty()andeq()exist perimpl_bytes!inbytes.rs)U256 Private Field: U256(Bytes32) constructor isn’t public (pub struct U256(Bytes32)has a private field), and nofrom_big_endianorfrom_little_endian methodsexist—onlyFrom<u64>,empty(), andmax()are available.switching to Bytes32 resolved this:
now,
Bytes32directly wraps[u8; 32]in non-WASM (viaimpl_bytes!), and the macro generatesERC20Name::get()as a simplesload, expecting a Bytes32 value. this avoidsU256’s construction issues and matches the storage slot format ([u8; 32]).bypassing contract calls to avoid revert
the test (
test_storage) uses directevm.storage()reads instead of contract calls likename():this was necessary because runtime calls consistently reverted:
revert Cause: the message "Empty from address" originates from _transfer:
unexpected trigger:
name()(self.name() -> ERC20Name::get()) is a storage read (sload at slot 0), yet it reverts with this message. which i think (not sure) is a dispatcher issue in zinkc.direct
evm.storage()readsslot 0 (name),1 (symbol), and2 (total_supply)without WASM execution, confirming the macro’sconstruct()sets storage correctly. this isolates the problem to runtime dispatch, not storage setup.the runtime revert is a blocker for testing core logic (
transfer(), approve()). It seemszinkcmisroutes external calls (e.g.,name()selector0x06fdde03) to_transfer (0xa9059cbb), unlike erc20.rs where separate structs work fine. could this be:a dispatcher bug in selector::external or zinkc bytecode generation?
a problem with unified structs vs. separate ones?
i’d love your take on this—any ideas on why
_transferis hijacking calls? maybe a peek at the WASM output or dispatcher logic could shed light?i’ve kept the test minimal to prove storage, but i really want to get runtime calls working.