-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(zink): introduce storage mapping (#233)
* feat(zink): introduce storage registry * docs(storage): design of storage * feat(zink): introduce mapping interface * feat(zink): expand module storage * feat(zink): mainly use trait for kv storage * feat(storage): introduce mapping interface * refactor(zink): declare storage on exposed struct * feat(zink): proc-macro for mapping storage * feat(zink): add tests of mapping * feat(zink): mapping tests in bytecode level * feat(zink): complete the test of mappings * feat(zink): clean unused work * feat(zink): bump version to 0.1.11
- Loading branch information
Showing
27 changed files
with
496 additions
and
148 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Storage | ||
|
||
The storage keys in Zink is slot based, for example, the first detected | ||
storage in compilation will be using `0` as storage key. | ||
|
||
```solidity | ||
// Loading storage at 0 | ||
PUSH0 | ||
SLOAD | ||
// Loading storage at 1 | ||
PUSH1 0x01 | ||
SLOAD | ||
``` | ||
|
||
## Key-Value | ||
|
||
As mentioned above, all key-value pairs follows using number as storage key, however, the value | ||
will be limited with 32 bytes, dynamic value like string is currently not supported. | ||
|
||
## Mapping | ||
|
||
Mapping keys are generated via `keccak256(slot, key)` | ||
|
||
## Array | ||
|
||
Similar to mappings, but the keys will be using `u32` / `u64` for indexing due to the optimization | ||
on the wasm side in the zink compiler, which means, the max size of an array is `max(u64)`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
//! Storage example. | ||
#![cfg_attr(target_arch = "wasm32", no_std)] | ||
#![cfg_attr(target_arch = "wasm32", no_main)] | ||
|
||
extern crate zink; | ||
|
||
use zink::Mapping as _; | ||
|
||
/// Counter with value type `i32` | ||
#[zink::storage(i32 => i32)] | ||
pub struct Mapping; | ||
|
||
/// Set the mapping | ||
#[zink::external] | ||
pub fn mset(key: i32, value: i32) { | ||
Mapping::set(key, value); | ||
} | ||
|
||
/// Get from ampping | ||
#[zink::external] | ||
pub fn mget(key: i32) -> i32 { | ||
Mapping::get(key) | ||
} | ||
|
||
#[cfg(not(target_arch = "wasm32"))] | ||
fn main() {} | ||
|
||
#[test] | ||
fn mapping() -> anyhow::Result<()> { | ||
use zint::{Bytes32, Contract}; | ||
|
||
let mut contract = Contract::search("mapping")?.compile()?; | ||
let mut evm = contract.deploy()?.commit(true); | ||
|
||
let key = 0x00; | ||
let value: i32 = 0x42; | ||
|
||
// set value to storage | ||
let calldata = contract.encode(&[ | ||
b"mset(int32,int32)".to_vec(), | ||
value.to_bytes32().to_vec(), | ||
key.to_bytes32().to_vec(), | ||
])?; | ||
let info = evm.calldata(&calldata).call(contract.address)?; | ||
assert!(info.ret.is_empty()); | ||
|
||
tracing::debug!("{info:?}"); | ||
// verify result with database | ||
let storage_key = zint::keccak256(&[0; 0x40]); | ||
assert_eq!( | ||
evm.storage(contract.address, storage_key)?, | ||
value.to_bytes32(), | ||
); | ||
|
||
// get value from storage | ||
let calldata = contract.encode(&[b"mget(int32)".to_vec(), key.to_bytes32().to_vec()])?; | ||
let info = evm.calldata(&calldata).call(contract.address)?; | ||
assert_eq!(info.ret, value.to_bytes32(), "{info:#?}",); | ||
Ok(()) | ||
} |
Oops, something went wrong.