diff --git a/.github/dependabot.yml b/.github/_dependabot.yml
similarity index 100%
rename from .github/dependabot.yml
rename to .github/_dependabot.yml
diff --git a/Cargo.lock b/Cargo.lock
index 7508de694..6a9b7cbc2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
-version = "0.8.7"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
+checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
@@ -31,24 +31,61 @@ dependencies = [
[[package]]
name = "aho-corasick"
-version = "1.1.2"
+version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
-version = "0.2.16"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
+checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
+
+[[package]]
+name = "alloy-eip2930"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41"
+dependencies = [
+ "alloy-primitives",
+ "alloy-rlp",
+]
+
+[[package]]
+name = "alloy-eip7702"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37d319bb544ca6caeab58c39cea8921c55d924d4f68f2c60f24f914673f9a74a"
+dependencies = [
+ "alloy-primitives",
+ "alloy-rlp",
+ "k256",
+]
+
+[[package]]
+name = "alloy-eips"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c35df7b972b06f1b2f4e8b7a53328522fa788054a9d3e556faf2411c5a51d5a"
+dependencies = [
+ "alloy-eip2930",
+ "alloy-eip7702",
+ "alloy-primitives",
+ "alloy-rlp",
+ "c-kzg",
+ "derive_more",
+ "once_cell",
+ "serde",
+]
[[package]]
name = "alloy-primitives"
-version = "0.4.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0628ec0ba5b98b3370bb6be17b12f23bfce8ee4ad83823325a20546d9b03b78"
+checksum = "411aff151f2a73124ee473708e82ed51b2535f68928b6a1caa8bc1246ae6f7cd"
dependencies = [
"alloy-rlp",
"bytes",
@@ -57,15 +94,20 @@ dependencies = [
"derive_more",
"hex-literal",
"itoa",
+ "k256",
+ "keccak-asm",
+ "proptest",
+ "rand",
"ruint",
+ "serde",
"tiny-keccak",
]
[[package]]
name = "alloy-rlp"
-version = "0.3.4"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac"
+checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62"
dependencies = [
"alloy-rlp-derive",
"arrayvec",
@@ -74,58 +116,59 @@ dependencies = [
[[package]]
name = "alloy-rlp-derive"
-version = "0.3.4"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83"
+checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "anstream"
-version = "0.6.11"
+version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
+checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
+ "is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
-version = "1.0.5"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220"
+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
-version = "0.2.3"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
+checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.0.2"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
+checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.2"
+version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
+checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
@@ -133,38 +176,172 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.79"
+version = "1.0.88"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
+
+[[package]]
+name = "ark-ff"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6"
+dependencies = [
+ "ark-ff-asm 0.3.0",
+ "ark-ff-macros 0.3.0",
+ "ark-serialize 0.3.0",
+ "ark-std 0.3.0",
+ "derivative",
+ "num-bigint",
+ "num-traits",
+ "paste",
+ "rustc_version 0.3.3",
+ "zeroize",
+]
+
+[[package]]
+name = "ark-ff"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba"
+dependencies = [
+ "ark-ff-asm 0.4.2",
+ "ark-ff-macros 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
+ "derivative",
+ "digest 0.10.7",
+ "itertools",
+ "num-bigint",
+ "num-traits",
+ "paste",
+ "rustc_version 0.4.1",
+ "zeroize",
+]
+
+[[package]]
+name = "ark-ff-asm"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44"
+dependencies = [
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "ark-ff-asm"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348"
+dependencies = [
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "ark-ff-macros"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20"
+dependencies = [
+ "num-bigint",
+ "num-traits",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "ark-ff-macros"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565"
+dependencies = [
+ "num-bigint",
+ "num-traits",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "ark-serialize"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
+checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671"
+dependencies = [
+ "ark-std 0.3.0",
+ "digest 0.9.0",
+]
+
+[[package]]
+name = "ark-serialize"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5"
+dependencies = [
+ "ark-std 0.4.0",
+ "digest 0.10.7",
+ "num-bigint",
+]
+
+[[package]]
+name = "ark-std"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c"
+dependencies = [
+ "num-traits",
+ "rand",
+]
+
+[[package]]
+name = "ark-std"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185"
+dependencies = [
+ "num-traits",
+ "rand",
+]
[[package]]
name = "arrayvec"
-version = "0.7.4"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+
+[[package]]
+name = "aurora-engine-modexp"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
+checksum = "0aef7712851e524f35fbbb74fa6599c5cd8692056a1c36f9ca0d2001b670e7e5"
+dependencies = [
+ "hex",
+ "num",
+]
[[package]]
name = "auto_impl"
-version = "1.1.2"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "823b8bb275161044e2ac7a25879cb3e2480cb403e3943022c7c769c599b756aa"
+checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "autocfg"
-version = "1.1.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "backtrace"
-version = "0.3.69"
+version = "0.3.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
dependencies = [
"addr2line",
"cc",
@@ -188,39 +365,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
-name = "bindgen"
-version = "0.66.1"
+name = "bit-set"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7"
+checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
dependencies = [
- "bitflags 2.4.2",
- "cexpr",
- "clang-sys",
- "lazy_static",
- "lazycell",
- "log",
- "peeking_take_while",
- "prettyplease",
- "proc-macro2",
- "quote",
- "regex",
- "rustc-hash",
- "shlex",
- "syn 2.0.48",
- "which",
+ "bit-vec",
]
[[package]]
-name = "bitflags"
-version = "1.3.2"
+name = "bit-vec"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
-version = "2.4.2"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bitvec"
@@ -245,9 +408,9 @@ dependencies = [
[[package]]
name = "blst"
-version = "0.3.11"
+version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b"
+checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874"
dependencies = [
"cc",
"glob",
@@ -257,9 +420,15 @@ dependencies = [
[[package]]
name = "bumpalo"
-version = "3.14.0"
+version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
+[[package]]
+name = "byte-slice-cast"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
[[package]]
name = "byteorder"
@@ -269,39 +438,39 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.5.0"
+version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
[[package]]
name = "c-kzg"
-version = "0.1.1"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac926d808fb72fe09ebf471a091d6d72918876ccf0b4989766093d2d0d24a0ef"
+checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928"
dependencies = [
- "bindgen",
"blst",
"cc",
"glob",
"hex",
"libc",
+ "once_cell",
"serde",
]
[[package]]
name = "camino"
-version = "1.1.6"
+version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
+checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
dependencies = [
"serde",
]
[[package]]
name = "cargo-platform"
-version = "0.1.6"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d"
+checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
dependencies = [
"serde",
]
@@ -314,7 +483,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
dependencies = [
"camino",
"cargo-platform",
- "semver",
+ "semver 1.0.23",
"serde",
"serde_json",
"thiserror",
@@ -322,12 +491,13 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.0.83"
+version = "1.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
dependencies = [
"jobserver",
"libc",
+ "shlex",
]
[[package]]
@@ -342,37 +512,17 @@ dependencies = [
"tracing-subscriber",
]
-[[package]]
-name = "cexpr"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
-dependencies = [
- "nom",
-]
-
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-[[package]]
-name = "clang-sys"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1"
-dependencies = [
- "glob",
- "libc",
- "libloading",
-]
-
[[package]]
name = "clap"
-version = "4.4.18"
+version = "4.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
+checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac"
dependencies = [
"clap_builder",
"clap_derive",
@@ -380,9 +530,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.4.18"
+version = "4.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
+checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73"
dependencies = [
"anstream",
"anstyle",
@@ -392,21 +542,21 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.4.7"
+version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
+checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
- "heck",
+ "heck 0.5.0",
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "clap_lex"
-version = "0.6.0"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
+checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "cobs"
@@ -426,9 +576,9 @@ dependencies = [
[[package]]
name = "color-eyre"
-version = "0.6.2"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
+checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5"
dependencies = [
"backtrace",
"color-spantrace",
@@ -453,9 +603,9 @@ dependencies = [
[[package]]
name = "colorchoice"
-version = "1.0.0"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "colored"
@@ -469,9 +619,9 @@ dependencies = [
[[package]]
name = "const-hex"
-version = "1.10.0"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557"
+checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -486,17 +636,11 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
-[[package]]
-name = "convert_case"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
-
[[package]]
name = "cpufeatures"
-version = "0.2.12"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
+checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
dependencies = [
"libc",
]
@@ -531,9 +675,9 @@ dependencies = [
[[package]]
name = "cxx"
-version = "1.0.115"
+version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de00f15a6fa069c99b88c5c78c4541d0e7899a33b86f7480e23df2431fce0bc"
+checksum = "54ccead7d199d584d139148b04b4a368d1ec7556a1d9ea2548febb1b9d49f9a4"
dependencies = [
"cc",
"cxxbridge-flags",
@@ -543,9 +687,9 @@ dependencies = [
[[package]]
name = "cxx-build"
-version = "1.0.115"
+version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a71e1e631fa2f2f5f92e8b0d860a00c198c6771623a6cefcc863e3554f0d8d6"
+checksum = "c77953e99f01508f89f55c494bfa867171ef3a6c8cea03d26975368f2121a5c1"
dependencies = [
"cc",
"codespan-reporting",
@@ -553,49 +697,77 @@ dependencies = [
"proc-macro2",
"quote",
"scratch",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "cxxbridge-flags"
-version = "1.0.115"
+version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f3fed61d56ba497c4efef9144dfdbaa25aa58f2f6b3a7cf441d4591c583745c"
+checksum = "65777e06cc48f0cb0152024c77d6cf9e4bdb4408e7b48bea993d42fa0f5b02b6"
[[package]]
name = "cxxbridge-macro"
-version = "1.0.115"
+version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8908e380a8efd42150c017b0cfa31509fc49b6d47f7cb6b33e93ffb8f4e3661e"
+checksum = "98532a60dedaebc4848cb2cba5023337cc9ea3af16a5b062633fabfd9f18fb60"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "der"
-version = "0.7.8"
+version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
+checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
dependencies = [
"const-oid",
"zeroize",
]
[[package]]
-name = "derive_more"
-version = "0.99.17"
+name = "derivative"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
- "convert_case",
"proc-macro2",
"quote",
- "rustc_version",
"syn 1.0.109",
]
+[[package]]
+name = "derive_more"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
+dependencies = [
+ "derive_more-impl",
+]
+
+[[package]]
+name = "derive_more-impl"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.77",
+ "unicode-xid",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "digest"
version = "0.10.7"
@@ -608,6 +780,12 @@ dependencies = [
"subtle",
]
+[[package]]
+name = "dyn-clone"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
+
[[package]]
name = "ecdsa"
version = "0.16.9"
@@ -615,7 +793,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
dependencies = [
"der",
- "digest",
+ "digest 0.10.7",
"elliptic-curve",
"rfc6979",
"signature",
@@ -624,20 +802,20 @@ dependencies = [
[[package]]
name = "either"
-version = "1.9.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "elko"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
"anyhow",
"cargo_metadata",
"ccli",
"colored",
"etc",
- "semver",
+ "semver 1.0.23",
"serde",
"thiserror",
"toml",
@@ -653,7 +831,7 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
dependencies = [
"base16ct",
"crypto-bigint",
- "digest",
+ "digest 0.10.7",
"ff",
"generic-array",
"group",
@@ -670,15 +848,21 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
+[[package]]
+name = "embedded-io"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
+
[[package]]
name = "enumn"
-version = "0.1.13"
+version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42"
+checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
@@ -689,9 +873,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
-version = "0.3.8"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -699,13 +883,13 @@ dependencies = [
[[package]]
name = "etc"
-version = "0.1.19"
+version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed70d0ae6f3c7bc89341edb96cce201d5e009b7bb038b72c98d210acffbce2e3"
+checksum = "1b241177c7107d9829286c2ffdc5eee98d992d6356f3515e7f412f988b1a72fd"
[[package]]
name = "evm-opcodes"
-version = "0.0.3"
+version = "0.0.4"
dependencies = [
"paste",
]
@@ -722,9 +906,20 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "2.0.1"
+version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
+checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
+
+[[package]]
+name = "fastrlp"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418"
+dependencies = [
+ "arrayvec",
+ "auto_impl",
+ "bytes",
+]
[[package]]
name = "ff"
@@ -736,6 +931,24 @@ dependencies = [
"subtle",
]
+[[package]]
+name = "fixed-hash"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534"
+dependencies = [
+ "byteorder",
+ "rand",
+ "rustc-hex",
+ "static_assertions",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
[[package]]
name = "funty"
version = "2.0.0"
@@ -755,9 +968,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.12"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
@@ -789,9 +1002,9 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.14.3"
+version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
@@ -803,11 +1016,17 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
[[package]]
name = "hermit-abi"
-version = "0.3.4"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f"
+checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hex"
@@ -827,16 +1046,27 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
- "digest",
+ "digest 0.10.7",
]
[[package]]
-name = "home"
-version = "0.5.9"
+name = "impl-codec"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
+checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f"
dependencies = [
- "windows-sys 0.52.0",
+ "parity-scale-codec",
+]
+
+[[package]]
+name = "impl-trait-for-tuples"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
]
[[package]]
@@ -847,25 +1077,40 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexmap"
-version = "2.2.2"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520"
+checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
dependencies = [
"equivalent",
"hashbrown",
]
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
[[package]]
name = "itoa"
-version = "1.0.10"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
+checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "jobserver"
-version = "0.1.27"
+version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
+checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
dependencies = [
"libc",
]
@@ -884,19 +1129,23 @@ dependencies = [
]
[[package]]
-name = "lazy_static"
-version = "1.4.0"
+name = "keccak-asm"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6"
dependencies = [
- "spin",
+ "digest 0.10.7",
+ "sha3-asm",
]
[[package]]
-name = "lazycell"
-version = "1.3.0"
+name = "lazy_static"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+dependencies = [
+ "spin",
+]
[[package]]
name = "leb128"
@@ -906,19 +1155,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
-version = "0.2.153"
+version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
-
-[[package]]
-name = "libloading"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
-dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
-]
+checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]]
name = "libm"
@@ -937,15 +1176,15 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
-version = "0.4.13"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "log"
-version = "0.4.20"
+version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "matchers"
@@ -958,35 +1197,19 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
-
-[[package]]
-name = "minimal-lexical"
-version = "0.2.1"
+version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "miniz_oxide"
-version = "0.7.2"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
+checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
]
-[[package]]
-name = "nom"
-version = "7.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
-
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
@@ -999,9 +1222,9 @@ dependencies = [
[[package]]
name = "num"
-version = "0.4.1"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
+checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
dependencies = [
"num-bigint",
"num-complex",
@@ -1013,39 +1236,37 @@ dependencies = [
[[package]]
name = "num-bigint"
-version = "0.4.4"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
- "autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-complex"
-version = "0.4.4"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
+checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
-version = "0.1.45"
+version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
- "autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
-version = "0.1.43"
+version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
+checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
dependencies = [
"autocfg",
"num-integer",
@@ -1054,11 +1275,10 @@ dependencies = [
[[package]]
name = "num-rational"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
+checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
- "autocfg",
"num-bigint",
"num-integer",
"num-traits",
@@ -1066,9 +1286,9 @@ dependencies = [
[[package]]
name = "num-traits"
-version = "0.2.17"
+version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
@@ -1111,23 +1331,54 @@ version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
+[[package]]
+name = "parity-scale-codec"
+version = "3.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee"
+dependencies = [
+ "arrayvec",
+ "bitvec",
+ "byte-slice-cast",
+ "impl-trait-for-tuples",
+ "parity-scale-codec-derive",
+ "serde",
+]
+
+[[package]]
+name = "parity-scale-codec-derive"
+version = "3.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
[[package]]
name = "paste"
-version = "1.0.14"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
-name = "peeking_take_while"
-version = "0.1.2"
+name = "pest"
+version = "2.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+checksum = "9c73c26c01b8c87956cea613c907c9d6ecffd8d18a2a5908e5de0adfaa185cea"
+dependencies = [
+ "memchr",
+ "thiserror",
+ "ucd-trie",
+]
[[package]]
name = "pin-project-lite"
-version = "0.2.13"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "pkcs8"
@@ -1141,59 +1392,85 @@ dependencies = [
[[package]]
name = "postcard"
-version = "1.0.8"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8"
+checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e"
dependencies = [
"cobs",
- "embedded-io",
+ "embedded-io 0.4.0",
+ "embedded-io 0.6.1",
"serde",
]
[[package]]
name = "ppv-lite86"
-version = "0.2.17"
+version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+dependencies = [
+ "zerocopy",
+]
[[package]]
-name = "prettyplease"
-version = "0.2.16"
+name = "primitive-types"
+version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
+checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2"
dependencies = [
- "proc-macro2",
- "syn 2.0.48",
+ "fixed-hash",
+ "impl-codec",
+ "uint",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
+dependencies = [
+ "toml_edit",
]
[[package]]
name = "proc-macro2"
-version = "1.0.78"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "proptest"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf"
+checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d"
dependencies = [
- "bitflags 2.4.2",
+ "bit-set",
+ "bit-vec",
+ "bitflags",
+ "lazy_static",
"num-traits",
"rand",
"rand_chacha",
"rand_xorshift",
+ "regex-syntax 0.8.4",
+ "rusty-fork",
+ "tempfile",
"unarray",
]
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
[[package]]
name = "quote"
-version = "1.0.35"
+version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
@@ -1210,6 +1487,8 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
+ "libc",
+ "rand_chacha",
"rand_core",
]
@@ -1241,25 +1520,16 @@ dependencies = [
"rand_core",
]
-[[package]]
-name = "redox_syscall"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
-dependencies = [
- "bitflags 1.3.2",
-]
-
[[package]]
name = "regex"
-version = "1.10.3"
+version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
+checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
- "regex-automata 0.4.5",
- "regex-syntax 0.8.2",
+ "regex-automata 0.4.7",
+ "regex-syntax 0.8.4",
]
[[package]]
@@ -1273,13 +1543,13 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.5"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
+checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
- "regex-syntax 0.8.2",
+ "regex-syntax 0.8.4",
]
[[package]]
@@ -1290,39 +1560,45 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
-version = "0.8.2"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "revm"
-version = "3.5.0"
+version = "14.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68f4ca8ae0345104523b4af1a8a7ea97cfa1865cdb7a7c25d23c1a18d9b48598"
+checksum = "1f719e28cc6fdd086f8bc481429e587740d20ad89729cec3f5f5dd7b655474df"
dependencies = [
"auto_impl",
+ "cfg-if",
+ "dyn-clone",
"revm-interpreter",
"revm-precompile",
+ "serde",
+ "serde_json",
]
[[package]]
name = "revm-interpreter"
-version = "1.3.0"
+version = "10.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f959cafdf64a7f89b014fa73dc2325001cf654b3d9400260b212d19a2ebe3da0"
+checksum = "959ecbc36802de6126852479844737f20194cf8e6718e0c30697d306a2cca916"
dependencies = [
"revm-primitives",
+ "serde",
]
[[package]]
name = "revm-precompile"
-version = "2.2.0"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d360a88223d85709d2e95d4609eb1e19c649c47e28954bfabae5e92bb37e83e"
+checksum = "6e25f604cb9db593ca3013be8c00f310d6790ccb1b7d8fbbdd4660ec8888043a"
dependencies = [
+ "aurora-engine-modexp",
"c-kzg",
+ "cfg-if",
"k256",
- "num",
"once_cell",
"revm-primitives",
"ripemd",
@@ -1333,18 +1609,21 @@ dependencies = [
[[package]]
name = "revm-primitives"
-version = "1.3.0"
+version = "9.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51187b852d9e458816a2e19c81f1dd6c924077e1a8fccd16e4f044f865f299d7"
+checksum = "0ccb981ede47ccf87c68cebf1ba30cdbb7ec935233ea305f3dfff4c1e10ae541"
dependencies = [
+ "alloy-eips",
"alloy-primitives",
- "alloy-rlp",
"auto_impl",
- "bitflags 2.4.2",
+ "bitflags",
"bitvec",
+ "cfg-if",
+ "dyn-clone",
"enumn",
"hashbrown",
"hex",
+ "serde",
]
[[package]]
@@ -1363,18 +1642,37 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f"
dependencies = [
- "digest",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "rlp"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec"
+dependencies = [
+ "bytes",
+ "rustc-hex",
]
[[package]]
name = "ruint"
-version = "1.11.1"
+version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825"
+checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286"
dependencies = [
"alloy-rlp",
+ "ark-ff 0.3.0",
+ "ark-ff 0.4.2",
+ "bytes",
+ "fastrlp",
+ "num-bigint",
+ "num-traits",
+ "parity-scale-codec",
+ "primitive-types",
"proptest",
"rand",
+ "rlp",
"ruint-macro",
"serde",
"valuable",
@@ -1383,21 +1681,15 @@ dependencies = [
[[package]]
name = "ruint-macro"
-version = "1.1.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09"
+checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18"
[[package]]
name = "rustc-demangle"
-version = "0.1.23"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
-
-[[package]]
-name = "rustc-hash"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hex"
@@ -1407,20 +1699,29 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
[[package]]
name = "rustc_version"
-version = "0.4.0"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
+dependencies = [
+ "semver 0.11.0",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
- "semver",
+ "semver 1.0.23",
]
[[package]]
name = "rustix"
-version = "0.38.31"
+version = "0.38.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
+checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
dependencies = [
- "bitflags 2.4.2",
+ "bitflags",
"errno",
"libc",
"linux-raw-sys",
@@ -1429,15 +1730,27 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.14"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
+checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
+
+[[package]]
+name = "rusty-fork"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f"
+dependencies = [
+ "fnv",
+ "quick-error",
+ "tempfile",
+ "wait-timeout",
+]
[[package]]
name = "ryu"
-version = "1.0.16"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
+checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "scratch"
@@ -1461,67 +1774,88 @@ dependencies = [
[[package]]
name = "secp256k1"
-version = "0.27.0"
+version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
+checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113"
dependencies = [
+ "rand",
"secp256k1-sys",
]
[[package]]
name = "secp256k1-sys"
-version = "0.8.1"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
+checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9"
dependencies = [
"cc",
]
[[package]]
name = "semver"
-version = "1.0.21"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
+checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
dependencies = [
"serde",
]
+[[package]]
+name = "semver-parser"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
+dependencies = [
+ "pest",
+]
+
[[package]]
name = "serde"
-version = "1.0.196"
+version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
+checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.196"
+version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
+checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "serde_json"
-version = "1.0.113"
+version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
+checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
dependencies = [
+ "indexmap",
"itoa",
+ "memchr",
"ryu",
"serde",
]
[[package]]
name = "serde_spanned"
-version = "0.6.5"
+version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
+checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
dependencies = [
"serde",
]
@@ -1534,7 +1868,17 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
- "digest",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "sha3-asm"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46"
+dependencies = [
+ "cc",
+ "cfg-if",
]
[[package]]
@@ -1558,15 +1902,15 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
- "digest",
+ "digest 0.10.7",
"rand_core",
]
[[package]]
name = "smallvec"
-version = "1.13.1"
+version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "sol-abi"
@@ -1574,14 +1918,14 @@ version = "0.0.1"
dependencies = [
"quote",
"serde",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "spin"
-version = "0.5.2"
+version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "spki"
@@ -1593,11 +1937,17 @@ dependencies = [
"der",
]
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
[[package]]
name = "strsim"
-version = "0.10.0"
+version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
@@ -1611,7 +1961,7 @@ version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
dependencies = [
- "heck",
+ "heck 0.4.1",
"proc-macro2",
"quote",
"rustversion",
@@ -1633,9 +1983,9 @@ dependencies = [
[[package]]
name = "subtle"
-version = "2.5.0"
+version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
@@ -1650,9 +2000,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.48"
+version = "2.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
+checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
dependencies = [
"proc-macro2",
"quote",
@@ -1667,15 +2017,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
-version = "3.9.0"
+version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
+checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
dependencies = [
"cfg-if",
"fastrand",
- "redox_syscall",
+ "once_cell",
"rustix",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -1689,29 +2039,29 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.56"
+version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
+checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.56"
+version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
+checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "thread_local"
-version = "1.1.7"
+version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
@@ -1737,9 +2087,9 @@ dependencies = [
[[package]]
name = "toml"
-version = "0.8.9"
+version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6a4b9e8023eb94392d3dca65d717c53abc5dad49c07cb65bb8fcd87115fa325"
+checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
dependencies = [
"serde",
"serde_spanned",
@@ -1749,18 +2099,18 @@ dependencies = [
[[package]]
name = "toml_datetime"
-version = "0.6.5"
+version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
+checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
-version = "0.21.1"
+version = "0.22.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
+checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
dependencies = [
"indexmap",
"serde",
@@ -1788,7 +2138,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
@@ -1846,6 +2196,24 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+[[package]]
+name = "ucd-trie"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
+
+[[package]]
+name = "uint"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52"
+dependencies = [
+ "byteorder",
+ "crunchy",
+ "hex",
+ "static_assertions",
+]
+
[[package]]
name = "unarray"
version = "0.1.4"
@@ -1854,21 +2222,27 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-width"
-version = "0.1.11"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
+checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
[[package]]
name = "utf8parse"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
@@ -1878,9 +2252,18 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "version_check"
-version = "0.9.4"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "wait-timeout"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
+dependencies = [
+ "libc",
+]
[[package]]
name = "wasi"
@@ -1890,18 +2273,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-encoder"
-version = "0.41.0"
+version = "0.217.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e09bca7d6388637d27fb5edbeab11f56bfabcef8743c55ae34370e1e5030a071"
+checksum = "7b88b0814c9a2b323a9b46c687e726996c255ac8b64aa237dd11c81ed4854760"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-opt"
-version = "0.116.0"
+version = "0.116.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc942673e7684671f0c5708fc18993569d184265fd5223bb51fc8e5b9b6cfd52"
+checksum = "2fd87a4c135535ffed86123b6fb0f0a5a0bc89e50416c942c5f0662c645f679c"
dependencies = [
"anyhow",
"libc",
@@ -1939,20 +2322,20 @@ dependencies = [
[[package]]
name = "wasmparser"
-version = "0.121.0"
+version = "0.121.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "953cf6a7606ab31382cb1caa5ae403e77ba70c7f8e12eeda167e7040d42bfda8"
+checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab"
dependencies = [
- "bitflags 2.4.2",
+ "bitflags",
"indexmap",
- "semver",
+ "semver 1.0.23",
]
[[package]]
name = "wast"
-version = "70.0.2"
+version = "217.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3d5061300042ff5065123dae1e27d00c03f567d34a2937c8472255148a216dc"
+checksum = "79004ecebded92d3c710d4841383368c7f04b63d0992ddd6b0c7d5029b7629b7"
dependencies = [
"bumpalo",
"leb128",
@@ -1963,25 +2346,13 @@ dependencies = [
[[package]]
name = "wat"
-version = "1.0.85"
+version = "1.217.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afd7357b6cc46d46a2509c43dcb1dd4131dafbf4e75562d87017b5a05ffad2d6"
+checksum = "c126271c3d92ca0f7c63e4e462e40c69cca52fd4245fcda730d1cf558fb55088"
dependencies = [
"wast",
]
-[[package]]
-name = "which"
-version = "4.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
-dependencies = [
- "either",
- "home",
- "once_cell",
- "rustix",
-]
-
[[package]]
name = "winapi"
version = "0.3.9"
@@ -2000,11 +2371,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
-version = "0.1.6"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
- "winapi",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -2028,7 +2399,16 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets 0.52.0",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
]
[[package]]
@@ -2048,17 +2428,18 @@ dependencies = [
[[package]]
name = "windows-targets"
-version = "0.52.0"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
- "windows_aarch64_gnullvm 0.52.0",
- "windows_aarch64_msvc 0.52.0",
- "windows_i686_gnu 0.52.0",
- "windows_i686_msvc 0.52.0",
- "windows_x86_64_gnu 0.52.0",
- "windows_x86_64_gnullvm 0.52.0",
- "windows_x86_64_msvc 0.52.0",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
]
[[package]]
@@ -2069,9 +2450,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.52.0"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
@@ -2081,9 +2462,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.52.0"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
@@ -2093,9 +2474,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
-version = "0.52.0"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
@@ -2105,9 +2492,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
-version = "0.52.0"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
@@ -2117,9 +2504,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.52.0"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -2129,9 +2516,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.52.0"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
@@ -2141,15 +2528,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.52.0"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
-version = "0.5.37"
+version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7cad8365489051ae9f054164e459304af2e7e9bb407c958076c8bf4aef52da5"
+checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
dependencies = [
"memchr",
]
@@ -2165,42 +2552,43 @@ dependencies = [
[[package]]
name = "zabi"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
"hex",
"postcard",
"serde",
"sol-abi",
- "syn 2.0.48",
+ "syn 2.0.77",
"thiserror",
"tiny-keccak",
]
[[package]]
name = "zerocopy"
-version = "0.7.32"
+version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
+ "byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.7.32"
+version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "zeroize"
-version = "1.7.0"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
dependencies = [
"zeroize_derive",
]
@@ -2213,15 +2601,16 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
]
[[package]]
name = "zingen"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
"anyhow",
"evm-opcodes",
+ "hex",
"indexmap",
"paste",
"smallvec",
@@ -2233,10 +2622,14 @@ dependencies = [
[[package]]
name = "zink"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
"anyhow",
+ "evm-opcodes",
+ "hex",
"paste",
+ "tiny-keccak",
+ "tracing",
"zink-codegen",
"zinkc-filetests",
"zint",
@@ -2244,17 +2637,19 @@ dependencies = [
[[package]]
name = "zink-codegen"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
+ "heck 0.5.0",
+ "hex",
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
"zabi",
]
[[package]]
name = "zinkc"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
"anyhow",
"ccli",
@@ -2275,13 +2670,13 @@ dependencies = [
[[package]]
name = "zinkc-filetests"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
"anyhow",
"cargo_metadata",
"proc-macro2",
"quote",
- "syn 2.0.48",
+ "syn 2.0.77",
"tracing",
"tracing-subscriber",
"wat",
@@ -2290,7 +2685,7 @@ dependencies = [
[[package]]
name = "zint"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
"anyhow",
"cargo_metadata",
diff --git a/Cargo.toml b/Cargo.toml
index d373d7a67..88bef034e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,7 +17,7 @@ members = [
resolver = "2"
[workspace.package]
-version = "0.1.10"
+version = "0.1.11"
authors = ["clearloop"]
edition = "2021"
license = "GPL-3.0-only"
@@ -30,20 +30,21 @@ cargo_metadata = "0.18.1"
ccli = "0.0.1"
colored = "2.1.0"
etc = "0.1.19"
+heck = "0.5.0"
hex = "0.4.3"
indexmap = "2.2.2"
paste = "1.0.14"
postcard = { version = "1.0.8", default-features = false }
proc-macro2 = "1.0.78"
quote = "1.0.35"
-revm = { version = "3.5.0", default-features = false }
+revm = { version = "14", default-features = false }
semver = "1.0.21"
serde = { version = "1.0.196", default-features = false }
serde_json = "1.0.113"
smallvec = "1.13.1"
-syn = { version = "2.0.48", features = [ "full" ] }
+syn = { version = "2.0.77", features = [ "full" ] }
thiserror = "1.0.56"
-tiny-keccak = "2.0.2"
+tiny-keccak = { version = "2.0.2", features = ["keccak"], default-features = false }
toml = "0.8.9"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
@@ -52,18 +53,18 @@ wasmparser = "0.121.0"
wat = "1.0.85"
## EVM packages
-opcodes = { package = "evm-opcodes", path = "evm/opcodes", version = "=0.0.3", features = [ "data" ] }
+opcodes = { package = "evm-opcodes", path = "evm/opcodes", version = "=0.0.4", features = [ "data" ] }
sol-abi = { path = "evm/abi", version = "=0.0.1" }
## Zink packages
-elko = { path = "elko", version = "0.1.10" }
-filetests = { package = "zinkc-filetests", path = "compiler/filetests", version = "0.1.10" }
-zabi = { path = "abi", version = "0.1.10" }
-zingen = { path = "codegen", version = "0.1.10" }
-zink = { path = ".", version = "0.1.10" }
-zink-codegen = { path = "zink/codegen", version = "0.1.10" }
-zinkc = { path = "compiler", version = "0.1.10" }
-zint = { path = "zint", version = "0.1.10" }
+elko = { path = "elko", version = "0.1.11" }
+filetests = { package = "zinkc-filetests", path = "compiler/filetests", version = "0.1.11" }
+zabi = { path = "abi", version = "0.1.11" }
+zingen = { path = "codegen", version = "0.1.11" }
+zink = { path = ".", version = "0.1.11" }
+zink-codegen = { path = "zink/codegen", version = "0.1.11" }
+zinkc = { path = "compiler", version = "0.1.11" }
+zint = { path = "zint", version = "0.1.11" }
[workspace.metadata.conta]
packages = [
@@ -99,7 +100,13 @@ path = "zink/src/lib.rs"
paste.workspace = true
zink-codegen.workspace = true
+[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
+tiny-keccak.workspace = true
+
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
anyhow.workspace = true
filetests.workspace = true
+opcodes = { workspace = true, features = ["data"] }
+tracing.workspace = true
zint.workspace = true
+hex.workspace = true
diff --git a/README.md b/README.md
index beb84fae3..e876791da 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
# The Zink Project
@@ -68,7 +68,18 @@ pub extern "C" fn recursion(n: usize) -> usize {
As an example for the benchmark, calculating fibonacci sequence with recursion, missed
vyper because it doesn't support recursion...Zink is 5x fast on this, but it is mainly
caused by our current implementation is not completed yet ( missing logic to adapt to more
-situations ), let's keep tuned for `v0.3.0`.
+situations ), let's stay tuned for `v0.3.0`.
+
+## Donation
+
+After completing the ERC20 implementation, Zink will focus on MEV logic since everything could
+be even more compact and realistic from this dark forest.
+
+Zink is now moving forward without any grants or backups, if you like this dreaming project,
+please feel free to reach out, would be appreciated for any opportunities ^ ^
+
+- ETH: `0xf0306047Fa598fe95502f466aeb49b68dd94365B`
+- SOL: `AZGXAerErfwVzJkiSR8moVPZxe1nEhvjdkvxQ7qR6Yst`
## LICENSE
diff --git a/_typos.toml b/_typos.toml
index f963cf966..61b063d72 100644
--- a/_typos.toml
+++ b/_typos.toml
@@ -1,2 +1,7 @@
+[default]
+extend-ignore-re = [
+ "\\w{44,52}",
+]
+
[default.extend-words]
zink = "zink"
diff --git a/abi/src/abi.rs b/abi/src/abi.rs
new file mode 100644
index 000000000..36986047f
--- /dev/null
+++ b/abi/src/abi.rs
@@ -0,0 +1,77 @@
+//! Zink ABI implementation
+//!
+//! Currently just a wrapper of solidity ABI.
+
+use core::ops::{Deref, DerefMut};
+
+/// Function ABI.
+#[derive(Clone, Debug, Default)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+pub struct Abi(sol_abi::Abi);
+
+impl Deref for Abi {
+ type Target = sol_abi::Abi;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl DerefMut for Abi {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+}
+
+#[cfg(feature = "bytes")]
+impl Abi {
+ /// Convert [`Abi`] to bytes.
+ pub fn to_bytes(&self) -> postcard::Result> {
+ postcard::to_stdvec(self).map_err(Into::into)
+ }
+
+ /// Convert bytes to [`Abi`].
+ pub fn from_bytes(bytes: impl AsRef<[u8]>) -> postcard::Result {
+ postcard::from_bytes(bytes.as_ref()).map_err(Into::into)
+ }
+}
+
+#[cfg(feature = "hex")]
+mod hex_impl {
+ use crate::{result::Result, Abi};
+ use core::fmt;
+
+ impl Abi {
+ /// Convert [`Abi`] to hex string.
+ pub fn to_hex(&self) -> Result {
+ Ok("0x".to_string() + &hex::encode(self.to_bytes()?))
+ }
+
+ /// Convert hex string to [`Abi`].
+ pub fn from_hex(hex: impl AsRef) -> Result {
+ Self::from_bytes(hex::decode(hex.as_ref().trim_start_matches("0x"))?)
+ .map_err(Into::into)
+ }
+ }
+
+ impl fmt::Display for Abi {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.to_hex().unwrap_or_default())
+ }
+ }
+
+ impl core::str::FromStr for Abi {
+ type Err = crate::result::Error;
+
+ fn from_str(hex: &str) -> Result {
+ Self::from_hex(hex)
+ }
+ }
+}
+
+#[cfg(feature = "syn")]
+impl From<&syn::Signature> for Abi {
+ fn from(sig: &syn::Signature) -> Self {
+ Self(sol_abi::Abi::from(sig))
+ }
+}
diff --git a/abi/src/lib.rs b/abi/src/lib.rs
index cf14b2dcf..32871f5e4 100644
--- a/abi/src/lib.rs
+++ b/abi/src/lib.rs
@@ -2,78 +2,11 @@
//!
//! Currently just a wrapper of solidity ABI.
+mod abi;
pub mod result;
pub mod selector;
-use core::ops::{Deref, DerefMut};
+pub use abi::Abi;
-/// Function ABI.
-#[derive(Clone, Debug, Default)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct Abi(sol_abi::Abi);
-
-impl Deref for Abi {
- type Target = sol_abi::Abi;
-
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-
-impl DerefMut for Abi {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.0
- }
-}
-
-#[cfg(feature = "bytes")]
-impl Abi {
- /// Convert [`Abi`] to bytes.
- pub fn to_bytes(&self) -> postcard::Result> {
- postcard::to_stdvec(self).map_err(Into::into)
- }
-
- /// Convert bytes to [`Abi`].
- pub fn from_bytes(bytes: impl AsRef<[u8]>) -> postcard::Result {
- postcard::from_bytes(bytes.as_ref()).map_err(Into::into)
- }
-}
-
-#[cfg(feature = "hex")]
-mod hex_impl {
- use crate::{result::Result, Abi};
-
- impl Abi {
- /// Convert [`Abi`] to hex string.
- pub fn to_hex(&self) -> Result {
- Ok("0x".to_string() + &hex::encode(self.to_bytes()?))
- }
-
- /// Convert hex string to [`Abi`].
- pub fn from_hex(hex: impl AsRef) -> Result {
- Self::from_bytes(hex::decode(hex.as_ref().trim_start_matches("0x"))?)
- .map_err(Into::into)
- }
- }
-
- impl ToString for Abi {
- fn to_string(&self) -> String {
- self.to_hex().unwrap_or_default()
- }
- }
-
- impl core::str::FromStr for Abi {
- type Err = crate::result::Error;
-
- fn from_str(hex: &str) -> Result {
- Self::from_hex(hex)
- }
- }
-}
-
-#[cfg(feature = "syn")]
-impl From<&syn::Signature> for Abi {
- fn from(sig: &syn::Signature) -> Self {
- Self(sol_abi::Abi::from(sig))
- }
-}
+#[cfg(feature = "selector")]
+pub use selector::keccak256;
diff --git a/abi/src/selector.rs b/abi/src/selector.rs
index 7f5e15f34..a41a9a483 100644
--- a/abi/src/selector.rs
+++ b/abi/src/selector.rs
@@ -2,11 +2,11 @@
#![cfg(feature = "selector")]
use crate::Abi;
-use tiny_keccak::{Hasher, Sha3};
+use tiny_keccak::{Hasher, Keccak};
/// Generate a keccak hash of the input (sha3)
pub fn keccak256(input: &[u8]) -> [u8; 32] {
- let mut hasher = Sha3::v256();
+ let mut hasher = Keccak::v256();
let mut output = [0; 32];
hasher.update(input);
hasher.finalize(&mut output);
diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml
index b561fee29..60adb4f60 100644
--- a/codegen/Cargo.toml
+++ b/codegen/Cargo.toml
@@ -19,3 +19,4 @@ thiserror.workspace = true
tracing.workspace = true
wasmparser.workspace = true
zabi = { workspace = true, features = [ "hex", "selector", "syn" ] }
+hex.workspace = true
diff --git a/codegen/src/asm.rs b/codegen/src/asm.rs
index f0e1d7211..329f66407 100644
--- a/codegen/src/asm.rs
+++ b/codegen/src/asm.rs
@@ -6,7 +6,7 @@ use crate::{Buffer, Error, Result};
use opcodes::{for_each_shanghai_operator, OpCode as _, ShangHai as OpCode};
/// Low level assembler implementation for EVM.
-#[derive(Default, Clone)]
+#[derive(Default, Clone, Debug)]
pub struct Assembler {
/// Buffer of the assembler.
buffer: Buffer,
@@ -46,8 +46,8 @@ impl Assembler {
return Ok(());
}
- tracing::trace!(
- "increment stack pointer {}({items}) -> {}",
+ tracing::debug!(
+ "increment stack pointer {}.add({items}) -> {}",
self.sp,
self.sp + items
);
@@ -67,15 +67,18 @@ impl Assembler {
return Ok(());
}
- tracing::trace!(
- "decrement stack pointer {}({items}) -> {}",
+ tracing::debug!(
+ "decrement stack pointer {}.sub({items}) -> {}",
self.sp,
self.sp - items
);
- self.sp = self
- .sp
- .checked_sub(items)
- .ok_or(Error::StackUnderflow(self.sp, items))?;
+ self.sp = if self.sp == items {
+ 0
+ } else {
+ self.sp
+ .checked_sub(items)
+ .ok_or(Error::StackUnderflow(self.sp, items))?
+ };
Ok(())
}
diff --git a/codegen/src/backtrace.rs b/codegen/src/backtrace.rs
index e5a4aae97..e674487e4 100644
--- a/codegen/src/backtrace.rs
+++ b/codegen/src/backtrace.rs
@@ -23,6 +23,11 @@ impl Backtrace {
self.instrs.pop_last().unwrap_or_default().1
}
+ /// Get the last byte
+ pub fn last(&self) -> Option> {
+ self.instrs.last_key_value().map(|(_, op)| op.clone())
+ }
+
/// Pop the last `n` operands from the backtrace.
pub fn popn(&mut self, n: usize) -> Vec> {
let mut r: Vec> = Default::default();
diff --git a/codegen/src/codegen/constructor.rs b/codegen/src/codegen/constructor.rs
index 92a5dd5b1..a2428022c 100644
--- a/codegen/src/codegen/constructor.rs
+++ b/codegen/src/codegen/constructor.rs
@@ -1,118 +1,74 @@
//! Contract constructor.
-use crate::{wasm::ToLSBytes, Buffer, Function, JumpTable, MacroAssembler, Result};
-use wasmparser::FuncType;
+use crate::{wasm::ToLSBytes, Buffer, MacroAssembler, Result};
+use smallvec::SmallVec;
+use std::collections::HashMap;
+
+/// Initial storage of contracts
+pub type InitStorage = HashMap, SmallVec<[u8; 32]>>;
/// Contract constructor.
-///
-/// # Bytecode
-/// - `CREATE` instruction
-/// - `INIT_CODE`
-/// - `INIT_LOGIC`
-/// - `RETURN RUNTIME_BYTECODE`
-/// - `RUNTIME_BYTECODE`
-///
-/// TODO: introduce ABI for constructor
+#[derive(Default, Debug, Clone)]
pub struct Constructor {
/// Code generator.
- pub masm: MacroAssembler,
- /// Code buffer.
- pub init_code: Buffer,
- /// Runtime bytecode.
- pub runtime_bytecode: Buffer,
+ masm: MacroAssembler,
}
impl Constructor {
- /// Create a new constructor.
- pub fn new(constructor: Option, runtime_bytecode: Buffer) -> Result {
- let mut init_code = Buffer::new();
- if let Some(constructor) = constructor {
- let codegen = Function::new(
- Default::default(),
- constructor,
- // No `return` instruction in the generated code.
- false,
- )?;
-
- let mut jump_table = JumpTable::default();
- init_code = codegen.finish(&mut jump_table, 0)?;
- jump_table.relocate(&mut init_code)?;
- };
+ /// preset storage for the contract
+ pub fn storage(&mut self, mapping: InitStorage) -> Result<()> {
+ for (key, value) in mapping.into_iter() {
+ self.masm.push(&value)?;
+ self.masm.push(&key)?;
+ self.masm._sstore()?;
+ }
- Ok(Self {
- masm: MacroAssembler::default(),
- init_code,
- runtime_bytecode,
- })
+ Ok(())
}
/// Concat the constructor code.
///
/// Here we override the memory totally with
/// the runtime bytecode.
- pub fn finish(&mut self) -> Result {
- let init_code_length = self.init_code.len();
- let runtime_bytecode_length = self.runtime_bytecode.len();
- let return_instr_length =
- Self::return_instr_length(init_code_length, runtime_bytecode_length);
-
- // Copy init code and runtime bytecode to memory from offset 0.
- //
- // 1. code size ( init_code + instr_return + runtime_bytecode )
- // 2. byte offset of code which is fixed to N.
- // 3. destination offset which is fixed to 0.
- {
- self.masm.push(
- &(init_code_length + return_instr_length + runtime_bytecode_length).to_ls_bytes(),
- )?;
- // # SAFETY
- //
- // The length of the most significiant bytes of
- // the bytecode offset is fixed to 1.
- self.masm
- .push(&((self.masm.pc_offset() as usize + 9).to_ls_bytes()))?;
- self.masm._push0()?;
- self.masm._codecopy()?;
- }
+ pub fn finish(&self, runtime_bytecode: Buffer) -> Result {
+ let init_code = self.masm.buffer();
+ let init_code_len = init_code.len();
+ let runtime_bytecode_len = runtime_bytecode.len();
+ let runtime_bytecode_size = runtime_bytecode_len.to_ls_bytes();
+ let runtime_bytecode_offset =
+ Self::runtime_bytcode_offset(init_code_len, runtime_bytecode_size.len());
- // Process instruction `CREATE`
- {
- self.masm._push0()?;
- self.masm._push0()?;
- self.masm._push0()?;
- self.masm._calldataload()?;
- self.masm._create()?;
- }
-
- self.masm.buffer_mut().extend_from_slice(&self.init_code);
+ let mut masm = self.masm.clone();
- // Process `RETURN`.
- //
- // 1. size of the runtime bytecode
- // 2. offset of the runtime bytecode in memory
- {
- self.masm.push(&runtime_bytecode_length.to_ls_bytes())?;
- self.masm
- .push(&(init_code_length + return_instr_length).to_ls_bytes())?;
- self.masm.asm._return()?;
- }
+ // 1. copy runtime bytecode to memory
+ masm.push(&runtime_bytecode_size)?; // code size
+ masm.push(&runtime_bytecode_offset.to_ls_bytes())?; // code offset
+ masm._push0()?; // dest offset in memory
+ masm._codecopy()?;
- self.masm
- .buffer_mut()
- .extend_from_slice(&self.runtime_bytecode);
+ // 2. return runtime bytecode
+ masm.push(&runtime_bytecode_size)?; // code size
+ masm._push0()?; // memory offset
+ masm.asm._return()?;
+ masm.buffer_mut().extend_from_slice(&runtime_bytecode);
- Ok(self.masm.buffer().into())
+ Ok(masm.buffer().into())
}
- /// Returns the length of instructions.
- fn return_instr_length(init_code_length: usize, runtime_bytecode_length: usize) -> usize {
- let mut expected_length =
- runtime_bytecode_length.to_ls_bytes().len() + init_code_length.to_ls_bytes().len() + 3;
-
- if init_code_length < 0xff && init_code_length + expected_length > 0xff {
- expected_length += 1;
+ /// Returns the offset of runtime bytecode.
+ ///
+ /// [
+ /// init_code,
+ /// pushn, runtime_bytecode_size, pushn + , push0, code_copy
+ /// pushn, runtime_bytecode_size, push0, return,
+ ///
+ /// ]
+ fn runtime_bytcode_offset(init_code_len: usize, runtime_bytecode_size_len: usize) -> usize {
+ let mut offset = init_code_len + runtime_bytecode_size_len * 2 + 8;
+ if (offset <= 0xff) && (offset + offset.to_ls_bytes().len() > 0xff) {
+ offset += 1;
}
- expected_length
+ offset
}
}
diff --git a/codegen/src/codegen/dispatcher.rs b/codegen/src/codegen/dispatcher.rs
index 3f4c5cce6..d103d84e2 100644
--- a/codegen/src/codegen/dispatcher.rs
+++ b/codegen/src/codegen/dispatcher.rs
@@ -1,13 +1,11 @@
//! Code generator for EVM dispatcher.
-use std::collections::BTreeMap;
-
use crate::{
- codegen::code::ExtFunc,
- wasm::{self, Env, Functions, ToLSBytes},
- Error, JumpTable, MacroAssembler, Result,
+ wasm::{self, Env, Functions},
+ JumpTable, MacroAssembler, Result,
};
-use wasmparser::{FuncType, Operator};
+use std::collections::BTreeMap;
+use wasmparser::FuncType;
use zabi::Abi;
/// Code generator for EVM dispatcher.
@@ -44,14 +42,13 @@ impl Dispatcher {
/// Emit compiled code to the given buffer.
pub fn finish(&mut self, selectors: Functions<'_>, table: &mut JumpTable) -> Result> {
if selectors.is_empty() {
- return Err(Error::SelectorNotFound);
+ return Ok(Default::default());
}
self.asm._push0()?;
self.asm._calldataload()?;
self.asm.push(&[0xe0])?;
self.asm._shr()?;
-
let mut len = selectors.len();
for (_, func) in selectors.iter() {
self.emit_selector(func, len == 1)?;
@@ -62,188 +59,35 @@ impl Dispatcher {
Ok(self.asm.buffer().into())
}
- /// Query exported function from selector.
- fn query_func(&self, name: &str) -> Result {
- for (index, export) in self.env.exports.iter() {
- if export == name {
- return Ok(*index);
- }
- }
-
- Err(Error::FuncNotImported(name.into()))
- }
-
- /// Load function ABI.
- fn load_abi(&mut self, selector: &wasm::Function<'_>) -> Result {
- let mut reader = selector.body.get_operators_reader()?;
-
- let Operator::I32Const { value: offset } = reader.read()? else {
- return Err(Error::InvalidSelector);
- };
- let Operator::I32Const { value: length } = reader.read()? else {
- return Err(Error::InvalidSelector);
- };
-
- // Validate zinkc helper `emit_abi`
- let Operator::Call {
- function_index: index,
- } = reader.read()?
- else {
- return Err(Error::InvalidSelector);
- };
-
- if !self.env.imports.is_emit_abi(index) {
- return Err(Error::FuncNotImported("emit_abi".into()));
- }
-
- let abi = self.env.data.load(offset, length as usize)?;
- Abi::from_hex(String::from_utf8_lossy(&abi)).map_err(Into::into)
- }
-
- /// Emit return of ext function.
- fn ext_return(&mut self, sig: &FuncType) -> Result<()> {
- self.asm.increment_sp(1)?;
- let asm = self.asm.clone();
-
- {
- self.asm.main_return(sig.results())?;
- }
-
- let bytecode = {
- let jumpdest = vec![0x5b];
- let ret = self.asm.buffer()[asm.buffer().len()..].to_vec();
- [jumpdest, ret].concat()
- };
-
- *self.asm = asm;
- let ret = ExtFunc {
- bytecode,
- stack_in: 0,
- stack_out: 0,
- };
- self.table.ext(self.asm.pc_offset(), ret);
- Ok(())
- }
-
- // Process to the selected function.
- //
- // 1. drop selector.
- // 2. load calldata to stack.
- // 3. jump to the callee function.
- fn process(&mut self, len: usize, last: bool) -> Result {
- let len = len as u8;
- if last && len == 0 {
- return Ok(false);
- }
-
- self.asm.increment_sp(1)?;
- let asm = self.asm.clone();
- {
- if !last {
- // TODO: check the safety of this.
- //
- // [ ret, callee, selector ] -> [ selector, ret, callee ]
- self.asm.shift_stack(2, false)?;
- // [ selector, ret, callee ] -> [ ret, callee ]
- self.asm._drop()?;
- } else {
- self.asm._swap1()?;
- }
-
- if len > 0 {
- // [ ret, callee ] -> [ param * len, ret, callee ]
- for p in (0..len).rev() {
- let offset = 4 + p * 32;
- self.asm.push(&offset.to_ls_bytes())?;
- self.asm._calldataload()?;
- }
-
- // [ param * len, ret, callee ] -> [ ret, param * len, callee ]
- self.asm.shift_stack(len, false)?;
- // [ ret, param * len, callee ] -> [ callee, ret, param * len ]
- self.asm.shift_stack(len + 1, false)?;
- } else {
- self.asm._swap1()?;
- }
-
- self.asm._jump()?;
- }
-
- let bytecode = {
- let jumpdest = vec![0x5b];
- let ret = self.asm.buffer()[asm.buffer().len()..].to_vec();
- [jumpdest, ret].concat()
- };
- *self.asm = asm;
- let ret = ExtFunc {
- bytecode,
- stack_in: len,
- stack_out: 1,
- };
- self.table.ext(self.asm.pc_offset(), ret);
- Ok(true)
- }
-
/// Emit selector to buffer.
fn emit_selector(&mut self, selector: &wasm::Function<'_>, last: bool) -> Result<()> {
- let abi = self.load_abi(selector)?;
-
- // TODO: refactor this. (#206)
+ let abi = self.env.load_abi(selector)?;
self.abi.push(abi.clone());
let selector_bytes = abi.selector();
-
tracing::trace!(
"Emitting selector {:?} for function: {}",
selector_bytes,
abi.signature(),
);
- let func = self.query_func(&abi.name)?;
- let sig = self
- .funcs
- .get(&func)
- .ok_or(Error::FuncNotFound(func))?
- .clone();
-
- // TODO: optimize this on parameter length (#165)
- {
- // Prepare the `PC` of the callee function.
- //
- // TODO: remove this (#160)
- {
- self.asm.increment_sp(1)?;
- self.table.call(self.asm.pc_offset(), func);
- self.asm._jumpdest()?;
- }
+ let func = self.env.query_func(&abi.name)?;
+ self.asm.increment_sp(1)?;
- // Jump to the end of the current function.
- //
- // TODO: detect the bytes of the position. (#157)
- self.ext_return(&sig)?;
- }
+ // Prepare the `PC` of the callee function.
+ self.table.call(self.asm.pc_offset(), func);
if last {
- self.asm._swap2()?;
+ self.asm._swap1()?;
} else {
- self.asm._dup3()?;
+ self.asm._dup2()?;
}
self.asm.push(&selector_bytes)?;
self.asm._eq()?;
- let processed = self.process(sig.params().len(), last)?;
- if last && !processed {
- self.asm._swap1()?;
- }
+ self.asm._swap1()?;
self.asm._jumpi()?;
- if !last {
- // drop the PC of the previous callee function.
- self.asm._drop()?;
- // drop the PC of the previous callee function preprocessor.
- self.asm._drop()?;
- }
-
Ok(())
}
}
diff --git a/codegen/src/codegen/function.rs b/codegen/src/codegen/function.rs
index 054d28962..09c40e625 100644
--- a/codegen/src/codegen/function.rs
+++ b/codegen/src/codegen/function.rs
@@ -9,10 +9,14 @@ use crate::{
wasm::Env,
Buffer, Error, Result,
};
+use opcodes::ShangHai as OpCode;
use wasmparser::{FuncType, FuncValidator, LocalsReader, OperatorsReader, ValidatorResources};
+use zabi::Abi;
/// The code generation abstraction.
pub struct Function {
+ /// Abi of this function,
+ pub abi: Option,
/// The backtrace.
pub backtrace: Backtrace,
/// Control stack frames.
@@ -33,13 +37,10 @@ pub struct Function {
impl Function {
/// Create a new code generator.
- pub fn new(env: Env, ty: FuncType, is_main: bool) -> Result {
- let mut params_count = 0;
- if !is_main {
- params_count = ty.params().len() as u8;
- }
-
+ pub fn new(env: Env, ty: FuncType, abi: Option, is_main: bool) -> Result {
+ let is_external = abi.is_some();
let mut codegen = Self {
+ abi,
backtrace: Backtrace::default(),
control: ControlStack::default(),
env,
@@ -50,14 +51,22 @@ impl Function {
is_main,
};
+ if is_main {
+ return Ok(codegen);
+ }
+
// post process program counter and stack pointer.
- if !is_main {
+ if is_external {
+ // codegen.masm.increment_sp(1)?;
+ tracing::debug!("");
+ codegen.masm._jumpdest()?;
+ } else {
// Mock the stack frame for the callee function
//
- // STACK: PC + params
- codegen.masm.increment_sp(1 + params_count)?;
+ // STACK: [ PC ]
+ tracing::debug!("");
+ codegen.masm.increment_sp(1)?;
codegen.masm._jumpdest()?;
- codegen.masm.shift_stack(params_count, true)?;
}
Ok(codegen)
@@ -68,7 +77,7 @@ impl Function {
/// 1. the function parameters.
/// 2. function body locals.
///
- /// NOTE: we don't care about the origin offset of the locals.
+ /// NOTE: we don't care about the original offset of the locals.
/// bcz we will serialize the locals to an index map anyway.
pub fn emit_locals(
&mut self,
@@ -88,10 +97,8 @@ impl Function {
//
// Record the offset for validation.
while let Ok((count, val)) = locals.read() {
- let validation_offset = locals.original_position();
for _ in 0..count {
- // Init locals with zero.
- self.masm.push(&[0])?;
+ // TODO: the below here is outdated, sp is not required anymore after #245
// Define locals.
self.locals
@@ -100,6 +107,7 @@ impl Function {
sp += 1;
}
+ let validation_offset = locals.original_position();
validator.define_locals(validation_offset, count, val)?;
}
@@ -119,13 +127,19 @@ impl Function {
ops.visit_operator(&mut validate_then_visit)???;
}
+ if (self.abi.is_some() || self.is_main)
+ && self.masm.buffer().last() != Some(&OpCode::RETURN.into())
+ {
+ self._end()?;
+ }
+
Ok(())
}
/// Finish code generation.
pub fn finish(self, jump_table: &mut JumpTable, pc: u16) -> Result {
let sp = self.masm.sp();
- if !self.is_main && self.masm.sp() != self.ty.results().len() as u8 {
+ if !self.is_main && self.abi.is_none() && self.masm.sp() != self.ty.results().len() as u8 {
return Err(Error::StackNotBalanced(sp));
}
diff --git a/codegen/src/codegen/mod.rs b/codegen/src/codegen/mod.rs
index 80fac4e5e..ab43c84fb 100644
--- a/codegen/src/codegen/mod.rs
+++ b/codegen/src/codegen/mod.rs
@@ -12,7 +12,7 @@ mod function;
pub use self::{
code::{Code, ExtFunc},
- constructor::Constructor,
+ constructor::{Constructor, InitStorage},
dispatcher::Dispatcher,
function::Function,
};
diff --git a/codegen/src/jump/table.rs b/codegen/src/jump/table.rs
index c32c6b31c..af7d874bd 100644
--- a/codegen/src/jump/table.rs
+++ b/codegen/src/jump/table.rs
@@ -47,7 +47,7 @@ impl JumpTable {
self.jump.insert(pc, Jump::Label(label));
}
- /// Register a label.
+ /// Register a label at the specific PC offset
pub fn offset(&mut self, pc: u16, offset: u16) {
self.jump.insert(pc, Jump::Offset(offset));
}
diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs
index 2e1665770..0d01c24d9 100644
--- a/codegen/src/lib.rs
+++ b/codegen/src/lib.rs
@@ -4,7 +4,7 @@
pub use crate::{
asm::Assembler,
- codegen::{Code, Constructor, Dispatcher, Function},
+ codegen::{Code, Constructor, Dispatcher, Function, InitStorage},
control::{ControlStack, ControlStackFrame, ControlStackFrameType},
jump::JumpTable,
local::{LocalSlot, Locals},
diff --git a/codegen/src/local.rs b/codegen/src/local.rs
index 664c2b229..d2a1df71d 100644
--- a/codegen/src/local.rs
+++ b/codegen/src/local.rs
@@ -79,18 +79,19 @@ impl Locals {
/// Get the lower significant bytes of the byte offset of a local.
///
/// - **Parameter**: If the local is a parameter, the offset is relative to the offset
- /// of the calldata.
+ /// of the calldata.
/// - **Variable**: If the local is a variable, the offset is relative to the offset
- /// of the memory.
+ /// of the memory.
pub fn offset_of(&self, index: usize) -> Result> {
let local = self.get(index)?;
let offset = if local.ty() == &LocalSlotType::Parameter {
self.inner[..index].iter().fold(0, |acc, x| acc + x.align())
} else {
- self.inner[..index]
- .iter()
- .filter(|x| x.ty() == &LocalSlotType::Variable)
- .fold(0, |acc, x| acc + x.align())
+ panic!("This should never be reached");
+ // self.inner[..index]
+ // .iter()
+ // .filter(|x| x.ty() == &LocalSlotType::Variable)
+ // .fold(0, |acc, x| acc + x.align())
}
.to_ls_bytes()
.to_vec()
diff --git a/codegen/src/masm/mod.rs b/codegen/src/masm/mod.rs
index 5f0ff72ed..6a7cf60cd 100644
--- a/codegen/src/masm/mod.rs
+++ b/codegen/src/masm/mod.rs
@@ -17,7 +17,7 @@ mod ret;
mod stack;
/// EVM MacroAssembler.
-#[derive(Default)]
+#[derive(Default, Debug, Clone)]
pub struct MacroAssembler {
/// Low level assembler.
pub(crate) asm: Assembler,
@@ -87,6 +87,14 @@ impl MacroAssembler {
/// Place n bytes on stack.
pub fn push(&mut self, bytes: &[u8]) -> Result<()> {
tracing::trace!("push bytes: 0x{:x?}", bytes);
+
+ // TODO: support PUSH0 #247
+ //
+ // if !bytes.iter().any(|b| *b != 0) {
+ // self.asm._push0()?;
+ // return Ok(());
+ // }
+
let len = bytes.len();
match len {
0 => self.asm._push0(),
diff --git a/codegen/src/masm/ret.rs b/codegen/src/masm/ret.rs
index cf9fadd9e..ee1c9dd1c 100644
--- a/codegen/src/masm/ret.rs
+++ b/codegen/src/masm/ret.rs
@@ -32,20 +32,15 @@ impl MacroAssembler {
/// Handle the return of a call.
pub fn call_return(&mut self, results: &[ValType]) -> Result<()> {
let len = results.len() as u8;
- let sp = self.sp();
- tracing::trace!("current stack items: {sp}");
- for i in 0..len {
- // TODO: arthmetic overflow.
- //
- // 2 is for PC and self.
- self.swap(sp.saturating_sub(i).saturating_sub(2))?;
- }
tracing::trace!("cleaning frame stack, target: {}", len + 1);
while self.sp() > len + 1 {
self._drop()?;
}
+ // Shift stack to prompt the jump instruction,
+ // what about just dup it?
+ //
// TODO: handle the length of results > u8::MAX.
self.shift_stack(len, false)?;
self._jump()
diff --git a/codegen/src/result.rs b/codegen/src/result.rs
index 60c703e64..1889e1bbd 100644
--- a/codegen/src/result.rs
+++ b/codegen/src/result.rs
@@ -3,6 +3,9 @@
/// Codegen error
#[derive(Debug, thiserror::Error)]
pub enum Error {
+ /// Any error
+ #[error("{0}")]
+ Anyhow(#[from] anyhow::Error),
/// Failed to parse function ABI.
#[error(transparent)]
Abi(#[from] zabi::result::Error),
@@ -61,7 +64,7 @@ pub enum Error {
#[error("Invalid data size {0}")]
InvalidDataSize(usize),
/// Failed to get frame info of the given depth.
- #[error("Invalid contract stack fram depth {0}")]
+ #[error("Invalid contract stack frame depth {0}")]
InvalidDepth(usize),
/// Failed to parse function selector.
#[error("Invalid function selector")]
diff --git a/codegen/src/validator.rs b/codegen/src/validator.rs
index b6cbd06c0..2584f4c54 100644
--- a/codegen/src/validator.rs
+++ b/codegen/src/validator.rs
@@ -32,17 +32,17 @@ fn visit_op_when_unreachable(op: Operator) -> bool {
matches!(op, If { .. } | Block { .. } | Loop { .. } | Else | End)
}
-/// Trait to handle reachability state.
-trait ReachableState {
- /// Returns true if the current state of the program is reachable.
- fn is_reachable(&self) -> bool;
-}
-
-impl ReachableState for Function {
- fn is_reachable(&self) -> bool {
- true
- }
-}
+// /// Trait to handle reachability state.
+// trait ReachableState {
+// /// Returns true if the current state of the program is reachable.
+// fn is_reachable(&self) -> bool;
+// }
+//
+// impl ReachableState for Function {
+// fn is_reachable(&self) -> bool {
+// true
+// }
+// }
impl<'a, T> VisitOperator<'a> for ValidateThenVisit<'_, T>
where
diff --git a/codegen/src/visitor/call.rs b/codegen/src/visitor/call.rs
index 0dd986853..115c86080 100644
--- a/codegen/src/visitor/call.rs
+++ b/codegen/src/visitor/call.rs
@@ -1,6 +1,10 @@
//! call instructions
-use crate::{wasm::HostFunc, Error, Function, Result};
+use crate::{
+ wasm::{HostFunc, ToLSBytes},
+ Error, Function, Result,
+};
+use anyhow::anyhow;
use opcodes::ShangHai as OpCode;
impl Function {
@@ -17,6 +21,11 @@ impl Function {
/// The call instruction calls a function specified by its index.
pub fn _call(&mut self, index: u32) -> Result<()> {
+ if self.env.is_external(index) {
+ // TODO: throw with error
+ panic!("External functions could not be called internally");
+ }
+
if self.env.imports.len() as u32 > index {
self.call_imported(index)
} else {
@@ -26,26 +35,60 @@ impl Function {
/// Call internal functions
fn call_internal(&mut self, index: u32) -> Result<()> {
+ if self.env.index == Some(index) {
+ return Err(anyhow!(
+ "Recursion is no more supported in this version, see https://github.com/zink-lang/zink/issues/248"
+ )
+ .into());
+ }
+
tracing::trace!("call internal function: index={index}");
- // record the current program counter and
- // pass it to the callee function.
- self.table.offset(self.masm.pc_offset(), 6);
+ let (params, results) = self.env.funcs.get(&index).unwrap_or(&(0, 0));
+
+ // TODO: adapat the case that the params is larger than 0xff (#247)
+ //
+ // 1. record the program counter of the end of this expression
+ // call and pass it to the callee function.
+ //
+ // [ ..,
+ // ,
+ // params[SWAP], params[PUSH, SLOT, MSTORE],
+ // PUSH, PC, JUMP,
+ // ]
+ // <- selfparams[PUSH, OFFSET, CALLDATALOAD]
+ //
+ // 2. move PC before the params in stack
+ self.table
+ .offset(self.masm.pc_offset(), 5 + 4 * (*params as u16));
self.masm.increment_sp(1)?;
- self.masm._jumpdest()?;
- // Call an internal function.
+ // Stack
+ // =====
//
- // register the call index to the jump table.
+ // from [ , PC ]
+ // to [ PC, ]
+ self.masm.shift_stack(*params as u8, true)?;
+
+ // Call an internal function.
//
+ // 1. store params in memory
+ // 2. register the call index to the jump table.
+ let reserved = self.env.slots.get(&index).unwrap_or(&0);
+ for i in (0..*params).rev() {
+ tracing::trace!("storing local at {} for function {index}", i + reserved);
+ self.masm.push(&((i + reserved) * 0x20).to_ls_bytes())?;
+ self.masm._mstore()?;
+ }
+
// TODO: support same pc different jumps. (#160)
self.table.call(self.masm.pc_offset(), index);
// jump to the callee function
- //
- // TODO: check the stack output.
self.masm._jump()?;
self.masm._jumpdest()?;
+ // Stack: [ , ..results ]
+ self.masm.increment_sp(*results as u8)?;
Ok(())
}
@@ -69,7 +112,7 @@ impl Function {
HostFunc::Evm(OpCode::LOG3) => self.log(3),
HostFunc::Evm(OpCode::LOG4) => self.log(4),
HostFunc::Evm(op) => self.masm.emit_op(op),
- HostFunc::NoOp => Ok(()),
+ HostFunc::NoOp | HostFunc::Label(_) => Ok(()),
_ => {
tracing::error!("unsupported host function {func:?}");
Err(Error::UnsupportedHostFunc(func))
diff --git a/codegen/src/visitor/control.rs b/codegen/src/visitor/control.rs
index 361743f9c..f8a50987d 100644
--- a/codegen/src/visitor/control.rs
+++ b/codegen/src/visitor/control.rs
@@ -130,20 +130,21 @@ impl Function {
/// Handle the end of instructions for different situations.
///
- /// TODO: (#28)
- ///
/// - End of control flow operators.
/// - End of function.
/// - End of program.
pub fn _end(&mut self) -> Result<()> {
if let Ok(frame) = self.control.pop() {
- self.handle_frame_popping(frame)
- } else if !self.is_main {
- tracing::trace!("end of call");
- self.handle_call_return()
- } else {
+ return self.handle_frame_popping(frame);
+ }
+
+ let results = self.ty.results();
+ if self.is_main || self.abi.is_some() {
tracing::trace!("end of main function");
- self.handle_return()
+ self.masm.main_return(results)
+ } else {
+ tracing::trace!("end of call");
+ self.masm.call_return(results)
}
}
@@ -160,4 +161,25 @@ impl Function {
pub fn _nop(&mut self) -> Result<()> {
Ok(())
}
+
+ /// Handle the popping of a frame.
+ ///
+ /// TODO: validate stack IO for all frames (#59)
+ pub(crate) fn handle_frame_popping(&mut self, frame: ControlStackFrame) -> Result<()> {
+ match frame.ty {
+ ControlStackFrameType::If(true) => Ok(()),
+ ControlStackFrameType::Block => self.masm._jumpdest(),
+ ControlStackFrameType::Loop => Ok(()),
+ _ => {
+ self.table
+ .label(frame.original_pc_offset, self.masm.pc_offset());
+
+ // TODO: Check the stack output and make decisions
+ // how to handle the results.
+
+ // Emit JUMPDEST after at the end of the control flow.
+ self.masm._jumpdest()
+ }
+ }
+ }
}
diff --git a/codegen/src/visitor/handlers.rs b/codegen/src/visitor/handlers.rs
deleted file mode 100644
index 2f1435c73..000000000
--- a/codegen/src/visitor/handlers.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-//! Case handlers
-
-use crate::{ControlStackFrame, ControlStackFrameType, Function, Result};
-
-impl Function {
- /// Handle the end of the function.
- pub(crate) fn handle_return(&mut self) -> Result<()> {
- let results = self.ty.results();
- tracing::trace!("handle return, results: {results:?}");
-
- self.masm.main_return(results)
- }
-
- /// Handle the return of a call.
- pub(crate) fn handle_call_return(&mut self) -> Result<()> {
- let results = self.ty.results();
- tracing::trace!("handle call return: {:?}", results);
-
- self.masm.call_return(results)
- }
-
- /// Handle the popping of a frame.
- ///
- /// TODO: validate stack IO for all frames (#59)
- pub(crate) fn handle_frame_popping(&mut self, frame: ControlStackFrame) -> Result<()> {
- match frame.ty {
- ControlStackFrameType::If(true) => {
- // TODO: fix this for nested if-else.
- self.handle_return()
- }
- ControlStackFrameType::Block => self.masm._jumpdest(),
- ControlStackFrameType::Loop => Ok(()),
- _ => self.handle_jumpdest(frame.original_pc_offset),
- }
- }
-
- /// Handle jumpdest.
- pub(crate) fn handle_jumpdest(&mut self, original_pc: u16) -> Result<()> {
- self.table.label(original_pc, self.masm.pc_offset());
-
- // TODO: Check the stack output and make decisions
- // how to handle the results.
-
- // Emit JUMPDEST after at the end of the control flow.
- self.masm._jumpdest()?;
-
- Ok(())
- }
-}
diff --git a/codegen/src/visitor/local.rs b/codegen/src/visitor/local.rs
index e02ede6c8..ac7c73051 100644
--- a/codegen/src/visitor/local.rs
+++ b/codegen/src/visitor/local.rs
@@ -1,28 +1,24 @@
//! Local instructions
-use crate::{Error, Function, Result};
+use crate::{wasm::ToLSBytes, Error, Function, Result};
impl Function {
/// This instruction gets the value of a variable.
pub fn _local_get(&mut self, local_index: u32) -> Result<()> {
let local_index = local_index as usize;
- if self.is_main && local_index < self.ty.params().len() {
+ if (self.is_main && local_index < self.ty.params().len()) || self.abi.is_some() {
+ // Parsing data from selector.
self._local_get_calldata(local_index)
} else {
+ // Passing data between local functions.
self._local_get_var(local_index)
}
}
/// This instruction sets the value of a variable.
pub fn _local_set(&mut self, local_index: u32) -> Result<()> {
- let index = local_index as usize;
- let sp = self.masm.sp();
- let local = self.locals.get(index)?;
- let local_sp = local.sp as u8;
-
- tracing::trace!("local_set: {index} {local_sp} {sp}");
- self.masm.swap(sp - local_sp - 1)?;
- self.masm._drop()?;
+ self.masm.push(&self.env.alloc(local_index))?;
+ self.masm._mstore()?;
Ok(())
}
@@ -47,7 +43,11 @@ impl Function {
/// Local get from calldata.
fn _local_get_calldata(&mut self, local_index: usize) -> Result<()> {
- let offset = self.locals.offset_of(local_index)?;
+ let mut offset = self.locals.offset_of(local_index)?;
+ if self.abi.is_some() {
+ offset = (4 + local_index * 32).to_ls_bytes().to_vec().into();
+ }
+
self.masm.push(&offset)?;
self.masm._calldataload()?;
@@ -56,25 +56,14 @@ impl Function {
/// Local get for variables.
fn _local_get_var(&mut self, local_index: usize) -> Result<()> {
+ tracing::trace!("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));
}
- // If local is already on stack.
- if self.masm.buffer().len() == self.locals.len() + 1 {
- return Ok(());
- }
-
- tracing::debug!("buffer: {:?}", self.masm.buffer());
-
- let local = self.locals.get(local_index)?;
- let local_sp = local.sp as u8;
- let sp = self.masm.sp();
-
- tracing::trace!("local_get: {local_index} {local_sp} {sp}");
-
- // TODO: Arthmetic checks
- self.masm.dup(sp - local_sp)?;
+ self.masm.push(&self.env.alloc(local_index as u32))?;
+ self.masm._mload()?;
Ok(())
}
}
diff --git a/codegen/src/visitor/mod.rs b/codegen/src/visitor/mod.rs
index 374652ae5..6b95a1de5 100644
--- a/codegen/src/visitor/mod.rs
+++ b/codegen/src/visitor/mod.rs
@@ -11,7 +11,6 @@ use wasmparser::{for_each_operator, BlockType, BrTable, Ieee32, Ieee64, MemArg,
mod call;
mod control;
-mod handlers;
mod local;
mod log;
@@ -20,7 +19,7 @@ mod log;
/// This macro calls itself recursively;
/// 1. It no-ops when matching a supported operator.
/// 2. Defines the visitor function and panics when
-/// matching an unsupported operator.
+/// matching an unsupported operator.
macro_rules! impl_visit_operator {
( @mvp $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
impl_visit_operator!($($rest)*);
diff --git a/codegen/src/wasm/func.rs b/codegen/src/wasm/func.rs
index 79085cb28..12424e08b 100644
--- a/codegen/src/wasm/func.rs
+++ b/codegen/src/wasm/func.rs
@@ -54,17 +54,6 @@ impl<'f> Functions<'f> {
);
}
- /// Remove constructor function
- pub fn remove_constructor(&mut self, exports: &Exports) -> Option {
- for (index, export) in exports.iter() {
- if export.as_str() == "constructor" {
- return self.remove(index)?.sig().ok();
- }
- }
-
- None
- }
-
/// Remove all selector functions
pub fn drain_selectors(&mut self, exports: &Exports) -> Self {
let mut functions = Self::default();
diff --git a/codegen/src/wasm/host.rs b/codegen/src/wasm/host.rs
index 8ab2e1f2d..22301c9c8 100644
--- a/codegen/src/wasm/host.rs
+++ b/codegen/src/wasm/host.rs
@@ -15,6 +15,10 @@ pub enum HostFunc {
//
/// Emit ABI to the compiler.
EmitABI,
+ /// check equal of two addresses
+ AddressEq,
+ /// Compiler labels
+ Label(CompilerLabel),
}
impl HostFunc {
@@ -48,12 +52,14 @@ impl TryFrom<(&str, &str)> for HostFunc {
Ok(Self::NoOp)
}
}
- ("evm", name) => {
- Ok(Self::Evm(OpCode::from_str(name).map_err(|_| {
- Error::HostFuncNotFound(module.into(), name.into())
- })?))
- }
+ ("evm", name) => Ok(Self::Evm(OpCode::from_str(name).map_err(|_| {
+ tracing::error!("Failed to load host function: {:?}", import);
+ Error::HostFuncNotFound(module.into(), name.into())
+ })?)),
("zinkc", "emit_abi") => Ok(Self::EmitABI),
+ ("zinkc", "address_eq") => Ok(Self::Evm(OpCode::EQ)),
+ ("zinkc", "label_reserve_mem_32") => Ok(Self::Label(CompilerLabel::ReserveMemory32)),
+ ("zinkc", "label_reserve_mem_64") => Ok(Self::Label(CompilerLabel::ReserveMemory64)),
_ => {
tracing::warn!("Failed to load host function: {:?}", import);
Err(Error::HostFuncNotFound(module.into(), name.into()))
@@ -61,3 +67,10 @@ impl TryFrom<(&str, &str)> for HostFunc {
}
}
}
+
+/// Labels in host functions
+#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
+pub enum CompilerLabel {
+ ReserveMemory32,
+ ReserveMemory64,
+}
diff --git a/codegen/src/wasm/mod.rs b/codegen/src/wasm/mod.rs
index 9bfaa4623..bd08d56a2 100644
--- a/codegen/src/wasm/mod.rs
+++ b/codegen/src/wasm/mod.rs
@@ -11,7 +11,12 @@ pub use self::{
func::{Function, Functions},
host::HostFunc,
};
+use crate::{Error, Result};
+use host::CompilerLabel;
+use smallvec::SmallVec;
use std::collections::BTreeMap;
+use wasmparser::Operator;
+use zabi::Abi;
macro_rules! impl_deref {
($doc:literal, $name:ident, $target:ty) => {
@@ -40,7 +45,9 @@ macro_rules! impl_deref {
impl_deref! {
("WASM import section", Imports, BTreeMap),
- ("WASM export section", Exports, BTreeMap)
+ ("WASM export section", Exports, BTreeMap),
+ ("WASM slot registry", Slots, BTreeMap),
+ ("WASM function registry", Funcs, BTreeMap)
}
/// A struct that holds the environment wasm module.
@@ -50,8 +57,109 @@ pub struct Env {
pub imports: Imports,
/// WASM exports
pub exports: Exports,
+ /// Function memory slots
+ pub slots: Slots,
+ /// Function params count
+ pub funcs: Funcs,
/// WASM data slots
pub data: Data,
+ /// Current function index
+ pub index: Option,
+}
+
+impl Env {
+ /// Load abis from functions
+ pub fn load_abis(&self, funs: &Functions<'_>) -> Result> {
+ let mut abis: Vec<_> = Default::default();
+ for (_, fun) in funs.iter() {
+ abis.push(self.load_abi(fun)?);
+ }
+
+ Ok(abis)
+ }
+
+ /// Load abi from function
+ pub fn load_abi(&self, fun: &Function<'_>) -> Result {
+ let mut reader = fun.body.get_operators_reader()?;
+
+ let Operator::I32Const { value: offset } = reader.read()? else {
+ return Err(Error::InvalidSelector);
+ };
+ let Operator::I32Const { value: length } = reader.read()? else {
+ return Err(Error::InvalidSelector);
+ };
+
+ // Validate zinkc helper `emit_abi`
+ let Operator::Call {
+ function_index: index,
+ } = reader.read()?
+ else {
+ return Err(Error::InvalidSelector);
+ };
+
+ if !self.imports.is_emit_abi(index) {
+ return Err(Error::FuncNotImported("emit_abi".into()));
+ }
+
+ let abi = self.data.load(offset, length as usize)?;
+ Abi::from_hex(String::from_utf8_lossy(&abi)).map_err(Into::into)
+ }
+
+ /// Query exported function from selector.
+ pub fn query_func(&self, name: &str) -> Result {
+ for (index, export) in self.exports.iter() {
+ if export == name {
+ return Ok(*index);
+ }
+ }
+
+ Err(Error::FuncNotImported(name.into()))
+ }
+
+ /// Check if the input function is external function
+ pub fn is_external(&self, index: u32) -> bool {
+ // self.exports.get(&index).is_some()
+ let Some(name) = self.exports.get(&index) else {
+ return false;
+ };
+
+ let selector = name.to_owned() + "_selector";
+ self.exports.iter().any(|(_, n)| **n == selector)
+ }
+
+ /// If the present function index is the main function
+ ///
+ /// NOTE: in wasm the indexes of the imports will be ordered
+ /// before the functions
+ pub fn is_main(&self, index: u32) -> bool {
+ self.imports.len() as u32 == index
+ }
+
+ /// Clone a new environment with function index provided
+ pub fn with_index(&self, index: u32) -> Self {
+ let mut this = self.clone();
+ this.index = Some(index);
+ this
+ }
+
+ /// Get reserved slots
+ pub fn reserved(&self) -> u32 {
+ let Some(index) = self.index else {
+ return 0;
+ };
+
+ *self.slots.get(&index).unwrap_or(&0)
+ }
+
+ /// Allocate memory slots from local index
+ pub fn alloc(&self, index: u32) -> SmallVec<[u8; 4]> {
+ let slots = index + self.reserved();
+ tracing::trace!(
+ "allocating memory for local {index} of function {:?}, slot: {slots}",
+ self.index
+ );
+ (slots * 0x20).to_ls_bytes()
+ }
}
impl Imports {
@@ -59,6 +167,22 @@ impl Imports {
pub fn is_emit_abi(&self, index: u32) -> bool {
self.get(&index) == Some(&HostFunc::EmitABI)
}
+
+ /// Get reserved slots in memory for storage calculations
+ pub fn reserved(&self) -> u32 {
+ let mut reserved = 0;
+ for host_fn in self.0.values() {
+ match *host_fn {
+ HostFunc::Label(CompilerLabel::ReserveMemory32) => reserved = 1,
+ HostFunc::Label(CompilerLabel::ReserveMemory64) => {
+ return 2;
+ }
+ _ => {}
+ }
+ }
+
+ reserved
+ }
}
impl Exports {
diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml
index 64498aa43..8c0d3f191 100644
--- a/compiler/Cargo.toml
+++ b/compiler/Cargo.toml
@@ -20,6 +20,7 @@ tracing.workspace = true
wasmparser.workspace = true
zabi.workspace = true
zingen.workspace = true
+hex.workspace = true
# Optional dependencies
ccli = { workspace = true, optional = true }
diff --git a/compiler/filetests/lib.rs b/compiler/filetests/lib.rs
index 92603f020..cba0fafcd 100644
--- a/compiler/filetests/lib.rs
+++ b/compiler/filetests/lib.rs
@@ -26,9 +26,14 @@ impl Test {
.ok();
let Test { module, name, wasm } = self;
- tracing::info!("Compiling {}/{}", module, name);
+ tracing::info!("Compiling {module}::{name}");
- zinkc::Compiler::default().compile(&wasm)?;
+ let compiler = zinkc::Compiler::default();
+ // TODO: after #248
+ if name == "fibonacci" {
+ return Ok(());
+ }
+ compiler.compile(&wasm)?;
Ok(())
}
}
diff --git a/compiler/filetests/wat/br_if/as_block_last.wat b/compiler/filetests/wat/br_if/as_block_last.wat
index 237c90323..5d5130a8e 100644
--- a/compiler/filetests/wat/br_if/as_block_last.wat
+++ b/compiler/filetests/wat/br_if/as_block_last.wat
@@ -1,11 +1,15 @@
;;! target = "evm"
(module
- (func (export "as-block-last") (param i32)
- (block
- (call $dummy)
- (call $dummy)
- (br_if 0 (local.get 0))
- )
- )
- (func $dummy)
-)
+ (func (export "as-block-last") (param i32)
+ (local.get 0)
+ (call $internal)
+ )
+ (func $internal (param i32)
+ (block
+ (call $dummy)
+ (call $dummy)
+ (br_if 0 (local.get 0))
+ )
+ )
+ (func $dummy)
+ )
diff --git a/compiler/filetests/wat/recursion/fibonacci.wat b/compiler/filetests/wat/recursion/fibonacci.wat
index f95146463..636fe6660 100644
--- a/compiler/filetests/wat/recursion/fibonacci.wat
+++ b/compiler/filetests/wat/recursion/fibonacci.wat
@@ -1,39 +1,39 @@
(module
- (type (;0;) (func (param i32) (result i32)))
- (func (;0;) (type 0) (param i32) (result i32)
- local.get 0
- call 1)
- (func (;1;) (type 0) (param i32) (result i32)
- (local i32)
- local.get 0
- i32.const 2
- i32.ge_u
- if ;; label = @1
- loop ;; label = @2
- local.get 0 ;; 1
- i32.const 1 ;; 2
- i32.sub ;; 1
- call 1 ;; 1
- local.get 1 ;; 2
- i32.add ;; 1
- local.set 1 ;; 0
- local.get 0 ;; 1
- i32.const 2 ;; 2
- i32.sub ;; 1
- local.tee 0 ;; 1
- i32.const 1 ;; 2
- i32.gt_u ;; 1
- br_if 0 (;@2;) ;; 2 -> 0
- end
- end
- local.get 0
- local.get 1
- i32.add)
- (memory (;0;) 16)
- (global (;0;) i32 (i32.const 1048576))
- (global (;1;) i32 (i32.const 1048576))
- (export "memory" (memory 0))
- (export "fibonacci" (func 0))
- (export "recursion" (func 1))
- (export "__data_end" (global 0))
- (export "__heap_base" (global 1)))
+ (type (;0;) (func (param i32) (result i32)))
+ (func (;0;) (type 0) (param i32) (result i32)
+ local.get 0
+ call 1)
+ (func (;1;) (type 0) (param i32) (result i32)
+ (local i32)
+ local.get 0
+ i32.const 2
+ i32.ge_u
+ if ;; label = @1
+ loop ;; label = @2
+ local.get 0 ;; 1
+ i32.const 1 ;; 2
+ i32.sub ;; 1
+ call 1 ;; 1
+ local.get 1 ;; 2
+ i32.add ;; 1
+ local.set 1 ;; 0
+ local.get 0 ;; 1
+ i32.const 2 ;; 2
+ i32.sub ;; 1
+ local.tee 0 ;; 1
+ i32.const 1 ;; 2
+ i32.gt_u ;; 1
+ br_if 0 (;@2;) ;; 2 -> 0
+ end
+ end
+ local.get 0
+ local.get 1
+ i32.add)
+ (memory (;0;) 16)
+ (global (;0;) i32 (i32.const 1048576))
+ (global (;1;) i32 (i32.const 1048576))
+ (export "memory" (memory 0))
+ (export "fibonacci" (func 0))
+ (export "recursion" (func 1))
+ (export "__data_end" (global 0))
+ (export "__heap_base" (global 1)))
diff --git a/compiler/filetests/wat/storage/dispatcher.wat b/compiler/filetests/wat/storage/dispatcher.wat
deleted file mode 100644
index b5c0ce792..000000000
--- a/compiler/filetests/wat/storage/dispatcher.wat
+++ /dev/null
@@ -1,46 +0,0 @@
-(module
- (type (;0;) (func))
- (type (;1;) (func (param i32 i32)))
- (type (;2;) (func (param i32) (result i32)))
- (type (;3;) (func (param i32)))
- (type (;4;) (func (result i32)))
- (import "evm" "sstore" (func (;0;) (type 1)))
- (import "evm" "sload" (func (;1;) (type 2)))
- (import "zinkc" "emit_abi" (func (;2;) (type 1)))
- (import "env" "memory" (memory (;0;) 17))
- (func (;3;) (type 2) (param i32) (result i32)
- local.get 0
- i32.const 0
- call 0
- i32.const 0
- call 1)
- (func (;4;) (type 0)
- i32.const 1048576
- i32.const 34
- call 2)
- (func (;5;) (type 3) (param i32)
- local.get 0
- i32.const 0
- call 0)
- (func (;6;) (type 0)
- i32.const 1048610
- i32.const 18
- call 2)
- (func (;7;) (type 4) (result i32)
- i32.const 0
- call 1)
- (func (;8;) (type 0)
- i32.const 1048628
- i32.const 10
- call 2)
- (global (;0;) i32 (i32.const 1048638))
- (global (;1;) i32 (i32.const 1048640))
- (export "set_and_get" (func 3))
- (export "set_and_get_selector" (func 4))
- (export "set" (func 5))
- (export "set_selector" (func 6))
- (export "get" (func 7))
- (export "get_selector" (func 8))
- (export "__data_end" (global 0))
- (export "__heap_base" (global 1))
- (data (;0;) (i32.const 1048576) "0b7365745f616e645f67657401036933320373657401036933320367657400"))
diff --git a/compiler/src/artifact.rs b/compiler/src/artifact.rs
index 6db40ec4c..c6ff44c0b 100644
--- a/compiler/src/artifact.rs
+++ b/compiler/src/artifact.rs
@@ -1,9 +1,7 @@
//! Zink compiler artifact
-use crate::{Compiler, Config};
-use wasmparser::FuncType;
+use crate::Config;
use zabi::Abi;
-use zingen::Constructor;
/// Zink compiler artifact
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -11,36 +9,8 @@ use zingen::Constructor;
pub struct Artifact {
/// Contract ABIs
pub abi: Vec,
- /// Bytecode of the contract.
- pub bytecode: Vec,
/// Compiler configuration.
pub config: Config,
/// Runtime bytecode of the contract.
pub runtime_bytecode: Vec,
}
-
-impl TryFrom<(Compiler, Option)> for Artifact {
- type Error = anyhow::Error;
-
- fn try_from(
- (compiler, constructor): (Compiler, Option),
- ) -> Result {
- let Compiler {
- abi,
- buffer,
- config,
- ..
- } = compiler;
-
- let bytecode = Constructor::new(constructor, buffer.clone())?
- .finish()?
- .to_vec();
-
- Ok(Self {
- abi,
- bytecode,
- config,
- runtime_bytecode: buffer.to_vec(),
- })
- }
-}
diff --git a/compiler/src/cli.rs b/compiler/src/cli.rs
index bc86c280e..b2cd87892 100644
--- a/compiler/src/cli.rs
+++ b/compiler/src/cli.rs
@@ -36,7 +36,7 @@ impl Compile {
let artifact = compiler.compile(&fs::read(&self.input)?)?;
output.parent().map(fs::create_dir_all);
- fs::write(&output, artifact.bytecode)?;
+ fs::write(&output, artifact.runtime_bytecode)?;
if !self.abi {
return Ok(());
diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs
index 0bc1db1c0..67cc50212 100644
--- a/compiler/src/compiler.rs
+++ b/compiler/src/compiler.rs
@@ -34,34 +34,51 @@ impl Compiler {
/// Returns runtime bytecode.
pub fn compile(mut self, wasm: &[u8]) -> Result {
let mut parser = Parser::try_from(wasm)?;
- let constructor = parser.remove_constructor();
+ let env = parser.env.clone();
self.compile_dispatcher(&mut parser)?;
- let env = parser.to_func_env();
for func in parser.funcs.into_funcs() {
- self.compile_func(env.clone(), func)?;
+ self.compile_func(env.with_index(func.index()), func)?;
}
self.table.code_offset(self.buffer.len() as u16);
self.table.relocate(&mut self.buffer)?;
+ self.artifact()
+ }
- Artifact::try_from((self, constructor)).map_err(Into::into)
+ /// Generate artifact
+ ///
+ /// yields runtime bytecode and construct bytecode
+ fn artifact(self) -> Result {
+ let Compiler {
+ abi,
+ buffer,
+ config,
+ ..
+ } = self;
+
+ Ok(Artifact {
+ abi,
+ config,
+ runtime_bytecode: buffer.to_vec(),
+ })
}
/// Compile EVM dispatcher.
///
- /// Drain selectors anyway, if dispatcher is
- /// enabled, compile dispatcher.
+ /// Drain selectors anyway, compile dispatcher if it is enabled.
fn compile_dispatcher(&mut self, parser: &mut Parser) -> Result<()> {
- let selectors = parser.funcs.drain_selectors(&parser.exports);
+ let selectors = parser.drain_selectors();
+ let env = parser.env.clone();
+
if !self.config.dispatcher {
+ self.abi.append(&mut env.load_abis(&selectors)?);
return Ok(());
}
- let mut dispatcher = Dispatcher::new(parser.to_env(), &parser.funcs)?;
+ let mut dispatcher = Dispatcher::new(env, &parser.funcs)?;
let buffer = dispatcher.finish(selectors, &mut self.table)?;
self.buffer.extend_from_slice(&buffer);
-
if self.buffer.len() > BUFFER_LIMIT {
return Err(Error::BufferOverflow(self.buffer.len()));
}
@@ -74,15 +91,12 @@ impl Compiler {
fn compile_func(&mut self, env: Env, mut func: wasm::Function<'_>) -> Result<()> {
let func_index = func.index();
let sig = func.sig()?;
+ let abi = self.abi(&env, func_index);
- tracing::trace!("compile function {}: {:?}", func_index, sig);
- let is_main = if self.config.dispatcher {
- false
- } else {
- func_index - (env.imports.len() as u32) == 0
- };
+ tracing::debug!("compile function {func_index} {:?}, abi: {abi:#?}", sig);
+ let is_main = !self.config.dispatcher && env.is_main(func_index);
- let mut codegen = Function::new(env, sig, is_main)?;
+ let mut codegen = Function::new(env, sig, abi, is_main)?;
let mut locals_reader = func.body.get_locals_reader()?;
let mut ops_reader = func.body.get_operators_reader()?;
@@ -106,4 +120,10 @@ impl Compiler {
Ok(())
}
+
+ /// Get abi from env and function index
+ fn abi(&self, env: &Env, index: u32) -> Option {
+ let name = env.exports.get(&index)?;
+ self.abi.iter().find(|a| name == &a.name).cloned()
+ }
}
diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs
index 25611710b..bcd388032 100644
--- a/compiler/src/lib.rs
+++ b/compiler/src/lib.rs
@@ -7,6 +7,7 @@ pub use crate::{
config::Config,
result::{Error, Result},
};
+pub use zingen::{Constructor, InitStorage};
mod artifact;
pub mod cli;
diff --git a/compiler/src/parser.rs b/compiler/src/parser.rs
index d3fac7471..7e4c05682 100644
--- a/compiler/src/parser.rs
+++ b/compiler/src/parser.rs
@@ -3,18 +3,18 @@
use crate::{Error, Result};
use std::iter::IntoIterator;
use wasmparser::{
- Data, DataKind, Export, ExternalKind, FuncType, Import, Operator, Payload, SectionLimited,
- TypeRef, ValidPayload, Validator,
+ Data, DataKind, Export, ExternalKind, Import, Operator, Payload, SectionLimited, TypeRef,
+ ValidPayload, Validator,
};
use zingen::wasm::{Data as DataSet, Env, Exports, Functions, HostFunc, Imports};
/// WASM module parser
#[derive(Default)]
pub struct Parser<'p> {
- pub imports: Imports,
- pub data: DataSet,
+ /// Function environment
+ pub env: Env,
+ /// All functions
pub funcs: Functions<'p>,
- pub exports: Exports,
}
impl<'p> Parser<'p> {
@@ -28,9 +28,9 @@ impl<'p> Parser<'p> {
let valid_payload = validator.payload(&payload)?;
match &payload {
- Payload::ImportSection(reader) => self.imports = Self::imports(reader)?,
- Payload::DataSection(reader) => self.data = Self::data(reader)?,
- Payload::ExportSection(reader) => self.exports = Self::exports(reader)?,
+ Payload::ImportSection(reader) => self.env.imports = Self::imports(reader)?,
+ Payload::DataSection(reader) => self.env.data = Self::data(reader)?,
+ Payload::ExportSection(reader) => self.env.exports = Self::exports(reader)?,
_ => {}
}
@@ -40,11 +40,37 @@ impl<'p> Parser<'p> {
}
}
+ // compute slots from functions
+ let mut slots = self.env.imports.reserved();
+ for (idx, fun) in self.funcs.iter() {
+ let sig = fun.sig()?;
+ let locals = fun.body.get_locals_reader()?.get_count();
+ let params = sig.params().len();
+ tracing::trace!(
+ "computing slots for function {idx}, locals: {locals}, params: {params}, reserved: {slots}"
+ );
+
+ self.env.slots.insert(fun.index(), slots);
+ self.env
+ .funcs
+ .insert(fun.index(), (params as u32, sig.results().len() as u32));
+
+ slots += locals;
+ if !self.env.is_external(fun.index()) && !self.env.is_main(fun.index()) {
+ slots += params as u32;
+ }
+ }
+
Ok(())
}
+ /// Drain selectors from parsed functions
+ pub fn drain_selectors(&mut self) -> Functions<'p> {
+ self.funcs.drain_selectors(&self.env.exports)
+ }
+
/// Parse data section.
- pub fn data(reader: &SectionLimited) -> Result {
+ fn data(reader: &SectionLimited) -> Result {
let mut dataset = DataSet::default();
let mut iter = reader.clone().into_iter();
while let Some(Ok(data)) = iter.next() {
@@ -103,29 +129,6 @@ impl<'p> Parser<'p> {
Ok(imports)
}
-
- /// Returns constructor if some.
- pub fn remove_constructor(&mut self) -> Option {
- self.funcs.remove_constructor(&self.exports)
- }
-
- /// Returns full environment.
- pub fn to_env(&self) -> Env {
- Env {
- imports: self.imports.clone(),
- data: self.data.clone(),
- exports: self.exports.clone(),
- }
- }
-
- /// Returns function environment.
- pub fn to_func_env(&self) -> Env {
- Env {
- imports: self.imports.clone(),
- data: self.data.clone(),
- exports: self.exports.clone(),
- }
- }
}
impl<'p> TryFrom<&'p [u8]> for Parser<'p> {
diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index 4a37b203d..a83f17bd5 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -10,9 +10,6 @@
- [Log](./examples/log.md)
- [Select](./examples/select.md)
- [Storage](./examples/storage.md)
-- [Command Line Tool](./cli/README.md)
- - [elko](./cli/elko.md)
- - [zinkc](./cli/zinkc.md)
- [Styles](./styles/README.md)
- [Compiler](./compiler/README.md)
- [Arithmetic](./compiler/arithmetic.md)
@@ -20,6 +17,7 @@
- [Control Flow](./compiler/control-flow.md)
- [Locals](./compiler/locals.md)
- [Recursion](./compiler/recursion.md)
+ - [Storage](./compiler/storage.md)
- [Stability](./stability/README.md)
- [v0.1.0](./stability/v0.1.0.md)
- [Security](./security.md)
@@ -27,6 +25,9 @@
- [Fibonacci](./benchmarks/fibonacci.md)
- [Log](./benchmarks/log.md)
- [Storage](./benchmarks/storage.md)
+- [Command Line Tool](./cli/README.md)
+ - [elko](./cli/elko.md)
+ - [zinkc](./cli/zinkc.md)
- [Contributing](./contributing/README.md)
- [Architecture](./contributing/architecture.md)
- [Building](./contributing/building.md)
diff --git a/docs/compiler/storage.md b/docs/compiler/storage.md
new file mode 100644
index 000000000..e316a91e8
--- /dev/null
+++ b/docs/compiler/storage.md
@@ -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)`.
diff --git a/elko/src/build.rs b/elko/src/build.rs
index d6508f034..af100f7de 100644
--- a/elko/src/build.rs
+++ b/elko/src/build.rs
@@ -64,7 +64,7 @@ impl Build {
let artifact = Compiler::new(config).compile(&wasm)?;
let dst = builder.output()?.with_extension("bin");
- fs::write(dst, artifact.bytecode)?;
+ fs::write(dst, artifact.runtime_bytecode)?;
Ok(())
}
}
diff --git a/evm/abi/README.md b/evm/abi/README.md
index 63246d06f..2f614e530 100644
--- a/evm/abi/README.md
+++ b/evm/abi/README.md
@@ -1,10 +1,49 @@
-# Solidity ABI
+# Solidity ABIA
-An implementation of solidity ABI in rust.
+An straightforward solidity ABI implementation for zink.
+
+This library only contains a part of the solidity ABI implementation,
+if you are looking for a complete implementation of solidity ABI
+in rust, see [alloy-core][alloy-core].
+
+## Static Types
+
+Only rust primitive types are supported in this static type port,
+
+| rust | solidity |
+|--------|-----------|
+| `i8` | `int8` |
+| `u8` | `uint8` |
+| `i16` | `int16` |
+| `u16` | `uint16` |
+| `i32` | `int32` |
+| `u32` | `uint32` |
+| `i64` | `int64` |
+| `u64` | `uint64` |
+| `i128` | `int128` |
+| `u128` | `uint128` |
+| `bool` | `bool` |
+
+
+## Dynamic Types
+
+The implementation of dynamic arguments follows [use-of-dynamic-types][dyn-types],
+same as the static types, only ports the rust types:
+
+| rust | solidity |
+|------------|-----------|
+| `Vec` | `bytes` |
+| `[u8; 20]` | `address` |
+| `String` | `string` |
+
+More complex types are currently not supported.
-Currently only used by the zink language, so the provided features
-is syncing with the development of zink.
## LICENSE
GPL-3.0
+
+
+[alloy-core]: https://github.com/alloy-rs/core
+[dyn-types]: https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types
+[zink]: https://github.com/zink-lang/zink
diff --git a/evm/abi/src/abi.rs b/evm/abi/src/abi.rs
index 92c22ff47..c4a91f1ef 100644
--- a/evm/abi/src/abi.rs
+++ b/evm/abi/src/abi.rs
@@ -1,7 +1,10 @@
//! Solidity ABI abstraction.
use crate::Arg;
-use core::{convert::Infallible, str::FromStr};
+use core::{convert::Infallible, fmt, str::FromStr};
+
+#[cfg(feature = "syn")]
+use quote::ToTokens;
#[cfg(not(feature = "std"))]
use crate::std::{String, ToString, Vec};
@@ -28,9 +31,9 @@ impl From<&syn::Signature> for Abi {
.inputs
.iter()
.filter_map(|arg| {
- if let syn::FnArg::Typed(syn::PatType { ty, .. }) = arg {
+ if let syn::FnArg::Typed(syn::PatType { pat, ty, .. }) = arg {
Some(Arg {
- name: sig.ident.to_string(),
+ name: pat.to_token_stream().to_string(),
ty: crate::Param::from(ty),
})
} else {
@@ -41,7 +44,8 @@ impl From<&syn::Signature> for Abi {
let outputs = if let syn::ReturnType::Type(_, ty) = &sig.output {
vec![Arg {
- name: sig.ident.to_string(),
+ // TODO: how to name the output?
+ name: "output".into(),
ty: crate::Param::from(ty),
}]
} else {
@@ -96,8 +100,9 @@ impl AsRef for Type {
}
}
-impl ToString for Type {
- fn to_string(&self) -> String {
- self.as_ref().to_string()
+impl fmt::Display for Type {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let ty: &str = self.as_ref();
+ write!(f, "{ty}")
}
}
diff --git a/evm/abi/src/arg.rs b/evm/abi/src/arg.rs
index 7d3969a9c..609dba96d 100644
--- a/evm/abi/src/arg.rs
+++ b/evm/abi/src/arg.rs
@@ -1,6 +1,6 @@
//! Arg of solidity ABI.
-use core::{convert::Infallible, str::FromStr};
+use core::{convert::Infallible, fmt, str::FromStr};
#[cfg(not(feature = "std"))]
use crate::std::{String, ToString};
@@ -21,27 +21,50 @@ pub struct Arg {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum Param {
+ /// A 8-bit integer.
+ Int8,
+ /// A 16-bit integer.
+ Int16,
/// A 32-bit integer.
Int32,
/// A 64-bit integer.
Int64,
+ /// A 8-bit unsigned integer.
+ UInt8,
+ /// A 16-bit unsigned integer.
+ UInt16,
/// A 32-bit unsigned integer.
UInt32,
/// A 64-bit unsigned integer.
UInt64,
- /// An unknown type.
+ /// A boolean type.
+ Bool,
+ /// An EVM address.
+ Address,
+ /// A byte array.
#[default]
- Unknown,
+ Bytes,
+ /// A string type.
+ String,
+ /// An unknown type.
+ Unknown(String),
}
impl From<&str> for Param {
fn from(s: &str) -> Self {
match s {
+ "i8" | "int8" => Param::Int8,
+ "u8" | "uint8" => Param::UInt8,
"i32" | "int32" => Param::Int32,
"i64" | "int64" => Param::Int64,
+ "u16" | "uint16" => Param::UInt16,
"u32" | "uint32" => Param::UInt32,
- "usize" | "u64" | "uint64" => Param::UInt64,
- _ => Param::Unknown,
+ "u64" | "uint64" => Param::UInt64,
+ "bool" => Param::Bool,
+ "address" | "Address" => Param::Address,
+ "Bytes" | "Vec" => Param::Bytes,
+ "String" => Param::String,
+ _ => Param::Unknown(s.to_string()),
}
}
}
@@ -57,18 +80,27 @@ impl FromStr for Param {
impl AsRef for Param {
fn as_ref(&self) -> &str {
match self {
+ Param::Int8 => "int8",
+ Param::Int16 => "int16",
Param::Int32 => "int32",
Param::Int64 => "int64",
+ Param::UInt8 => "uint8",
+ Param::UInt16 => "uint16",
Param::UInt32 => "uint32",
Param::UInt64 => "uint64",
- Param::Unknown => "unknown",
+ Param::Address => "address",
+ Param::Bool => "boolean",
+ Param::Bytes => "bytes",
+ Param::String => "string",
+ Param::Unknown(ty) => ty.as_ref(),
}
}
}
-impl ToString for Param {
- fn to_string(&self) -> String {
- self.as_ref().to_string()
+impl fmt::Display for Param {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let p: &str = self.as_ref();
+ write!(f, "{p}")
}
}
diff --git a/evm/opcodes/Cargo.toml b/evm/opcodes/Cargo.toml
index f32e739f6..367692ac2 100644
--- a/evm/opcodes/Cargo.toml
+++ b/evm/opcodes/Cargo.toml
@@ -2,7 +2,7 @@
name = "evm-opcodes"
description = "Rust implementation of EVM opcode"
documentation = "https://docs.rs/evm-opcodes"
-version = "0.0.3"
+version = "0.0.4"
authors.workspace = true
edition.workspace = true
homepage.workspace = true
diff --git a/evm/opcodes/src/shanghai.rs b/evm/opcodes/src/shanghai.rs
index 01428ba0c..5c3cf8986 100644
--- a/evm/opcodes/src/shanghai.rs
+++ b/evm/opcodes/src/shanghai.rs
@@ -30,7 +30,7 @@ opcodes! {
(0x1b, SHL, 3, 2, 1, "Left shift operation", Constantinople, ComparisonBitwiseLogic),
(0x1c, SHR, 3, 2, 1, "Logical right shift operation", Constantinople, ComparisonBitwiseLogic),
(0x1d, SAR, 3, 2, 1, "Arithmetic (signed) right shift operation", Constantinople, ComparisonBitwiseLogic),
- (0x20, SHA3, 30, 2, 1, "Compute Keccak-256 hash.", Frontier, StopArithmetic),
+ (0x20, KECCAK256, 30, 2, 1, "Compute Keccak-256 hash.", Frontier, StopArithmetic),
(0x30, ADDRESS, 2, 0, 1, "Get address of currently executing account.", Frontier, EnvironmentalInformation),
(0x31, BALANCE, 20, 1, 1, "Get balance of the given account.", Frontier, EnvironmentalInformation),
(0x32, ORIGIN, 2, 0, 1, "Get execution origination address.", Frontier, EnvironmentalInformation),
diff --git a/examples/addition.rs b/examples/addition.rs
index ee618a2fe..b64c2c597 100644
--- a/examples/addition.rs
+++ b/examples/addition.rs
@@ -22,7 +22,7 @@ fn test() -> anyhow::Result<()> {
&1u64.to_bytes32(),
&2u64.to_bytes32(),
])?;
- assert_eq!(info.ret, 3u64.to_bytes32());
+ assert_eq!(info.ret, 3u64.to_bytes32());
Ok(())
}
diff --git a/examples/constructor.rs b/examples/constructor.rs
index 719049103..8f289ea92 100644
--- a/examples/constructor.rs
+++ b/examples/constructor.rs
@@ -13,36 +13,51 @@ use zink::Storage;
/// Storage key is taken based on macro order
/// (e.g this macro is first and only in this project,
/// so it will take 0x0 contract storage key)
-#[zink::storage]
-pub type Counter = i32;
-
-/// Get value from the storage.
-#[zink::external]
-pub fn get() -> i32 {
- Counter::get() + 1
-}
-
-/// Set value to the storage.
-#[zink::constructor]
-pub fn constructor(value: i32) {
- Counter::set(value);
-}
+#[zink::storage(i32)]
+pub struct Counter;
#[cfg(not(target_arch = "wasm32"))]
fn main() {}
#[test]
-fn deploy() -> anyhow::Result<()> {
+fn noop() -> anyhow::Result<()> {
use zint::{Bytes32, Contract, EVM};
let contract = Contract::search("constructor")?.compile()?;
+ // empty constructor
let mut evm = EVM::default();
- let mut info = evm.deploy(&contract.bytecode())?;
+ let mut info = evm.deploy(&contract.bytecode()?)?;
info = evm
.calldata(&contract.encode(&["get()"])?)
.call(info.address)?;
- assert_eq!(info.ret, 1.to_bytes32());
+ assert_eq!(info.ret, 0.to_bytes32());
+ Ok(())
+}
+
+#[test]
+fn init_storage() -> anyhow::Result<()> {
+ use zint::{Bytes32, Contract, EVM};
+
+ let mut contract = Contract::search("constructor")?.compile()?;
+ let value = 0x42;
+
+ // empty constructor
+ let mut evm = EVM::default();
+ let mut info = evm.deploy(
+ &contract
+ .construct(
+ [(vec![0].try_into()?, vec![value].try_into()?)]
+ .into_iter()
+ .collect(),
+ )?
+ .bytecode()?,
+ )?;
+ info = evm
+ .calldata(&contract.encode(&["counter()"])?)
+ .call(info.address)?;
+
+ assert_eq!(info.ret, value.to_bytes32());
Ok(())
}
diff --git a/examples/dkmapping.rs b/examples/dkmapping.rs
new file mode 100644
index 000000000..230fa72f2
--- /dev/null
+++ b/examples/dkmapping.rs
@@ -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::DoubleKeyMapping as _;
+
+/// Counter with value type `i32`
+#[zink::storage(i32, i32, i32)]
+pub struct DoubleKeyMapping;
+
+/// Set the mapping
+#[zink::external]
+pub fn mset(key1: i32, key2: i32, value: i32) {
+ DoubleKeyMapping::set(key1, key2, value);
+}
+
+#[cfg(not(target_arch = "wasm32"))]
+fn main() {}
+
+#[test]
+fn storage_double_key_mapping() -> anyhow::Result<()> {
+ use zint::{Bytes32, Contract};
+
+ let mut contract = Contract::search("dkmapping")?.compile()?;
+ let mut evm = contract.deploy()?.commit(true);
+
+ let key1 = 0x00;
+ let key2 = 0x01;
+ let value: i32 = 0x42;
+
+ // set value to storage
+ let calldata = contract.encode(&[
+ b"mset(int32,int32,int32)".to_vec(),
+ key1.to_bytes32().to_vec(),
+ key2.to_bytes32().to_vec(),
+ value.to_bytes32().to_vec(),
+ ])?;
+ let info = evm.calldata(&calldata).call(contract.address)?;
+ assert!(info.ret.is_empty());
+
+ // verify result with database
+ let storage_key = DoubleKeyMapping::storage_key(key1, key2);
+ tracing::info!("Storage key: {}", hex::encode(storage_key));
+ assert_eq!(
+ evm.storage(contract.address, storage_key)?,
+ value.to_bytes32(),
+ );
+
+ // get value from storage
+ let calldata = contract.encode(&[
+ b"double_key_mapping(int32,int32)".to_vec(),
+ key1.to_bytes32().to_vec(),
+ key2.to_bytes32().to_vec(),
+ ])?;
+ let info = evm.calldata(&calldata).call(contract.address)?;
+ assert_eq!(info.ret, value.to_bytes32(), "{info:#?}",);
+ Ok(())
+}
diff --git a/examples/fibonacci.rs b/examples/fibonacci.rs
index 511bdcaf4..606518689 100644
--- a/examples/fibonacci.rs
+++ b/examples/fibonacci.rs
@@ -7,7 +7,12 @@ extern crate zink;
/// Calculates the nth fibonacci number.
#[zink::external]
-pub fn fib(n: usize) -> usize {
+pub fn fib(n: u64) -> u64 {
+ internal_rec(n)
+}
+
+#[inline(never)]
+fn internal_rec(n: u64) -> u64 {
if n < 2 {
n
} else {
@@ -18,6 +23,7 @@ pub fn fib(n: usize) -> usize {
#[cfg(not(target_arch = "wasm32"))]
fn main() {}
+#[ignore]
#[test]
fn test() -> anyhow::Result<()> {
use zint::{Bytes32, Contract};
@@ -25,27 +31,27 @@ fn test() -> anyhow::Result<()> {
let selector = "fib(uint64)".as_bytes();
// x = 0
- let info = contract.execute([selector, &0usize.to_bytes32()])?;
+ let info = contract.execute([selector, &0u64.to_bytes32()])?;
assert_eq!(0.to_bytes32().to_vec(), info.ret);
// x = 1
- let info = contract.execute([selector, &1usize.to_bytes32()])?;
+ let info = contract.execute([selector, &1u64.to_bytes32()])?;
assert_eq!(1.to_bytes32().to_vec(), info.ret);
// x = 2
- let info = contract.execute([selector, &2usize.to_bytes32()])?;
+ let info = contract.execute([selector, &2u64.to_bytes32()])?;
assert_eq!(1.to_bytes32().to_vec(), info.ret);
// x = 3
- let info = contract.execute([selector, &3usize.to_bytes32()])?;
+ let info = contract.execute([selector, &3u64.to_bytes32()])?;
assert_eq!(2.to_bytes32().to_vec(), info.ret);
// x = 4
- let info = contract.execute([selector, &4usize.to_bytes32()])?;
+ let info = contract.execute([selector, &4u64.to_bytes32()])?;
assert_eq!(3.to_bytes32().to_vec(), info.ret);
// x = 5
- let info = contract.execute([selector, &5usize.to_bytes32()])?;
+ let info = contract.execute([selector, &5u64.to_bytes32()])?;
assert_eq!(5.to_bytes32().to_vec(), info.ret);
Ok(())
diff --git a/examples/log.rs b/examples/log.rs
index a73b90a24..f5a19602f 100644
--- a/examples/log.rs
+++ b/examples/log.rs
@@ -44,23 +44,35 @@ fn test() -> anyhow::Result<()> {
let mut contract = Contract::search("log")?.compile()?;
let info = contract.execute(["log0()"])?;
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
+ assert_eq!(
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
+ );
let info = contract.execute(["log1()"])?;
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
- assert_eq!(info.logs[0].topics, vec![b"pong".to_vec().to_bytes32()]);
+ assert_eq!(
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
+ );
+ assert_eq!(info.logs[0].topics(), vec![b"pong".to_vec().to_bytes32()]);
let info = contract.execute(["log2()"])?;
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
assert_eq!(
- info.logs[0].topics,
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
+ );
+ assert_eq!(
+ info.logs[0].topics(),
vec![b"pong".to_vec().to_bytes32(), b"ping".to_vec().to_bytes32()]
);
let info = contract.execute(["log3()"])?;
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
assert_eq!(
- info.logs[0].topics,
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
+ );
+ assert_eq!(
+ info.logs[0].topics(),
vec![
b"pong".to_vec().to_bytes32(),
b"ping".to_vec().to_bytes32(),
@@ -69,9 +81,12 @@ fn test() -> anyhow::Result<()> {
);
let info = contract.execute(["log4()"])?;
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
assert_eq!(
- info.logs[0].topics,
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
+ );
+ assert_eq!(
+ info.logs[0].topics(),
vec![
b"pong".to_vec().to_bytes32(),
b"ping".to_vec().to_bytes32(),
diff --git a/examples/mapping.rs b/examples/mapping.rs
new file mode 100644
index 000000000..0fa5675ee
--- /dev/null
+++ b/examples/mapping.rs
@@ -0,0 +1,53 @@
+//! 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);
+}
+
+#[cfg(not(target_arch = "wasm32"))]
+fn main() {}
+
+#[test]
+fn storage_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(),
+ key.to_bytes32().to_vec(),
+ value.to_bytes32().to_vec(),
+ ])?;
+ let info = evm.calldata(&calldata).call(contract.address)?;
+ assert!(info.ret.is_empty());
+
+ // verify result with database
+ let storage_key = Mapping::storage_key(key);
+ assert_eq!(
+ evm.storage(contract.address, storage_key)?,
+ value.to_bytes32(),
+ );
+
+ // get value from storage
+ let calldata = contract.encode(&[b"mapping(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(())
+}
diff --git a/examples/owner.rs b/examples/owner.rs
new file mode 100644
index 000000000..0dcf51175
--- /dev/null
+++ b/examples/owner.rs
@@ -0,0 +1,58 @@
+//! Bytes example.
+#![cfg_attr(target_arch = "wasm32", no_std)]
+#![cfg_attr(target_arch = "wasm32", no_main)]
+
+extern crate zink;
+
+use zink::{primitives::Address, Storage};
+
+/// Contract owner storage
+#[zink::storage(Address)]
+pub struct Owner;
+
+/// check if the passing address is owner
+#[zink::external]
+pub fn is_owner(owner: Address) -> bool {
+ Owner::get().eq(owner)
+}
+
+#[cfg(not(target_arch = "wasm32"))]
+fn main() {}
+
+#[test]
+fn test_owner() -> anyhow::Result<()> {
+ use zint::{Bytes32, Contract};
+ let mut contract = Contract::search("owner")?.compile()?;
+ let not_owner = [8; 20];
+ let mut evm = contract
+ .construct(
+ [(vec![0].try_into()?, not_owner.to_vec().try_into()?)]
+ .into_iter()
+ .collect(),
+ )?
+ .deploy()?
+ .commit(true);
+
+ assert_eq!(
+ evm.storage(contract.address, [0; 32])?,
+ not_owner.to_bytes32(),
+ );
+
+ assert_eq!(
+ evm.calldata(&contract.encode(&[b"is_owner(address)".to_vec(), [0; 32].to_vec()])?)
+ .call(contract.address)?
+ .ret,
+ false.to_bytes32().to_vec()
+ );
+
+ assert_eq!(
+ evm.calldata(&contract.encode(&[
+ b"is_owner(address)".to_vec(),
+ not_owner.to_bytes32().to_vec(),
+ ])?)
+ .call(contract.address)?
+ .ret,
+ true.to_bytes32().to_vec()
+ );
+ Ok(())
+}
diff --git a/examples/storage.rs b/examples/storage.rs
index b477db0e4..eb5974266 100644
--- a/examples/storage.rs
+++ b/examples/storage.rs
@@ -6,22 +6,9 @@ extern crate zink;
use zink::Storage;
-/// It gets expanded to 'Counter' struct
-/// that implements zink::Storage trait
-/// (::set and ::get)
-///
-/// Storage key is taken based on macro order
-/// (e.g this macro is first and only in this project,
-/// so it will take 0x0 contract storage key)
-#[zink::storage]
-pub type Counter = i32;
-
-/// Set value to the storage and get it.
-#[zink::external]
-pub fn set_and_get(value: i32) -> i32 {
- Counter::set(value);
- Counter::get()
-}
+/// Counter with value type `i32`
+#[zink::storage(i32)]
+pub struct Counter;
/// set value to the storage.
#[zink::external]
@@ -29,42 +16,29 @@ pub fn set(value: i32) {
Counter::set(value);
}
-/// Get value from the storage.
-#[zink::external]
-pub fn get() -> i32 {
- Counter::get()
-}
-
#[cfg(not(target_arch = "wasm32"))]
fn main() {}
#[test]
-fn selector() -> anyhow::Result<()> {
+fn value() -> anyhow::Result<()> {
use zint::{Bytes32, Contract, U256};
let mut contract = Contract::search("storage")?.compile()?;
{
- let key = 0;
let value: i32 = 42;
let info = contract.execute(&[b"set(int32)".to_vec(), value.to_bytes32().to_vec()])?;
assert!(info.ret.is_empty());
- assert_eq!(info.storage.get(&U256::from(key)), Some(&U256::from(value)));
+ assert_eq!(
+ info.storage.get(&U256::from_le_bytes(Counter::STORAGE_KEY)),
+ Some(&U256::from(value))
+ );
}
{
- let info = contract.execute(&["get()"])?;
+ let info = contract.execute(&["counter()"])?;
assert_eq!(info.ret, 0.to_bytes32());
}
- {
- let key = 0;
- let value = 42;
- let info =
- contract.execute(&[b"set_and_get(int32)".to_vec(), value.to_bytes32().to_vec()])?;
- assert_eq!(info.ret, value.to_bytes32());
- assert_eq!(info.storage.get(&U256::from(key)), Some(&U256::from(value)));
- }
-
Ok(())
}
diff --git a/tests/br_if.rs b/tests/br_if.rs
index aa64630e8..ff83dcda3 100644
--- a/tests/br_if.rs
+++ b/tests/br_if.rs
@@ -1,20 +1,18 @@
//! br_if tests for the zink compiler.
use anyhow::Result;
use filetests::Test;
-use zint::{Contract, Halt, OutOfGasError};
+use zint::Contract;
#[test]
fn as_block_last() -> Result<()> {
let mut contract = Contract::from(Test::BR_IF_AS_BLOCK_LAST).pure().compile()?;
let info = contract.execute(&[0])?;
+ assert!(info.halt.is_none());
assert!(info.ret.is_empty());
let info = contract.execute(&[42])?;
- assert_eq!(
- info.halt,
- Some(Halt::OutOfGas(OutOfGasError::BasicOutOfGas))
- );
+ assert!(info.halt.is_none());
assert!(info.ret.is_empty());
Ok(())
diff --git a/tests/log.rs b/tests/log.rs
index 4d67f438a..8d9c3c578 100644
--- a/tests/log.rs
+++ b/tests/log.rs
@@ -10,7 +10,10 @@ fn log0() -> Result<()> {
// returns the bigger number.
let info = contract.execute::<()>([])?;
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
+ assert_eq!(
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
+ );
Ok(())
}
@@ -19,9 +22,12 @@ fn log1() -> Result<()> {
let mut contract = Contract::from(Test::LOG_LOG1).pure().compile()?;
let info = contract.execute::<()>([])?;
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
assert_eq!(
- info.logs[0].topics[0].to_vec(),
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
+ );
+ assert_eq!(
+ info.logs[0].topics()[0].to_vec(),
b"pong".to_vec().to_bytes32()
);
Ok(())
@@ -32,13 +38,16 @@ fn log2() -> Result<()> {
let mut contract = Contract::from(Test::LOG_LOG2).pure().compile()?;
let info = contract.execute::<()>([])?;
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
assert_eq!(
- info.logs[0].topics[0].to_vec(),
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
+ );
+ assert_eq!(
+ info.logs[0].topics()[0].to_vec(),
b"pong".to_vec().to_bytes32()
);
assert_eq!(
- info.logs[0].topics[1].to_vec(),
+ info.logs[0].topics()[1].to_vec(),
b"ping".to_vec().to_bytes32()
);
Ok(())
@@ -48,20 +57,15 @@ fn log2() -> Result<()> {
fn log3() -> Result<()> {
let mut contract = Contract::from(Test::LOG_LOG3).pure().compile()?;
let info = contract.execute::<()>([])?;
+ let topics = info.logs[0].topics();
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
assert_eq!(
- info.logs[0].topics[0].to_vec(),
- b"pong".to_vec().to_bytes32()
- );
- assert_eq!(
- info.logs[0].topics[1].to_vec(),
- b"ping".to_vec().to_bytes32()
- );
- assert_eq!(
- info.logs[0].topics[2].to_vec(),
- b"pong".to_vec().to_bytes32()
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
);
+ assert_eq!(topics[0].to_vec(), b"pong".to_vec().to_bytes32());
+ assert_eq!(topics[1].to_vec(), b"ping".to_vec().to_bytes32());
+ assert_eq!(topics[2].to_vec(), b"pong".to_vec().to_bytes32());
Ok(())
}
@@ -69,23 +73,15 @@ fn log3() -> Result<()> {
fn log4() -> Result<()> {
let mut contract = Contract::from(Test::LOG_LOG4).pure().compile()?;
let info = contract.execute::<()>([])?;
+ let topics = info.logs[0].topics();
- assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32());
- assert_eq!(
- info.logs[0].topics[0].to_vec(),
- b"pong".to_vec().to_bytes32()
- );
assert_eq!(
- info.logs[0].topics[1].to_vec(),
- b"ping".to_vec().to_bytes32()
- );
- assert_eq!(
- info.logs[0].topics[2].to_vec(),
- b"pong".to_vec().to_bytes32()
- );
- assert_eq!(
- info.logs[0].topics[3].to_vec(),
- b"pong".to_vec().to_bytes32()
+ info.logs[0].data.data.to_vec(),
+ b"Ping".to_vec().to_bytes32()
);
+ assert_eq!(topics[0].to_vec(), b"pong".to_vec().to_bytes32());
+ assert_eq!(topics[1].to_vec(), b"ping".to_vec().to_bytes32());
+ assert_eq!(topics[2].to_vec(), b"pong".to_vec().to_bytes32());
+ assert_eq!(topics[3].to_vec(), b"pong".to_vec().to_bytes32());
Ok(())
}
diff --git a/tests/loop.rs b/tests/loop.rs
index 0af208c3b..c23873c64 100644
--- a/tests/loop.rs
+++ b/tests/loop.rs
@@ -2,7 +2,7 @@
use anyhow::Result;
use filetests::Test;
-use zint::{Bytes32, Contract, Halt, OutOfGasError};
+use zint::{Bytes32, Contract, HaltReason, OutOfGasError};
#[test]
fn singular() -> Result<()> {
@@ -18,10 +18,7 @@ fn singular() -> Result<()> {
fn as_br_if() -> Result<()> {
let mut contract = Contract::from(Test::LOOP_AS_BR_IF).pure().compile()?;
let info = contract.execute([0])?;
- assert_eq!(
- info.halt,
- Some(Halt::OutOfGas(OutOfGasError::BasicOutOfGas))
- );
+ assert_eq!(info.halt, Some(HaltReason::OutOfGas(OutOfGasError::Basic)));
let info = contract.execute([1])?;
assert_eq!(info.ret, 7.to_bytes32());
diff --git a/tests/recursion.rs b/tests/recursion.rs
index b50d5f024..2008e6058 100644
--- a/tests/recursion.rs
+++ b/tests/recursion.rs
@@ -2,6 +2,7 @@ use anyhow::Result;
use filetests::Test;
use zint::{Bytes32, Contract};
+#[ignore]
#[test]
fn fibonacci() -> Result<()> {
let mut contract = Contract::from(Test::RECURSION_FIBONACCI).pure().compile()?;
@@ -16,6 +17,7 @@ fn fibonacci() -> Result<()> {
// x = 2
let info = contract.execute([2])?;
+ assert_eq!(info.halt, None);
assert_eq!(1.to_bytes32().to_vec(), info.ret);
// x = 3
diff --git a/tests/storage.rs b/tests/storage.rs
index 78e10ffb4..30734eea1 100644
--- a/tests/storage.rs
+++ b/tests/storage.rs
@@ -3,7 +3,7 @@
use anyhow::Result;
use filetests::Test;
-use zint::{Bytes32, Contract, U256};
+use zint::{keccak256, Bytes32, Contract, EVM, U256};
#[test]
fn store() -> Result<()> {
@@ -39,3 +39,76 @@ fn basic() -> Result<()> {
Ok(())
}
+
+#[test]
+fn mapping() -> Result<()> {
+ use opcodes::ShangHai;
+ use zint::Bytes32;
+
+ zint::setup_logger();
+
+ let hashing: Vec = vec![
+ // storage value
+ ShangHai::PUSH1,
+ ShangHai::Data(0x42),
+ // Load storage slot
+ //
+ // write index to memory
+ ShangHai::PUSH0,
+ ShangHai::PUSH0,
+ ShangHai::MSTORE8,
+ // write key to memory
+ ShangHai::PUSH0,
+ ShangHai::PUSH1,
+ ShangHai::Data(0x01),
+ ShangHai::MSTORE,
+ // hash key
+ ShangHai::PUSH1,
+ ShangHai::Data(0x20),
+ ShangHai::PUSH0,
+ ShangHai::KECCAK256,
+ // write storage
+ ShangHai::SSTORE,
+ // Load storage slot
+ //
+ // write index to memory
+ ShangHai::PUSH0,
+ ShangHai::PUSH0,
+ ShangHai::MSTORE8,
+ // write key to memory
+ ShangHai::PUSH0,
+ ShangHai::PUSH1,
+ ShangHai::Data(0x01),
+ ShangHai::MSTORE,
+ // hash key
+ ShangHai::PUSH1,
+ ShangHai::Data(0x20),
+ ShangHai::PUSH0,
+ ShangHai::KECCAK256,
+ // load storage to stack
+ ShangHai::SLOAD,
+ // write storage to memory
+ ShangHai::PUSH0,
+ ShangHai::MSTORE,
+ // return
+ ShangHai::PUSH1,
+ ShangHai::Data(0x20),
+ ShangHai::PUSH0,
+ ShangHai::RETURN,
+ ]
+ .into_iter()
+ .map(Into::into)
+ .collect();
+
+ let info = EVM::interp(&hashing, &[])?;
+ tracing::debug!("bytecode: {}", hex::encode(&hashing));
+
+ let key = keccak256(&[0; 0x20]);
+ assert_eq!(
+ info.storage.get(&U256::from_be_bytes(key)),
+ Some(&U256::from_be_bytes(0x42.to_bytes32())),
+ "{info:#?}"
+ );
+ assert_eq!(0x42.to_bytes32().to_vec(), info.ret);
+ Ok(())
+}
diff --git a/zink/codegen/Cargo.toml b/zink/codegen/Cargo.toml
index 6e05dc850..f925f27bb 100644
--- a/zink/codegen/Cargo.toml
+++ b/zink/codegen/Cargo.toml
@@ -13,6 +13,8 @@ repository.workspace = true
proc-macro = true
[dependencies]
+heck.workspace = true
+hex.workspace = true
proc-macro2.workspace = true
quote.workspace = true
syn.workspace = true
diff --git a/zink/codegen/src/constructor.rs b/zink/codegen/src/constructor.rs
deleted file mode 100644
index 4b6d4a1a2..000000000
--- a/zink/codegen/src/constructor.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//! Contract constructor.
-
-use proc_macro2::TokenStream;
-use quote::ToTokens;
-use syn::{parse_quote, ItemFn};
-
-/// Parse function into contract constructor.
-pub fn parse(input: ItemFn) -> TokenStream {
- let block = input.block;
- let inputs = input.sig.inputs;
- let mut constructor: ItemFn = parse_quote! {
- #[no_mangle]
- pub extern "C" fn constructor( #inputs ) {
- #block
- }
- };
-
- constructor.attrs = input.attrs;
- constructor.into_token_stream()
-}
diff --git a/zink/codegen/src/lib.rs b/zink/codegen/src/lib.rs
index 026cabdf7..b2edf79c1 100644
--- a/zink/codegen/src/lib.rs
+++ b/zink/codegen/src/lib.rs
@@ -1,9 +1,9 @@
//! Code generation library for the zink API
+#![allow(unused)]
use proc_macro::TokenStream;
-use syn::{parse_macro_input, DeriveInput, ItemFn, ItemType};
+use syn::{parse_macro_input, Attribute, DeriveInput, ItemFn, ItemStruct};
-mod constructor;
mod event;
mod selector;
mod storage;
@@ -38,38 +38,22 @@ pub fn event(input: TokenStream) -> TokenStream {
event::parse(input)
}
-/// Order-based storage macro.
-/// Currently only i32 is supported
+/// Declare on-chain storage
///
/// ```ignore
-/// use zink::storage;
+/// /// storage value
+/// #[zink::storage(i32)]
+/// pub struct Counter;
///
-/// #[storage]
-/// pub type Counter = i32;
-/// ```
-///
-/// will generate:
-///
-/// ```ignore
-/// struct Counter;
-///
-/// impl zink::Storage for Counter {
-/// // if this macro were the second one in the project, this key would be 1i32
-/// const STORAGE_KEY: i32 = 0i32;
-///
-/// fn get() -> i32 {
-/// zink::ffi::evm::sload(Self::STORAGE_KEY)
-/// }
-///
-/// fn set(value: i32) {
-/// zink::ffi::evm::sstore(Self::STORAGE_KEY, value);
-/// }
-/// }
+/// /// storage mapping
+/// #[zink::storage(i32, i32)]
+/// pub struct Mapping;
/// ```
#[proc_macro_attribute]
-pub fn storage(_args: TokenStream, input: TokenStream) -> TokenStream {
- let input = parse_macro_input!(input as ItemType);
- storage::parse(input).into()
+pub fn storage(attr: TokenStream, input: TokenStream) -> TokenStream {
+ let ty = storage::StorageType::from(attr);
+ let input = parse_macro_input!(input as ItemStruct);
+ storage::Storage::parse(ty, input)
}
/// Mark the function as an external entry point.
@@ -78,10 +62,3 @@ pub fn external(_args: TokenStream, input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as ItemFn);
selector::external(input)
}
-
-/// Mark the function as constructor
-#[proc_macro_attribute]
-pub fn constructor(_args: TokenStream, input: TokenStream) -> TokenStream {
- let input = parse_macro_input!(input as ItemFn);
- constructor::parse(input).into()
-}
diff --git a/zink/codegen/src/storage.rs b/zink/codegen/src/storage.rs
index 43549287d..dad1b3c24 100644
--- a/zink/codegen/src/storage.rs
+++ b/zink/codegen/src/storage.rs
@@ -1,51 +1,261 @@
extern crate proc_macro;
-use proc_macro2::TokenStream;
-use quote::{quote, ToTokens};
-use std::sync::atomic::{AtomicI32, Ordering::Relaxed};
-use syn::ItemType;
-
-static IOTA: AtomicI32 = AtomicI32::new(0);
-
-/// Parse storage attribute.
-///
-/// Method `get` unwraps the ptr as the original type, mainly
-/// mainly for passing the compilation checks at the moment,
-/// and it works for WASM in real cases as well.
-///
-/// For the cases in EVM, it doesn't matter it returns pointer
-/// since the value will be left on stack anyway.
-pub fn parse(input: ItemType) -> TokenStream {
- let name = input.ident;
- let ty = input.ty.to_token_stream();
-
- // Temporary solution, we'll switch to 32 byte storage keys later
- let key = IOTA.fetch_add(1, Relaxed);
- let expanded = quote! {
- #[doc = concat!(" Storage ", stringify!($variable_name))]
- struct #name;
-
- impl zink::Storage<#ty> for #name {
- const STORAGE_KEY: i32 = #key;
-
- fn get() -> #ty {
- zink::Asm::push(Self::STORAGE_KEY);
- unsafe {
- paste::paste! {
- zink::ffi::asm::[< sload_ #ty >]()
- }
+use heck::AsSnakeCase;
+use proc_macro::TokenStream;
+use proc_macro2::{Literal, Span, TokenTree};
+use quote::quote;
+use std::{cell::RefCell, collections::HashSet};
+use syn::{
+ meta::{self, ParseNestedMeta},
+ parse::{Parse, ParseStream, Result},
+ parse_quote, Attribute, Ident, ItemFn, ItemStruct, Visibility,
+};
+
+thread_local! {
+ static STORAGE_REGISTRY: RefCell> = RefCell::new(HashSet::new());
+}
+
+/// Storage attributes parser
+pub struct Storage {
+ /// kind of the storage
+ ty: StorageType,
+ /// The source and the target storage struct
+ target: ItemStruct,
+ /// Getter function of storage
+ getter: Option,
+}
+
+impl Storage {
+ /// Parse from proc_macro attribute
+ pub fn parse(ty: StorageType, target: ItemStruct) -> TokenStream {
+ let storage = Self::from((ty, target));
+ storage.expand()
+ }
+
+ fn expand(mut self) -> TokenStream {
+ match &self.ty {
+ StorageType::Value(value) => self.expand_value(value.clone()),
+ StorageType::Mapping { key, value } => self.expand_mapping(key.clone(), value.clone()),
+ StorageType::DoubleKeyMapping { key1, key2, value } => {
+ self.expand_dk_mapping(key1.clone(), key2.clone(), value.clone())
+ }
+ StorageType::Invalid => panic!("Invalid storage type"),
+ }
+ }
+
+ fn expand_value(&mut self, value: Ident) -> TokenStream {
+ let is = &self.target;
+ let name = self.target.ident.clone();
+ let slot = storage_slot(name.to_string());
+ let mut key = [0; 32];
+ key[28..].copy_from_slice(&slot.to_le_bytes());
+
+ let keyl = Literal::byte_string(&key);
+ let mut expanded = quote! {
+ #is
+
+ impl zink::storage::Storage for #name {
+ #[cfg(not(target_family = "wasm"))]
+ const STORAGE_KEY: [u8; 32] = *#keyl;
+ const STORAGE_SLOT: i32 = #slot;
+
+ type Value = #value;
+ }
+ };
+
+ if let Some(getter) = self.getter() {
+ // TODO: generate docs from the storage doc
+ let gs: proc_macro2::TokenStream = parse_quote! {
+ #[allow(missing_docs)]
+ #[zink::external]
+ pub fn #getter() -> #value {
+ #name::get()
+ }
+ };
+ expanded.extend(gs);
+ }
+
+ expanded.into()
+ }
+
+ fn expand_mapping(&mut self, key: Ident, value: Ident) -> TokenStream {
+ let is = &self.target;
+ let name = self.target.ident.clone();
+ let slot = storage_slot(name.to_string());
+
+ let mut expanded = quote! {
+ #is
+
+ impl zink::storage::Mapping for #name {
+ const STORAGE_SLOT: i32 = #slot;
+
+ type Key = #key;
+ type Value = #value;
+
+ #[cfg(not(target_family = "wasm"))]
+ fn storage_key(key: Self::Key) -> [u8; 32] {
+ use zink::Asm;
+
+ let mut seed = [0; 64];
+ seed[..32].copy_from_slice(&key.bytes32());
+ seed[60..].copy_from_slice(&Self::STORAGE_SLOT.to_le_bytes());
+ zink::keccak256(&seed)
+ }
+ }
+ };
+
+ if let Some(getter) = self.getter() {
+ // TODO: generate docs from the storage doc
+ let gs: proc_macro2::TokenStream = parse_quote! {
+ #[allow(missing_docs)]
+ #[zink::external]
+ pub fn #getter(key: #key) -> #value {
+ #name::get(key)
+ }
+ };
+ expanded.extend(gs);
+ }
+
+ expanded.into()
+ }
+
+ fn expand_dk_mapping(&mut self, key1: Ident, key2: Ident, value: Ident) -> TokenStream {
+ let is = &self.target;
+ let name = self.target.ident.clone();
+ let slot = storage_slot(name.to_string());
+
+ let mut expanded = quote! {
+ #is
+
+ impl zink::DoubleKeyMapping for #name {
+ const STORAGE_SLOT: i32 = #slot;
+
+ type Key1 = #key1;
+ type Key2 = #key2;
+ type Value = #value;
+
+ #[cfg(not(target_family = "wasm"))]
+ fn storage_key(key1: Self::Key1, key2: Self::Key2) -> [u8; 32] {
+ use zink::Asm;
+
+ let mut seed = [0; 64];
+ seed[..32].copy_from_slice(&key1.bytes32());
+ seed[60..].copy_from_slice(&Self::STORAGE_SLOT.to_le_bytes());
+ let skey1 = zink::keccak256(&seed);
+ seed[..32].copy_from_slice(&skey1);
+ seed[32..].copy_from_slice(&key2.bytes32());
+ zink::keccak256(&seed)
}
}
+ };
- fn set(value: #ty) {
- zink::Asm::push(value);
- zink::Asm::push(Self::STORAGE_KEY);
- unsafe {
- zink::ffi::evm::sstore();
+ if let Some(getter) = self.getter() {
+ // TODO: generate docs from the storage doc
+ let gs: proc_macro2::TokenStream = parse_quote! {
+ #[allow(missing_docs)]
+ #[zink::external]
+ pub fn #getter(key1: #key1, key2: #key2) -> #value {
+ #name::get(key1, key2)
}
+ };
+ expanded.extend(gs);
+ }
+
+ expanded.into()
+ }
+
+ /// Get the getter of this storage
+ fn getter(&mut self) -> Option {
+ let mut getter = if matches!(self.target.vis, Visibility::Public(_)) {
+ let fname = Ident::new(
+ &AsSnakeCase(self.target.ident.to_string()).to_string(),
+ Span::call_site(),
+ );
+ Some(fname)
+ } else {
+ None
+ };
+
+ self.getter.take().or(getter)
+ }
+}
+
+impl From<(StorageType, ItemStruct)> for Storage {
+ fn from(patts: (StorageType, ItemStruct)) -> Self {
+ let mut this = Self {
+ ty: patts.0,
+ target: patts.1,
+ getter: None,
+ };
+
+ let mut attrs: Vec = Default::default();
+ for attr in this.target.attrs.iter().cloned() {
+ if !attr.path().is_ident("getter") {
+ attrs.push(attr);
+ continue;
}
+
+ let Ok(list) = attr.meta.require_list().clone() else {
+ panic!("Invali getter arguments");
+ };
+
+ let Some(TokenTree::Ident(getter)) = list.tokens.clone().into_iter().nth(0) else {
+ panic!("Invalid getter function name");
+ };
+
+ this.getter = Some(getter);
+ }
+
+ this.target.attrs = attrs;
+ this
+ }
+}
+
+/// Zink storage type parser
+#[derive(Default, Debug)]
+pub enum StorageType {
+ /// Single value storage
+ Value(Ident),
+ /// Mapping storage
+ Mapping { key: Ident, value: Ident },
+ /// Double key mapping storage
+ DoubleKeyMapping {
+ key1: Ident,
+ key2: Ident,
+ value: Ident,
+ },
+ /// Invalid storage type
+ #[default]
+ Invalid,
+}
+
+impl From for StorageType {
+ fn from(input: TokenStream) -> Self {
+ let tokens = input.to_string();
+ let types: Vec<_> = tokens.split(',').collect();
+ match types.len() {
+ 1 => StorageType::Value(Ident::new(types[0].trim(), Span::call_site())),
+ 2 => StorageType::Mapping {
+ key: Ident::new(types[0].trim(), Span::call_site()),
+ value: Ident::new(types[1].trim(), Span::call_site()),
+ },
+ 3 => StorageType::DoubleKeyMapping {
+ key1: Ident::new(types[0].trim(), Span::call_site()),
+ key2: Ident::new(types[1].trim(), Span::call_site()),
+ value: Ident::new(types[2].trim(), Span::call_site()),
+ },
+ _ => panic!("Invalid storage attributes"),
+ }
+ }
+}
+
+fn storage_slot(name: String) -> i32 {
+ STORAGE_REGISTRY.with_borrow_mut(|r| {
+ let key = r.len();
+ if !r.insert(name.clone()) {
+ panic!("Storage {name} has already been declared");
}
- };
- expanded
+ key
+ }) as i32
}
diff --git a/zink/src/asm.rs b/zink/src/asm.rs
index b26b94bdf..1fdd26858 100644
--- a/zink/src/asm.rs
+++ b/zink/src/asm.rs
@@ -4,9 +4,12 @@ use crate::ffi;
use paste::paste;
/// Types implemented this trait are able to be pushed on stack.
-pub trait Asm {
+pub trait Asm: Copy {
/// Push self on the stack.
fn push(self);
+
+ #[cfg(not(target_family = "wasm"))]
+ fn bytes32(&self) -> [u8; 32];
}
macro_rules! impl_asm {
@@ -17,14 +20,10 @@ macro_rules! impl_asm {
paste! { ffi::asm::[](self); }
}
}
- }
- };
- ($len:expr) => {
- impl Asm for [u8; $len] {
- fn push(self) {
- unsafe {
- paste! { ffi::evm::[](self.as_ptr() as i32); }
- }
+
+ #[cfg(not(target_family = "wasm"))]
+ fn bytes32(&self) -> [u8; 32] {
+ crate::to_bytes32(&self.to_le_bytes())
}
}
};
@@ -33,7 +32,4 @@ macro_rules! impl_asm {
};
}
-impl_asm!(
- i8, u8, i16, u16, i32, u32, i64, u64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
-);
+impl_asm!(i8, u8, i16, u16, i32, u32, i64, u64);
diff --git a/zink/src/ffi/asm.rs b/zink/src/ffi/asm.rs
index 6bec21db3..77d88ec08 100644
--- a/zink/src/ffi/asm.rs
+++ b/zink/src/ffi/asm.rs
@@ -1,5 +1,7 @@
//! Assembly FFI.
+use crate::primitives::Address;
+
#[link(wasm_import_module = "asm")]
#[allow(improper_ctypes)]
extern "C" {
@@ -27,6 +29,9 @@ extern "C" {
/// Push a 64-bit unsigned integer to the stack.
pub fn push_u64(val: u64);
+ /// Push address to stack
+ pub fn push_address(address: Address);
+
/// Load a 8-bit signed integer from the storage.
pub fn sload_i8() -> i8;
@@ -50,4 +55,7 @@ extern "C" {
/// Load a 64-bit unsigned integer from the storage.
pub fn sload_u64() -> u64;
+
+ /// Load address from storage
+ pub fn sload_address() -> Address;
}
diff --git a/zink/src/ffi/evm.rs b/zink/src/ffi/evm.rs
index ffa2ffcc9..398ec523c 100644
--- a/zink/src/ffi/evm.rs
+++ b/zink/src/ffi/evm.rs
@@ -108,6 +108,18 @@ extern "C" {
/// Load a value from the storage
pub fn sload();
+ /// Save word to memory
+ pub fn mstore();
+
+ /// Save byte to memory
+ pub fn mstore8();
+
+ /// Load word from memory
+ pub fn mload();
+
+ /// Compute Keccak-256 hash
+ pub fn keccak256();
+
/// Append log record with no topics
pub fn log0(name: &'static [u8]);
diff --git a/zink/src/ffi/mod.rs b/zink/src/ffi/mod.rs
index f40d7d1e2..2f41799fe 100644
--- a/zink/src/ffi/mod.rs
+++ b/zink/src/ffi/mod.rs
@@ -1,5 +1,7 @@
//! Zink FFI.
+use crate::primitives::Address;
+
pub mod asm;
pub mod evm;
@@ -9,4 +11,12 @@ extern "C" {
/// Emit ABI to host state.
pub fn emit_abi(ptr: u32, len: u32);
+ /// Equal operation for addresses
+ pub fn address_eq(this: Address, other: Address) -> bool;
+
+ /// Set up a label for reserving 32 bytes in memory
+ pub fn label_reserve_mem_32();
+
+ /// Set up a label for reserving 64 bytes in memory
+ pub fn label_reserve_mem_64();
}
diff --git a/zink/src/lib.rs b/zink/src/lib.rs
index a1fd75fba..8fa280035 100644
--- a/zink/src/lib.rs
+++ b/zink/src/lib.rs
@@ -2,13 +2,49 @@
#![no_std]
+#[cfg(not(target_family = "wasm"))]
+extern crate alloc;
+
mod asm;
mod event;
pub mod ffi;
-mod storage;
+pub mod primitives;
+pub mod storage;
+
+pub use self::{asm::Asm, event::Event};
+pub use storage::{DoubleKeyMapping, Mapping, Storage};
+pub use zink_codegen::{external, storage, Event};
+
+/// Generate a keccak hash of the input (sha3)
+#[cfg(not(target_family = "wasm"))]
+pub fn keccak256(input: &[u8]) -> [u8; 32] {
+ use tiny_keccak::{Hasher, Keccak};
+ let mut hasher = Keccak::v256();
+ let mut output = [0; 32];
+ hasher.update(input);
+ hasher.finalize(&mut output);
+ output
+}
+
+/// Convert bytes to ls bytes
+#[cfg(not(target_family = "wasm"))]
+pub fn to_bytes32(src: &[u8]) -> [u8; 32] {
+ use alloc::vec::Vec;
+ let mut bytes = [0u8; 32];
+ let ls_bytes = {
+ src.iter()
+ .cloned()
+ .rev()
+ .skip_while(|b| *b == 0)
+ .collect::>()
+ .into_iter()
+ .rev()
+ .collect::>()
+ };
-pub use self::{asm::Asm, event::Event, storage::Storage};
-pub use zink_codegen::{constructor, external, storage, Event};
+ bytes[(32 - ls_bytes.len())..].copy_from_slice(&ls_bytes);
+ bytes
+}
// Panic hook implementation
#[cfg(target_arch = "wasm32")]
diff --git a/zink/src/primitives/address.rs b/zink/src/primitives/address.rs
new file mode 100644
index 000000000..be979b915
--- /dev/null
+++ b/zink/src/primitives/address.rs
@@ -0,0 +1,38 @@
+use crate::{ffi, storage::StorageValue, Asm};
+
+/// Account address
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct Address(
+ #[cfg(target_family = "wasm")] i32,
+ #[cfg(not(target_family = "wasm"))] [u8; 20],
+);
+
+impl Address {
+ /// if self equal to another
+ ///
+ /// NOTE: not using core::cmp because it uses registers in wasm
+ #[allow(clippy::should_implement_trait)]
+ pub fn eq(self, other: Self) -> bool {
+ unsafe { ffi::address_eq(self, other) }
+ }
+}
+
+impl Asm for Address {
+ fn push(self) {
+ unsafe { ffi::asm::push_address(self) }
+ }
+
+ #[cfg(not(target_family = "wasm"))]
+ fn bytes32(&self) -> [u8; 32] {
+ let mut output = [0; 32];
+ output[12..].copy_from_slice(&self.0);
+ output
+ }
+}
+
+impl StorageValue for Address {
+ fn sload() -> Self {
+ unsafe { ffi::asm::sload_address() }
+ }
+}
diff --git a/zink/src/primitives/mod.rs b/zink/src/primitives/mod.rs
new file mode 100644
index 000000000..d0f41fb0b
--- /dev/null
+++ b/zink/src/primitives/mod.rs
@@ -0,0 +1,5 @@
+//! Zink primitive types
+
+mod address;
+
+pub use address::Address;
diff --git a/zink/src/storage/dkmapping.rs b/zink/src/storage/dkmapping.rs
new file mode 100644
index 000000000..95aa21d1d
--- /dev/null
+++ b/zink/src/storage/dkmapping.rs
@@ -0,0 +1,67 @@
+//! Double key mapping
+
+use crate::{ffi, storage::StorageValue, Asm};
+
+/// Storage mapping interface
+pub trait DoubleKeyMapping {
+ const STORAGE_SLOT: i32;
+
+ type Key1: Asm;
+ type Key2: Asm;
+ type Value: StorageValue;
+
+ #[cfg(not(target_family = "wasm"))]
+ fn storage_key(key1: Self::Key1, key2: Self::Key2) -> [u8; 32];
+
+ /// Get value from storage key.
+ fn get(key1: Self::Key1, key2: Self::Key2) -> Self::Value {
+ load_double_key(key1, key2, Self::STORAGE_SLOT);
+ Self::Value::sload()
+ }
+
+ /// Set key and value
+ fn set(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
+ value.push();
+ load_double_key(key1, key2, Self::STORAGE_SLOT);
+ unsafe {
+ ffi::evm::sstore();
+ }
+ }
+}
+
+/// Load storage key to stack
+#[inline(always)]
+fn load_double_key(key1: impl Asm, key2: impl Asm, index: i32) {
+ unsafe {
+ ffi::label_reserve_mem_64();
+
+ // write key1 to memory
+ key1.push();
+ ffi::evm::push0();
+ ffi::evm::mstore();
+
+ // write index to memory
+ index.push();
+ ffi::asm::push_u8(0x20);
+ ffi::evm::mstore();
+
+ // hash key
+ ffi::asm::push_u8(0x40);
+ ffi::evm::push0();
+ ffi::evm::keccak256();
+
+ // stores the hash
+ ffi::evm::push0();
+ ffi::evm::mstore();
+
+ // write index to memory
+ key2.push();
+ ffi::asm::push_u8(0x20);
+ ffi::evm::mstore();
+
+ // hash key
+ ffi::asm::push_u8(0x40);
+ ffi::evm::push0();
+ ffi::evm::keccak256();
+ }
+}
diff --git a/zink/src/storage/mapping.rs b/zink/src/storage/mapping.rs
index b6113ccca..669c8f836 100644
--- a/zink/src/storage/mapping.rs
+++ b/zink/src/storage/mapping.rs
@@ -1 +1,51 @@
-//! Zink storage mapping implementation.
+//! Storage Mapping
+
+use crate::{ffi, storage::StorageValue, Asm};
+
+/// Storage mapping interface
+pub trait Mapping {
+ const STORAGE_SLOT: i32;
+
+ type Key: Asm;
+ type Value: StorageValue;
+
+ #[cfg(not(target_family = "wasm"))]
+ fn storage_key(key: Self::Key) -> [u8; 32];
+
+ /// Get value from storage key.
+ fn get(key: Self::Key) -> Self::Value {
+ load_key(key, Self::STORAGE_SLOT);
+ Self::Value::sload()
+ }
+
+ /// Set key and value
+ fn set(key: Self::Key, value: Self::Value) {
+ value.push();
+ load_key(key, Self::STORAGE_SLOT);
+ unsafe {
+ ffi::evm::sstore();
+ }
+ }
+}
+
+/// Load storage key to stack
+fn load_key(key: impl Asm, index: i32) {
+ unsafe {
+ ffi::label_reserve_mem_32();
+
+ // write key to memory
+ key.push();
+ ffi::evm::push0();
+ ffi::evm::mstore();
+
+ // write index to memory
+ index.push();
+ ffi::asm::push_u8(0x20);
+ ffi::evm::mstore();
+
+ // hash key
+ ffi::asm::push_u8(0x40);
+ ffi::evm::push0();
+ ffi::evm::keccak256();
+ }
+}
diff --git a/zink/src/storage/mod.rs b/zink/src/storage/mod.rs
index c8f034449..8eaef9326 100644
--- a/zink/src/storage/mod.rs
+++ b/zink/src/storage/mod.rs
@@ -1,16 +1,20 @@
//! Zink storage implementation.
-use crate::Asm;
+use crate::{ffi, Asm};
+pub use {dkmapping::DoubleKeyMapping, mapping::Mapping, value::Storage};
+mod dkmapping;
mod mapping;
+mod value;
-/// Storage trait. Currently not for public use
-pub trait Storage {
- const STORAGE_KEY: i32;
-
- /// Get value from storage.
- fn get() -> T;
+/// Interface for the value of kv based storage
+pub trait StorageValue: Asm {
+ /// Load from storage
+ fn sload() -> Self;
+}
- /// Set value to storage.
- fn set(value: T);
+impl StorageValue for i32 {
+ fn sload() -> Self {
+ unsafe { ffi::asm::sload_i32() }
+ }
}
diff --git a/zink/src/storage/value.rs b/zink/src/storage/value.rs
new file mode 100644
index 000000000..d3c5caa3d
--- /dev/null
+++ b/zink/src/storage/value.rs
@@ -0,0 +1,26 @@
+//! Key-Value storage
+use crate::{ffi, storage::StorageValue, Asm};
+
+/// Storage trait. Currently not for public use
+pub trait Storage {
+ #[cfg(not(target_family = "wasm"))]
+ const STORAGE_KEY: [u8; 32];
+ const STORAGE_SLOT: i32;
+
+ type Value: StorageValue + Asm;
+
+ /// Get value from storage.
+ fn get() -> Self::Value {
+ Asm::push(Self::STORAGE_SLOT);
+ Self::Value::sload()
+ }
+
+ /// Set value to storage.
+ fn set(value: Self::Value) {
+ value.push();
+ Asm::push(Self::STORAGE_SLOT);
+ unsafe {
+ ffi::evm::sstore();
+ }
+ }
+}
diff --git a/zint/src/bytes.rs b/zint/src/bytes.rs
index 90707ad06..c866aef95 100644
--- a/zint/src/bytes.rs
+++ b/zint/src/bytes.rs
@@ -6,7 +6,9 @@ pub trait Bytes32: Sized {
fn to_bytes32(&self) -> [u8; 32];
/// Convert type to vec of bytes.
- fn to_vec(&self) -> Vec;
+ fn to_vec(&self) -> Vec {
+ self.to_bytes32().to_vec()
+ }
}
/// Implement Bytes32 for types.
@@ -51,6 +53,14 @@ impl Bytes32 for Vec {
}
}
+impl Bytes32 for [u8; 20] {
+ fn to_bytes32(&self) -> [u8; 32] {
+ let mut bytes = [0u8; 32];
+ bytes[12..].copy_from_slice(self);
+ bytes
+ }
+}
+
impl Bytes32 for [u8; 32] {
fn to_bytes32(&self) -> [u8; 32] {
*self
@@ -95,4 +105,15 @@ impl Bytes32 for &str {
}
}
+impl Bytes32 for bool {
+ fn to_bytes32(&self) -> [u8; 32] {
+ let mut output = [0; 32];
+ if *self {
+ output[31] = 1;
+ }
+
+ output
+ }
+}
+
impl_bytes32!(i8, u8, i16, u16, i32, u32, usize, i64, u64, i128, u128);
diff --git a/zint/src/contract.rs b/zint/src/contract.rs
index 2120d76cf..b53be3d03 100644
--- a/zint/src/contract.rs
+++ b/zint/src/contract.rs
@@ -3,7 +3,7 @@
use crate::{lookup, Bytes32, Info, EVM};
use anyhow::{anyhow, Result};
use std::fs;
-use zinkc::{Artifact, Compiler, Config};
+use zinkc::{Artifact, Compiler, Config, Constructor, InitStorage};
/// Contract instance for testing.
#[derive(Default)]
@@ -14,6 +14,10 @@ pub struct Contract {
pub artifact: Artifact,
/// The source WASM of the contract.
pub wasm: Vec,
+ /// Bytecode constructor
+ pub constructor: Constructor,
+ /// Address in evm
+ pub address: [u8; 20],
}
impl From for Contract
@@ -33,8 +37,20 @@ where
impl Contract {
/// Get the bytecode of the contract.
- pub fn bytecode(&self) -> &[u8] {
- &self.artifact.bytecode
+ pub fn bytecode(&self) -> Result> {
+ let bytecode = self
+ .constructor
+ .finish(self.artifact.runtime_bytecode.clone().into())
+ .map(|v| v.to_vec())?;
+
+ Ok(bytecode)
+ }
+
+ /// Preset the storage of the contract, similar with the concept `constructor`
+ /// in solidity, but just in time.
+ pub fn construct(&mut self, storage: InitStorage) -> Result<&mut Self> {
+ self.constructor.storage(storage)?;
+ Ok(self)
}
/// Compile WASM to EVM bytecode.
@@ -44,10 +60,19 @@ impl Contract {
self.artifact = compiler.compile(&self.wasm)?;
tracing::debug!("abi: {:#}", self.json_abi()?);
- tracing::debug!("bytecode: {:?}", hex::encode(&self.artifact.bytecode));
+ tracing::debug!("bytecode: {}", hex::encode(&self.artifact.runtime_bytecode));
Ok(self)
}
+ /// Deploy self to evm
+ pub fn deploy<'e>(&mut self) -> Result> {
+ let mut evm = EVM::default();
+ let info = evm.deploy(&self.bytecode()?)?;
+
+ self.address.copy_from_slice(&info.address);
+ Ok(evm)
+ }
+
/// Load zink contract defined in the current
/// package.
///
@@ -77,6 +102,7 @@ impl Contract {
calldata.extend_from_slice(&input.to_bytes32());
}
+ tracing::debug!("calldata: {}", hex::encode(&calldata));
Ok(calldata)
}
diff --git a/zint/src/evm.rs b/zint/src/evm.rs
index 138eac2ed..9d82c6f47 100644
--- a/zint/src/evm.rs
+++ b/zint/src/evm.rs
@@ -2,11 +2,12 @@
use anyhow::{anyhow, Result};
use revm::{
+ db::EmptyDB,
primitives::{
- AccountInfo, Bytecode, Bytes, CreateScheme, Eval, ExecutionResult, Halt, Log, Output,
- ResultAndState, TransactTo, U256,
+ AccountInfo, Bytecode, Bytes, ExecutionResult, HaltReason, Log, Output, ResultAndState,
+ SuccessReason, TransactTo, TxKind, U256,
},
- InMemoryDB, EVM as REVM,
+ Database, Evm as Revm, InMemoryDB,
};
use std::collections::HashMap;
@@ -20,24 +21,26 @@ pub const ALICE: [u8; 20] = [0; 20];
pub const CONTRACT: [u8; 20] = [1; 20];
/// Wrapper of full REVM
-pub struct EVM {
- inner: REVM,
+pub struct EVM<'e> {
+ inner: Revm<'e, (), InMemoryDB>,
+ /// If commit changes
+ commit: bool,
}
-impl Default for EVM {
+impl<'e> Default for EVM<'e> {
fn default() -> Self {
let mut db = InMemoryDB::default();
db.insert_account_info(ALICE.into(), AccountInfo::from_balance(U256::MAX));
- let mut evm = REVM::new();
- evm.database(db);
- evm.env.tx.gas_limit = GAS_LIMIT;
-
- Self { inner: evm }
+ let evm = Revm::<'e, (), EmptyDB>::builder().with_db(db).build();
+ Self {
+ inner: evm,
+ commit: false,
+ }
}
}
-impl EVM {
+impl<'e> EVM<'e> {
/// Interpret runtime bytecode with provided arguments
pub fn interp(runtime_bytecode: &[u8], input: &[u8]) -> Result {
Self::default()
@@ -46,24 +49,43 @@ impl EVM {
.call(CONTRACT)
}
+ /// Get storage from address and storage index
+ pub fn storage(&mut self, address: [u8; 20], key: [u8; 32]) -> Result<[u8; 32]> {
+ let db = self.inner.db_mut();
+ Ok(db
+ .storage(address.into(), U256::from_be_bytes(key))?
+ .to_be_bytes())
+ }
+
+ /// If commit changes
+ pub fn commit(mut self, flag: bool) -> Self {
+ self.commit = flag;
+ self
+ }
+
/// Send transaction to the provided address.
pub fn call(&mut self, to: [u8; 20]) -> Result {
let to = TransactTo::Call(to.into());
- self.inner.env.tx.transact_to = to.clone();
- let result = self.inner.transact_ref().map_err(|e| anyhow!(e))?;
- (result, to).try_into()
+ self.inner.tx_mut().gas_limit = GAS_LIMIT;
+ self.inner.tx_mut().transact_to = to;
+ if self.commit {
+ self.inner.transact_commit()?.try_into()
+ } else {
+ let result = self.inner.transact().map_err(|e| anyhow!(e))?;
+ (result, to).try_into()
+ }
}
/// Interpret runtime bytecode with provided arguments
pub fn deploy(&mut self, bytecode: &[u8]) -> Result {
self.calldata(bytecode);
- self.inner.env.tx.transact_to = TransactTo::Create(CreateScheme::Create);
+ self.inner.tx_mut().transact_to = TxKind::Create;
self.inner.transact_commit()?.try_into()
}
/// Fill the calldata of the present transaction.
pub fn calldata(&mut self, input: &[u8]) -> &mut Self {
- self.inner.env.tx.data = Bytes::copy_from_slice(input);
+ self.inner.tx_mut().data = Bytes::copy_from_slice(input);
self
}
@@ -83,9 +105,7 @@ impl EVM {
}
fn db(&mut self) -> &mut InMemoryDB {
- self.inner
- .db()
- .unwrap_or_else(|| unreachable!("provided on initialization"))
+ self.inner.db_mut()
}
}
@@ -103,7 +123,7 @@ pub struct Info {
/// Execution logs.
pub logs: Vec,
/// Transaction halt reason.
- pub halt: Option,
+ pub halt: Option,
}
impl TryFrom for Info {
@@ -122,7 +142,7 @@ impl TryFrom for Info {
output,
..
} => {
- if reason != Eval::Return {
+ if reason != SuccessReason::Return {
return Err(anyhow!("Transaction is not returned: {reason:?}"));
}
info.logs = logs;
diff --git a/zint/src/lib.rs b/zint/src/lib.rs
index 789be21fd..6a4a52ed1 100644
--- a/zint/src/lib.rs
+++ b/zint/src/lib.rs
@@ -12,7 +12,7 @@ pub use self::{
evm::{Info, EVM},
};
pub use hex;
-pub use revm::primitives::{Halt, OutOfGasError, U256};
+pub use revm::primitives::{HaltReason, OutOfGasError, U256};
pub use tracing as log;
pub use zabi::selector::keccak256;