difftreelog
refactor move evm-coder out of the repo
in: master
51 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -172,9 +172,9 @@
[[package]]
name = "anyhow"
-version = "1.0.68"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
+checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
[[package]]
name = "app-promotion-rpc"
@@ -343,9 +343,9 @@
[[package]]
name = "async-trait"
-version = "0.1.63"
+version = "0.1.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1"
+checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
dependencies = [
"proc-macro2",
"quote",
@@ -706,20 +706,9 @@
[[package]]
name = "bstr"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
-dependencies = [
- "lazy_static",
- "memchr",
- "regex-automata",
-]
-
-[[package]]
-name = "bstr"
-version = "1.1.0"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b"
+checksum = "b7f0778972c64420fdedc63f09919c8a88bda7b25135357fd25a5d9f3257e832"
dependencies = [
"memchr",
"serde",
@@ -760,9 +749,9 @@
[[package]]
name = "bytes"
-version = "1.3.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
+checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "bzip2-sys"
@@ -808,9 +797,9 @@
[[package]]
name = "cc"
-version = "1.0.78"
+version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
]
@@ -1027,18 +1016,6 @@
]
[[package]]
-name = "console"
-version = "0.15.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
-dependencies = [
- "encode_unicode",
- "lazy_static",
- "libc",
- "windows-sys 0.42.0",
-]
-
-[[package]]
name = "const-oid"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1221,9 +1198,9 @@
[[package]]
name = "crc"
-version = "3.0.0"
+version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3"
+checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
dependencies = [
"crc-catalog",
]
@@ -1874,9 +1851,9 @@
[[package]]
name = "curve25519-dalek"
-version = "4.0.0-pre.5"
+version = "4.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67bc65846be335cb20f4e52d49a437b773a2c1fdb42b19fc84e79e6f6771536f"
+checksum = "8da00a7a9a4eb92a0a0f8e75660926d48f0d0f3c537e455c457bcdaa1e16b1ac"
dependencies = [
"cfg-if",
"fiat-crypto",
@@ -1888,9 +1865,9 @@
[[package]]
name = "cxx"
-version = "1.0.87"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e"
+checksum = "bc831ee6a32dd495436e317595e639a587aa9907bef96fe6e6abc290ab6204e9"
dependencies = [
"cc",
"cxxbridge-flags",
@@ -1900,9 +1877,9 @@
[[package]]
name = "cxx-build"
-version = "1.0.87"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200"
+checksum = "94331d54f1b1a8895cd81049f7eaaaef9d05a7dcb4d1fd08bf3ff0806246789d"
dependencies = [
"cc",
"codespan-reporting",
@@ -1915,15 +1892,15 @@
[[package]]
name = "cxxbridge-flags"
-version = "1.0.87"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea"
+checksum = "48dcd35ba14ca9b40d6e4b4b39961f23d835dbb8eed74565ded361d93e1feb8a"
[[package]]
name = "cxxbridge-macro"
-version = "1.0.87"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e"
+checksum = "81bbeb29798b407ccd82a3324ade1a7286e0d29851475990b612670f6f5124d2"
dependencies = [
"proc-macro2",
"quote",
@@ -2268,9 +2245,9 @@
[[package]]
name = "either"
-version = "1.8.0"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "elliptic-curve"
@@ -2295,12 +2272,6 @@
]
[[package]]
-name = "encode_unicode"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
-
-[[package]]
name = "enum-as-inner"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2474,24 +2445,20 @@
[[package]]
name = "evm-coder"
-version = "0.1.6"
+version = "0.3.0"
+source = "git+https://github.com/uniquenetwork/evm-coder?tag=v0.3.0#c4bfdf39d84fbe74c6178417177f2a7f81d92bdd"
dependencies = [
"ethereum",
"evm-coder-procedural",
- "evm-core",
- "frame-support",
- "hex",
- "hex-literal",
"impl-trait-for-tuples",
"primitive-types",
"sha3-const",
- "similar-asserts",
- "trybuild",
]
[[package]]
name = "evm-coder-procedural"
-version = "0.2.3"
+version = "0.3.0"
+source = "git+https://github.com/uniquenetwork/evm-coder?tag=v0.3.0#c4bfdf39d84fbe74c6178417177f2a7f81d92bdd"
dependencies = [
"Inflector",
"hex",
@@ -2502,6 +2469,15 @@
]
[[package]]
+name = "evm-coder-substrate-procedural"
+version = "0.1.0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "evm-core"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3227,9 +3203,9 @@
[[package]]
name = "fs_extra"
-version = "1.2.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
+checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "funty"
@@ -3239,9 +3215,9 @@
[[package]]
name = "futures"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
+checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84"
dependencies = [
"futures-channel",
"futures-core",
@@ -3254,9 +3230,9 @@
[[package]]
name = "futures-channel"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
+checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
dependencies = [
"futures-core",
"futures-sink",
@@ -3264,15 +3240,15 @@
[[package]]
name = "futures-core"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
+checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
[[package]]
name = "futures-executor"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
+checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e"
dependencies = [
"futures-core",
"futures-task",
@@ -3282,9 +3258,9 @@
[[package]]
name = "futures-io"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
+checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
[[package]]
name = "futures-lite"
@@ -3303,9 +3279,9 @@
[[package]]
name = "futures-macro"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
+checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
dependencies = [
"proc-macro2",
"quote",
@@ -3325,15 +3301,15 @@
[[package]]
name = "futures-sink"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
+checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
[[package]]
name = "futures-task"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
+checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
[[package]]
name = "futures-timer"
@@ -3343,9 +3319,9 @@
[[package]]
name = "futures-util"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
+checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
dependencies = [
"futures-channel",
"futures-core",
@@ -3469,7 +3445,7 @@
checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
dependencies = [
"aho-corasick",
- "bstr 1.1.0",
+ "bstr",
"fnv",
"log",
"regex",
@@ -3545,9 +3521,9 @@
[[package]]
name = "heck"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
@@ -3568,6 +3544,12 @@
]
[[package]]
+name = "hermit-abi"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01"
+
+[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3697,9 +3679,9 @@
[[package]]
name = "hyper"
-version = "0.14.23"
+version = "0.14.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
+checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c"
dependencies = [
"bytes",
"futures-channel",
@@ -3914,12 +3896,12 @@
[[package]]
name = "io-lifetimes"
-version = "1.0.4"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
+checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
dependencies = [
"libc",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
]
[[package]]
@@ -3948,14 +3930,14 @@
[[package]]
name = "is-terminal"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
+checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
dependencies = [
- "hermit-abi 0.2.6",
- "io-lifetimes 1.0.4",
- "rustix 0.36.7",
- "windows-sys 0.42.0",
+ "hermit-abi 0.3.0",
+ "io-lifetimes 1.0.5",
+ "rustix 0.36.8",
+ "windows-sys 0.45.0",
]
[[package]]
@@ -3984,9 +3966,9 @@
[[package]]
name = "js-sys"
-version = "0.3.60"
+version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
dependencies = [
"wasm-bindgen",
]
@@ -4974,7 +4956,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb"
dependencies = [
- "rustix 0.36.7",
+ "rustix 0.36.8",
]
[[package]]
@@ -5284,9 +5266,9 @@
[[package]]
name = "netlink-packet-utils"
-version = "0.5.1"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25af9cf0dc55498b7bd94a1508af7a78706aa0ab715a73c5169273e03c84845e"
+checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34"
dependencies = [
"anyhow",
"byteorder",
@@ -6248,6 +6230,8 @@
version = "0.1.3"
dependencies = [
"evm-coder",
+ "evm-coder-substrate-procedural",
+ "evm-core",
"frame-benchmarking",
"frame-support",
"frame-system",
@@ -6256,6 +6240,7 @@
"scale-info",
"sp-core",
"sp-std",
+ "spez",
"up-data-structs",
]
@@ -7272,9 +7257,9 @@
[[package]]
name = "parity-scale-codec"
-version = "3.2.2"
+version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7ab01d0f889e957861bc65888d5ccbe82c158d0270136ba46820d43837cdf72"
+checksum = "c3840933452adf7b3b9145e27086a5a3376c619dca1a21b1e5a5af0d54979bed"
dependencies = [
"arrayvec 0.7.2",
"bitvec",
@@ -7333,7 +7318,7 @@
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
- "parking_lot_core 0.9.6",
+ "parking_lot_core 0.9.7",
]
[[package]]
@@ -7352,15 +7337,15 @@
[[package]]
name = "parking_lot_core"
-version = "0.9.6"
+version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
+checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
]
[[package]]
@@ -8838,10 +8823,16 @@
]
[[package]]
+name = "proc-macro-hack"
+version = "0.5.20+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
+
+[[package]]
name = "proc-macro2"
-version = "1.0.50"
+version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
+checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
dependencies = [
"unicode-ident",
]
@@ -9675,16 +9666,16 @@
[[package]]
name = "rustix"
-version = "0.36.7"
+version = "0.36.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
+checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
dependencies = [
"bitflags",
"errno",
- "io-lifetimes 1.0.4",
+ "io-lifetimes 1.0.5",
"libc",
"linux-raw-sys 0.1.4",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
]
[[package]]
@@ -10996,9 +10987,9 @@
[[package]]
name = "security-framework"
-version = "2.8.1"
+version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c4437699b6d34972de58652c68b98cb5b53a4199ab126db8e20ec8ded29a721"
+checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
dependencies = [
"bitflags",
"core-foundation",
@@ -11072,9 +11063,9 @@
[[package]]
name = "serde_json"
-version = "1.0.91"
+version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
+checksum = "7434af0dc1cbd59268aa98b4c22c131c0584d2232f6fb166efb993e2832e896a"
dependencies = [
"itoa",
"ryu",
@@ -11206,26 +11197,6 @@
]
[[package]]
-name = "similar"
-version = "2.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
-dependencies = [
- "bstr 0.2.17",
- "unicode-segmentation",
-]
-
-[[package]]
-name = "similar-asserts"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbf644ad016b75129f01a34a355dcb8d66a5bc803e417c7a77cc5d5ee9fa0f18"
-dependencies = [
- "console",
- "similar",
-]
-
-[[package]]
name = "slab"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -11275,14 +11246,14 @@
[[package]]
name = "snow"
-version = "0.9.0"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "774d05a3edae07ce6d68ea6984f3c05e9bba8927e3dd591e3b479e5b03213d0d"
+checksum = "12ba5f4d4ff12bdb6a169ed51b7c48c0e0ac4b0b4b31012b2571e97d78d3201d"
dependencies = [
"aes-gcm 0.9.4",
"blake2",
"chacha20poly1305",
- "curve25519-dalek 4.0.0-pre.5",
+ "curve25519-dalek 4.0.0-rc.0",
"rand_core 0.6.4",
"ring",
"rustc_version 0.4.0",
@@ -12031,6 +12002,28 @@
]
[[package]]
+name = "spez"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "304d2fd6a79879f77b207ba8cd5079c22f872eaad65a3fb8d71799e5bacf368b"
+dependencies = [
+ "proc-macro-hack",
+ "spez-macros",
+]
+
+[[package]]
+name = "spez-macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7fa06037d8ccb6cdadc151129062ebc9e4281c1ea44b2c704582245d017d1dc"
+dependencies = [
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -12612,15 +12605,15 @@
[[package]]
name = "tinyvec_macros"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.24.2"
+version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
+checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
dependencies = [
"autocfg",
"bytes",
@@ -12702,9 +12695,9 @@
[[package]]
name = "toml_edit"
-version = "0.18.0"
+version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "729bfd096e40da9c001f778f5cdecbd2957929a24e10e5883d9392220a751581"
+checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b"
dependencies = [
"indexmap",
"nom8",
@@ -12976,21 +12969,6 @@
"sp-weights",
"substrate-rpc-client",
"zstd",
-]
-
-[[package]]
-name = "trybuild"
-version = "1.0.76"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed2c57956f91546d4d33614265a85d55c8e1ab91484853a10335894786d7db6"
-dependencies = [
- "glob",
- "once_cell",
- "serde",
- "serde_derive",
- "serde_json",
- "termcolor",
- "toml",
]
[[package]]
@@ -13108,12 +13086,6 @@
dependencies = [
"tinyvec",
]
-
-[[package]]
-name = "unicode-segmentation"
-version = "1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
[[package]]
name = "unicode-width"
@@ -13446,9 +13418,9 @@
[[package]]
name = "uuid"
-version = "1.2.2"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
+checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
dependencies = [
"getrandom 0.2.8",
]
@@ -13543,9 +13515,9 @@
[[package]]
name = "wasm-bindgen"
-version = "0.2.83"
+version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@@ -13553,9 +13525,9 @@
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.83"
+version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
dependencies = [
"bumpalo",
"log",
@@ -13568,9 +13540,9 @@
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.33"
+version = "0.4.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
+checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
dependencies = [
"cfg-if",
"js-sys",
@@ -13580,9 +13552,9 @@
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.83"
+version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -13590,9 +13562,9 @@
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.83"
+version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
dependencies = [
"proc-macro2",
"quote",
@@ -13603,9 +13575,9 @@
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.83"
+version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
[[package]]
name = "wasm-instrument"
@@ -13886,9 +13858,9 @@
[[package]]
name = "web-sys"
-version = "0.3.60"
+version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -14338,6 +14310,30 @@
]
[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.1",
+ "windows_i686_gnu 0.42.1",
+ "windows_i686_msvc 0.42.1",
+ "windows_x86_64_gnu 0.42.1",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.1",
+]
+
+[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -14644,9 +14640,9 @@
[[package]]
name = "zstd-sys"
-version = "2.0.5+zstd.1.5.2"
+version = "2.0.6+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edc50ffce891ad571e9f9afe5039c4837bede781ac4bb13052ed7ae695518596"
+checksum = "68a3f9792c0c3dc6c165840a75f47ae1f4da402c2d006881129579f6597e801b"
dependencies = [
"cc",
"libc",
Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,7 +19,7 @@
[workspace.dependencies]
# Unique
-evm-coder = { default-features = false, path = "crates/evm-coder" }
+evm-coder = { git = "https://github.com/uniquenetwork/evm-coder", tag = "v0.3.0", default-features = false }
struct-versioning = { path = "crates/struct-versioning" }
precompile-utils-macro = { path = "runtime/common/ethereum/precompiles/utils/macro" }
up-common = { path = "primitives/common", default-features = false }
crates/evm-coder/CHANGELOG.mddiffbeforeafterboth--- a/crates/evm-coder/CHANGELOG.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Change Log
-
-All notable changes to this project will be documented in this file.
-
-<!-- bureaucrate goes here -->
-## [v0.1.6] - 2023-01-12
-
-### Added
-- Support Option<T> type.
-### Removed
-- Frontier dependency.
-
-## [v0.1.5] - 2022-11-30
-
-### Added
-- Derive macro to support structures and enums.
-
-## [v0.1.4] - 2022-11-02
-
-### Added
-
-- Named structures support.
-
-## [v0.1.3] - 2022-08-29
-
-### Fixed
-
-- Parsing simple values.
-
-## [v0.1.2] 2022-08-19
-
-### Added
-
-- Implementation `AbiWrite` for tuples.
-
-### Fixes
-
-- Tuple generation for solidity.
-
-## [v0.1.1] 2022-08-16
-
-### Other changes
-
-- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
-
-- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
-
-- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
crates/evm-coder/Cargo.tomldiffbeforeafterboth--- a/crates/evm-coder/Cargo.toml
+++ /dev/null
@@ -1,32 +0,0 @@
-[package]
-edition = "2021"
-license = "GPLv3"
-name = "evm-coder"
-version = "0.1.6"
-
-[dependencies]
-sha3-const = { version = "0.1.1", default-features = false }
-# evm-coder reexports those proc-macro
-evm-coder-procedural = { path = "./procedural" }
-# Evm uses primitive-types for H160, H256 and others
-primitive-types = { workspace = true }
-# Evm doesn't have reexports for log and others
-ethereum = { workspace = true }
-frame-support = { workspace = true }
-# Error types for execution
-evm-core = { workspace = true }
-# We have tuple-heavy code in solidity.rs
-impl-trait-for-tuples = { workspace = true }
-
-[dev-dependencies]
-# We want to assert some large binary blobs equality in tests
-hex = "0.4.3"
-hex-literal = { workspace = true }
-similar-asserts = "1.4.2"
-trybuild = "1.0"
-
-[features]
-default = ["std"]
-std = ["ethereum/std", "evm-core/std", "frame-support/std", "primitive-types/std"]
-# Stub/interface generation
-stubgen = []
crates/evm-coder/README.mddiffbeforeafterboth--- a/crates/evm-coder/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# evm-coder
-
-Library for seamless call translation between Rust and Solidity code
-
-By encoding solidity definitions in Rust, this library also provides generation of
-solidity interfaces for ethereum developers
-
-## Overview
-
-Most of this library functionality shouldn't be used directly, but via macros
-
-- [`solidity_interface`]
-- [`ToLog`]
-
-<!-- TODO: make links useable on github, by publishing crate to docs.rs, and linking it from here instead -->
\ No newline at end of file
crates/evm-coder/procedural/Cargo.tomldiffbeforeafterboth--- a/crates/evm-coder/procedural/Cargo.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-[package]
-edition = "2021"
-license = "GPLv3"
-name = "evm-coder-procedural"
-version = "0.2.3"
-
-[lib]
-proc-macro = true
-
-[dependencies]
-# Ethereum uses keccak (=sha3) for selectors
-sha3 = "0.10.1"
-# Value formatting
-Inflector = "0.11.4"
-hex = "0.4.3"
-# General proc-macro utilities
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = { version = "1.0", features = ["full"] }
crates/evm-coder/procedural/src/abi_derive/derive_enum.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
+++ /dev/null
@@ -1,199 +0,0 @@
-use quote::quote;
-
-use super::extract_docs;
-
-pub fn impl_solidity_option<'a>(
- docs: Vec<String>,
- name: &proc_macro2::Ident,
- enum_options: impl Iterator<Item = &'a syn::Variant> + Clone,
-) -> proc_macro2::TokenStream {
- let variant_names = enum_options.clone().map(|opt| {
- let opt = &opt.ident;
- let s = name.to_string() + "." + opt.to_string().as_str();
- let as_string = proc_macro2::Literal::string(s.as_str());
- quote!(#name::#opt => #as_string,)
- });
- let solidity_name = name.to_string();
-
- let solidity_fields = enum_options.map(|v| {
- let docs = extract_docs(&v.attrs).expect("TODO: handle bad docs");
- let name = v.ident.to_string();
- quote! {
- SolidityEnumVariant {
- docs: &[#(#docs),*],
- name: #name,
- }
- }
- });
-
- quote!(
- #[cfg(feature = "stubgen")]
- impl ::evm_coder::solidity::SolidityEnumTy for #name {
- fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector) -> String {
- use evm_coder::solidity::*;
- use core::fmt::Write;
- let interface = SolidityEnum {
- docs: &[#(#docs),*],
- name: #solidity_name,
- fields: &[#(
- #solidity_fields,
- )*],
- };
- let mut out = String::new();
- let _ = interface.format(&mut out, tc);
- tc.collect(out);
- #solidity_name.to_string()
- }
- fn solidity_option(&self) -> &str {
- match self {
- #(#variant_names)*
- }
- }
- }
- )
-}
-
-pub fn impl_enum_from_u8<'a>(
- name: &proc_macro2::Ident,
- enum_options: impl Iterator<Item = &'a syn::Variant>,
-) -> proc_macro2::TokenStream {
- let error_str = format!("Value not convertible into enum \"{name}\"");
- let error_str = proc_macro2::Literal::string(&error_str);
- let enum_options = enum_options.enumerate().map(|(i, opt)| {
- let opt = &opt.ident;
- let n = proc_macro2::Literal::u8_suffixed(i as u8);
- quote! {#n => Ok(#name::#opt),}
- });
-
- quote!(
- impl TryFrom<u8> for #name {
- type Error = &'static str;
-
- fn try_from(value: u8) -> ::core::result::Result<Self, Self::Error> {
- const err: &'static str = #error_str;
- match value {
- #(#enum_options)*
- _ => Err(err)
- }
- }
- }
- )
-}
-
-pub fn impl_enum_abi_type(name: &syn::Ident) -> proc_macro2::TokenStream {
- quote! {
- impl ::evm_coder::abi::AbiType for #name {
- const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = <u8 as ::evm_coder::abi::AbiType>::SIGNATURE;
-
- fn is_dynamic() -> bool {
- <u8 as ::evm_coder::abi::AbiType>::is_dynamic()
- }
- fn size() -> usize {
- <u8 as ::evm_coder::abi::AbiType>::size()
- }
- }
- }
-}
-
-pub fn impl_enum_abi_read(name: &syn::Ident) -> proc_macro2::TokenStream {
- quote!(
- impl ::evm_coder::abi::AbiRead for #name {
- fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {
- Ok(
- <u8 as ::evm_coder::abi::AbiRead>::abi_read(reader)?
- .try_into()?
- )
- }
- }
- )
-}
-
-pub fn impl_enum_abi_write(name: &syn::Ident) -> proc_macro2::TokenStream {
- quote!(
- impl ::evm_coder::abi::AbiWrite for #name {
- fn abi_write(&self, writer: &mut ::evm_coder::abi::AbiWriter) {
- ::evm_coder::abi::AbiWrite::abi_write(&(*self as u8), writer);
- }
- }
- )
-}
-
-pub fn impl_enum_solidity_type_name(name: &syn::Ident) -> proc_macro2::TokenStream {
- quote!(
- #[cfg(feature = "stubgen")]
- impl ::evm_coder::solidity::SolidityTypeName for #name {
- fn solidity_name(
- writer: &mut impl ::core::fmt::Write,
- tc: &::evm_coder::solidity::TypeCollector,
- ) -> ::core::fmt::Result {
- write!(writer, "{}", tc.collect_enum::<Self>())
- }
-
- fn is_simple() -> bool {
- true
- }
-
- fn solidity_default(
- writer: &mut impl ::core::fmt::Write,
- tc: &::evm_coder::solidity::TypeCollector,
- ) -> ::core::fmt::Result {
- write!(writer, "{}", <#name as ::evm_coder::solidity::SolidityEnumTy>::solidity_option(&<#name>::default()))
- }
- }
- )
-}
-
-pub fn check_enum_fields(de: &syn::DataEnum) -> syn::Result<()> {
- for v in de.variants.iter() {
- if !v.fields.is_empty() {
- return Err(syn::Error::new(
- v.ident.span(),
- "Enumeration parameters should not have fields",
- ));
- } else if v.discriminant.is_some() {
- return Err(syn::Error::new(
- v.ident.span(),
- "Enumeration options should not have an explicit specified value",
- ));
- }
- }
-
- Ok(())
-}
-
-pub fn check_repr_u8(name: &syn::Ident, attrs: &[syn::Attribute]) -> syn::Result<()> {
- let mut has_repr = false;
- for attr in attrs.iter() {
- if attr.path.is_ident("repr") {
- has_repr = true;
- let meta = attr.parse_meta()?;
- check_meta_u8(&meta)?;
- }
- }
-
- if !has_repr {
- return Err(syn::Error::new(name.span(), "Enum is not \"repr(u8)\""));
- }
-
- Ok(())
-}
-
-fn check_meta_u8(meta: &syn::Meta) -> Result<(), syn::Error> {
- if let syn::Meta::List(p) = meta {
- for nm in p.nested.iter() {
- if let syn::NestedMeta::Meta(syn::Meta::Path(p)) = nm {
- if !p.is_ident("u8") {
- return Err(syn::Error::new(
- p.segments
- .first()
- .expect("repr segments are empty")
- .ident
- .span(),
- "Enum is not \"repr(u8)\"",
- ));
- }
- }
- }
- }
- Ok(())
-}
crates/evm-coder/procedural/src/abi_derive/derive_struct.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/abi_derive/derive_struct.rs
+++ /dev/null
@@ -1,231 +0,0 @@
-use super::extract_docs;
-use quote::quote;
-use syn::Field;
-
-pub fn tuple_type<'a>(
- field_types: impl Iterator<Item = &'a syn::Type> + Clone,
-) -> proc_macro2::TokenStream {
- let field_types = field_types.map(|ty| quote!(#ty,));
- quote! {(#(#field_types)*)}
-}
-
-pub fn tuple_ref_type<'a>(
- field_types: impl Iterator<Item = &'a syn::Type> + Clone,
-) -> proc_macro2::TokenStream {
- let field_types = field_types.map(|ty| quote!(&#ty,));
- quote! {(#(#field_types)*)}
-}
-
-pub fn tuple_data_as_ref(
- is_named_fields: bool,
- field_names: impl Iterator<Item = syn::Ident> + Clone,
-) -> proc_macro2::TokenStream {
- let field_names = field_names.enumerate().map(|(i, field)| {
- if is_named_fields {
- quote!(&self.#field,)
- } else {
- let field = proc_macro2::Literal::usize_unsuffixed(i);
- quote!(&self.#field,)
- }
- });
- quote! {(#(#field_names)*)}
-}
-
-pub fn tuple_names(
- is_named_fields: bool,
- field_names: impl Iterator<Item = syn::Ident> + Clone,
-) -> proc_macro2::TokenStream {
- let field_names = field_names.enumerate().map(|(i, field)| {
- if is_named_fields {
- quote!(#field,)
- } else {
- let field = proc_macro2::Ident::new(
- format!("field{}", i).as_str(),
- proc_macro2::Span::call_site(),
- );
- quote!(#field,)
- }
- });
- quote! {(#(#field_names)*)}
-}
-
-pub fn struct_from_tuple(
- name: &syn::Ident,
- is_named_fields: bool,
- field_names: impl Iterator<Item = syn::Ident> + Clone,
-) -> proc_macro2::TokenStream {
- let field_names = field_names.enumerate().map(|(i, field)| {
- if is_named_fields {
- quote!(#field,)
- } else {
- let field = proc_macro2::Ident::new(
- format!("field{}", i).as_str(),
- proc_macro2::Span::call_site(),
- );
- quote!(#field,)
- }
- });
-
- if is_named_fields {
- quote! {#name {#(#field_names)*}}
- } else {
- quote! {#name (#(#field_names)*)}
- }
-}
-
-pub fn map_field_to_name(field: (usize, &syn::Field)) -> syn::Ident {
- match field.1.ident.as_ref() {
- Some(name) => name.clone(),
- None => {
- let mut name = "field".to_string();
- name.push_str(field.0.to_string().as_str());
- syn::Ident::new(name.as_str(), proc_macro2::Span::call_site())
- }
- }
-}
-
-pub fn map_field_to_type(field: &syn::Field) -> &syn::Type {
- &field.ty
-}
-
-pub fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {
- quote! {
- impl ::evm_coder::sealed::CanBePlacedInVec for #ident {}
- }
-}
-
-pub fn impl_struct_abi_type(
- name: &syn::Ident,
- tuple_type: proc_macro2::TokenStream,
-) -> proc_macro2::TokenStream {
- quote! {
- impl ::evm_coder::abi::AbiType for #name {
- const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = <#tuple_type as ::evm_coder::abi::AbiType>::SIGNATURE;
- fn is_dynamic() -> bool {
- <#tuple_type as ::evm_coder::abi::AbiType>::is_dynamic()
- }
- fn size() -> usize {
- <#tuple_type as ::evm_coder::abi::AbiType>::size()
- }
- }
- }
-}
-
-pub fn impl_struct_abi_read(
- name: &syn::Ident,
- tuple_type: proc_macro2::TokenStream,
- tuple_names: proc_macro2::TokenStream,
- struct_from_tuple: proc_macro2::TokenStream,
-) -> proc_macro2::TokenStream {
- quote!(
- impl ::evm_coder::abi::AbiRead for #name {
- fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {
- let #tuple_names = <#tuple_type as ::evm_coder::abi::AbiRead>::abi_read(reader)?;
- Ok(#struct_from_tuple)
- }
- }
- )
-}
-
-pub fn impl_struct_abi_write(
- name: &syn::Ident,
- _is_named_fields: bool,
- tuple_type: proc_macro2::TokenStream,
- tuple_data: proc_macro2::TokenStream,
-) -> proc_macro2::TokenStream {
- quote!(
- impl ::evm_coder::abi::AbiWrite for #name {
- fn abi_write(&self, writer: &mut ::evm_coder::abi::AbiWriter) {
- <#tuple_type as ::evm_coder::abi::AbiWrite>::abi_write(&#tuple_data, writer)
- }
- }
- )
-}
-
-pub fn impl_struct_solidity_type<'a>(
- name: &syn::Ident,
- docs: Vec<String>,
- fields: impl Iterator<Item = &'a Field> + Clone,
-) -> proc_macro2::TokenStream {
- let solidity_name = name.to_string();
- let solidity_fields = fields.enumerate().map(|(i, f)| {
- let name = f
- .ident
- .as_ref()
- .map(|i| i.to_string())
- .unwrap_or_else(|| format!("field_{i}"));
- let ty = &f.ty;
- let docs = extract_docs(&f.attrs).expect("TODO: handle bad docs");
- quote! {
- SolidityStructField::<#ty> {
- docs: &[#(#docs),*],
- name: #name,
- ty: ::core::marker::PhantomData,
- }
- }
- });
- quote! {
- #[cfg(feature = "stubgen")]
- impl ::evm_coder::solidity::SolidityStructTy for #name {
- /// Generate solidity definitions for methods described in this struct
- fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector) -> String {
- use evm_coder::solidity::*;
- use core::fmt::Write;
- let interface = SolidityStruct {
- docs: &[#(#docs),*],
- name: #solidity_name,
- fields: (#(
- #solidity_fields,
- )*),
- };
- let mut out = String::new();
- let _ = interface.format(&mut out, tc);
- tc.collect(out);
- #solidity_name.to_string()
- }
- }
- }
-}
-
-pub fn impl_struct_solidity_type_name<'a>(
- name: &syn::Ident,
- field_types: impl Iterator<Item = &'a syn::Type> + Clone,
- params_count: usize,
-) -> proc_macro2::TokenStream {
- let arg_dafaults = field_types.enumerate().map(|(i, ty)| {
- let mut defult_value = quote!(<#ty as ::evm_coder::solidity::SolidityTypeName
- >::solidity_default(writer, tc)?;);
- let last_item = params_count - 1;
- if i != last_item {
- defult_value.extend(quote! {write!(writer, ",")?;})
- }
- defult_value
- });
-
- quote! {
- #[cfg(feature = "stubgen")]
- impl ::evm_coder::solidity::SolidityTypeName for #name {
- fn solidity_name(
- writer: &mut impl ::core::fmt::Write,
- tc: &::evm_coder::solidity::TypeCollector,
- ) -> ::core::fmt::Result {
- write!(writer, "{}", tc.collect_struct::<Self>())
- }
-
- fn is_simple() -> bool {
- false
- }
-
- fn solidity_default(
- writer: &mut impl ::core::fmt::Write,
- tc: &::evm_coder::solidity::TypeCollector,
- ) -> ::core::fmt::Result {
- write!(writer, "{}(", tc.collect_struct::<Self>())?;
-
- #(#arg_dafaults)*
-
- write!(writer, ")")
- }
- }
- }
-}
crates/evm-coder/procedural/src/abi_derive/mod.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/abi_derive/mod.rs
+++ /dev/null
@@ -1,118 +0,0 @@
-mod derive_enum;
-mod derive_struct;
-
-use quote::quote;
-use derive_struct::*;
-use derive_enum::*;
-
-pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
- let name = &ast.ident;
- match &ast.data {
- syn::Data::Struct(ds) => expand_struct(ds, ast),
- syn::Data::Enum(de) => expand_enum(de, ast),
- syn::Data::Union(_) => Err(syn::Error::new(name.span(), "Unions not supported")),
- }
-}
-
-fn expand_struct(
- ds: &syn::DataStruct,
- ast: &syn::DeriveInput,
-) -> syn::Result<proc_macro2::TokenStream> {
- let name = &ast.ident;
- let docs = extract_docs(&ast.attrs)?;
- let (is_named_fields, field_names, field_types, params_count) = match ds.fields {
- syn::Fields::Named(ref fields) => Ok((
- true,
- fields.named.iter().enumerate().map(map_field_to_name),
- fields.named.iter().map(map_field_to_type),
- fields.named.len(),
- )),
- syn::Fields::Unnamed(ref fields) => Ok((
- false,
- fields.unnamed.iter().enumerate().map(map_field_to_name),
- fields.unnamed.iter().map(map_field_to_type),
- fields.unnamed.len(),
- )),
- syn::Fields::Unit => Err(syn::Error::new(name.span(), "Unit structs not supported")),
- }?;
-
- if params_count == 0 {
- return Err(syn::Error::new(name.span(), "Empty structs not supported"));
- };
-
- let tuple_type = tuple_type(field_types.clone());
- let tuple_ref_type = tuple_ref_type(field_types.clone());
- let tuple_data = tuple_data_as_ref(is_named_fields, field_names.clone());
- let tuple_names = tuple_names(is_named_fields, field_names.clone());
- let struct_from_tuple = struct_from_tuple(name, is_named_fields, field_names.clone());
-
- let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
- let abi_type = impl_struct_abi_type(name, tuple_type.clone());
- let abi_read = impl_struct_abi_read(name, tuple_type, tuple_names, struct_from_tuple);
- let abi_write = impl_struct_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);
- let solidity_type = impl_struct_solidity_type(name, docs, ds.fields.iter());
- let solidity_type_name =
- impl_struct_solidity_type_name(name, field_types.clone(), params_count);
-
- Ok(quote! {
- #can_be_plcaed_in_vec
- #abi_type
- #abi_read
- #abi_write
- #solidity_type
- #solidity_type_name
- })
-}
-
-fn expand_enum(
- de: &syn::DataEnum,
- ast: &syn::DeriveInput,
-) -> syn::Result<proc_macro2::TokenStream> {
- let name = &ast.ident;
- check_repr_u8(name, &ast.attrs)?;
- check_enum_fields(de)?;
- let docs = extract_docs(&ast.attrs)?;
- let enum_options = de.variants.iter();
-
- let from = impl_enum_from_u8(name, enum_options.clone());
- let solidity_option = impl_solidity_option(docs, name, enum_options.clone());
- let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
- let abi_type = impl_enum_abi_type(name);
- let abi_read = impl_enum_abi_read(name);
- let abi_write = impl_enum_abi_write(name);
- let solidity_type_name = impl_enum_solidity_type_name(name);
-
- Ok(quote! {
- #from
- #solidity_option
- #can_be_plcaed_in_vec
- #abi_type
- #abi_read
- #abi_write
- #solidity_type_name
- })
-}
-
-fn extract_docs(attrs: &[syn::Attribute]) -> syn::Result<Vec<String>> {
- attrs
- .iter()
- .filter_map(|attr| {
- if let Some(ps) = attr.path.segments.first() {
- if ps.ident == "doc" {
- let meta = match attr.parse_meta() {
- Ok(meta) => meta,
- Err(e) => return Some(Err(e)),
- };
- match meta {
- syn::Meta::NameValue(mnv) => match &mnv.lit {
- syn::Lit::Str(ls) => return Some(Ok(ls.value())),
- _ => unreachable!(),
- },
- _ => unreachable!(),
- }
- }
- }
- None
- })
- .collect()
-}
crates/evm-coder/procedural/src/lib.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/lib.rs
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![allow(dead_code)]
-
-use inflector::cases;
-use proc_macro::TokenStream;
-use quote::quote;
-use sha3::{Digest, Keccak256};
-use syn::{
- DeriveInput, GenericArgument, Ident, ItemImpl, Pat, Path, PathArguments, PathSegment, Type,
- parse_macro_input, spanned::Spanned,
-};
-
-mod abi_derive;
-mod solidity_interface;
-mod to_log;
-
-fn fn_selector_str(input: &str) -> u32 {
- let mut hasher = Keccak256::new();
- hasher.update(input.as_bytes());
- let result = hasher.finalize();
-
- let mut selector_bytes = [0; 4];
- selector_bytes.copy_from_slice(&result[0..4]);
-
- u32::from_be_bytes(selector_bytes)
-}
-
-/// Returns solidity function selector (first 4 bytes of hash) by its
-/// textual representation
-///
-/// ```ignore
-/// use evm_coder_macros::fn_selector;
-///
-/// assert_eq!(fn_selector!(transfer(address, uint256)), 0xa9059cbb);
-/// ```
-#[proc_macro]
-pub fn fn_selector(input: TokenStream) -> TokenStream {
- let input = input.to_string().replace(' ', "");
- let selector = fn_selector_str(&input);
-
- (quote! {
- #selector
- })
- .into()
-}
-
-fn event_selector_str(input: &str) -> [u8; 32] {
- let mut hasher = Keccak256::new();
- hasher.update(input.as_bytes());
- let result = hasher.finalize();
-
- let mut selector_bytes = [0; 32];
- selector_bytes.copy_from_slice(&result[0..32]);
- selector_bytes
-}
-
-/// Returns solidity topic (hash) by its textual representation
-///
-/// ```ignore
-/// use evm_coder_macros::event_topic;
-///
-/// assert_eq!(
-/// format!("{:x}", event_topic!(Transfer(address, address, uint256))),
-/// "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
-/// );
-/// ```
-#[proc_macro]
-pub fn event_topic(stream: TokenStream) -> TokenStream {
- let input = stream.to_string().replace(' ', "");
- let selector_bytes = event_selector_str(&input);
-
- (quote! {
- ::primitive_types::H256([#(
- #selector_bytes,
- )*])
- })
- .into()
-}
-
-fn parse_path(ty: &Type) -> syn::Result<&Path> {
- match &ty {
- syn::Type::Path(pat) => {
- if let Some(qself) = &pat.qself {
- return Err(syn::Error::new(qself.ty.span(), "no receiver expected"));
- }
- Ok(&pat.path)
- }
- _ => Err(syn::Error::new(ty.span(), "expected ty to be path")),
- }
-}
-
-fn parse_path_segment(path: &Path) -> syn::Result<&PathSegment> {
- if path.segments.len() != 1 {
- return Err(syn::Error::new(
- path.span(),
- "expected path to have only one segment",
- ));
- }
- let last_segment = &path.segments.last().unwrap();
- Ok(last_segment)
-}
-
-fn parse_ident_from_pat(pat: &Pat) -> syn::Result<&Ident> {
- match pat {
- Pat::Ident(i) => Ok(&i.ident),
- _ => Err(syn::Error::new(pat.span(), "expected pat ident")),
- }
-}
-
-fn parse_ident_from_segment(segment: &PathSegment, allow_generics: bool) -> syn::Result<&Ident> {
- if segment.arguments != PathArguments::None && !allow_generics {
- return Err(syn::Error::new(
- segment.arguments.span(),
- "unexpected generic type",
- ));
- }
- Ok(&segment.ident)
-}
-
-fn parse_ident_from_path(path: &Path, allow_generics: bool) -> syn::Result<&Ident> {
- let segment = parse_path_segment(path)?;
- parse_ident_from_segment(segment, allow_generics)
-}
-
-fn parse_ident_from_type(ty: &Type, allow_generics: bool) -> syn::Result<&Ident> {
- let path = parse_path(ty)?;
- parse_ident_from_path(path, allow_generics)
-}
-
-// Gets T out of Result<T>
-fn parse_result_ok(ty: &Type) -> syn::Result<&Type> {
- let path = parse_path(ty)?;
- let segment = parse_path_segment(path)?;
-
- if segment.ident != "Result" {
- return Err(syn::Error::new(
- ty.span(),
- "expected Result as return type (no renamed aliases allowed)",
- ));
- }
- let args = match &segment.arguments {
- PathArguments::AngleBracketed(e) => e,
- _ => {
- return Err(syn::Error::new(
- segment.arguments.span(),
- "missing Result generics",
- ))
- }
- };
-
- let args = &args.args;
- let arg = args.first().unwrap();
-
- let ty = match arg {
- GenericArgument::Type(ty) => ty,
- _ => {
- return Err(syn::Error::new(
- arg.span(),
- "expected first generic to be type",
- ))
- }
- };
-
- Ok(ty)
-}
-
-fn pascal_ident_to_call(ident: &Ident) -> Ident {
- let name = format!("{}Call", ident);
- Ident::new(&name, ident.span())
-}
-fn snake_ident_to_pascal(ident: &Ident) -> Ident {
- let name = ident.to_string();
- let name = cases::pascalcase::to_pascal_case(&name);
- Ident::new(&name, ident.span())
-}
-fn snake_ident_to_screaming(ident: &Ident) -> Ident {
- let name = ident.to_string();
- let name = cases::screamingsnakecase::to_screaming_snake_case(&name);
- Ident::new(&name, ident.span())
-}
-fn pascal_ident_to_snake_call(ident: &Ident) -> Ident {
- let name = ident.to_string();
- let name = cases::snakecase::to_snake_case(&name);
- let name = format!("call_{}", name);
- Ident::new(&name, ident.span())
-}
-
-/// See documentation for this proc-macro reexported in `evm-coder` crate
-#[proc_macro_attribute]
-pub fn solidity_interface(args: TokenStream, stream: TokenStream) -> TokenStream {
- let args = parse_macro_input!(args as solidity_interface::InterfaceInfo);
-
- let input: ItemImpl = match syn::parse(stream) {
- Ok(t) => t,
- Err(e) => return e.to_compile_error().into(),
- };
-
- let expanded = match solidity_interface::SolidityInterface::try_from(args, &input) {
- Ok(v) => v.expand(),
- Err(e) => e.to_compile_error(),
- };
-
- (quote! {
- #input
-
- #expanded
- })
- .into()
-}
-
-#[proc_macro_attribute]
-pub fn solidity(_args: TokenStream, stream: TokenStream) -> TokenStream {
- stream
-}
-#[proc_macro_attribute]
-pub fn weight(_args: TokenStream, stream: TokenStream) -> TokenStream {
- stream
-}
-
-/// See documentation for this proc-macro reexported in `evm-coder` crate
-#[proc_macro_derive(ToLog, attributes(indexed))]
-pub fn to_log(value: TokenStream) -> TokenStream {
- let input = parse_macro_input!(value as DeriveInput);
-
- match to_log::Events::try_from(&input) {
- Ok(e) => e.expand(),
- Err(e) => e.to_compile_error(),
- }
- .into()
-}
-
-#[proc_macro_derive(AbiCoder)]
-pub fn abi_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- let ast = syn::parse(input).unwrap();
- let ts = match abi_derive::impl_abi_macro(&ast) {
- Ok(e) => e,
- Err(e) => e.to_compile_error(),
- };
- ts.into()
-}
crates/evm-coder/procedural/src/solidity_interface.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/solidity_interface.rs
+++ /dev/null
@@ -1,1099 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![allow(dead_code)]
-
-// NOTE: In order to understand this Rust macro better, first read this chapter
-// about Procedural Macros in Rust book:
-// https://doc.rust-lang.org/reference/procedural-macros.html
-
-use proc_macro2::TokenStream;
-use quote::{quote, format_ident};
-use inflector::cases;
-use syn::{
- Expr, FnArg, Generics, Ident, ImplItem, ImplItemMethod, ItemImpl, Lit, Meta, MetaNameValue,
- PatType, ReturnType, Type,
- spanned::Spanned,
- parse::{Parse, ParseStream},
- parenthesized, Token, LitInt, LitStr,
-};
-
-use crate::{
- parse_ident_from_pat, parse_ident_from_path, parse_path, parse_path_segment, parse_result_ok,
- pascal_ident_to_call, pascal_ident_to_snake_call, snake_ident_to_pascal,
- snake_ident_to_screaming,
-};
-
-struct Is {
- name: Ident,
- pascal_call_name: Ident,
- snake_call_name: Ident,
- via: Option<(Type, Ident)>,
- condition: Option<Expr>,
-}
-impl Is {
- fn expand_call_def(&self, gen_ref: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
- let name = &self.name;
- let pascal_call_name = &self.pascal_call_name;
- quote! {
- #name(#pascal_call_name #gen_ref)
- }
- }
-
- fn expand_interface_id(&self) -> proc_macro2::TokenStream {
- let pascal_call_name = &self.pascal_call_name;
- quote! {
- interface_id ^= u32::from_be_bytes(#pascal_call_name::interface_id());
- }
- }
-
- fn expand_supports_interface(
- &self,
- generics: &proc_macro2::TokenStream,
- ) -> proc_macro2::TokenStream {
- let pascal_call_name = &self.pascal_call_name;
- let condition = self.condition.as_ref().map(|condition| {
- quote! {
- (#condition) &&
- }
- });
- quote! {
- #condition <#pascal_call_name #generics>::supports_interface(this, interface_id)
- }
- }
-
- fn expand_variant_weight(&self) -> proc_macro2::TokenStream {
- let name = &self.name;
- quote! {
- Self::#name(call) => call.weight()
- }
- }
-
- fn expand_variant_call(
- &self,
- call_name: &proc_macro2::Ident,
- generics: &proc_macro2::TokenStream,
- ) -> proc_macro2::TokenStream {
- let name = &self.name;
- let pascal_call_name = &self.pascal_call_name;
- let via_typ = self
- .via
- .as_ref()
- .map(|(t, _)| quote! {#t})
- .unwrap_or_else(|| quote! {Self});
- let via_map = self
- .via
- .as_ref()
- .map(|(_, i)| quote! {.#i()})
- .unwrap_or_default();
- let condition = self.condition.as_ref().map(|condition| {
- quote! {
- if ({let this = &self; (#condition)})
- }
- });
- quote! {
- #call_name::#name(call) #condition => return <#via_typ as ::evm_coder::Callable<#pascal_call_name #generics>>::call(self #via_map, Msg {
- call,
- caller: c.caller,
- value: c.value,
- })
- }
- }
-
- fn expand_parse(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
- let name = &self.name;
- let pascal_call_name = &self.pascal_call_name;
- quote! {
- if let Some(parsed_call) = <#pascal_call_name #generics>::parse(method_id, reader)? {
- return Ok(Some(Self::#name(parsed_call)))
- }
- }
- }
-
- fn expand_generator(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
- let pascal_call_name = &self.pascal_call_name;
- quote! {
- <#pascal_call_name #generics>::generate_solidity_interface(tc, is_impl);
- }
- }
-
- fn expand_event_generator(&self) -> proc_macro2::TokenStream {
- let name = &self.name;
- quote! {
- #name::generate_solidity_interface(tc, is_impl);
- }
- }
-}
-
-#[derive(Default)]
-struct IsList(Vec<Is>);
-impl Parse for IsList {
- fn parse(input: ParseStream) -> syn::Result<Self> {
- let mut out = vec![];
- loop {
- if input.is_empty() {
- break;
- }
- let name = input.parse::<Ident>()?;
- let lookahead = input.lookahead1();
-
- let mut condition: Option<Expr> = None;
- let mut via: Option<(Type, Ident)> = None;
-
- if lookahead.peek(syn::token::Paren) {
- let contents;
- parenthesized!(contents in input);
- let input = contents;
-
- while !input.is_empty() {
- let lookahead = input.lookahead1();
- if lookahead.peek(Token![if]) {
- input.parse::<Token![if]>()?;
- let contents;
- parenthesized!(contents in input);
- let contents = contents.parse::<Expr>()?;
-
- if condition.replace(contents).is_some() {
- return Err(syn::Error::new(input.span(), "condition is already set"));
- }
- } else if lookahead.peek(kw::via) {
- input.parse::<kw::via>()?;
- let contents;
- parenthesized!(contents in input);
-
- let method = contents.parse::<Ident>()?;
- contents.parse::<kw::returns>()?;
- let ty = contents.parse::<Type>()?;
-
- if via.replace((ty, method)).is_some() {
- return Err(syn::Error::new(input.span(), "via is already set"));
- }
- } else {
- return Err(lookahead.error());
- }
-
- if input.peek(Token![,]) {
- input.parse::<Token![,]>()?;
- } else if !input.is_empty() {
- return Err(syn::Error::new(input.span(), "expected end"));
- }
- }
- } else if lookahead.peek(Token![,]) || input.is_empty() {
- // Pass
- } else {
- return Err(lookahead.error());
- };
- out.push(Is {
- pascal_call_name: pascal_ident_to_call(&name),
- snake_call_name: pascal_ident_to_snake_call(&name),
- name,
- via,
- condition,
- });
- if input.peek(Token![,]) {
- input.parse::<Token![,]>()?;
- continue;
- } else {
- break;
- }
- }
- Ok(Self(out))
- }
-}
-
-pub struct InterfaceInfo {
- name: Ident,
- is: IsList,
- inline_is: IsList,
- events: IsList,
- expect_selector: Option<u32>,
-}
-impl Parse for InterfaceInfo {
- fn parse(input: ParseStream) -> syn::Result<Self> {
- let mut name = None;
- let mut is = None;
- let mut inline_is = None;
- let mut events = None;
- let mut expect_selector = None;
- // TODO: create proc-macro to optimize proc-macro boilerplate? :D
- loop {
- let lookahead = input.lookahead1();
- if lookahead.peek(kw::name) {
- let k = input.parse::<kw::name>()?;
- input.parse::<Token![=]>()?;
- if name.replace(input.parse::<Ident>()?).is_some() {
- return Err(syn::Error::new(k.span(), "name is already set"));
- }
- } else if lookahead.peek(kw::is) {
- let k = input.parse::<kw::is>()?;
- let contents;
- parenthesized!(contents in input);
- if is.replace(contents.parse::<IsList>()?).is_some() {
- return Err(syn::Error::new(k.span(), "is is already set"));
- }
- } else if lookahead.peek(kw::inline_is) {
- let k = input.parse::<kw::inline_is>()?;
- let contents;
- parenthesized!(contents in input);
- if inline_is.replace(contents.parse::<IsList>()?).is_some() {
- return Err(syn::Error::new(k.span(), "inline_is is already set"));
- }
- } else if lookahead.peek(kw::events) {
- let k = input.parse::<kw::events>()?;
- let contents;
- parenthesized!(contents in input);
- if events.replace(contents.parse::<IsList>()?).is_some() {
- return Err(syn::Error::new(k.span(), "events is already set"));
- }
- } else if lookahead.peek(kw::expect_selector) {
- let k = input.parse::<kw::expect_selector>()?;
- input.parse::<Token![=]>()?;
- let value = input.parse::<LitInt>()?;
- if expect_selector
- .replace(value.base10_parse::<u32>()?)
- .is_some()
- {
- return Err(syn::Error::new(k.span(), "expect_selector is already set"));
- }
- } else if input.is_empty() {
- break;
- } else {
- return Err(lookahead.error());
- }
- if input.peek(Token![,]) {
- input.parse::<Token![,]>()?;
- } else {
- break;
- }
- }
- Ok(Self {
- name: name.ok_or_else(|| syn::Error::new(input.span(), "missing name"))?,
- is: is.unwrap_or_default(),
- inline_is: inline_is.unwrap_or_default(),
- events: events.unwrap_or_default(),
- expect_selector,
- })
- }
-}
-
-struct MethodInfo {
- rename_selector: Option<String>,
- hide: bool,
-}
-impl Parse for MethodInfo {
- fn parse(input: ParseStream) -> syn::Result<Self> {
- let mut rename_selector = None;
- let mut hide = false;
- while !input.is_empty() {
- let lookahead = input.lookahead1();
- if lookahead.peek(kw::rename_selector) {
- let k = input.parse::<kw::rename_selector>()?;
- input.parse::<Token![=]>()?;
- if rename_selector
- .replace(input.parse::<LitStr>()?.value())
- .is_some()
- {
- return Err(syn::Error::new(k.span(), "rename_selector is already set"));
- }
- } else if lookahead.peek(kw::hide) {
- input.parse::<kw::hide>()?;
- hide = true;
- } else {
- return Err(lookahead.error());
- }
-
- if input.peek(Token![,]) {
- input.parse::<Token![,]>()?;
- } else if !input.is_empty() {
- return Err(syn::Error::new(input.span(), "expected end"));
- }
- }
- Ok(Self {
- rename_selector,
- hide,
- })
- }
-}
-
-trait AbiTypeHelper {
- fn plain(&self) -> syn::Result<&Ident>;
- fn is_value(&self) -> bool;
- fn is_caller(&self) -> bool;
- fn is_special(&self) -> bool;
-}
-
-impl AbiTypeHelper for Type {
- fn plain(&self) -> syn::Result<&Ident> {
- let path = parse_path(self)?;
- let segment = parse_path_segment(path)?;
- if !segment.arguments.is_empty() {
- return Err(syn::Error::new(self.span(), "Not plain type"));
- }
- Ok(&segment.ident)
- }
-
- fn is_value(&self) -> bool {
- if let Ok(ident) = self.plain() {
- return ident == "Value";
- }
- false
- }
-
- fn is_caller(&self) -> bool {
- if let Ok(ident) = self.plain() {
- return ident == "Caller";
- }
- false
- }
-
- fn is_special(&self) -> bool {
- self.is_caller() || self.is_value()
- }
-}
-
-#[derive(Debug)]
-struct MethodArg {
- name: Ident,
- camel_name: String,
- ty: Type,
-}
-impl MethodArg {
- fn try_from(value: &PatType) -> syn::Result<Self> {
- let name = parse_ident_from_pat(&value.pat)?.clone();
- Ok(Self {
- camel_name: cases::camelcase::to_camel_case(&name.to_string()),
- name,
- ty: value.ty.as_ref().clone(),
- })
- }
- fn is_value(&self) -> bool {
- self.ty.is_value()
- }
- fn is_caller(&self) -> bool {
- self.ty.is_caller()
- }
- fn is_special(&self) -> bool {
- self.ty.is_special()
- }
-
- fn expand_call_def(&self) -> proc_macro2::TokenStream {
- assert!(!self.is_special());
- let name = &self.name;
- let ty = &self.ty;
-
- quote! {
- #name: #ty
- }
- }
-
- fn expand_parse(&self) -> proc_macro2::TokenStream {
- assert!(!self.is_special());
- let name = &self.name;
- let ty = &self.ty;
- quote! {
- #name: {
- let value = <#ty as ::evm_coder::abi::AbiRead>::abi_read(reader)?;
- if !is_dynamic {reader.bytes_read(<#ty as ::evm_coder::abi::AbiType>::size())};
- value
- }
- }
- }
-
- fn expand_call_arg(&self) -> proc_macro2::TokenStream {
- if self.is_value() {
- quote! {
- c.value.clone()
- }
- } else if self.is_caller() {
- quote! {
- c.caller.clone()
- }
- } else {
- let name = &self.name;
- quote! {
- #name
- }
- }
- }
-
- fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
- let camel_name = &self.camel_name.to_string();
- let ty = &self.ty;
- quote! {
- <NamedArgument<#ty>>::new(#camel_name)
- }
- }
-}
-
-#[derive(PartialEq)]
-enum Mutability {
- Mutable,
- View,
- Pure,
-}
-
-/// Group all keywords for this macro. Usage example:
-/// #[solidity_interface(name = "B", inline_is(A))]
-mod kw {
- syn::custom_keyword!(weight);
-
- syn::custom_keyword!(via);
- syn::custom_keyword!(returns);
- syn::custom_keyword!(name);
- syn::custom_keyword!(is);
- syn::custom_keyword!(inline_is);
- syn::custom_keyword!(events);
- syn::custom_keyword!(expect_selector);
-
- syn::custom_keyword!(rename_selector);
- syn::custom_keyword!(hide);
-}
-
-/// Rust methods are parsed into this structure when Solidity code is generated
-struct Method {
- name: Ident,
- camel_name: String,
- pascal_name: Ident,
- screaming_name: Ident,
- hide: bool,
- args: Vec<MethodArg>,
- has_normal_args: bool,
- has_value_args: bool,
- mutability: Mutability,
- result: Type,
- weight: Option<Expr>,
- docs: Vec<String>,
-}
-impl Method {
- fn try_from(value: &ImplItemMethod) -> syn::Result<Self> {
- let mut info = MethodInfo {
- rename_selector: None,
- hide: false,
- };
- let mut docs = Vec::new();
- let mut weight = None;
- for attr in &value.attrs {
- let ident = parse_ident_from_path(&attr.path, false)?;
- if ident == "solidity" {
- info = attr.parse_args::<MethodInfo>()?;
- } else if ident == "doc" {
- let args = attr.parse_meta().unwrap();
- let value = match args {
- Meta::NameValue(MetaNameValue {
- lit: Lit::Str(str), ..
- }) => str.value(),
- _ => unreachable!(),
- };
- docs.push(value);
- } else if ident == "weight" {
- weight = Some(attr.parse_args::<Expr>()?);
- }
- }
- let ident = &value.sig.ident;
- let ident_str = ident.to_string();
- if !cases::snakecase::is_snake_case(&ident_str) {
- return Err(syn::Error::new(ident.span(), "method name should be snake_cased\nif alternative solidity name needs to be set - use #[solidity] attribute"));
- }
-
- let mut mutability = Mutability::Pure;
-
- if let Some(FnArg::Receiver(receiver)) = value
- .sig
- .inputs
- .iter()
- .find(|arg| matches!(arg, FnArg::Receiver(_)))
- {
- if receiver.reference.is_none() {
- return Err(syn::Error::new(
- receiver.span(),
- "receiver should be by ref",
- ));
- }
- if receiver.mutability.is_some() {
- mutability = Mutability::Mutable;
- } else {
- mutability = Mutability::View;
- }
- }
- let mut args = Vec::new();
- for typ in value
- .sig
- .inputs
- .iter()
- .filter(|arg| matches!(arg, FnArg::Typed(_)))
- {
- let typ = match typ {
- FnArg::Typed(typ) => typ,
- _ => unreachable!(),
- };
- args.push(MethodArg::try_from(typ)?);
- }
-
- if mutability != Mutability::Mutable && args.iter().any(|arg| arg.is_value()) {
- return Err(syn::Error::new(
- args.iter().find(|arg| arg.is_value()).unwrap().ty.span(),
- "payable function should be mutable",
- ));
- }
-
- let result = match &value.sig.output {
- ReturnType::Type(_, ty) => ty,
- _ => return Err(syn::Error::new(value.sig.output.span(), "interface method should return Result<value>\nif there is no value to return - specify void (which is alias to unit)")),
- };
- let result = parse_result_ok(result)?;
-
- let camel_name = info
- .rename_selector
- .unwrap_or_else(|| cases::camelcase::to_camel_case(&ident.to_string()));
- let has_normal_args = args.iter().filter(|arg| !arg.is_special()).count() != 0;
- let has_value_args = args.iter().any(|a| a.is_value());
-
- Ok(Self {
- name: ident.clone(),
- camel_name,
- pascal_name: snake_ident_to_pascal(ident),
- screaming_name: snake_ident_to_screaming(ident),
- hide: info.hide,
- args,
- has_normal_args,
- has_value_args,
- mutability,
- result: result.clone(),
- weight,
- docs,
- })
- }
- fn expand_call_def(&self) -> proc_macro2::TokenStream {
- let defs = self
- .args
- .iter()
- .filter(|a| !a.is_special())
- .map(|a| a.expand_call_def());
- let pascal_name = &self.pascal_name;
- let docs = &self.docs;
-
- if self.has_normal_args {
- quote! {
- #(#[doc = #docs])*
- #[allow(missing_docs)]
- #pascal_name {
- #(
- #defs,
- )*
- }
- }
- } else {
- quote! {
- #(#[doc = #docs])*
- #[allow(missing_docs)]
- #pascal_name
- }
- }
- }
-
- fn expand_const(&self) -> proc_macro2::TokenStream {
- let screaming_name = &self.screaming_name;
- let screaming_name_signature = format_ident!("{}_SIGNATURE", &self.screaming_name);
- let custom_signature = self.expand_custom_signature();
- quote! {
- const #screaming_name_signature: ::evm_coder::custom_signature::SignatureUnit = #custom_signature;
- const #screaming_name: ::evm_coder::types::Bytes4 = {
- let mut sum = ::evm_coder::sha3_const::Keccak256::new();
- let mut pos = 0;
- while pos < Self::#screaming_name_signature.len {
- sum = sum.update(&[Self::#screaming_name_signature.data[pos]; 1]);
- pos += 1;
- }
- let a = sum.finalize();
- [a[0], a[1], a[2], a[3]]
- };
- }
- }
-
- fn expand_interface_id(&self) -> proc_macro2::TokenStream {
- let screaming_name = &self.screaming_name;
- quote! {
- interface_id ^= u32::from_be_bytes(Self::#screaming_name);
- }
- }
-
- fn expand_parse(&self) -> proc_macro2::TokenStream {
- let pascal_name = &self.pascal_name;
- let screaming_name = &self.screaming_name;
- if self.has_normal_args {
- let args_iter = self.args.iter().filter(|a| !a.is_special());
- let arg_type = args_iter.clone().map(|a| &a.ty);
- let parsers = args_iter.map(|a| a.expand_parse());
- quote! {
- Self::#screaming_name => {
- let is_dynamic = false #(|| <#arg_type as ::evm_coder::abi::AbiType>::is_dynamic())*;
- return Ok(Some(Self::#pascal_name {
- #(
- #parsers,
- )*
- }))
- }
- }
- } else {
- quote! { Self::#screaming_name => return Ok(Some(Self::#pascal_name)) }
- }
- }
-
- fn expand_variant_call(&self, call_name: &proc_macro2::Ident) -> proc_macro2::TokenStream {
- let pascal_name = &self.pascal_name;
- let name = &self.name;
-
- let matcher = if self.has_normal_args {
- let names = self
- .args
- .iter()
- .filter(|a| !a.is_special())
- .map(|a| &a.name);
-
- quote! {{
- #(
- #names,
- )*
- }}
- } else {
- quote! {}
- };
-
- let receiver = match self.mutability {
- Mutability::Mutable | Mutability::View => quote! {self.},
- Mutability::Pure => quote! {Self::},
- };
- let args = self.args.iter().map(|a| a.expand_call_arg());
-
- quote! {
- #call_name::#pascal_name #matcher => {
- #[allow(deprecated)]
- let result = #receiver #name(
- #(
- #args,
- )*
- )?;
- (&result).to_result()
- }
- }
- }
-
- fn expand_variant_weight(&self) -> proc_macro2::TokenStream {
- let pascal_name = &self.pascal_name;
- if let Some(weight) = &self.weight {
- let matcher = if self.has_normal_args {
- let names = self
- .args
- .iter()
- .filter(|a| !a.is_special())
- .map(|a| &a.name);
-
- quote! {{
- #(
- #names,
- )*
- }}
- } else {
- quote! {}
- };
- quote! {
- Self::#pascal_name #matcher => (#weight).into()
- }
- } else {
- let matcher = if self.has_normal_args {
- quote! {{..}}
- } else {
- quote! {}
- };
- quote! {
- Self::#pascal_name #matcher => ().into()
- }
- }
- }
-
- fn expand_custom_signature(&self) -> proc_macro2::TokenStream {
- let mut args = TokenStream::new();
-
- let mut has_params = false;
- for arg in self.args.iter().filter(|a| !a.is_special()) {
- has_params = true;
- let ty = &arg.ty;
- args.extend(quote! {nameof(<#ty>::SIGNATURE)});
- args.extend(quote! {fixed(",")})
- }
-
- // Remove trailing comma
- if has_params {
- args.extend(quote! {shift_left(1)})
- }
-
- let func_name = self.camel_name.clone();
- quote! { ::evm_coder::make_signature!(new fixed(#func_name) fixed("(") #args fixed(")")) }
- }
-
- fn expand_solidity_function(&self) -> proc_macro2::TokenStream {
- let camel_name = &self.camel_name;
- let mutability = match self.mutability {
- Mutability::Mutable => quote! {SolidityMutability::Mutable},
- Mutability::View => quote! { SolidityMutability::View },
- Mutability::Pure => quote! {SolidityMutability::Pure},
- };
- let result = &self.result;
-
- let args = self
- .args
- .iter()
- .filter(|a| !a.is_special())
- .map(MethodArg::expand_solidity_argument);
- let docs = &self.docs;
- let screaming_name = &self.screaming_name;
- let hide = self.hide;
- let custom_signature = self.expand_custom_signature();
- let is_payable = self.has_value_args;
-
- quote! {
- SolidityFunction {
- docs: &[#(#docs),*],
- hide: #hide,
- selector: u32::from_be_bytes(Self::#screaming_name),
- custom_signature: #custom_signature,
- name: #camel_name,
- mutability: #mutability,
- is_payable: #is_payable,
- args: (
- #(
- #args,
- )*
- ),
- result: <UnnamedArgument<#result>>::default(),
- }
- }
- }
-}
-
-fn generics_list(gen: &Generics) -> proc_macro2::TokenStream {
- if gen.params.is_empty() {
- return quote! {};
- }
- let params = gen.params.iter().map(|p| match p {
- syn::GenericParam::Type(id) => {
- let v = &id.ident;
- quote! {#v}
- }
- syn::GenericParam::Lifetime(lt) => {
- let v = <.lifetime;
- quote! {#v}
- }
- syn::GenericParam::Const(c) => {
- let i = &c.ident;
- quote! {#i}
- }
- });
- quote! { #(#params),* }
-}
-fn generics_reference(gen: &Generics) -> proc_macro2::TokenStream {
- if gen.params.is_empty() {
- return quote! {};
- }
- let list = generics_list(gen);
- quote! { <#list> }
-}
-fn generics_stub(gen: &Generics) -> proc_macro2::TokenStream {
- if gen.params.is_empty() {
- return quote! {};
- }
- let params = (0..gen.params.len()).map(|_| quote! {()});
- quote! {<#(#params,)*>}
-}
-fn generics_data(gen: &Generics) -> proc_macro2::TokenStream {
- let list = generics_list(gen);
- if gen.params.len() == 1 {
- quote! {#list}
- } else {
- quote! { (#list) }
- }
-}
-
-pub struct SolidityInterface {
- generics: Generics,
- name: Box<syn::Type>,
- info: InterfaceInfo,
- methods: Vec<Method>,
- docs: Vec<String>,
-}
-impl SolidityInterface {
- pub fn try_from(info: InterfaceInfo, value: &ItemImpl) -> syn::Result<Self> {
- let mut methods = Vec::new();
-
- for item in &value.items {
- if let ImplItem::Method(method) = item {
- methods.push(Method::try_from(method)?)
- }
- }
- let mut docs = vec![];
- for attr in &value.attrs {
- let ident = parse_ident_from_path(&attr.path, false)?;
- if ident == "doc" {
- let args = attr.parse_meta().unwrap();
- let value = match args {
- Meta::NameValue(MetaNameValue {
- lit: Lit::Str(str), ..
- }) => str.value(),
- _ => unreachable!(),
- };
- docs.push(value);
- }
- }
- Ok(Self {
- generics: value.generics.clone(),
- name: value.self_ty.clone(),
- info,
- methods,
- docs,
- })
- }
- pub fn expand(self) -> proc_macro2::TokenStream {
- let name = self.name;
-
- let solidity_name = self.info.name.to_string();
- let call_name = pascal_ident_to_call(&self.info.name);
- let generics = self.generics;
- let gen_ref = generics_reference(&generics);
- let gen_data = generics_data(&generics);
- let gen_stub = generics_stub(&generics);
- let gen_where = &generics.where_clause;
-
- let call_sub = self
- .info
- .inline_is
- .0
- .iter()
- .chain(self.info.is.0.iter())
- .map(|c| Is::expand_call_def(c, &gen_ref));
- let call_parse = self
- .info
- .inline_is
- .0
- .iter()
- .chain(self.info.is.0.iter())
- .map(|is| Is::expand_parse(is, &gen_ref));
- let call_variants = self
- .info
- .inline_is
- .0
- .iter()
- .chain(self.info.is.0.iter())
- .map(|c| Is::expand_variant_call(c, &call_name, &gen_ref));
- let weight_variants = self
- .info
- .inline_is
- .0
- .iter()
- .chain(self.info.is.0.iter())
- .map(Is::expand_variant_weight);
-
- let inline_interface_id = self.info.inline_is.0.iter().map(Is::expand_interface_id);
- let supports_interface = self
- .info
- .is
- .0
- .iter()
- .map(|is| Is::expand_supports_interface(is, &gen_ref));
-
- let calls = self.methods.iter().map(Method::expand_call_def);
- let consts = self.methods.iter().map(Method::expand_const);
- let interface_id = self.methods.iter().map(Method::expand_interface_id);
- let parsers = self.methods.iter().map(Method::expand_parse);
- let call_variants_this = self
- .methods
- .iter()
- .map(|m| Method::expand_variant_call(m, &call_name));
- let weight_variants_this = self.methods.iter().map(Method::expand_variant_weight);
- let solidity_functions = self.methods.iter().map(Method::expand_solidity_function);
-
- // TODO: Inline inline_is
- let solidity_is = self
- .info
- .is
- .0
- .iter()
- .chain(self.info.inline_is.0.iter())
- .map(|is| is.name.to_string());
- let solidity_events_is = self.info.events.0.iter().map(|is| is.name.to_string());
- let solidity_generators = self
- .info
- .is
- .0
- .iter()
- .chain(self.info.inline_is.0.iter())
- .map(|is| Is::expand_generator(is, &gen_ref));
- let solidity_event_generators = self.info.events.0.iter().map(Is::expand_event_generator);
- let solidity_events_idents = self.info.events.0.iter().map(|is| is.name.clone());
- let docs = &self.docs;
-
- let expect_selector = self.info.expect_selector.map(|s| {
- quote! {
- const _: () = assert!(#s == u32::from_be_bytes(<#call_name #gen_stub>::interface_id()), "selector mismatch, review contained function selectors");
- }
- });
-
- quote! {
- #(
- const _: ::core::marker::PhantomData<#solidity_events_idents> = ::core::marker::PhantomData;
- )*
- #[derive(Debug)]
- #(#[doc = #docs])*
- pub enum #call_name #gen_ref {
- /// Inherited method
- ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<#gen_data>),
- #(
- #calls,
- )*
- #(
- #call_sub,
- )*
- }
-
- #expect_selector
-
- impl #gen_ref #call_name #gen_ref {
- #(
- #consts
- )*
- /// Return this call ERC165 selector
- pub const fn interface_id() -> ::evm_coder::types::Bytes4 {
- let mut interface_id = 0;
- #(#interface_id)*
- #(#inline_interface_id)*
- u32::to_be_bytes(interface_id)
- }
- /// Generate solidity definitions for methods described in this interface
- #[cfg(feature = "stubgen")]
- pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) {
- use evm_coder::solidity::*;
- use core::fmt::Write;
- let interface = SolidityInterface {
- docs: &[#(#docs),*],
- name: #solidity_name,
- selector: Self::interface_id(),
- is: &["Dummy", "ERC165", #(
- #solidity_is,
- )* #(
- #solidity_events_is,
- )* ],
- functions: (#(
- #solidity_functions,
- )*),
- };
-
- let mut out = ::evm_coder::types::String::new();
- if #solidity_name.starts_with("Inline") {
- out.push_str("/// @dev inlined interface\n");
- }
- let _ = interface.format(is_impl, &mut out, tc);
- tc.collect(out);
- #(
- #solidity_event_generators
- )*
- #(
- #solidity_generators
- )*
- if is_impl {
- tc.collect("/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into());
- } else {
- tc.collect("/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into());
- }
- }
- }
- impl #gen_ref ::evm_coder::Call for #call_name #gen_ref {
- fn parse(method_id: ::evm_coder::types::Bytes4, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {
- use ::evm_coder::abi::AbiRead;
- match method_id {
- ::evm_coder::ERC165Call::INTERFACE_ID => return Ok(
- ::evm_coder::ERC165Call::parse(method_id, reader)?
- .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData))
- ),
- #(
- #parsers,
- )*
- _ => {},
- }
- #(
- #call_parse
- )else*
- return Ok(None);
- }
- }
- impl #generics #call_name #gen_ref
- #gen_where
- {
- /// Is this contract implements specified ERC165 selector
- pub fn supports_interface(this: &#name, interface_id: ::evm_coder::types::Bytes4) -> bool {
- interface_id != u32::to_be_bytes(0xffffff) && (
- interface_id == ::evm_coder::ERC165Call::INTERFACE_ID ||
- interface_id == Self::interface_id()
- #(
- || #supports_interface
- )*
- )
- }
- }
- impl #generics ::evm_coder::Weighted for #call_name #gen_ref
- #gen_where
- {
- #[allow(unused_variables)]
- fn weight(&self) -> ::evm_coder::execution::DispatchInfo {
- match self {
- #(
- #weight_variants,
- )*
- // TODO: It should be very cheap, but not free
- Self::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {..}, _) => ::frame_support::weights::Weight::from_ref_time(100).into(),
- #(
- #weight_variants_this,
- )*
- }
- }
- }
- impl #generics ::evm_coder::Callable<#call_name #gen_ref> for #name
- #gen_where
- {
- #[allow(unreachable_code)] // In case of no inner calls
- fn call(&mut self, c: Msg<#call_name #gen_ref>) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {
- use ::evm_coder::abi::AbiWrite;
- match c.call {
- #(
- #call_variants,
- )*
- #call_name::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {interface_id}, _) => {
- let mut writer = ::evm_coder::abi::AbiWriter::default();
- writer.bool(&<#call_name #gen_ref>::supports_interface(self, interface_id));
- return Ok(writer.into());
- }
- _ => {},
- }
- let mut writer = ::evm_coder::abi::AbiWriter::default();
- match c.call {
- #(
- #call_variants_this,
- )*
- _ => Err(::evm_coder::execution::Error::from("method is not available").into()),
- }
- }
- }
- }
- }
-}
crates/evm-coder/procedural/src/to_log.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/to_log.rs
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-use inflector::cases;
-use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};
-use quote::quote;
-
-use crate::{parse_ident_from_path, parse_ident_from_type, snake_ident_to_screaming};
-
-struct EventField {
- name: Ident,
- camel_name: String,
- ty: Ident,
- indexed: bool,
-}
-
-impl EventField {
- fn try_from(field: &Field) -> syn::Result<Self> {
- let name = field.ident.as_ref().unwrap();
- let ty = parse_ident_from_type(&field.ty, false)?;
- let mut indexed = false;
- for attr in &field.attrs {
- if let Ok(ident) = parse_ident_from_path(&attr.path, false) {
- if ident == "indexed" {
- indexed = true;
- }
- }
- }
- Ok(Self {
- name: name.to_owned(),
- camel_name: cases::camelcase::to_camel_case(&name.to_string()),
- ty: ty.to_owned(),
- indexed,
- })
- }
- fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
- let camel_name = &self.camel_name;
- let ty = &self.ty;
- let indexed = self.indexed;
- quote! {
- <SolidityEventArgument<#ty>>::new(#indexed, #camel_name)
- }
- }
-}
-
-struct Event {
- name: Ident,
- name_screaming: Ident,
- fields: Vec<EventField>,
- selector: proc_macro2::TokenStream,
-}
-
-impl Event {
- fn try_from(variant: &Variant) -> syn::Result<Self> {
- let name = &variant.ident;
- let name_lit = proc_macro2::Literal::string(name.to_string().as_str());
- let name_screaming = snake_ident_to_screaming(name);
-
- let named = match &variant.fields {
- Fields::Named(named) => named,
- _ => {
- return Err(syn::Error::new(
- variant.fields.span(),
- "expected named fields",
- ))
- }
- };
- let mut fields = Vec::new();
- for field in &named.named {
- fields.push(EventField::try_from(field)?);
- }
- if fields.iter().filter(|f| f.indexed).count() > 3 {
- return Err(syn::Error::new(
- variant.fields.span(),
- "events can have at most 4 indexed fields (1 indexed field is reserved for event signature)"
- ));
- }
-
- let args = fields.iter().map(|f| {
- let ty = &f.ty;
- quote! {nameof(<#ty as ::evm_coder::abi::AbiType>::SIGNATURE) fixed(",")}
- });
- // Remove trailing comma
- let shift = (!fields.is_empty()).then(|| quote! {shift_left(1)});
-
- let signature = quote! { ::evm_coder::make_signature!(new fixed(#name_lit) fixed("(") #(#args)* #shift fixed(")")) };
- let selector = quote! {
- {
- let signature = #signature;
- let mut sum = ::evm_coder::sha3_const::Keccak256::new();
- let mut pos = 0;
- while pos < signature.len {
- sum = sum.update(&[signature.data[pos]; 1]);
- pos += 1;
- }
- let a = sum.finalize();
- let mut selector_bytes = [0; 32];
- let mut i = 0;
- while i != 32 {
- selector_bytes[i] = a[i];
- i += 1;
- }
- selector_bytes
- }
- };
-
- Ok(Self {
- name: name.to_owned(),
- name_screaming,
- fields,
- selector,
- })
- }
-
- fn expand_serializers(&self) -> proc_macro2::TokenStream {
- let name = &self.name;
- let name_screaming = &self.name_screaming;
- let fields = self.fields.iter().map(|f| &f.name);
-
- let indexed = self.fields.iter().filter(|f| f.indexed).map(|f| &f.name);
- let plain = self.fields.iter().filter(|f| !f.indexed).map(|f| &f.name);
-
- quote! {
- Self::#name {#(
- #fields,
- )*} => {
- topics.push(::evm_coder::types::Topic::from(Self::#name_screaming));
- #(
- topics.push(#indexed.to_topic());
- )*
- #(
- #plain.abi_write(&mut writer);
- )*
- }
- }
- }
-
- fn expand_consts(&self) -> proc_macro2::TokenStream {
- let name_screaming = &self.name_screaming;
- let selector = &self.selector;
-
- quote! {
- const #name_screaming: [u8; 32] = #selector;
- }
- }
-
- fn expand_solidity_function(&self) -> proc_macro2::TokenStream {
- let name = self.name.to_string();
- let args = self.fields.iter().map(EventField::expand_solidity_argument);
- quote! {
- SolidityEvent {
- name: #name,
- args: (
- #(
- #args,
- )*
- ),
- }
- }
- }
-}
-
-pub struct Events {
- name: Ident,
- events: Vec<Event>,
-}
-
-impl Events {
- pub fn try_from(data: &DeriveInput) -> syn::Result<Self> {
- let name = &data.ident;
- let en = match &data.data {
- Data::Enum(en) => en,
- _ => return Err(syn::Error::new(data.span(), "expected enum")),
- };
- let mut events = Vec::new();
- for variant in &en.variants {
- events.push(Event::try_from(variant)?);
- }
- Ok(Self {
- name: name.to_owned(),
- events,
- })
- }
- pub fn expand(&self) -> proc_macro2::TokenStream {
- let name = &self.name;
-
- let consts = self.events.iter().map(Event::expand_consts);
- let serializers = self.events.iter().map(Event::expand_serializers);
- let solidity_name = self.name.to_string();
- let solidity_functions = self.events.iter().map(Event::expand_solidity_function);
-
- quote! {
- impl #name {
- #(
- #consts
- )*
-
- /// Generate solidity definitions for methods described in this interface
- #[cfg(feature = "stubgen")]
- pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) {
- use evm_coder::solidity::*;
- use core::fmt::Write;
- let interface = SolidityInterface {
- docs: &[],
- selector: [0; 4],
- name: #solidity_name,
- is: &[],
- functions: (#(
- #solidity_functions,
- )*),
- };
- let mut out = ::evm_coder::types::String::new();
- out.push_str("/// @dev inlined interface\n");
- let _ = interface.format(is_impl, &mut out, tc);
- tc.collect(out);
- }
- }
-
- #[automatically_derived]
- impl ::evm_coder::events::ToLog for #name {
- fn to_log(&self, contract: Address) -> ::evm_coder::ethereum::Log {
- use ::evm_coder::events::ToTopic;
- use ::evm_coder::abi::AbiWrite;
- let mut writer = ::evm_coder::abi::AbiWriter::new();
- let mut topics = Vec::new();
- match self {
- #(
- #serializers,
- )*
- }
- ::evm_coder::ethereum::Log {
- address: contract,
- topics,
- data: writer.finish(),
- }
- }
- }
- }
- }
-}
crates/evm-coder/src/abi/impls.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/impls.rs
+++ /dev/null
@@ -1,296 +0,0 @@
-use crate::{
- custom_signature::SignatureUnit,
- execution::{Result, ResultWithPostInfo, WithPostDispatchInfo},
- make_signature, sealed,
- types::*,
-};
-use super::{traits::*, ABI_ALIGNMENT, AbiReader, AbiWriter};
-use primitive_types::{U256, H160};
-
-#[cfg(not(feature = "std"))]
-use alloc::vec::Vec;
-
-macro_rules! impl_abi_type {
- ($ty:ty, $name:ident, $dynamic:literal) => {
- impl sealed::CanBePlacedInVec for $ty {}
-
- impl AbiType for $ty {
- const SIGNATURE: SignatureUnit = make_signature!(new fixed(stringify!($name)));
-
- fn is_dynamic() -> bool {
- $dynamic
- }
-
- fn size() -> usize {
- ABI_ALIGNMENT
- }
- }
- };
-}
-
-macro_rules! impl_abi_readable {
- ($ty:ty, $method:ident) => {
- impl AbiRead for $ty {
- fn abi_read(reader: &mut AbiReader) -> Result<$ty> {
- reader.$method()
- }
- }
- };
-}
-
-macro_rules! impl_abi_writeable {
- ($ty:ty, $method:ident) => {
- impl AbiWrite for $ty {
- fn abi_write(&self, writer: &mut AbiWriter) {
- writer.$method(&self)
- }
- }
- };
-}
-
-macro_rules! impl_abi {
- ($ty:ty, $method:ident, $dynamic:literal) => {
- impl_abi_type!($ty, $method, $dynamic);
- impl_abi_readable!($ty, $method);
- impl_abi_writeable!($ty, $method);
- };
-}
-
-impl_abi!(bool, bool, false);
-impl_abi!(u8, uint8, false);
-impl_abi!(u32, uint32, false);
-impl_abi!(u64, uint64, false);
-impl_abi!(u128, uint128, false);
-impl_abi!(U256, uint256, false);
-impl_abi!(H160, address, false);
-impl_abi!(String, string, true);
-
-impl_abi_writeable!(&str, string);
-
-impl_abi_type!(Bytes, bytes, true);
-
-impl AbiRead for Bytes {
- fn abi_read(reader: &mut AbiReader) -> Result<Bytes> {
- Ok(Bytes(reader.bytes()?))
- }
-}
-
-impl AbiWrite for Bytes {
- fn abi_write(&self, writer: &mut AbiWriter) {
- writer.bytes(self.0.as_slice())
- }
-}
-
-impl_abi_type!(Bytes4, bytes4, false);
-impl AbiRead for Bytes4 {
- fn abi_read(reader: &mut AbiReader) -> Result<Bytes4> {
- reader.bytes4()
- }
-}
-
-impl<T: AbiWrite> AbiWrite for &T {
- fn abi_write(&self, writer: &mut AbiWriter) {
- T::abi_write(self, writer);
- }
-}
-
-impl<T: AbiType> AbiType for &T {
- const SIGNATURE: SignatureUnit = T::SIGNATURE;
-
- fn is_dynamic() -> bool {
- T::is_dynamic()
- }
-
- fn size() -> usize {
- T::size()
- }
-}
-
-impl<T: AbiType + AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<T> {
- fn abi_read(reader: &mut AbiReader) -> Result<Vec<T>> {
- let mut sub = reader.subresult(None)?;
- let size = sub.uint32()? as usize;
- sub.subresult_offset = sub.offset;
- let is_dynamic = <T as AbiType>::is_dynamic();
- let mut out = Vec::with_capacity(size);
- for _ in 0..size {
- out.push(<T as AbiRead>::abi_read(&mut sub)?);
- if !is_dynamic {
- sub.bytes_read(<T as AbiType>::size());
- };
- }
- Ok(out)
- }
-}
-
-impl<T: AbiType> AbiType for Vec<T> {
- const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-
- fn is_dynamic() -> bool {
- true
- }
-
- fn size() -> usize {
- ABI_ALIGNMENT
- }
-}
-
-impl<T: AbiWrite + AbiType> AbiWrite for Vec<T> {
- fn abi_write(&self, writer: &mut AbiWriter) {
- let is_dynamic = T::is_dynamic();
- let mut sub = if is_dynamic {
- AbiWriter::new_dynamic(is_dynamic)
- } else {
- AbiWriter::new()
- };
-
- // Write items count
- (self.len() as u32).abi_write(&mut sub);
-
- for item in self {
- item.abi_write(&mut sub);
- }
- writer.write_subresult(sub);
- }
-}
-
-impl AbiWrite for () {
- fn abi_write(&self, _writer: &mut AbiWriter) {}
-}
-
-/// This particular AbiWrite implementation should be split to another trait,
-/// which only implements `to_result`, but due to lack of specialization feature
-/// in stable Rust, we can't have blanket impl of this trait `for T where T: AbiWrite`,
-/// so here we abusing default trait methods for it
-impl<T: AbiWrite> AbiWrite for ResultWithPostInfo<T> {
- fn abi_write(&self, _writer: &mut AbiWriter) {
- debug_assert!(false, "shouldn't be called, see comment")
- }
- fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {
- match self {
- Ok(v) => Ok(WithPostDispatchInfo {
- post_info: v.post_info.clone(),
- data: {
- let mut out = AbiWriter::new();
- v.data.abi_write(&mut out);
- out
- },
- }),
- Err(e) => Err(e.clone()),
- }
- }
-}
-
-macro_rules! impl_tuples {
- ($($ident:ident)+) => {
- impl<$($ident: AbiType,)+> AbiType for ($($ident,)+)
- where
- $(
- $ident: AbiType,
- )+
- {
- const SIGNATURE: SignatureUnit = make_signature!(
- new fixed("(")
- $(nameof(<$ident>::SIGNATURE) fixed(","))+
- shift_left(1)
- fixed(")")
- );
-
- fn is_dynamic() -> bool {
- false
- $(
- || <$ident>::is_dynamic()
- )*
- }
-
- fn size() -> usize {
- 0 $(+ <$ident>::size())+
- }
- }
-
- impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}
-
- impl<$($ident),+> AbiRead for ($($ident,)+)
- where
- Self: AbiType,
- $($ident: AbiRead + AbiType,)+
- {
- fn abi_read(reader: &mut AbiReader) -> Result<($($ident,)+)> {
- let is_dynamic = <Self>::is_dynamic();
- let size = if !is_dynamic { Some(<Self>::size()) } else { None };
- let mut subresult = reader.subresult(size)?;
- Ok((
- $({
- let value = <$ident>::abi_read(&mut subresult)?;
- if !is_dynamic {subresult.bytes_read(<$ident as AbiType>::size())};
- value
- },)+
- ))
- }
- }
-
- #[allow(non_snake_case)]
- impl<$($ident),+> AbiWrite for ($($ident,)+)
- where
- $($ident: AbiWrite + AbiType,)+
- {
- fn abi_write(&self, writer: &mut AbiWriter) {
- let ($($ident,)+) = self;
- if <Self as AbiType>::is_dynamic() {
- let mut sub = AbiWriter::new();
- $($ident.abi_write(&mut sub);)+
- writer.write_subresult(sub);
- } else {
- $($ident.abi_write(writer);)+
- }
- }
- }
- };
-}
-
-impl_tuples! {A}
-impl_tuples! {A B}
-impl_tuples! {A B C}
-impl_tuples! {A B C D}
-impl_tuples! {A B C D E}
-impl_tuples! {A B C D E F}
-impl_tuples! {A B C D E F G}
-impl_tuples! {A B C D E F G H}
-impl_tuples! {A B C D E F G H I}
-impl_tuples! {A B C D E F G H I J}
-
-//----- impls for Option -----
-impl<T: AbiType> AbiType for Option<T> {
- const SIGNATURE: SignatureUnit = <(bool, T)>::SIGNATURE;
-
- fn is_dynamic() -> bool {
- <(bool, T)>::is_dynamic()
- }
-
- fn size() -> usize {
- <(bool, T)>::size()
- }
-}
-
-impl<T: AbiWrite + AbiType + Default> AbiWrite for Option<T> {
- fn abi_write(&self, writer: &mut AbiWriter) {
- match self {
- Some(value) => (true, value).abi_write(writer),
- None => (false, T::default()).abi_write(writer),
- }
- }
-}
-
-impl<T> AbiRead for Option<T>
-where
- Self: AbiType,
- T: AbiRead + AbiType,
-{
- fn abi_read(reader: &mut AbiReader) -> Result<Self>
- where
- Self: Sized,
- {
- let (status, value) = <(bool, T)>::abi_read(reader)?;
- Ok(if status { Some(value) } else { None })
- }
-}
crates/evm-coder/src/abi/mod.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/mod.rs
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-//! Implementation of EVM RLP reader/writer
-
-#![allow(dead_code)]
-
-mod traits;
-pub use traits::*;
-mod impls;
-
-#[cfg(test)]
-mod test;
-
-#[cfg(not(feature = "std"))]
-use alloc::vec::Vec;
-use evm_core::ExitError;
-use primitive_types::{H160, U256};
-
-use crate::{
- execution::{Result, Error},
- types::*,
-};
-
-const ABI_ALIGNMENT: usize = 32;
-
-/// View into RLP data, which provides method to read typed items from it
-#[derive(Clone)]
-pub struct AbiReader<'i> {
- buf: &'i [u8],
- subresult_offset: usize,
- offset: usize,
-}
-impl<'i> AbiReader<'i> {
- /// Start reading RLP buffer, assuming there is no padding bytes
- pub fn new(buf: &'i [u8]) -> Self {
- Self {
- buf,
- subresult_offset: 0,
- offset: 0,
- }
- }
- /// Start reading RLP buffer, parsing first 4 bytes as selector
- pub fn new_call(buf: &'i [u8]) -> Result<(Bytes4, Self)> {
- if buf.len() < 4 {
- return Err(Error::Error(ExitError::OutOfOffset));
- }
- let mut method_id = [0; 4];
- method_id.copy_from_slice(&buf[0..4]);
-
- Ok((
- method_id,
- Self {
- buf,
- subresult_offset: 4,
- offset: 4,
- },
- ))
- }
-
- fn read_pad<const S: usize>(
- buf: &[u8],
- offset: usize,
- pad_start: usize,
- pad_end: usize,
- block_start: usize,
- block_end: usize,
- ) -> Result<[u8; S]> {
- if buf.len() - offset < ABI_ALIGNMENT {
- return Err(Error::Error(ExitError::OutOfOffset));
- }
- let mut block = [0; S];
- let is_pad_zeroed = buf[pad_start..pad_end].iter().all(|&v| v == 0);
- if !is_pad_zeroed {
- return Err(Error::Error(ExitError::InvalidRange));
- }
- block.copy_from_slice(&buf[block_start..block_end]);
- Ok(block)
- }
-
- fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {
- let offset = self.offset;
- self.offset += ABI_ALIGNMENT;
- Self::read_pad(
- self.buf,
- offset,
- offset,
- offset + ABI_ALIGNMENT - S,
- offset + ABI_ALIGNMENT - S,
- offset + ABI_ALIGNMENT,
- )
- }
-
- fn read_padright<const S: usize>(&mut self) -> Result<[u8; S]> {
- let offset = self.offset;
- self.offset += ABI_ALIGNMENT;
- Self::read_pad(
- self.buf,
- offset,
- offset + S,
- offset + ABI_ALIGNMENT,
- offset,
- offset + S,
- )
- }
-
- /// Read [`H160`] at current position, then advance
- pub fn address(&mut self) -> Result<H160> {
- Ok(H160(self.read_padleft()?))
- }
-
- /// Read [`bool`] at current position, then advance
- pub fn bool(&mut self) -> Result<bool> {
- let data: [u8; 1] = self.read_padleft()?;
- match data[0] {
- 0 => Ok(false),
- 1 => Ok(true),
- _ => Err(Error::Error(ExitError::InvalidRange)),
- }
- }
-
- /// Read [`[u8; 4]`] at current position, then advance
- pub fn bytes4(&mut self) -> Result<[u8; 4]> {
- self.read_padright()
- }
-
- /// Read [`Vec<u8>`] at current position, then advance
- pub fn bytes(&mut self) -> Result<Vec<u8>> {
- let mut subresult = self.subresult(None)?;
- let length = subresult.uint32()? as usize;
- if subresult.buf.len() < subresult.offset + length {
- return Err(Error::Error(ExitError::OutOfOffset));
- }
- Ok(subresult.buf[subresult.offset..subresult.offset + length].into())
- }
-
- /// Read [`string`] at current position, then advance
- pub fn string(&mut self) -> Result<String> {
- String::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))
- }
-
- /// Read [`u8`] at current position, then advance
- pub fn uint8(&mut self) -> Result<u8> {
- Ok(self.read_padleft::<1>()?[0])
- }
-
- /// Read [`u32`] at current position, then advance
- pub fn uint32(&mut self) -> Result<u32> {
- Ok(u32::from_be_bytes(self.read_padleft()?))
- }
-
- /// Read [`u128`] at current position, then advance
- pub fn uint128(&mut self) -> Result<u128> {
- Ok(u128::from_be_bytes(self.read_padleft()?))
- }
-
- /// Read [`U256`] at current position, then advance
- pub fn uint256(&mut self) -> Result<U256> {
- let buf: [u8; 32] = self.read_padleft()?;
- Ok(U256::from_big_endian(&buf))
- }
-
- /// Read [`u64`] at current position, then advance
- pub fn uint64(&mut self) -> Result<u64> {
- Ok(u64::from_be_bytes(self.read_padleft()?))
- }
-
- /// Read [`usize`] at current position, then advance
- #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]
- pub fn read_usize(&mut self) -> Result<usize> {
- Ok(usize::from_be_bytes(self.read_padleft()?))
- }
-
- /// Slice recursive buffer, advance one word for buffer offset
- /// If `size` is [`None`] then [`Self::offset`] and [`Self::subresult_offset`] evals from [`Self::buf`].
- pub fn subresult(&mut self, size: Option<usize>) -> Result<AbiReader<'i>> {
- let subresult_offset = self.subresult_offset;
- let offset = if let Some(size) = size {
- self.offset += size;
- 0
- } else {
- self.uint32()? as usize
- };
-
- if offset + self.subresult_offset > self.buf.len() {
- return Err(Error::Error(ExitError::InvalidRange));
- }
-
- let new_offset = offset + subresult_offset;
- Ok(AbiReader {
- buf: self.buf,
- subresult_offset: new_offset,
- offset: new_offset,
- })
- }
-
- /// Notify about readed data portion.
- pub fn bytes_read(&mut self, size: usize) {
- self.subresult_offset += size;
- }
-
- /// Is this parser reached end of buffer?
- pub fn is_finished(&self) -> bool {
- self.buf.len() == self.offset
- }
-}
-
-/// Writer for RLP encoded data
-#[derive(Default)]
-pub struct AbiWriter {
- static_part: Vec<u8>,
- dynamic_part: Vec<(usize, AbiWriter)>,
- had_call: bool,
- is_dynamic: bool,
-}
-impl AbiWriter {
- /// Initialize internal buffers for output data, assuming no padding required
- pub fn new() -> Self {
- Self::default()
- }
-
- /// Initialize internal buffers with data size
- pub fn new_dynamic(is_dynamic: bool) -> Self {
- Self {
- is_dynamic,
- ..Default::default()
- }
- }
- /// Initialize internal buffers, inserting method selector at beginning
- pub fn new_call(method_id: u32) -> Self {
- let mut val = Self::new();
- val.static_part.extend(&method_id.to_be_bytes());
- val.had_call = true;
- val
- }
-
- fn write_padleft(&mut self, block: &[u8]) {
- assert!(block.len() <= ABI_ALIGNMENT);
- self.static_part
- .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);
- self.static_part.extend(block);
- }
-
- fn write_padright(&mut self, block: &[u8]) {
- assert!(block.len() <= ABI_ALIGNMENT);
- self.static_part.extend(block);
- self.static_part
- .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);
- }
-
- /// Write [`H160`] to end of buffer
- pub fn address(&mut self, address: &H160) {
- self.write_padleft(&address.0)
- }
-
- /// Write [`bool`] to end of buffer
- pub fn bool(&mut self, value: &bool) {
- self.write_padleft(&[if *value { 1 } else { 0 }])
- }
-
- /// Write [`u8`] to end of buffer
- pub fn uint8(&mut self, value: &u8) {
- self.write_padleft(&[*value])
- }
-
- /// Write [`u32`] to end of buffer
- pub fn uint32(&mut self, value: &u32) {
- self.write_padleft(&u32::to_be_bytes(*value))
- }
-
- /// Write [`u64`] to end of buffer
- pub fn uint64(&mut self, value: &u64) {
- self.write_padleft(&u64::to_be_bytes(*value))
- }
-
- /// Write [`u128`] to end of buffer
- pub fn uint128(&mut self, value: &u128) {
- self.write_padleft(&u128::to_be_bytes(*value))
- }
-
- /// Write [`U256`] to end of buffer
- pub fn uint256(&mut self, value: &U256) {
- let mut out = [0; 32];
- value.to_big_endian(&mut out);
- self.write_padleft(&out)
- }
-
- /// Write [`usize`] to end of buffer
- #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]
- pub fn write_usize(&mut self, value: &usize) {
- self.write_padleft(&usize::to_be_bytes(*value))
- }
-
- /// Append recursive data, writing pending offset at end of buffer
- pub fn write_subresult(&mut self, result: Self) {
- self.dynamic_part.push((self.static_part.len(), result));
- // Empty block, to be filled later
- self.write_padleft(&[]);
- }
-
- fn memory(&mut self, value: &[u8]) {
- let mut sub = Self::new();
- sub.uint32(&(value.len() as u32));
- for chunk in value.chunks(ABI_ALIGNMENT) {
- sub.write_padright(chunk);
- }
- self.write_subresult(sub);
- }
-
- /// Append recursive [`str`] at end of buffer
- pub fn string(&mut self, value: &str) {
- self.memory(value.as_bytes())
- }
-
- /// Append recursive [`[u8]`] at end of buffer
- pub fn bytes(&mut self, value: &[u8]) {
- self.memory(value)
- }
-
- /// Finish writer, concatenating all internal buffers
- pub fn finish(mut self) -> Vec<u8> {
- for (static_offset, part) in self.dynamic_part {
- let part_offset = self.static_part.len()
- - if self.had_call { 4 } else { 0 }
- - if self.is_dynamic { ABI_ALIGNMENT } else { 0 };
-
- let encoded_dynamic_offset = usize::to_be_bytes(part_offset);
- let start = static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len();
- let stop = static_offset + ABI_ALIGNMENT;
- self.static_part[start..stop].copy_from_slice(&encoded_dynamic_offset);
- self.static_part.extend(part.finish())
- }
- self.static_part
- }
-}
crates/evm-coder/src/abi/test.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/test.rs
+++ /dev/null
@@ -1,605 +0,0 @@
-use crate::{
- abi::{AbiRead, AbiWrite},
- types::*,
-};
-
-use super::{AbiReader, AbiWriter};
-use hex_literal::hex;
-use primitive_types::{H160, U256};
-
-fn test_impl<T>(function_identifier: u32, decoded_data: T, encoded_data: &[u8])
-where
- T: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
-{
- let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();
- assert_eq!(call, u32::to_be_bytes(function_identifier));
- let data = <T>::abi_read(&mut decoder).unwrap();
- assert_eq!(data, decoded_data);
-
- let mut writer = AbiWriter::new_call(function_identifier);
- decoded_data.abi_write(&mut writer);
- let ed = writer.finish();
- similar_asserts::assert_eq!(encoded_data, ed.as_slice());
-}
-
-macro_rules! test_impl_uint {
- ($type:ident) => {
- test_impl::<$type>(
- 0xdeadbeef,
- 255 as $type,
- &hex!(
- "
- deadbeef
- 00000000000000000000000000000000000000000000000000000000000000ff
- "
- ),
- );
- };
-}
-
-#[test]
-fn encode_decode_uint8() {
- test_impl_uint!(u8);
-}
-
-#[test]
-fn encode_decode_uint32() {
- test_impl_uint!(u32);
-}
-
-#[test]
-fn encode_decode_uint128() {
- test_impl_uint!(u128);
-}
-
-#[test]
-fn encode_decode_uint256() {
- test_impl::<U256>(
- 0xdeadbeef,
- U256([255, 0, 0, 0]),
- &hex!(
- "
- deadbeef
- 00000000000000000000000000000000000000000000000000000000000000ff
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_string() {
- test_impl::<String>(
- 0xdeadbeef,
- "some string".to_string(),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 000000000000000000000000000000000000000000000000000000000000000b
- 736f6d6520737472696e67000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple_string() {
- test_impl::<(String,)>(
- 0xdeadbeef,
- ("some string".to_string(),),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000020
- 000000000000000000000000000000000000000000000000000000000000000b
- 736f6d6520737472696e67000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_vec_tuple_address_uint256() {
- test_impl::<Vec<(Address, U256)>>(
- 0x1ACF2D55,
- vec![
- (
- H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),
- U256([10, 0, 0, 0]),
- ),
- (
- H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),
- U256([20, 0, 0, 0]),
- ),
- (
- H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),
- U256([30, 0, 0, 0]),
- ),
- ],
- &hex!(
- "
- 1ACF2D55
- 0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]
- 0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]
-
- 0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address
- 000000000000000000000000000000000000000000000000000000000000000A // uint256
-
- 000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address
- 0000000000000000000000000000000000000000000000000000000000000014 // uint256
-
- 0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address
- 000000000000000000000000000000000000000000000000000000000000001E // uint256
- "
- )
- );
-}
-
-#[test]
-fn encode_decode_vec_tuple_uint256_string() {
- test_impl::<Vec<(U256, String)>>(
- 0xdeadbeef,
- vec![
- (1.into(), "Test URI 0".to_string()),
- (11.into(), "Test URI 1".to_string()),
- (12.into(), "Test URI 2".to_string()),
- ],
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020 // offset of (uint256, string)[]
- 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]
-
- 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem
- 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem
- 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem
-
- 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60
- 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
- 000000000000000000000000000000000000000000000000000000000000000a // size of string
- 5465737420555249203000000000000000000000000000000000000000000000 // string
-
- 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0
- 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
- 000000000000000000000000000000000000000000000000000000000000000a // size of string
- 5465737420555249203100000000000000000000000000000000000000000000 // string
-
- 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160
- 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
- 000000000000000000000000000000000000000000000000000000000000000a // size of string
- 5465737420555249203200000000000000000000000000000000000000000000 // string
- "
- )
- );
-}
-
-#[test]
-fn dynamic_after_static() {
- let mut encoder = AbiWriter::new();
- encoder.bool(&true);
- encoder.string("test");
- let encoded = encoder.finish();
-
- let mut encoder = AbiWriter::new();
- encoder.bool(&true);
- // Offset to subresult
- encoder.uint32(&(32 * 2));
- // Len of "test"
- encoder.uint32(&4);
- encoder.write_padright(&[b't', b'e', b's', b't']);
- let alternative_encoded = encoder.finish();
-
- assert_eq!(encoded, alternative_encoded);
-
- let mut decoder = AbiReader::new(&encoded);
- assert!(decoder.bool().unwrap());
- assert_eq!(decoder.string().unwrap(), "test");
-}
-
-#[test]
-fn mint_sample() {
- let (call, mut decoder) = AbiReader::new_call(&hex!(
- "
- 50bb4e7f
- 000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374
- 0000000000000000000000000000000000000000000000000000000000000001
- 0000000000000000000000000000000000000000000000000000000000000060
- 0000000000000000000000000000000000000000000000000000000000000008
- 5465737420555249000000000000000000000000000000000000000000000000
- "
- ))
- .unwrap();
- assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));
- assert_eq!(
- format!("{:?}", decoder.address().unwrap()),
- "0xad2c0954693c2b5404b7e50967d3481bea432374"
- );
- assert_eq!(decoder.uint32().unwrap(), 1);
- assert_eq!(decoder.string().unwrap(), "Test URI");
-}
-
-#[test]
-fn parse_vec_with_dynamic_type() {
- let decoded_data = (
- 0x36543006,
- vec![
- (1.into(), "Test URI 0".to_string()),
- (11.into(), "Test URI 1".to_string()),
- (12.into(), "Test URI 2".to_string()),
- ],
- );
-
- let encoded_data = &hex!(
- "
- 36543006
- 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address
- 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]
- 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]
-
- 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem
- 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem
- 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem
-
- 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60
- 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
- 000000000000000000000000000000000000000000000000000000000000000a // size of string
- 5465737420555249203000000000000000000000000000000000000000000000 // string
-
- 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0
- 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
- 000000000000000000000000000000000000000000000000000000000000000a // size of string
- 5465737420555249203100000000000000000000000000000000000000000000 // string
-
- 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160
- 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
- 000000000000000000000000000000000000000000000000000000000000000a // size of string
- 5465737420555249203200000000000000000000000000000000000000000000 // string
- "
- );
-
- let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();
- assert_eq!(call, u32::to_be_bytes(decoded_data.0));
- let address = decoder.address().unwrap();
- let data = <Vec<(U256, String)>>::abi_read(&mut decoder).unwrap();
- assert_eq!(data, decoded_data.1);
-
- let mut writer = AbiWriter::new_call(decoded_data.0);
- address.abi_write(&mut writer);
- decoded_data.1.abi_write(&mut writer);
- let ed = writer.finish();
- similar_asserts::assert_eq!(encoded_data, ed.as_slice());
-}
-
-#[test]
-fn encode_decode_vec_tuple_string_bytes() {
- test_impl::<Vec<(String, Bytes)>>(
- 0xdeadbeef,
- vec![
- (
- "Test URI 0".to_string(),
- Bytes(vec![
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- ]),
- ),
- (
- "Test URI 1".to_string(),
- Bytes(vec![
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- ]),
- ),
- ("Test URI 2".to_string(), Bytes(vec![0x33, 0x33])),
- ],
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000003
-
- 0000000000000000000000000000000000000000000000000000000000000060
- 0000000000000000000000000000000000000000000000000000000000000140
- 0000000000000000000000000000000000000000000000000000000000000220
-
- 0000000000000000000000000000000000000000000000000000000000000040
- 0000000000000000000000000000000000000000000000000000000000000080
- 000000000000000000000000000000000000000000000000000000000000000a
- 5465737420555249203000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000030
- 1111111111111111111111111111111111111111111111111111111111111111
- 1111111111111111111111111111111100000000000000000000000000000000
-
- 0000000000000000000000000000000000000000000000000000000000000040
- 0000000000000000000000000000000000000000000000000000000000000080
- 000000000000000000000000000000000000000000000000000000000000000a
- 5465737420555249203100000000000000000000000000000000000000000000
- 000000000000000000000000000000000000000000000000000000000000002f
- 2222222222222222222222222222222222222222222222222222222222222222
- 2222222222222222222222222222220000000000000000000000000000000000
-
- 0000000000000000000000000000000000000000000000000000000000000040
- 0000000000000000000000000000000000000000000000000000000000000080
- 000000000000000000000000000000000000000000000000000000000000000a
- 5465737420555249203200000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000002
- 3333000000000000000000000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-// #[ignore = "reason"]
-fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() {
- let int = 0xff;
- let by = Bytes(vec![0x11, 0x22, 0x33]);
- let string = "some string".to_string();
-
- test_impl::<((u8,), (String, Bytes), (u8, Bytes))>(
- 0xdeadbeef,
- ((int,), (string.clone(), by.clone()), (int, by)),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 00000000000000000000000000000000000000000000000000000000000000ff
- 0000000000000000000000000000000000000000000000000000000000000060
- 0000000000000000000000000000000000000000000000000000000000000120
- 0000000000000000000000000000000000000000000000000000000000000040
- 0000000000000000000000000000000000000000000000000000000000000080
- 000000000000000000000000000000000000000000000000000000000000000b
- 736f6d6520737472696e67000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000003
- 1122330000000000000000000000000000000000000000000000000000000000
- 00000000000000000000000000000000000000000000000000000000000000ff
- 0000000000000000000000000000000000000000000000000000000000000040
- 0000000000000000000000000000000000000000000000000000000000000003
- 1122330000000000000000000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8_uint8_tuple1_uint8_uint8() {
- test_impl::<((u8,), (u8, u8), (u8, u8))>(
- 0xdeadbeef,
- ((43,), (44, 45), (46, 47)),
- &hex!(
- "
- deadbeef
- 000000000000000000000000000000000000000000000000000000000000002b
- 000000000000000000000000000000000000000000000000000000000000002c
- 000000000000000000000000000000000000000000000000000000000000002d
- 000000000000000000000000000000000000000000000000000000000000002e
- 000000000000000000000000000000000000000000000000000000000000002f
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8() {
- test_impl::<((u8,), (u8,))>(
- 0xdeadbeef,
- ((43,), (44,)),
- &hex!(
- "
- deadbeef
- 000000000000000000000000000000000000000000000000000000000000002b
- 000000000000000000000000000000000000000000000000000000000000002c
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_uint8() {
- test_impl::<((u8, u8),)>(
- 0xdeadbeef,
- ((43, 44),),
- &hex!(
- "
- deadbeef
- 000000000000000000000000000000000000000000000000000000000000002b
- 000000000000000000000000000000000000000000000000000000000000002c
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple_uint8_uint8() {
- test_impl::<(u8, u8)>(
- 0xdeadbeef,
- (43, 44),
- &hex!(
- "
- deadbeef
- 000000000000000000000000000000000000000000000000000000000000002b
- 000000000000000000000000000000000000000000000000000000000000002c
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_uint8_tuple1_uint8_uint8_and_uint8() {
- test_impl::<((u8, u8), (u8, u8), u8)>(
- 0xdeadbeef,
- ((10, 11), (12, 13), 14),
- &hex!(
- "
- deadbeef
- 000000000000000000000000000000000000000000000000000000000000000a
- 000000000000000000000000000000000000000000000000000000000000000b
- 000000000000000000000000000000000000000000000000000000000000000c
- 000000000000000000000000000000000000000000000000000000000000000d
- 000000000000000000000000000000000000000000000000000000000000000e
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_string() {
- test_impl::<((String,),)>(
- 0xdeadbeef,
- (("some string".to_string(),),),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000020
- 000000000000000000000000000000000000000000000000000000000000000b
- 736f6d6520737472696e67000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_string() {
- test_impl::<((u8, String),)>(
- 0xdeadbeef,
- ((0xff, "some string".to_string()),),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000020
- 00000000000000000000000000000000000000000000000000000000000000ff
- 0000000000000000000000000000000000000000000000000000000000000040
- 000000000000000000000000000000000000000000000000000000000000000b
- 736f6d6520737472696e67000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_string_bytes() {
- test_impl::<((String, Bytes),)>(
- 0xdeadbeef,
- (("some string".to_string(), Bytes(vec![1, 2, 3])),),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000040
- 0000000000000000000000000000000000000000000000000000000000000080
- 000000000000000000000000000000000000000000000000000000000000000b
- 736f6d6520737472696e67000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000003
- 0102030000000000000000000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_tuple1_string() {
- test_impl::<((u8,), (String,))>(
- 0xdeadbeef,
- ((0xff,), ("some string".to_string(),)),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 00000000000000000000000000000000000000000000000000000000000000ff
- 0000000000000000000000000000000000000000000000000000000000000040
- 0000000000000000000000000000000000000000000000000000000000000020
- 000000000000000000000000000000000000000000000000000000000000000b
- 736f6d6520737472696e67000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn parse_multiple_params() {
- let encoded_data = hex!(
- "
- deadbeef
- 000000000000000000000000000000000000000000000000000000000000000a
- 000000000000000000000000000000000000000000000000000000000000000b
- "
- );
- let (_, mut decoder) = AbiReader::new_call(&encoded_data).unwrap();
- let p1 = <u8>::abi_read(&mut decoder).unwrap();
- let p2 = <u8>::abi_read(&mut decoder).unwrap();
- assert_eq!(p1, 0x0a);
- assert_eq!(p2, 0x0b);
-}
-
-#[test]
-fn encode_decode_option_uint8_some() {
- test_impl::<Option<u8>>(
- 0xdeadbeef,
- Some(44),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000001
- 000000000000000000000000000000000000000000000000000000000000002c
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_option_uint8_none() {
- test_impl::<Option<u8>>(
- 0xdeadbeef,
- None,
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_option_string_some() {
- test_impl::<Option<String>>(
- 0xdeadbeef,
- Some("some string".to_string()),
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000001
- 0000000000000000000000000000000000000000000000000000000000000040
- 000000000000000000000000000000000000000000000000000000000000000b
- 736f6d6520737472696e67000000000000000000000000000000000000000000
- "
- ),
- );
-}
-
-#[test]
-fn encode_decode_option_string_none() {
- test_impl::<Option<String>>(
- 0xdeadbeef,
- None,
- &hex!(
- "
- deadbeef
- 0000000000000000000000000000000000000000000000000000000000000020
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000040
- 0000000000000000000000000000000000000000000000000000000000000000
- "
- ),
- );
-}
crates/evm-coder/src/abi/traits.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/traits.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use super::{AbiReader, AbiWriter};
-use crate::{
- custom_signature::*,
- execution::{Result, ResultWithPostInfo},
-};
-use core::str::from_utf8;
-
-/// Helper for type.
-pub trait AbiType {
- /// Signature for Etherium ABI.
- const SIGNATURE: SignatureUnit;
-
- /// Signature as str.
- fn as_str() -> &'static str {
- from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
- }
-
- /// Is type dynamic sized.
- fn is_dynamic() -> bool;
-
- /// Size for type aligned to [`ABI_ALIGNMENT`].
- fn size() -> usize;
-}
-
-/// [`AbiReader`] implements reading of many types.
-pub trait AbiRead {
- /// Read item from current position, advanding decoder
- fn abi_read(reader: &mut AbiReader) -> Result<Self>
- where
- Self: Sized;
-}
-
-/// For questions about inability to provide custom implementations,
-/// see [`AbiRead`]
-pub trait AbiWrite {
- /// Write value to end of specified encoder
- fn abi_write(&self, writer: &mut AbiWriter);
- /// Specialization for [`crate::solidity_interface`] implementation,
- /// see comment in `impl AbiWrite for ResultWithPostInfo`
- fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {
- let mut writer = AbiWriter::new();
- self.abi_write(&mut writer);
- Ok(writer.into())
- }
-}
crates/evm-coder/src/custom_signature.rsdiffbeforeafterboth--- a/crates/evm-coder/src/custom_signature.rs
+++ /dev/null
@@ -1,326 +0,0 @@
-//! # A module for custom signature support.
-//!
-//! ## Overview
-//! This module allows you to create arbitrary signatures for types and functions in compile time.
-//!
-//! ### Type signatures
-//! To create the desired type signature, you need to create your own trait with the `SIGNATURE` constant.
-//! Then in the implementation, for the required type, use the macro [`make_signature`]
-//! #### Example
-//! ```
-//! use std::str::from_utf8;
-//! use evm_coder::{custom_signature::SignatureUnit, make_signature};
-//!
-//! // Create trait for our signature
-//! trait SoliditySignature {
-//! const SIGNATURE: SignatureUnit;
-//!
-//! fn name() -> &'static str {
-//! from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
-//! }
-//! }
-//!
-//! // Make signatures for some types
-//! impl SoliditySignature for u8 {
-//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint8"));
-//! }
-//! impl SoliditySignature for u32 {
-//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint32"));
-//! }
-//! impl<T: SoliditySignature> SoliditySignature for Vec<T> {
-//! const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-//! }
-//! impl<A: SoliditySignature, B: SoliditySignature> SoliditySignature for (A, B) {
-//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("(") nameof(A::SIGNATURE) fixed(",") nameof(B::SIGNATURE) fixed(")"));
-//! }
-//! impl<A: SoliditySignature> SoliditySignature for (A,) {
-//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("(") nameof(A::SIGNATURE) fixed(",") shift_left(1) fixed(")"));
-//! }
-//!
-//! assert_eq!(u8::name(), "uint8");
-//! assert_eq!(<Vec<u8>>::name(), "uint8[]");
-//! assert_eq!(<(u32, u8)>::name(), "(uint32,uint8)");
-//! ```
-//!
-//! ### Function signatures
-//! To create a function signature, the macro [`make_signature`] is also used, which accepts
-//! settings for the function format [`SignaturePreferences`] and function parameters [`SignatureUnit`]
-//! #### Example
-//! ```
-//! use core::str::from_utf8;
-//! use evm_coder::{custom_signature::SignatureUnit, make_signature};
-//! // Trait for our signature
-//! trait SoliditySignature {
-//! const SIGNATURE: SignatureUnit;
-//!
-//! fn name() -> &'static str {
-//! from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
-//! }
-//! }
-//!
-//! // Make signatures for some types
-//! impl SoliditySignature for u8 {
-//! const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint8"));
-//! }
-//! impl<T: SoliditySignature> SoliditySignature for Vec<T> {
-//! const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-//! }
-//! ```
-
-/// The maximum length of the signature.
-pub const SIGNATURE_SIZE_LIMIT: usize = 256;
-
-/// Storage for the signature or its elements.
-#[derive(Debug)]
-pub struct SignatureUnit {
- /// Signature data.
- pub data: [u8; SIGNATURE_SIZE_LIMIT],
- /// The actual size of the data.
- pub len: usize,
-}
-
-impl SignatureUnit {
- /// Create a signature from `&str'.
- pub const fn new(name: &'static str) -> SignatureUnit {
- let mut signature = [0_u8; SIGNATURE_SIZE_LIMIT];
- let name = name.as_bytes();
- let name_len = name.len();
- let mut dst_offset = 0;
- crate::make_signature!(@copy(name, signature, name_len, dst_offset));
- SignatureUnit {
- data: signature,
- len: name_len,
- }
- }
- /// String conversion
- pub fn as_str(&self) -> Option<&str> {
- core::str::from_utf8(&self.data[0..self.len]).ok()
- }
-}
-
-/// ### Macro to create signatures of types and functions.
-///
-/// Format for creating a type of signature:
-/// ```ignore
-/// make_signature!(new fixed("uint8")); // Simple type
-/// make_signature!(new fixed("(") nameof(u8) fixed(",") nameof(u8) fixed(")")); // Composite type
-/// ```
-#[macro_export]
-macro_rules! make_signature {
- (new $($tt:tt)*) => {
- ($crate::custom_signature::SignatureUnit {
- data: {
- let mut out = [0u8; $crate::custom_signature::SIGNATURE_SIZE_LIMIT];
- let mut dst_offset = 0;
- $crate::make_signature!(@data(out, dst_offset); $($tt)*);
- out
- },
- len: {0 + $crate::make_signature!(@size; $($tt)*)},
- })
- };
-
- (@size;) => {
- 0
- };
- (@size; fixed($expr:expr) $($tt:tt)*) => {
- $expr.len() + $crate::make_signature!(@size; $($tt)*)
- };
- (@size; nameof($expr:expr) $($tt:tt)*) => {
- $expr.len + $crate::make_signature!(@size; $($tt)*)
- };
- (@size; numof($expr:expr) $($tt:tt)*) => {
- {
- let mut out = 0;
- let mut v = $expr;
- if v == 0 {
- out = 1;
- } else {
- while v > 0 {
- out += 1;
- v /= 10;
- }
- }
- out
- } + $crate::make_signature!(@size; $($tt)*)
- };
- (@size; shift_left($expr:expr) $($tt:tt)*) => {
- $crate::make_signature!(@size; $($tt)*) - $expr
- };
-
- (@data($dst:ident, $dst_offset:ident);) => {};
- (@data($dst:ident, $dst_offset:ident); fixed($expr:expr) $($tt:tt)*) => {
- {
- let data = $expr.as_bytes();
- let data_len = data.len();
- $crate::make_signature!(@copy(data, $dst, data_len, $dst_offset));
- }
- $crate::make_signature!(@data($dst, $dst_offset); $($tt)*)
- };
- (@data($dst:ident, $dst_offset:ident); nameof($expr:expr) $($tt:tt)*) => {
- {
- $crate::make_signature!(@copy(&$expr.data, $dst, $expr.len, $dst_offset));
- }
- $crate::make_signature!(@data($dst, $dst_offset); $($tt)*)
- };
- (@data($dst:ident, $dst_offset:ident); numof($expr:expr) $($tt:tt)*) => {
- {
- let mut v = $expr;
- let mut need_to_swap = 0;
- if v == 0 {
- $dst[$dst_offset] = b'0';
- $dst_offset += 1;
- } else {
- while v > 0 {
- let n = (v % 10) as u8;
- $dst[$dst_offset] = b'0' + n;
- v /= 10;
- need_to_swap += 1;
- $dst_offset += 1;
- }
- }
- let mut i = 0;
- #[allow(clippy::manual_swap)]
- while i < need_to_swap / 2 {
- let a = $dst_offset - i - 1;
- let b = $dst_offset - need_to_swap + i;
- let v = $dst[a];
- $dst[a] = $dst[b];
- $dst[b] = v;
- i += 1;
- }
- }
- $crate::make_signature!(@data($dst, $dst_offset); $($tt)*)
- };
- (@data($dst:ident, $dst_offset:ident); shift_left($expr:expr) $($tt:tt)*) => {
- $dst_offset -= $expr;
- $crate::make_signature!(@data($dst, $dst_offset); $($tt)*)
- };
-
- (@copy($src:expr, $dst:expr, $src_len:expr, $dst_offset:ident)) => {
- {
- let mut src_offset = 0;
- let src_len: usize = $src_len;
- while src_offset < src_len {
- $dst[$dst_offset] = $src[src_offset];
- $dst_offset += 1;
- src_offset += 1;
- }
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use core::str::from_utf8;
-
- use super::{SIGNATURE_SIZE_LIMIT, SignatureUnit};
-
- trait Name {
- const NAME: SignatureUnit;
-
- fn name() -> &'static str {
- from_utf8(&Self::NAME.data[..Self::NAME.len]).expect("bad utf-8")
- }
- }
-
- impl Name for u8 {
- const NAME: SignatureUnit = make_signature!(new fixed("uint8"));
- }
- impl Name for u32 {
- const NAME: SignatureUnit = make_signature!(new fixed("uint32"));
- }
- impl<T: Name> Name for Vec<T> {
- const NAME: SignatureUnit = make_signature!(new nameof(T::NAME) fixed("[]"));
- }
- impl<A: Name, B: Name> Name for (A, B) {
- const NAME: SignatureUnit =
- make_signature!(new fixed("(") nameof(A::NAME) fixed(",") nameof(B::NAME) fixed(")"));
- }
- impl<A: Name> Name for (A,) {
- const NAME: SignatureUnit =
- make_signature!(new fixed("(") nameof(A::NAME) fixed(",") shift_left(1) fixed(")"));
- }
- impl<A: Name, const SIZE: usize> Name for [A; SIZE] {
- const NAME: SignatureUnit =
- make_signature!(new nameof(A::NAME) fixed("[") numof(SIZE) fixed("]"));
- }
-
- struct MaxSize();
- impl Name for MaxSize {
- const NAME: SignatureUnit = SignatureUnit {
- data: [b'!'; SIGNATURE_SIZE_LIMIT],
- len: SIGNATURE_SIZE_LIMIT,
- };
- }
-
- #[test]
- fn simple() {
- assert_eq!(u8::name(), "uint8");
- assert_eq!(u32::name(), "uint32");
- }
-
- #[test]
- fn vector_of_simple() {
- assert_eq!(<Vec<u8>>::name(), "uint8[]");
- assert_eq!(<Vec<u32>>::name(), "uint32[]");
- }
-
- #[test]
- fn vector_of_vector() {
- assert_eq!(<Vec<Vec<u8>>>::name(), "uint8[][]");
- }
-
- #[test]
- fn tuple_of_simple() {
- assert_eq!(<(u32, u8)>::name(), "(uint32,uint8)");
- }
-
- #[test]
- fn tuple_of_tuple() {
- assert_eq!(
- <((u32, u8), (u8, u32))>::name(),
- "((uint32,uint8),(uint8,uint32))"
- );
- }
-
- #[test]
- fn vector_of_tuple() {
- assert_eq!(<Vec<(u32, u8)>>::name(), "(uint32,uint8)[]");
- }
-
- #[test]
- fn tuple_of_vector() {
- assert_eq!(<(Vec<u32>, u8)>::name(), "(uint32[],uint8)");
- }
-
- #[test]
- fn complex() {
- assert_eq!(
- <(Vec<u32>, (u32, Vec<u8>))>::name(),
- "(uint32[],(uint32,uint8[]))"
- );
- }
-
- #[test]
- fn max_size() {
- assert_eq!(<MaxSize>::name(), "!".repeat(SIGNATURE_SIZE_LIMIT));
- }
-
- #[test]
- fn shift() {
- assert_eq!(<(u32,)>::name(), "(uint32)");
- }
-
- #[test]
- fn num() {
- assert_eq!(<[u8; 0]>::name(), "uint8[0]");
- assert_eq!(<[u8; 1234]>::name(), "uint8[1234]");
- assert_eq!(<[u8; 12345]>::name(), "uint8[12345]");
- }
-
- #[test]
- fn over_max_size() {
- let t = trybuild::TestCases::new();
- t.compile_fail("tests/build_failed/custom_signature_over_max_size.rs");
- }
-}
crates/evm-coder/src/events.rsdiffbeforeafterboth--- a/crates/evm-coder/src/events.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-use ethereum::Log;
-use primitive_types::{H160, H256, U256};
-
-use crate::types::*;
-
-/// Implementation of this trait should not be written manually,
-/// instead use [`crate::ToLog`] proc macros.
-///
-/// See also [`evm_coder_procedural::ToLog`], [solidity docs on events](https://docs.soliditylang.org/en/develop/contracts.html#events)
-pub trait ToLog {
- /// Convert event to [`ethereum::Log`].
- /// Because event by itself doesn't contains current contract
- /// address, it should be specified manually.
- fn to_log(&self, contract: H160) -> Log;
-}
-
-/// Only items implementing `ToTopic` may be used as `#[indexed]` field
-/// in [`crate::ToLog`] macro usage.
-///
-/// See also (solidity docs on events)[<https://docs.soliditylang.org/en/develop/contracts.html#events>]
-pub trait ToTopic {
- /// Convert value to topic to be used in [`ethereum::Log`]
- fn to_topic(&self) -> H256;
-}
-
-impl ToTopic for H256 {
- fn to_topic(&self) -> H256 {
- *self
- }
-}
-
-impl ToTopic for U256 {
- fn to_topic(&self) -> H256 {
- let mut out = [0u8; 32];
- self.to_big_endian(&mut out);
- H256(out)
- }
-}
-
-impl ToTopic for Address {
- fn to_topic(&self) -> H256 {
- let mut out = [0u8; 32];
- out[12..32].copy_from_slice(&self.0);
- H256(out)
- }
-}
-
-impl ToTopic for u32 {
- fn to_topic(&self) -> H256 {
- let mut out = [0u8; 32];
- out[28..32].copy_from_slice(&self.to_be_bytes());
- H256(out)
- }
-}
crates/evm-coder/src/execution.rsdiffbeforeafterboth--- a/crates/evm-coder/src/execution.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-//! Contract execution related types
-
-#[cfg(not(feature = "std"))]
-use alloc::string::{String, ToString};
-use evm_core::{ExitError, ExitFatal};
-#[cfg(feature = "std")]
-use std::string::{String, ToString};
-
-use crate::Weight;
-
-/// Execution error, should be convertible between EVM and Substrate.
-#[derive(Debug, Clone)]
-pub enum Error {
- /// Non-fatal contract error occured
- Revert(String),
- /// EVM fatal error
- Fatal(ExitFatal),
- /// EVM normal error
- Error(ExitError),
-}
-
-impl<E> From<E> for Error
-where
- E: ToString,
-{
- fn from(e: E) -> Self {
- Self::Revert(e.to_string())
- }
-}
-
-/// To be used in [`crate::solidity_interface`] implementation.
-pub type Result<T> = core::result::Result<T, Error>;
-
-/// Static information collected from [`crate::weight`].
-pub struct DispatchInfo {
- /// Statically predicted call weight
- pub weight: Weight,
-}
-
-impl From<Weight> for DispatchInfo {
- fn from(weight: Weight) -> Self {
- Self { weight }
- }
-}
-impl From<u64> for DispatchInfo {
- fn from(weight: u64) -> Self {
- Self {
- weight: Weight::from_ref_time(weight),
- }
- }
-}
-impl From<()> for DispatchInfo {
- fn from(_: ()) -> Self {
- Self {
- weight: Weight::zero(),
- }
- }
-}
-
-/// Weight information that is only available post dispatch.
-/// Note: This can only be used to reduce the weight or fee, not increase it.
-#[derive(Default, Clone)]
-pub struct PostDispatchInfo {
- /// Actual weight consumed by call
- actual_weight: Option<Weight>,
-}
-
-impl PostDispatchInfo {
- /// Calculate amount to be returned back to user
- pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight {
- info.weight - self.calc_actual_weight(info)
- }
-
- /// Calculate actual consumed weight, saturating to weight reported
- /// pre-dispatch
- pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight {
- if let Some(actual_weight) = self.actual_weight {
- actual_weight.min(info.weight)
- } else {
- info.weight
- }
- }
-}
-
-/// Wrapper for PostDispatchInfo and any user-provided data
-#[derive(Clone)]
-pub struct WithPostDispatchInfo<T> {
- /// User provided data
- pub data: T,
- /// Info known after dispatch
- pub post_info: PostDispatchInfo,
-}
-
-impl<T> From<T> for WithPostDispatchInfo<T> {
- fn from(data: T) -> Self {
- Self {
- data,
- post_info: Default::default(),
- }
- }
-}
-
-/// Return type of items in [`crate::solidity_interface`] definition
-pub type ResultWithPostInfo<T> =
- core::result::Result<WithPostDispatchInfo<T>, WithPostDispatchInfo<Error>>;
crates/evm-coder/src/lib.rsdiffbeforeafterboth--- a/crates/evm-coder/src/lib.rs
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![doc = include_str!("../README.md")]
-#![deny(missing_docs)]
-#![macro_use]
-#![cfg_attr(not(feature = "std"), no_std)]
-#[cfg(not(feature = "std"))]
-extern crate alloc;
-
-use abi::{AbiRead, AbiReader, AbiWriter};
-pub use evm_coder_procedural::{event_topic, fn_selector};
-pub mod abi;
-pub use events::{ToLog, ToTopic};
-use execution::DispatchInfo;
-pub mod execution;
-#[macro_use]
-pub mod custom_signature;
-
-/// Derives call enum implementing [`crate::Callable`], [`crate::Weighted`]
-/// and [`crate::Call`] from impl block.
-///
-/// ## Macro syntax
-///
-/// `#[solidity_interface(name, is, inline_is, events)]`
-/// - *name* - used in generated code, and for Call enum name
-/// - *is* - used to provide inheritance in Solidity
-/// - *inline_is* - same as `is`, but ERC165::SupportsInterface will work differently: For `is` SupportsInterface(A) will return true
-/// if A is one of the interfaces the contract is inherited from (e.g. B is created as `is(A)`). If B is created as `inline_is(A)`
-/// SupportsInterface(A) will internally create a new interface that combines all methods of A and B, so SupportsInterface(A) will return
-/// false.
-///
-/// `#[weight(value)]`
-/// Can be added to every method of impl block, used for deriving [`crate::Weighted`], which
-/// is used by substrate bridge.
-/// - *value*: expression, which evaluates to weight required to call this method.
-/// This expression can use call arguments to calculate non-constant execution time.
-/// This expression should evaluate faster than actual execution does, and may provide worse case
-/// than one is called.
-///
-/// `#[solidity_interface(rename_selector)]`
-/// - *rename_selector* - by default, selector name will be generated by transforming method name
-/// from snake_case to camelCase. Use this option, if other naming convention is required.
-/// I.e: method `token_uri` will be automatically renamed to `tokenUri` in selector, but name
-/// required by ERC721 standard is `tokenURI`, thus we need to specify `rename_selector = "tokenURI"`
-/// explicitly.
-///
-/// Both contract and contract methods may have doccomments, which will end up in a generated
-/// solidity interface file, thus you should use [solidity syntax](https://docs.soliditylang.org/en/latest/natspec-format.html) for writing documentation in this macro
-///
-/// ## Example
-///
-/// ```ignore
-/// struct SuperContract;
-/// struct InlineContract;
-/// struct Contract;
-///
-/// #[derive(ToLog)]
-/// enum ContractEvents {
-/// Event(#[indexed] uint32),
-/// }
-///
-/// /// @dev This contract provides function to multiply two numbers
-/// #[solidity_interface(name = MyContract, is(SuperContract), inline_is(InlineContract))]
-/// impl Contract {
-/// /// Multiply two numbers
-/// /// @param a First number
-/// /// @param b Second number
-/// /// @return uint32 Product of two passed numbers
-/// /// @dev This function returns error in case of overflow
-/// #[weight(200 + a + b)]
-/// #[solidity_interface(rename_selector = "mul")]
-/// fn mul(&mut self, a: uint32, b: uint32) -> Result<uint32> {
-/// Ok(a.checked_mul(b).ok_or("overflow")?)
-/// }
-/// }
-/// ```
-pub use evm_coder_procedural::solidity_interface;
-/// See [`solidity_interface`]
-pub use evm_coder_procedural::solidity;
-/// See [`solidity_interface`]
-pub use evm_coder_procedural::weight;
-pub use evm_coder_procedural::AbiCoder;
-pub use sha3_const;
-
-/// macro reexports
-pub use ethereum;
-
-/// Derives [`ToLog`] for enum
-///
-/// Selectors will be derived from variant names, there is currently no way to have custom naming
-/// for them
-///
-/// `#[indexed]`
-/// Marks this field as indexed, so it will appear in [`ethereum::Log`] topics instead of data
-pub use evm_coder_procedural::ToLog;
-
-// Api of those modules shouldn't be consumed directly, it is only exported for usage in proc macros
-#[doc(hidden)]
-pub mod events;
-#[doc(hidden)]
-#[cfg(feature = "stubgen")]
-pub mod solidity;
-
-/// Sealed traits.
-pub mod sealed {
- /// Not every type should be directly placed in vec.
- /// Vec encoding is not memory efficient, as every item will be padded
- /// to 32 bytes.
- /// Instead you should use specialized types (`bytes` in case of `Vec<u8>`)
- pub trait CanBePlacedInVec {}
-}
-
-/// Solidity type definitions (aliases from solidity name to rust type)
-/// To be used in [`solidity_interface`] definitions, to make sure there is no
-/// type conflict between Rust code and generated definitions
-pub mod types {
- #![allow(non_camel_case_types, missing_docs)]
-
- #[cfg(not(feature = "std"))]
- use alloc::{vec::Vec};
- use primitive_types::{U256, H160, H256};
-
- pub type Address = H160;
- pub type Bytes4 = [u8; 4];
- pub type Topic = H256;
-
- #[cfg(not(feature = "std"))]
- pub type String = ::alloc::string::String;
- #[cfg(feature = "std")]
- pub type String = ::std::string::String;
-
- #[derive(Default, Debug, PartialEq, Eq, Clone)]
- pub struct Bytes(pub Vec<u8>);
-
- //#region Special types
- /// Makes function payable
- pub type Value = U256;
- /// Makes function caller-sensitive
- pub type Caller = Address;
- //#endregion
-
- /// Ethereum typed call message, similar to solidity
- /// `msg` object.
- pub struct Msg<C> {
- pub call: C,
- /// Address of user, which called this contract.
- pub caller: H160,
- /// Payment amount to contract.
- /// Contract should reject payment, if target call is not payable,
- /// and there is no `receiver()` function defined.
- pub value: U256,
- }
-
- impl From<Vec<u8>> for Bytes {
- fn from(src: Vec<u8>) -> Self {
- Self(src)
- }
- }
-
- #[allow(clippy::from_over_into)]
- impl Into<Vec<u8>> for Bytes {
- fn into(self) -> Vec<u8> {
- self.0
- }
- }
-
- impl Bytes {
- #[must_use]
- pub fn len(&self) -> usize {
- self.0.len()
- }
-
- #[must_use]
- pub fn is_empty(&self) -> bool {
- self.len() == 0
- }
- }
-}
-
-/// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro
-pub trait Call: Sized {
- /// Parse call buffer into typed call enum
- fn parse(selector: types::Bytes4, input: &mut AbiReader) -> execution::Result<Option<Self>>;
-}
-
-/// Intended to be used as `#[weight]` output type
-/// Should be same between evm-coder and substrate to avoid confusion
-///
-/// Isn't same thing as gas, some mapping is required between those types
-pub type Weight = frame_support::pallet_prelude::Weight;
-
-/// In substrate, we have benchmarking, which allows
-/// us to not rely on gas metering, but instead predict amount of gas to execute call
-pub trait Weighted: Call {
- /// Predict weight of this call
- fn weight(&self) -> DispatchInfo;
-}
-
-/// Type callable with ethereum message, may be implemented by [`solidity_interface`] macro
-/// on interface implementation, or for externally-owned real EVM contract
-pub trait Callable<C: Call> {
- /// Call contract using specified call data
- fn call(&mut self, call: types::Msg<C>) -> execution::ResultWithPostInfo<AbiWriter>;
-}
-
-/// Implementation of ERC165 is implicitly generated for all interfaces in [`solidity_interface`],
-/// this structure holds parsed data for ERC165Call subvariant
-///
-/// Note: no [`Callable`] implementation is provided, call implementation is inlined into every
-/// implementing contract
-///
-/// See <https://eips.ethereum.org/EIPS/eip-165>
-#[derive(Debug)]
-pub enum ERC165Call {
- /// ERC165 provides single method, which returns true, if contract
- /// implements specified interface
- SupportsInterface {
- /// Requested interface
- interface_id: types::Bytes4,
- },
-}
-
-impl ERC165Call {
- /// ERC165 selector is provided by standard
- pub const INTERFACE_ID: types::Bytes4 = u32::to_be_bytes(0x01ffc9a7);
-}
-
-impl Call for ERC165Call {
- fn parse(selector: types::Bytes4, input: &mut AbiReader) -> execution::Result<Option<Self>> {
- if selector != Self::INTERFACE_ID {
- return Ok(None);
- }
- Ok(Some(Self::SupportsInterface {
- interface_id: types::Bytes4::abi_read(input)?,
- }))
- }
-}
-
-/// Generate "tests", which will generate solidity code on execution and print it to stdout
-/// Script at .maintain/scripts/generate_api.sh can split this output from test runtime
-///
-/// This macro receives type usage as second argument, but you can use anything as generics,
-/// because no bounds are implied
-#[macro_export]
-macro_rules! generate_stubgen {
- ($name:ident, $decl:ty, $is_impl:literal) => {
- #[cfg(feature = "stubgen")]
- #[test]
- #[ignore]
- fn $name() {
- use evm_coder::solidity::TypeCollector;
- let mut out = TypeCollector::new();
- <$decl>::generate_solidity_interface(&mut out, $is_impl);
- println!("=== SNIP START ===");
- println!("// SPDX-License-Identifier: OTHER");
- println!("// This code is automatically generated");
- println!();
- println!("pragma solidity >=0.8.0 <0.9.0;");
- println!();
- for b in out.finish() {
- println!("{}", b);
- }
- println!("=== SNIP END ===");
- }
- };
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn function_selector_generation() {
- assert_eq!(fn_selector!(transfer(address, uint256)), 0xa9059cbb);
- }
-
- #[test]
- fn event_topic_generation() {
- assert_eq!(
- hex::encode(&event_topic!(Transfer(address, address, uint256))[..]),
- "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- );
- }
-}
crates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth--- a/crates/evm-coder/src/solidity/impls.rs
+++ /dev/null
@@ -1,179 +0,0 @@
-use super::{TypeCollector, SolidityTypeName, SolidityTupleTy};
-use crate::{sealed, types::*};
-use core::fmt;
-use primitive_types::{U256, H160};
-
-macro_rules! solidity_type_name {
- ($($ty:ty => $name:literal $simple:literal = $default:literal),* $(,)?) => {
- $(
- impl SolidityTypeName for $ty {
- fn solidity_name(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {
- write!(writer, $name)
- }
- fn is_simple() -> bool {
- $simple
- }
- fn solidity_default(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {
- write!(writer, $default)
- }
- }
- )*
- };
-}
-
-solidity_type_name! {
- u8 => "uint8" true = "0",
- u32 => "uint32" true = "0",
- u64 => "uint64" true = "0",
- u128 => "uint128" true = "0",
- U256 => "uint256" true = "0",
- Bytes4 => "bytes4" true = "bytes4(0)",
- H160 => "address" true = "0x0000000000000000000000000000000000000000",
- String => "string" false = "\"\"",
- Bytes => "bytes" false = "hex\"\"",
- bool => "bool" true = "false",
-}
-
-impl SolidityTypeName for () {
- fn solidity_name(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
- Ok(())
- }
- fn is_simple() -> bool {
- true
- }
- fn solidity_default(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
- Ok(())
- }
- fn is_void() -> bool {
- true
- }
-}
-
-impl<T: SolidityTypeName + sealed::CanBePlacedInVec> SolidityTypeName for Vec<T> {
- fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- T::solidity_name(writer, tc)?;
- write!(writer, "[]")
- }
- fn is_simple() -> bool {
- false
- }
- fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- write!(writer, "new ")?;
- T::solidity_name(writer, tc)?;
- write!(writer, "[](0)")
- }
-}
-
-macro_rules! count {
- () => (0usize);
- ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
-}
-
-macro_rules! impl_tuples {
- ($($ident:ident)+) => {
- impl<$($ident: SolidityTypeName + 'static),+> SolidityTupleTy for ($($ident,)+) {
- fn fields(tc: &TypeCollector) -> Vec<String> {
- let mut collected = Vec::with_capacity(Self::len());
- $({
- let mut out = String::new();
- $ident::solidity_name(&mut out, tc).expect("no fmt error");
- collected.push(out);
- })*;
- collected
- }
-
- fn len() -> usize {
- count!($($ident)*)
- }
- }
- impl<$($ident: SolidityTypeName + 'static),+> SolidityTypeName for ($($ident,)+) {
- fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- write!(writer, "{}", tc.collect_tuple::<Self>())
- }
- fn is_simple() -> bool {
- false
- }
- #[allow(unused_assignments)]
- fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- write!(writer, "{}(", tc.collect_tuple::<Self>())?;
- let mut first = true;
- $(
- if !first {
- write!(writer, ",")?;
- } else {
- first = false;
- }
- <$ident>::solidity_default(writer, tc)?;
- )*
- write!(writer, ")")
- }
- }
- };
-}
-
-impl_tuples! {A}
-impl_tuples! {A B}
-impl_tuples! {A B C}
-impl_tuples! {A B C D}
-impl_tuples! {A B C D E}
-impl_tuples! {A B C D E F}
-impl_tuples! {A B C D E F G}
-impl_tuples! {A B C D E F G H}
-impl_tuples! {A B C D E F G H I}
-impl_tuples! {A B C D E F G H I J}
-
-//----- impls for Option -----
-impl<T: SolidityTypeName + 'static> SolidityTypeName for Option<T> {
- fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- write!(writer, "{}", tc.collect_struct::<Self>())
- }
- fn is_simple() -> bool {
- false
- }
- fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- write!(writer, "{}(", tc.collect_struct::<Self>())?;
- bool::solidity_default(writer, tc)?;
- write!(writer, ", ");
- T::solidity_default(writer, tc)?;
- write!(writer, ")")
- }
-}
-
-impl<T: SolidityTypeName> super::SolidityStructTy for Option<T> {
- fn generate_solidity_interface(tc: &TypeCollector) -> String {
- let mut solidity_name = "Option".to_string();
- let mut generic_name = String::new();
- T::solidity_name(&mut generic_name, tc);
- solidity_name.push(
- generic_name
- .chars()
- .next()
- .expect("Generic name is empty")
- .to_ascii_uppercase(),
- );
- solidity_name.push_str(&generic_name[1..]);
-
- let interface = super::SolidityStruct {
- docs: &[" Optional value"],
- name: solidity_name.as_str(),
- fields: (
- super::SolidityStructField::<bool> {
- docs: &[" Shows the status of accessibility of value"],
- name: "status",
- ty: ::core::marker::PhantomData,
- },
- super::SolidityStructField::<T> {
- docs: &[" Actual value if `status` is true"],
- name: "value",
- ty: ::core::marker::PhantomData,
- },
- ),
- };
-
- let mut out = String::new();
- let _ = interface.format(&mut out, tc);
- tc.collect(out);
-
- solidity_name.to_string()
- }
-}
crates/evm-coder/src/solidity/mod.rsdiffbeforeafterboth--- a/crates/evm-coder/src/solidity/mod.rs
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-//! Implementation detail of [`crate::solidity_interface`] macro code-generation.
-//! You should not rely on any public item from this module, as it is only intended to be used
-//! by procedural macro, API and output format may be changed at any time.
-//!
-//! Purpose of this module is to receive solidity contract definition in module-specified
-//! format, and then output string, representing interface of this contract in solidity language
-
-mod traits;
-pub use traits::*;
-mod impls;
-
-#[cfg(not(feature = "std"))]
-use alloc::{vec::Vec, collections::BTreeMap, format};
-#[cfg(feature = "std")]
-use std::collections::BTreeMap;
-use core::{
- fmt::{self, Write},
- marker::PhantomData,
- cell::{Cell, RefCell},
- cmp::Reverse,
-};
-use impl_trait_for_tuples::impl_for_tuples;
-use crate::{types::*, custom_signature::SignatureUnit};
-
-#[derive(Default)]
-pub struct TypeCollector {
- /// Code => id
- /// id ordering is required to perform topo-sort on the resulting data
- structs: RefCell<BTreeMap<String, usize>>,
- anonymous: RefCell<BTreeMap<Vec<String>, usize>>,
- // generic: RefCell<BTreeMap<String, usize>>,
- id: Cell<usize>,
-}
-impl TypeCollector {
- pub fn new() -> Self {
- Self::default()
- }
- pub fn collect(&self, item: String) {
- let id = self.next_id();
- self.structs.borrow_mut().insert(item, id);
- }
- pub fn next_id(&self) -> usize {
- let v = self.id.get();
- self.id.set(v + 1);
- v
- }
- /// Collect typle, deduplicating it by type, and returning generated name
- pub fn collect_tuple<T: SolidityTupleTy>(&self) -> String {
- let names = T::fields(self);
- if let Some(id) = self.anonymous.borrow().get(&names).cloned() {
- return format!("Tuple{}", id);
- }
- let id = self.next_id();
- let mut str = String::new();
- writeln!(str, "/// @dev anonymous struct").unwrap();
- writeln!(str, "struct Tuple{} {{", id).unwrap();
- for (i, name) in names.iter().enumerate() {
- writeln!(str, "\t{} field_{};", name, i).unwrap();
- }
- writeln!(str, "}}").unwrap();
- self.collect(str);
- self.anonymous.borrow_mut().insert(names, id);
- format!("Tuple{}", id)
- }
- pub fn collect_struct<T: SolidityStructTy>(&self) -> String {
- T::generate_solidity_interface(self)
- }
- pub fn collect_enum<T: SolidityEnumTy>(&self) -> String {
- T::generate_solidity_interface(self)
- }
- pub fn finish(self) -> Vec<String> {
- let mut data = self.structs.into_inner().into_iter().collect::<Vec<_>>();
- data.sort_by_key(|(_, id)| Reverse(*id));
- data.into_iter().map(|(code, _)| code).collect()
- }
-}
-#[derive(Default)]
-pub struct UnnamedArgument<T>(PhantomData<*const T>);
-
-impl<T: SolidityTypeName> SolidityArguments for UnnamedArgument<T> {
- fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- if !T::is_void() {
- T::solidity_name(writer, tc)?;
- if !T::is_simple() {
- write!(writer, " memory")?;
- }
- Ok(())
- } else {
- Ok(())
- }
- }
- fn solidity_get(&self, _prefix: &str, _writer: &mut impl fmt::Write) -> fmt::Result {
- Ok(())
- }
- fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- T::solidity_default(writer, tc)
- }
- fn len(&self) -> usize {
- if T::is_void() {
- 0
- } else {
- 1
- }
- }
-}
-
-pub struct NamedArgument<T>(&'static str, PhantomData<*const T>);
-
-impl<T> NamedArgument<T> {
- pub fn new(name: &'static str) -> Self {
- Self(name, Default::default())
- }
-}
-
-impl<T: SolidityTypeName> SolidityArguments for NamedArgument<T> {
- fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- if !T::is_void() {
- T::solidity_name(writer, tc)?;
- if !T::is_simple() {
- write!(writer, " memory")?;
- }
- write!(writer, " {}", self.0)
- } else {
- Ok(())
- }
- }
- fn solidity_get(&self, prefix: &str, writer: &mut impl fmt::Write) -> fmt::Result {
- writeln!(writer, "\t{prefix}\t{};", self.0)
- }
- fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- T::solidity_default(writer, tc)
- }
- fn len(&self) -> usize {
- if T::is_void() {
- 0
- } else {
- 1
- }
- }
-}
-
-pub struct SolidityEventArgument<T>(pub bool, &'static str, PhantomData<*const T>);
-
-impl<T> SolidityEventArgument<T> {
- pub fn new(indexed: bool, name: &'static str) -> Self {
- Self(indexed, name, Default::default())
- }
-}
-
-impl<T: SolidityTypeName> SolidityArguments for SolidityEventArgument<T> {
- fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- if !T::is_void() {
- T::solidity_name(writer, tc)?;
- if self.0 {
- write!(writer, " indexed")?;
- }
- write!(writer, " {}", self.1)
- } else {
- Ok(())
- }
- }
- fn solidity_get(&self, prefix: &str, writer: &mut impl fmt::Write) -> fmt::Result {
- writeln!(writer, "\t{prefix}\t{};", self.1)
- }
- fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- T::solidity_default(writer, tc)
- }
- fn len(&self) -> usize {
- if T::is_void() {
- 0
- } else {
- 1
- }
- }
-}
-
-impl SolidityArguments for () {
- fn solidity_name(&self, _writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
- Ok(())
- }
- fn solidity_get(&self, _prefix: &str, _writer: &mut impl fmt::Write) -> fmt::Result {
- Ok(())
- }
- fn solidity_default(&self, _writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
- Ok(())
- }
- fn len(&self) -> usize {
- 0
- }
-}
-
-#[impl_for_tuples(1, 12)]
-impl SolidityArguments for Tuple {
- for_tuples!( where #( Tuple: SolidityArguments ),* );
-
- fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- let mut first = true;
- for_tuples!( #(
- if !Tuple.is_empty() {
- if !first {
- write!(writer, ", ")?;
- }
- first = false;
- Tuple.solidity_name(writer, tc)?;
- }
- )* );
- Ok(())
- }
- fn solidity_get(&self, prefix: &str, writer: &mut impl fmt::Write) -> fmt::Result {
- for_tuples!( #(
- Tuple.solidity_get(prefix, writer)?;
- )* );
- Ok(())
- }
- fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- if self.is_empty() {
- Ok(())
- } else if self.len() == 1 {
- for_tuples!( #(
- Tuple.solidity_default(writer, tc)?;
- )* );
- Ok(())
- } else {
- write!(writer, "(")?;
- let mut first = true;
- for_tuples!( #(
- if !Tuple.is_empty() {
- if !first {
- write!(writer, ", ")?;
- }
- first = false;
- Tuple.solidity_default(writer, tc)?;
- }
- )* );
- write!(writer, ")")?;
- Ok(())
- }
- }
- fn len(&self) -> usize {
- for_tuples!( #( Tuple.len() )+* )
- }
-}
-
-pub enum SolidityMutability {
- Pure,
- View,
- Mutable,
-}
-pub struct SolidityFunction<A, R> {
- pub docs: &'static [&'static str],
- pub selector: u32,
- pub hide: bool,
- pub custom_signature: SignatureUnit,
- pub name: &'static str,
- pub args: A,
- pub result: R,
- pub mutability: SolidityMutability,
- pub is_payable: bool,
-}
-impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {
- fn solidity_name(
- &self,
- is_impl: bool,
- writer: &mut impl fmt::Write,
- tc: &TypeCollector,
- ) -> fmt::Result {
- let hide_comment = self.hide.then_some("// ").unwrap_or("");
- for doc in self.docs {
- writeln!(writer, "\t{hide_comment}///{}", doc)?;
- }
- writeln!(
- writer,
- "\t{hide_comment}/// @dev EVM selector for this function is: 0x{:0>8x},",
- self.selector
- )?;
- writeln!(
- writer,
- "\t{hide_comment}/// or in textual repr: {}",
- self.custom_signature.as_str().expect("bad utf-8")
- )?;
- write!(writer, "\t{hide_comment}function {}(", self.name)?;
- self.args.solidity_name(writer, tc)?;
- write!(writer, ")")?;
- if is_impl {
- write!(writer, " public")?;
- } else {
- write!(writer, " external")?;
- }
- match &self.mutability {
- SolidityMutability::Pure => write!(writer, " pure")?,
- SolidityMutability::View => write!(writer, " view")?,
- SolidityMutability::Mutable => {}
- }
- if self.is_payable {
- write!(writer, " payable")?;
- }
- if !self.result.is_empty() {
- write!(writer, " returns (")?;
- self.result.solidity_name(writer, tc)?;
- write!(writer, ")")?;
- }
- if is_impl {
- writeln!(writer, " {{")?;
- writeln!(writer, "\t{hide_comment}\trequire(false, stub_error);")?;
- self.args.solidity_get(hide_comment, writer)?;
- match &self.mutability {
- SolidityMutability::Pure => {}
- SolidityMutability::View => writeln!(writer, "\t{hide_comment}\tdummy;")?,
- SolidityMutability::Mutable => writeln!(writer, "\t{hide_comment}\tdummy = 0;")?,
- }
- if !self.result.is_empty() {
- write!(writer, "\t{hide_comment}\treturn ")?;
- self.result.solidity_default(writer, tc)?;
- writeln!(writer, ";")?;
- }
- writeln!(writer, "\t{hide_comment}}}")?;
- } else {
- writeln!(writer, ";")?;
- }
- if self.hide {
- writeln!(writer, "// FORMATTING: FORCE NEWLINE")?;
- }
- Ok(())
- }
-}
-
-#[impl_for_tuples(0, 48)]
-impl SolidityFunctions for Tuple {
- for_tuples!( where #( Tuple: SolidityFunctions ),* );
-
- fn solidity_name(
- &self,
- is_impl: bool,
- writer: &mut impl fmt::Write,
- tc: &TypeCollector,
- ) -> fmt::Result {
- let mut first = false;
- for_tuples!( #(
- Tuple.solidity_name(is_impl, writer, tc)?;
- )* );
- Ok(())
- }
-}
-
-pub struct SolidityInterface<F: SolidityFunctions> {
- pub docs: &'static [&'static str],
- pub selector: Bytes4,
- pub name: &'static str,
- pub is: &'static [&'static str],
- pub functions: F,
-}
-
-impl<F: SolidityFunctions> SolidityInterface<F> {
- pub fn format(
- &self,
- is_impl: bool,
- out: &mut impl fmt::Write,
- tc: &TypeCollector,
- ) -> fmt::Result {
- const ZERO_BYTES: [u8; 4] = [0; 4];
- for doc in self.docs {
- writeln!(out, "///{}", doc)?;
- }
- if self.selector != ZERO_BYTES {
- writeln!(
- out,
- "/// @dev the ERC-165 identifier for this interface is 0x{:0>8x}",
- u32::from_be_bytes(self.selector)
- )?;
- }
- if is_impl {
- write!(out, "contract ")?;
- } else {
- write!(out, "interface ")?;
- }
- write!(out, "{}", self.name)?;
- if !self.is.is_empty() {
- write!(out, " is")?;
- for (i, n) in self.is.iter().enumerate() {
- if i != 0 {
- write!(out, ",")?;
- }
- write!(out, " {}", n)?;
- }
- }
- writeln!(out, " {{")?;
- self.functions.solidity_name(is_impl, out, tc)?;
- writeln!(out, "}}")?;
- Ok(())
- }
-}
-
-pub struct SolidityEvent<A> {
- pub name: &'static str,
- pub args: A,
-}
-
-impl<A: SolidityArguments> SolidityFunctions for SolidityEvent<A> {
- fn solidity_name(
- &self,
- _is_impl: bool,
- writer: &mut impl fmt::Write,
- tc: &TypeCollector,
- ) -> fmt::Result {
- write!(writer, "\tevent {}(", self.name)?;
- self.args.solidity_name(writer, tc)?;
- writeln!(writer, ");")
- }
-}
-
-#[impl_for_tuples(0, 48)]
-impl SolidityItems for Tuple {
- for_tuples!( where #( Tuple: SolidityItems ),* );
-
- fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- for_tuples!( #(
- Tuple.solidity_name(writer, tc)?;
- )* );
- Ok(())
- }
-}
-
-pub struct SolidityStructField<T> {
- pub docs: &'static [&'static str],
- pub name: &'static str,
- pub ty: PhantomData<*const T>,
-}
-
-impl<T> SolidityItems for SolidityStructField<T>
-where
- T: SolidityTypeName,
-{
- fn solidity_name(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- for doc in self.docs {
- writeln!(out, "///{}", doc)?;
- }
- write!(out, "\t")?;
- T::solidity_name(out, tc)?;
- writeln!(out, " {};", self.name)?;
- Ok(())
- }
-}
-pub struct SolidityStruct<'a, F> {
- pub docs: &'a [&'a str],
- // pub generics:
- pub name: &'a str,
- pub fields: F,
-}
-impl<F> SolidityStruct<'_, F>
-where
- F: SolidityItems,
-{
- pub fn format(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- for doc in self.docs {
- writeln!(out, "///{}", doc)?;
- }
- writeln!(out, "struct {} {{", self.name)?;
- self.fields.solidity_name(out, tc)?;
- writeln!(out, "}}")?;
- Ok(())
- }
-}
-
-pub struct SolidityEnumVariant {
- pub docs: &'static [&'static str],
- pub name: &'static str,
-}
-impl SolidityItems for SolidityEnumVariant {
- fn solidity_name(&self, out: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
- for doc in self.docs {
- writeln!(out, "///{}", doc)?;
- }
- write!(out, "\t{}", self.name)?;
- Ok(())
- }
-}
-pub struct SolidityEnum {
- pub docs: &'static [&'static str],
- pub name: &'static str,
- pub fields: &'static [SolidityEnumVariant],
-}
-impl SolidityEnum {
- pub fn format(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
- for doc in self.docs {
- writeln!(out, "///{}", doc)?;
- }
- write!(out, "enum {} {{", self.name)?;
- for (i, field) in self.fields.iter().enumerate() {
- if i != 0 {
- write!(out, ",")?;
- }
- writeln!(out)?;
- field.solidity_name(out, tc)?;
- }
- writeln!(out)?;
- writeln!(out, "}}")?;
- Ok(())
- }
-}
crates/evm-coder/src/solidity/traits.rsdiffbeforeafterboth--- a/crates/evm-coder/src/solidity/traits.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use super::TypeCollector;
-use core::fmt;
-
-pub trait SolidityTypeName: 'static {
- fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
- /// "simple" types are stored inline, no `memory` modifier should be used in solidity
- fn is_simple() -> bool;
- fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
- /// Specialization
- fn is_void() -> bool {
- false
- }
-}
-
-pub trait SolidityTupleTy: 'static {
- fn fields(tc: &TypeCollector) -> Vec<String>;
- fn len() -> usize;
-}
-pub trait SolidityStructTy: 'static {
- fn generate_solidity_interface(tc: &TypeCollector) -> String;
-}
-pub trait SolidityEnumTy: 'static {
- fn generate_solidity_interface(tc: &TypeCollector) -> String;
- fn solidity_option(&self) -> &str;
-}
-
-pub trait SolidityArguments {
- fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
- fn solidity_get(&self, prefix: &str, writer: &mut impl fmt::Write) -> fmt::Result;
- fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
- fn is_empty(&self) -> bool {
- self.len() == 0
- }
- fn len(&self) -> usize;
-}
-
-pub trait SolidityFunctions {
- fn solidity_name(
- &self,
- is_impl: bool,
- writer: &mut impl fmt::Write,
- tc: &TypeCollector,
- ) -> fmt::Result;
-}
-
-pub trait SolidityItems {
- fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
- // For PhantomData fields
- // fn is_void()
-}
crates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/abi_derive_generation.rs
+++ /dev/null
@@ -1,765 +0,0 @@
-mod test_struct {
- use evm_coder_procedural::AbiCoder;
- use evm_coder::types::Bytes;
-
- #[test]
- fn empty_struct() {
- let t = trybuild::TestCases::new();
- t.compile_fail("tests/build_failed/abi_derive_struct_generation.rs");
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct1SimpleParam {
- _a: u8,
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct1DynamicParam {
- _a: String,
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct2SimpleParam {
- _a: u8,
- _b: u32,
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct2DynamicParam {
- _a: String,
- _b: Bytes,
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct2MixedParam {
- _a: u8,
- _b: Bytes,
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct1DerivedSimpleParam {
- _a: TypeStruct1SimpleParam,
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct2DerivedSimpleParam {
- _a: TypeStruct1SimpleParam,
- _b: TypeStruct2SimpleParam,
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct1DerivedDynamicParam {
- _a: TypeStruct1DynamicParam,
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct2DerivedDynamicParam {
- _a: TypeStruct1DynamicParam,
- _b: TypeStruct2DynamicParam,
- }
-
- /// Some docs
- /// At multi
- /// line
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct3DerivedMixedParam {
- /// Docs for A
- /// multi
- /// line
- _a: TypeStruct1SimpleParam,
- /// Docs for B
- _b: TypeStruct2DynamicParam,
- /// Docs for C
- _c: TypeStruct2MixedParam,
- }
-
- #[test]
- fn impl_abi_type_signature() {
- assert_eq!(
- <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "(uint8)"
- );
- assert_eq!(
- <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "(string)"
- );
- assert_eq!(
- <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "(uint8,uint32)"
- );
- assert_eq!(
- <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "(string,bytes)"
- );
- assert_eq!(
- <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "(uint8,bytes)"
- );
- assert_eq!(
- <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "((uint8))"
- );
- assert_eq!(
- <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "((uint8),(uint8,uint32))"
- );
- assert_eq!(
- <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "((string))"
- );
- assert_eq!(
- <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "((string),(string,bytes))"
- );
- assert_eq!(
- <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- "((uint8),(string,bytes),(uint8,bytes))"
- );
- }
-
- #[test]
- fn impl_abi_type_is_dynamic() {
- assert_eq!(
- <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
- false
- );
- assert_eq!(
- <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
- true
- );
- assert_eq!(
- <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
- false
- );
- assert_eq!(
- <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
- true
- );
- assert_eq!(
- <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),
- true
- );
- assert_eq!(
- <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
- false
- );
- assert_eq!(
- <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
- false
- );
- assert_eq!(
- <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
- true
- );
- assert_eq!(
- <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
- true
- );
- assert_eq!(
- <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),
- true
- );
- }
-
- #[test]
- fn impl_abi_type_size() {
- const ABI_ALIGNMENT: usize = 32;
- assert_eq!(
- <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT
- );
- assert_eq!(
- <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT
- );
- assert_eq!(
- <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT * 2
- );
- assert_eq!(
- <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT * 2
- );
- assert_eq!(
- <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT * 2
- );
- assert_eq!(
- <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT
- );
- assert_eq!(
- <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT * 3
- );
- assert_eq!(
- <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT
- );
- assert_eq!(
- <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT * 3
- );
- assert_eq!(
- <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),
- ABI_ALIGNMENT * 5
- );
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct1SimpleParam(u8);
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct1DynamicParam(String);
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct2SimpleParam(u8, u32);
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct2DynamicParam(String, Bytes);
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct2MixedParam(u8, Bytes);
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);
-
- /// Some docs
- /// At multi
- /// line
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct3DerivedMixedParam(
- /// Docs for A
- /// multi
- /// line
- TupleStruct1SimpleParam,
- TupleStruct2DynamicParam,
- /// Docs for C
- TupleStruct2MixedParam,
- );
-
- #[test]
- fn impl_abi_type_signature_same_for_structs() {
- assert_eq!(
- <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap()
- );
- assert_eq!(
- <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap()
- );
- assert_eq!(
- <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap()
- );
- assert_eq!(
- <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap()
- );
- assert_eq!(
- <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- );
- assert_eq!(
- <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- );
- assert_eq!(
- <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- );
- assert_eq!(
- <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- );
- assert_eq!(
- <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- );
- assert_eq!(
- <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- );
- }
-
- #[test]
- fn impl_abi_type_is_dynamic_same_for_structs() {
- assert_eq!(
- <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- assert_eq!(
- <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),
- <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic()
- );
- }
-
- #[test]
- fn impl_abi_type_size_same_for_structs() {
- assert_eq!(
- <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct2MixedParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size()
- );
- assert_eq!(
- <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),
- <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size()
- );
- }
-
- const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;
-
- fn test_impl<Tuple, TupleStruct, TypeStruct>(
- tuple_data: Tuple,
- tuple_struct_data: TupleStruct,
- type_struct_data: TypeStruct,
- ) where
- TypeStruct: evm_coder::abi::AbiWrite
- + evm_coder::abi::AbiRead
- + std::cmp::PartialEq
- + std::fmt::Debug,
- TupleStruct: evm_coder::abi::AbiWrite
- + evm_coder::abi::AbiRead
- + std::cmp::PartialEq
- + std::fmt::Debug,
- Tuple: evm_coder::abi::AbiWrite
- + evm_coder::abi::AbiRead
- + std::cmp::PartialEq
- + std::fmt::Debug,
- {
- let encoded_type_struct = test_abi_write_impl(&type_struct_data);
- let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);
- let encoded_tuple = test_abi_write_impl(&tuple_data);
-
- similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);
- similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);
-
- {
- let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();
- let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();
- assert_eq!(restored_struct_data, type_struct_data);
- }
- {
- let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();
- let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();
- assert_eq!(restored_struct_data, tuple_struct_data);
- }
-
- {
- let (_, mut decoder) =
- evm_coder::abi::AbiReader::new_call(&encoded_type_struct).unwrap();
- let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
- assert_eq!(restored_tuple_data, tuple_data);
- }
- {
- let (_, mut decoder) =
- evm_coder::abi::AbiReader::new_call(&encoded_tuple_struct).unwrap();
- let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
- assert_eq!(restored_tuple_data, tuple_data);
- }
- }
-
- fn test_abi_write_impl<A>(data: &A) -> Vec<u8>
- where
- A: evm_coder::abi::AbiWrite
- + evm_coder::abi::AbiRead
- + std::cmp::PartialEq
- + std::fmt::Debug,
- {
- let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);
- data.abi_write(&mut writer);
- let encoded_tuple = writer.finish();
- encoded_tuple
- }
-
- #[test]
- fn codec_struct_1_simple() {
- let _a = 0xff;
- test_impl::<(u8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(
- (_a,),
- TupleStruct1SimpleParam(_a),
- TypeStruct1SimpleParam { _a },
- );
- }
-
- #[test]
- fn codec_struct_1_dynamic() {
- let _a: String = "some string".into();
- test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(
- (_a.clone(),),
- TupleStruct1DynamicParam(_a.clone()),
- TypeStruct1DynamicParam { _a },
- );
- }
-
- #[test]
- fn codec_struct_1_derived_simple() {
- let _a: u8 = 0xff;
- test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(
- ((_a,),),
- TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),
- TypeStruct1DerivedSimpleParam {
- _a: TypeStruct1SimpleParam { _a },
- },
- );
- }
-
- #[test]
- fn codec_struct_1_derived_dynamic() {
- let _a: String = "some string".into();
- test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(
- ((_a.clone(),),),
- TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),
- TypeStruct1DerivedDynamicParam {
- _a: TypeStruct1DynamicParam { _a },
- },
- );
- }
-
- #[test]
- fn codec_struct_2_simple() {
- let _a = 0xff;
- let _b = 0xbeefbaba;
- test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(
- (_a, _b),
- TupleStruct2SimpleParam(_a, _b),
- TypeStruct2SimpleParam { _a, _b },
- );
- }
-
- #[test]
- fn codec_struct_2_dynamic() {
- let _a: String = "some string".into();
- let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]);
- test_impl::<(String, Bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
- (_a.clone(), _b.clone()),
- TupleStruct2DynamicParam(_a.clone(), _b.clone()),
- TypeStruct2DynamicParam { _a, _b },
- );
- }
-
- #[test]
- fn codec_struct_2_mixed() {
- let _a: u8 = 0xff;
- let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]);
- test_impl::<(u8, Bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(
- (_a.clone(), _b.clone()),
- TupleStruct2MixedParam(_a.clone(), _b.clone()),
- TypeStruct2MixedParam { _a, _b },
- );
- }
-
- #[test]
- fn codec_struct_2_derived_simple() {
- let _a = 0xff;
- let _b = 0xbeefbaba;
- test_impl::<
- ((u8,), (u8, u32)),
- TupleStruct2DerivedSimpleParam,
- TypeStruct2DerivedSimpleParam,
- >(
- ((_a,), (_a, _b)),
- TupleStruct2DerivedSimpleParam(
- TupleStruct1SimpleParam(_a),
- TupleStruct2SimpleParam(_a, _b),
- ),
- TypeStruct2DerivedSimpleParam {
- _a: TypeStruct1SimpleParam { _a },
- _b: TypeStruct2SimpleParam { _a, _b },
- },
- );
- }
-
- #[test]
- fn codec_struct_2_derived_dynamic() {
- let _a = "some string".to_string();
- let _b = Bytes(vec![0x11, 0x22, 0x33]);
- test_impl::<
- ((String,), (String, Bytes)),
- TupleStruct2DerivedDynamicParam,
- TypeStruct2DerivedDynamicParam,
- >(
- ((_a.clone(),), (_a.clone(), _b.clone())),
- TupleStruct2DerivedDynamicParam(
- TupleStruct1DynamicParam(_a.clone()),
- TupleStruct2DynamicParam(_a.clone(), _b.clone()),
- ),
- TypeStruct2DerivedDynamicParam {
- _a: TypeStruct1DynamicParam { _a: _a.clone() },
- _b: TypeStruct2DynamicParam { _a, _b },
- },
- );
- }
-
- #[test]
- fn codec_struct_3_derived_mixed() {
- let int = 0xff;
- let by = Bytes(vec![0x11, 0x22, 0x33]);
- let string = "some string".to_string();
- test_impl::<
- ((u8,), (String, Bytes), (u8, Bytes)),
- TupleStruct3DerivedMixedParam,
- TypeStruct3DerivedMixedParam,
- >(
- ((int,), (string.clone(), by.clone()), (int, by.clone())),
- TupleStruct3DerivedMixedParam(
- TupleStruct1SimpleParam(int),
- TupleStruct2DynamicParam(string.clone(), by.clone()),
- TupleStruct2MixedParam(int, by.clone()),
- ),
- TypeStruct3DerivedMixedParam {
- _a: TypeStruct1SimpleParam { _a: int },
- _b: TypeStruct2DynamicParam {
- _a: string.clone(),
- _b: by.clone(),
- },
- _c: TypeStruct2MixedParam { _a: int, _b: by },
- },
- );
- }
-
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TypeStruct2SimpleStruct1Simple {
- _a: TypeStruct2SimpleParam,
- _b: TypeStruct2SimpleParam,
- _c: u8,
- }
- #[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct2SimpleStruct1Simple(TupleStruct2SimpleParam, TupleStruct2SimpleParam, u8);
-
- #[test]
- fn codec_struct_2_struct_simple_1_simple() {
- let _a = 0xff;
- let _b = 0xbeefbaba;
- test_impl::<
- ((u8, u32), (u8, u32), u8),
- TupleStruct2SimpleStruct1Simple,
- TypeStruct2SimpleStruct1Simple,
- >(
- ((_a, _b), (_a, _b), _a),
- TupleStruct2SimpleStruct1Simple(
- TupleStruct2SimpleParam(_a, _b),
- TupleStruct2SimpleParam(_a, _b),
- _a,
- ),
- TypeStruct2SimpleStruct1Simple {
- _a: TypeStruct2SimpleParam { _a, _b },
- _b: TypeStruct2SimpleParam { _a, _b },
- _c: _a,
- },
- );
- }
-}
-
-mod test_enum {
- use evm_coder::AbiCoder;
-
- /// Some docs
- /// At multi
- /// line
- #[derive(AbiCoder, Debug, PartialEq, Default, Clone, Copy)]
- #[repr(u8)]
- enum Color {
- /// Docs for Red
- /// multi
- /// line
- Red,
- Green,
- /// Docs for Blue
- #[default]
- Blue,
- }
-
- #[test]
- fn empty() {}
-
- #[test]
- fn bad_enums() {
- let t = trybuild::TestCases::new();
- t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");
- }
-
- #[test]
- fn impl_abi_type_signature_same_for_structs() {
- assert_eq!(
- <Color as evm_coder::abi::AbiType>::SIGNATURE
- .as_str()
- .unwrap(),
- <u8 as evm_coder::abi::AbiType>::SIGNATURE.as_str().unwrap()
- );
- }
-
- #[test]
- fn impl_abi_type_is_dynamic_same_for_structs() {
- assert_eq!(
- <Color as evm_coder::abi::AbiType>::is_dynamic(),
- <u8 as evm_coder::abi::AbiType>::is_dynamic()
- );
- }
-
- #[test]
- fn impl_abi_type_size_same_for_structs() {
- assert_eq!(
- <Color as evm_coder::abi::AbiType>::size(),
- <u8 as evm_coder::abi::AbiType>::size()
- );
- }
-
- #[test]
- fn test_coder() {
- const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;
-
- let encoded_enum = {
- let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);
- <Color as evm_coder::abi::AbiWrite>::abi_write(&Color::Green, &mut writer);
- writer.finish()
- };
-
- let encoded_u8 = {
- let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);
- <u8 as evm_coder::abi::AbiWrite>::abi_write(&(Color::Green as u8), &mut writer);
- writer.finish()
- };
-
- similar_asserts::assert_eq!(encoded_enum, encoded_u8);
-
- {
- let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_enum).unwrap();
- let restored_enum_data =
- <Color as evm_coder::abi::AbiRead>::abi_read(&mut decoder).unwrap();
- assert_eq!(restored_enum_data, Color::Green);
- }
- }
-}
crates/evm-coder/tests/build_failed/abi_derive_enum_generation.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/build_failed/abi_derive_enum_generation.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use evm_coder_procedural::AbiCoder;
-
-#[derive(AbiCoder)]
-enum NonRepr {
- A,
- B,
- C,
-}
-
-#[derive(AbiCoder)]
-#[repr(u32)]
-enum NonReprU8 {
- A,
- B,
- C,
-}
-
-#[derive(AbiCoder)]
-#[repr(u8)]
-enum RustEnum {
- A(u128),
- B,
- C,
-}
-
-#[derive(AbiCoder)]
-#[repr(u8)]
-enum WithExplicit {
- A = 128,
- B,
- C,
-}
-
-fn main() {
- assert!(false);
-}
crates/evm-coder/tests/build_failed/abi_derive_enum_generation.stderrdiffbeforeafterboth--- a/crates/evm-coder/tests/build_failed/abi_derive_enum_generation.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error: Enum is not "repr(u8)"
- --> tests/build_failed/abi_derive_enum_generation.rs:4:6
- |
-4 | enum NonRepr {
- | ^^^^^^^
-
-error: Enum is not "repr(u8)"
- --> tests/build_failed/abi_derive_enum_generation.rs:11:8
- |
-11 | #[repr(u32)]
- | ^^^
-
-error: Enumeration parameters should not have fields
- --> tests/build_failed/abi_derive_enum_generation.rs:21:2
- |
-21 | A(u128),
- | ^
-
-error: Enumeration options should not have an explicit specified value
- --> tests/build_failed/abi_derive_enum_generation.rs:29:2
- |
-29 | A = 128,
- | ^
crates/evm-coder/tests/build_failed/abi_derive_struct_generation.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/build_failed/abi_derive_struct_generation.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-use evm_coder_procedural::AbiCoder;
-
-#[derive(AbiCoder, PartialEq, Debug)]
-struct EmptyStruct {}
-
-#[derive(AbiCoder, PartialEq, Debug)]
-struct EmptyTupleStruct();
-
-fn main() {
- assert!(false);
-}
crates/evm-coder/tests/build_failed/abi_derive_struct_generation.stderrdiffbeforeafterboth--- a/crates/evm-coder/tests/build_failed/abi_derive_struct_generation.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: Empty structs not supported
- --> tests/build_failed/abi_derive_struct_generation.rs:4:8
- |
-4 | struct EmptyStruct {}
- | ^^^^^^^^^^^
-
-error: Empty structs not supported
- --> tests/build_failed/abi_derive_struct_generation.rs:7:8
- |
-7 | struct EmptyTupleStruct();
- | ^^^^^^^^^^^^^^^^
crates/evm-coder/tests/build_failed/custom_signature_over_max_size.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/build_failed/custom_signature_over_max_size.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-#![allow(dead_code)]
-use std::str::from_utf8;
-
-use evm_coder::{
- make_signature,
- custom_signature::{SignatureUnit, SIGNATURE_SIZE_LIMIT},
-};
-
-trait Name {
- const SIGNATURE: SignatureUnit;
-
- fn name() -> &'static str {
- from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
- }
-}
-
-impl<T: Name> Name for Vec<T> {
- const SIGNATURE: SignatureUnit =
- evm_coder::make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-}
-
-struct MaxSize();
-impl Name for MaxSize {
- const SIGNATURE: SignatureUnit = SignatureUnit {
- data: [b'!'; SIGNATURE_SIZE_LIMIT],
- len: SIGNATURE_SIZE_LIMIT,
- };
-}
-
-const NAME: SignatureUnit = <Vec<MaxSize>>::SIGNATURE;
-
-fn main() {
- assert!(false);
-}
crates/evm-coder/tests/build_failed/custom_signature_over_max_size.stderrdiffbeforeafterboth--- a/crates/evm-coder/tests/build_failed/custom_signature_over_max_size.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-warning: unused import: `make_signature`
- --> tests/build_failed/custom_signature_over_max_size.rs:5:2
- |
-5 | make_signature,
- | ^^^^^^^^^^^^^^
- |
- = note: `#[warn(unused_imports)]` on by default
-
-error[E0080]: evaluation of `<std::vec::Vec<MaxSize> as Name>::SIGNATURE` failed
- --> tests/build_failed/custom_signature_over_max_size.rs:19:3
- |
-19 | evm_coder::make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 256 but the index is 256
- |
- = note: this error originates in the macro `$crate::make_signature` which comes from the expansion of the macro `evm_coder::make_signature` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error[E0080]: evaluation of constant value failed
- --> tests/build_failed/custom_signature_over_max_size.rs:30:29
- |
-30 | const NAME: SignatureUnit = <Vec<MaxSize>>::SIGNATURE;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
crates/evm-coder/tests/conditional_is.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/conditional_is.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use evm_coder::{types::*, solidity_interface, execution::Result};
-
-pub struct Contract(bool);
-
-#[solidity_interface(name = A)]
-impl Contract {
- fn method_a() -> Result<()> {
- Ok(())
- }
-}
-
-#[solidity_interface(name = B)]
-impl Contract {
- fn method_b() -> Result<()> {
- Ok(())
- }
-}
-
-#[solidity_interface(name = Contract, is(
- A(if(this.0)),
- B(if(!this.0)),
-))]
-impl Contract {}
-
-#[test]
-fn conditional_erc165() {
- assert!(ContractCall::supports_interface(
- &Contract(true),
- ACall::METHOD_A
- ));
- assert!(!ContractCall::supports_interface(
- &Contract(false),
- ACall::METHOD_A
- ));
-
- assert!(ContractCall::supports_interface(
- &Contract(false),
- BCall::METHOD_B
- ));
- assert!(!ContractCall::supports_interface(
- &Contract(true),
- BCall::METHOD_B
- ));
-}
crates/evm-coder/tests/generics.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/generics.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-use std::marker::PhantomData;
-use evm_coder::{execution::Result, generate_stubgen, solidity_interface, types::*};
-use primitive_types::U256;
-
-pub struct Generic<T>(PhantomData<T>);
-
-#[solidity_interface(name = GenericIs)]
-impl<T> Generic<T> {
- fn test_1(&self) -> Result<U256> {
- unreachable!()
- }
-}
-
-#[solidity_interface(name = Generic, is(GenericIs))]
-impl<T: Into<u32>> Generic<T> {
- fn test_2(&self) -> Result<U256> {
- unreachable!()
- }
-}
-
-generate_stubgen!(gen_iface, GenericCall<()>, false);
-
-#[solidity_interface(name = GenericWhere)]
-impl<T> Generic<T>
-where
- T: core::fmt::Debug,
-{
- fn test_3(&self) -> Result<U256> {
- unreachable!()
- }
-}
-
-generate_stubgen!(gen_where_iface, GenericWhereCall<()>, false);
crates/evm-coder/tests/log.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/log.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![allow(dead_code)]
-
-use evm_coder::{ToLog, types::*};
-use primitive_types::U256;
-
-#[derive(ToLog)]
-enum ERC721Log {
- Transfer {
- #[indexed]
- from: Address,
- #[indexed]
- to: Address,
- value: U256,
- },
- Eee {
- #[indexed]
- aaa: Address,
- bbb: U256,
- },
-}
crates/evm-coder/tests/random.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/random.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![allow(dead_code)] // This test only checks that macros is not panicking
-
-use evm_coder::{
- abi::AbiType, ToLog, execution::Result, solidity_interface, types::*, solidity, weight,
-};
-use primitive_types::U256;
-
-pub struct Impls;
-
-#[solidity_interface(name = OurInterface)]
-impl Impls {
- fn fn_a(&self, _input: U256) -> Result<bool> {
- unreachable!()
- }
-}
-
-#[solidity_interface(name = OurInterface1)]
-impl Impls {
- fn fn_b(&self, _input: u128) -> Result<u32> {
- unreachable!()
- }
-}
-
-#[derive(ToLog)]
-enum OurEvents {
- Event1 {
- field1: u32,
- },
- Event2 {
- field1: u32,
- #[indexed]
- field2: u32,
- },
-}
-
-#[solidity_interface(
- name = OurInterface2,
- is(OurInterface),
- inline_is(OurInterface1),
- events(OurEvents)
-)]
-impl Impls {
- #[solidity(rename_selector = "fnK")]
- fn fn_c(&self, _input: u32) -> Result<u8> {
- unreachable!()
- }
- fn fn_d(&self, _value: u32) -> Result<u32> {
- unreachable!()
- }
-
- fn caller_sensitive(&self, _caller: Caller) -> Result<u8> {
- unreachable!()
- }
- fn payable(&mut self, _value: Value) -> Result<u8> {
- unreachable!()
- }
-
- #[weight(*_weight)]
- fn with_weight(&self, _weight: u64) -> Result<()> {
- unreachable!()
- }
-
- /// Doccoment example
- fn with_doc(&self) -> Result<()> {
- unreachable!()
- }
-}
-
-#[solidity_interface(
- name = ValidSelector,
- expect_selector = 0x00000000,
-)]
-impl Impls {}
crates/evm-coder/tests/solidity_generation.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/solidity_generation.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-use evm_coder::{abi::AbiType, execution::Result, generate_stubgen, solidity_interface, types::*};
-use primitive_types::U256;
-
-pub struct ERC20;
-
-#[solidity_interface(name = ERC20)]
-impl ERC20 {
- fn decimals(&self) -> Result<u8> {
- unreachable!()
- }
- /// Get balance of specified owner
- fn balance_of(&self, _owner: Address) -> Result<U256> {
- unreachable!()
- }
- fn transfer(&mut self, _caller: Caller, _to: Address, _value: U256) -> Result<bool> {
- unreachable!()
- }
- fn transfer_from(
- &mut self,
- _caller: Caller,
- _from: Address,
- _to: Address,
- _value: U256,
- ) -> Result<bool> {
- unreachable!()
- }
- fn approve(&mut self, _caller: Caller, _spender: Address, _value: U256) -> Result<bool> {
- unreachable!()
- }
- fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {
- unreachable!()
- }
-}
-
-generate_stubgen!(gen_impl, ERC20Call, true);
-generate_stubgen!(gen_iface, ERC20Call, false);
crates/struct-versioning/src/lib.rsdiffbeforeafterboth--- a/crates/struct-versioning/src/lib.rs
+++ b/crates/struct-versioning/src/lib.rs
@@ -223,7 +223,7 @@
};
let current_fields = fields
.iter()
- .filter_map(|(ver, field)| ver.exists_on(version).then(|| field));
+ .filter_map(|(ver, field)| ver.exists_on(version).then_some(field));
let mut doc = Vec::new();
if version > attr.first_version {
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -17,12 +17,12 @@
//! This module contains the implementation of pallet methods for evm.
pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};
-use evm_coder::{
+use pallet_evm_coder_substrate::{
abi::AbiType,
- solidity_interface, solidity, ToLog,
+ solidity_interface, ToLog,
types::*,
- execution::{Result, Error},
- weight,
+ execution::{Result, Error, PreDispatch},
+ frontier_contract,
};
use pallet_evm_coder_substrate::dispatch_to_evm;
use sp_std::{vec, vec::Vec};
@@ -36,6 +36,11 @@
Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf, eth, weights::WeightInfo,
};
+frontier_contract! {
+ macro_rules! CollectionHandle_result {...}
+ impl<T: Config> Contract for CollectionHandle<T> {...}
+}
+
/// Events for ethereum collection helper.
#[derive(ToLog)]
pub enum CollectionHelpersEvents {
@@ -83,7 +88,7 @@
}
/// @title A contract that allows you to work with collections.
-#[solidity_interface(name = Collection)]
+#[solidity_interface(name = Collection, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> CollectionHandle<T>
where
T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
@@ -272,7 +277,7 @@
None => return Ok(Default::default()),
};
- Ok(eth::CrossAddress::from_sub::<T>(&sponsor))
+ Ok(eth::CrossAddress::from_sub::<T>(sponsor))
}
/// Get current collection limits.
@@ -280,11 +285,6 @@
/// @return Array of collection limits
fn collection_limits(&self) -> Result<Vec<eth::CollectionLimit>> {
let limits = &self.collection.limits;
-
- let convert_value_from_bool = |ob: Option<bool>| match ob {
- Some(b) => Some(b as u32),
- None => None,
- };
Ok(vec![
eth::CollectionLimit::new(
@@ -307,10 +307,12 @@
None
}
})
- .unwrap_or(eth::CollectionLimit::new(
- eth::CollectionLimitField::SponsoredDataRateLimit,
- Default::default(),
- )),
+ .unwrap_or_else(|| {
+ eth::CollectionLimit::new(
+ eth::CollectionLimitField::SponsoredDataRateLimit,
+ Default::default(),
+ )
+ }),
eth::CollectionLimit::new(eth::CollectionLimitField::TokenLimit, limits.token_limit),
eth::CollectionLimit::new(
eth::CollectionLimitField::SponsorTransferTimeout,
@@ -322,15 +324,15 @@
),
eth::CollectionLimit::new(
eth::CollectionLimitField::OwnerCanTransfer,
- convert_value_from_bool(limits.owner_can_transfer),
+ limits.owner_can_transfer.map(u32::from),
),
eth::CollectionLimit::new(
eth::CollectionLimitField::OwnerCanDestroy,
- convert_value_from_bool(limits.owner_can_destroy),
+ limits.owner_can_destroy.map(u32::from),
),
eth::CollectionLimit::new(
eth::CollectionLimitField::TransferEnabled,
- convert_value_from_bool(limits.transfers_enabled),
+ limits.transfers_enabled.map(u32::from),
),
])
}
@@ -680,7 +682,7 @@
/// Contains static property keys and values.
pub mod static_property {
- use evm_coder::{
+ use pallet_evm_coder_substrate::{
execution::{Result, Error},
};
use alloc::format;
pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -105,7 +105,9 @@
}
}
/// Converts [`CrossAddress`] to `CrossAccountId`.
- pub fn into_sub_cross_account<T>(&self) -> evm_coder::execution::Result<T::CrossAccountId>
+ pub fn into_sub_cross_account<T>(
+ &self,
+ ) -> pallet_evm_coder_substrate::execution::Result<T::CrossAccountId>
where
T: pallet_evm::Config,
T::AccountId: From<[u8; 32]>,
@@ -130,7 +132,7 @@
}
impl TryFrom<up_data_structs::Property> for Property {
- type Error = evm_coder::execution::Error;
+ type Error = pallet_evm_coder_substrate::execution::Error;
fn try_from(from: up_data_structs::Property) -> Result<Self, Self::Error> {
let key = evm_coder::types::String::from_utf8(from.key.into())
@@ -141,7 +143,7 @@
}
impl TryInto<up_data_structs::Property> for Property {
- type Error = evm_coder::execution::Error;
+ type Error = pallet_evm_coder_substrate::execution::Error;
fn try_into(self) -> Result<up_data_structs::Property, Self::Error> {
let key = <Vec<u8>>::from(self.key)
@@ -212,7 +214,7 @@
}
impl TryInto<up_data_structs::CollectionLimits> for CollectionLimit {
- type Error = evm_coder::execution::Error;
+ type Error = pallet_evm_coder_substrate::execution::Error;
fn try_into(self) -> Result<up_data_structs::CollectionLimits, Self::Error> {
let value = self
@@ -378,7 +380,8 @@
/// Convert vector of [`TokenPropertyPermission`] into vector of [`up_data_structs::PropertyKeyPermission`].
pub fn into_property_key_permissions(
permissions: Vec<TokenPropertyPermission>,
- ) -> evm_coder::execution::Result<Vec<up_data_structs::PropertyKeyPermission>> {
+ ) -> pallet_evm_coder_substrate::execution::Result<Vec<up_data_structs::PropertyKeyPermission>>
+ {
let mut perms = Vec::new();
for TokenPropertyPermission { key, permissions } in permissions {
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -192,7 +192,10 @@
}
/// Consume gas for reading.
- pub fn consume_store_reads(&self, reads: u64) -> evm_coder::execution::Result<()> {
+ pub fn consume_store_reads(
+ &self,
+ reads: u64,
+ ) -> pallet_evm_coder_substrate::execution::Result<()> {
self.recorder
.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(
<T as frame_system::Config>::DbWeight::get()
@@ -202,7 +205,10 @@
}
/// Consume gas for writing.
- pub fn consume_store_writes(&self, writes: u64) -> evm_coder::execution::Result<()> {
+ pub fn consume_store_writes(
+ &self,
+ writes: u64,
+ ) -> pallet_evm_coder_substrate::execution::Result<()> {
self.recorder
.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(
<T as frame_system::Config>::DbWeight::get()
@@ -216,7 +222,7 @@
&self,
reads: u64,
writes: u64,
- ) -> evm_coder::execution::Result<()> {
+ ) -> pallet_evm_coder_substrate::execution::Result<()> {
let weight = <T as frame_system::Config>::DbWeight::get();
let reads = weight.read.saturating_mul(reads);
let writes = weight.read.saturating_mul(writes);
pallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth--- a/pallets/evm-coder-substrate/Cargo.toml
+++ b/pallets/evm-coder-substrate/Cargo.toml
@@ -7,10 +7,11 @@
[dependencies]
# Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it.
codec = { workspace = true, package = "parity-scale-codec" }
-
scale-info = { workspace = true }
evm-coder = { workspace = true }
+evm-core = { workspace = true }
+
frame-benchmarking = { workspace = true, optional = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
@@ -19,6 +20,9 @@
sp-std = { workspace = true }
up-data-structs = { workspace = true }
+evm-coder-substrate-procedural = { path = "./procedural" }
+spez = "0.1.1"
+
[features]
default = ["std"]
runtime-benchmarks = ['frame-benchmarking']
pallets/evm-coder-substrate/procedural/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/pallets/evm-coder-substrate/procedural/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+edition = "2021"
+name = "evm-coder-substrate-procedural"
+version = "0.1.0"
+
+[dependencies]
+proc-macro2 = "1.0"
+quote = "1.0"
+syn = "1.0"
+
+[lib]
+proc-macro = true
pallets/evm-coder-substrate/procedural/src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/pallets/evm-coder-substrate/procedural/src/lib.rs
@@ -0,0 +1,135 @@
+use std::result;
+
+use proc_macro2::{TokenStream, Ident};
+use quote::quote;
+use syn::{
+ Error, DeriveInput, Data, Attribute,
+ parse::{Parse, ParseBuffer},
+ spanned::Spanned,
+ Expr, parenthesized,
+};
+
+type Result<T = TokenStream, E = syn::Error> = result::Result<T, E>;
+
+fn parse_attr<A: Parse, I>(attrs: &[Attribute], ident: I) -> Result<Option<A>>
+where
+ Ident: PartialEq<I>,
+{
+ let attrs = attrs
+ .iter()
+ .filter(|a| a.path.is_ident(&ident))
+ .collect::<Vec<_>>();
+ if attrs.len() > 1 {
+ return Err(Error::new(
+ attrs[1].span(),
+ "this attribute may be specified only once",
+ ));
+ } else if attrs.is_empty() {
+ return Ok(None);
+ }
+ let attr = attrs[0];
+
+ let parsed = syn::parse2(attr.tokens.clone())?;
+ Ok(Some(parsed))
+}
+
+struct WeightAttr {
+ handler: Expr,
+}
+impl Parse for WeightAttr {
+ fn parse(input: &ParseBuffer) -> Result<Self> {
+ let expr;
+ parenthesized!(expr in input);
+ let handler = Expr::parse(&expr)?;
+
+ Ok(Self { handler })
+ }
+}
+
+#[proc_macro_derive(PreDispatch, attributes(pre_dispatch, weight))]
+pub fn derive_predispatch(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
+ fn inner(input: DeriveInput) -> Result {
+ let (impl_generics, ty_generics, _where_clause) = input.generics.split_for_impl();
+ let ident = &input.ident;
+ let Data::Enum(data) = &input.data else {
+ return Err(Error::new_spanned(input, "PreDispatch input is enum"))
+ };
+
+ let matching = data
+ .variants
+ .iter()
+ .map(|var| {
+ let name = &var.ident;
+ let handler = match &var.fields {
+ syn::Fields::Named(named) => {
+ if let Some(weight) = parse_attr::<WeightAttr, _>(&var.attrs, "weight")? {
+ let weight = &weight.handler;
+ let fields = named.named.iter().flat_map(|n| &n.ident);
+ quote! {
+ {#(#fields,)*} => {
+ ::pallet_evm_coder_substrate::execution::DispatchInfo {
+ weight: ::pallet_evm_coder_substrate::execution::Weight::from(#weight),
+ }
+ }
+ }
+ } else {
+ quote! {
+ {..} => {
+ ::pallet_evm_coder_substrate::execution::DispatchInfo {
+ weight: ::pallet_evm_coder_substrate::execution::Weight::zero()
+ }
+ }
+ }
+ }
+ }
+ syn::Fields::Unit => {
+ if let Some(weight) = parse_attr::<WeightAttr, _>(&var.attrs, "weight")? {
+ let weight = &weight.handler;
+ quote! {
+ => {
+ ::pallet_evm_coder_substrate::execution::DispatchInfo {
+ weight: ::pallet_evm_coder_substrate::execution::Weight::from(#weight),
+ }
+ }
+ }
+ } else {
+ quote! {
+ => {
+ ::pallet_evm_coder_substrate::execution::DispatchInfo {
+ weight: ::pallet_evm_coder_substrate::execution::Weight::zero()
+ }
+ }
+ }
+ }
+ }
+ syn::Fields::Unnamed(_) => {
+ quote! {
+ (call, ..) => {
+ call.dispatch_info()
+ }
+ }
+ }
+ };
+ Ok(quote! {
+ Self::#name #handler,
+ })
+ })
+ .collect::<Result>()?;
+
+ Ok(quote! {
+ #[allow(unused_variables)]
+ impl #impl_generics ::pallet_evm_coder_substrate::execution::PreDispatch for #ident #ty_generics where T: crate::Config {
+ fn dispatch_info(&self) -> ::pallet_evm_coder_substrate::execution::DispatchInfo {
+ match self {
+ #matching
+ }
+ }
+ }
+ })
+ }
+ let item = syn::parse_macro_input!(item as DeriveInput);
+ match inner(item) {
+ Ok(o) => o.into(),
+ Err(e) => e.into_compile_error().into(),
+ }
+}
pallets/evm-coder-substrate/src/execution.rsdiffbeforeafterboth--- /dev/null
+++ b/pallets/evm-coder-substrate/src/execution.rs
@@ -0,0 +1,186 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+//! Contract execution related types
+
+#[cfg(not(feature = "std"))]
+use alloc::string::{String, ToString};
+#[cfg(feature = "std")]
+use std::string::{String, ToString};
+
+use evm_coder::ERC165Call;
+use evm_core::{ExitError, ExitFatal};
+
+pub use frame_support::weights::Weight;
+pub use evm_coder_substrate_procedural::PreDispatch;
+
+/// Execution error, should be convertible between EVM and Substrate.
+#[derive(Debug, Clone)]
+pub enum Error {
+ /// Non-fatal contract error occured
+ Revert(String),
+ /// EVM fatal error
+ Fatal(ExitFatal),
+ /// EVM normal error
+ Error(ExitError),
+}
+
+impl<E> From<E> for Error
+where
+ E: ToString,
+{
+ fn from(e: E) -> Self {
+ Self::Revert(e.to_string())
+ }
+}
+
+/// To be used in [`crate::solidity_interface`] implementation.
+pub type Result<T> = core::result::Result<T, Error>;
+/// Return type of items in [`crate::solidity_interface`] definition
+pub type ResultWithPostInfo<T> =
+ core::result::Result<WithPostDispatchInfo<T>, WithPostDispatchInfo<Error>>;
+
+pub trait PreDispatch {
+ fn dispatch_info(&self) -> DispatchInfo;
+}
+
+impl PreDispatch for ERC165Call {
+ fn dispatch_info(&self) -> DispatchInfo {
+ DispatchInfo {
+ // ERC165 impl should be cheap
+ weight: Weight::from_ref_time(200),
+ }
+ }
+}
+
+/// Static information collected from [`crate::weight`].
+pub struct DispatchInfo {
+ /// Statically predicted call weight
+ pub weight: Weight,
+}
+
+impl From<Weight> for DispatchInfo {
+ fn from(weight: Weight) -> Self {
+ Self { weight }
+ }
+}
+impl From<u64> for DispatchInfo {
+ fn from(weight: u64) -> Self {
+ Self {
+ weight: Weight::from_ref_time(weight),
+ }
+ }
+}
+impl From<()> for DispatchInfo {
+ fn from(_: ()) -> Self {
+ Self {
+ weight: Weight::zero(),
+ }
+ }
+}
+
+/// Weight information that is only available post dispatch.
+/// Note: This can only be used to reduce the weight or fee, not increase it.
+#[derive(Default, Clone)]
+pub struct PostDispatchInfo {
+ /// Actual weight consumed by call
+ pub actual_weight: Option<Weight>,
+}
+
+impl PostDispatchInfo {
+ /// Calculate amount to be returned back to user
+ pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight {
+ info.weight - self.calc_actual_weight(info)
+ }
+
+ /// Calculate actual consumed weight, saturating to weight reported
+ /// pre-dispatch
+ pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight {
+ if let Some(actual_weight) = self.actual_weight {
+ actual_weight.min(info.weight)
+ } else {
+ info.weight
+ }
+ }
+}
+
+/// Wrapper for PostDispatchInfo and any user-provided data
+#[derive(Clone)]
+pub struct WithPostDispatchInfo<T> {
+ /// User provided data
+ pub data: T,
+ /// Info known after dispatch
+ pub post_info: PostDispatchInfo,
+}
+
+impl<T> From<T> for WithPostDispatchInfo<T> {
+ fn from(data: T) -> Self {
+ Self {
+ data,
+ post_info: Default::default(),
+ }
+ }
+}
+#[allow(clippy::crate_in_macro_def)]
+#[macro_export]
+macro_rules! frontier_contract {
+ (
+ macro_rules! $res:ident {...}
+ impl$(<$($gen:ident $(: $($(+)? $bound:ty)*)?),+ $(,)?>)? Contract for $ty:ty {...}
+ ) => {
+ /// Generate macro to convert function return value into Contract result
+ macro_rules! $res {
+ ($i:expr) => {{
+ pallet_evm_coder_substrate::spez! {
+ for res = $i;
+ match<T> ::pallet_evm_coder_substrate::execution::ResultWithPostInfo<T> -> ::pallet_evm_coder_substrate::execution::ResultWithPostInfo<T> {
+ res
+ }
+ match<T> ::pallet_evm_coder_substrate::execution::Result<T> -> ::pallet_evm_coder_substrate::execution::ResultWithPostInfo<T> {
+ res
+ .map(pallet_evm_coder_substrate::execution::WithPostDispatchInfo::from)
+ .map_err(pallet_evm_coder_substrate::execution::WithPostDispatchInfo::from)
+ }
+ match<T> T -> ::pallet_evm_coder_substrate::execution::ResultWithPostInfo<T> {
+ Ok(pallet_evm_coder_substrate::execution::WithPostDispatchInfo::from(res))
+ }
+ }
+ }};
+ }
+ impl $(<$($gen),+>)? $crate::Contract for $ty where T: crate::Config {
+ type Error = ::pallet_evm_coder_substrate::execution::Error;
+ type WithPostInfo<R> = ::pallet_evm_coder_substrate::execution::WithPostDispatchInfo<R>;
+ type Result<R, E> = core::result::Result<R, E>;
+ fn map_post<I, O>(
+ v: Self::WithPostInfo<I>,
+ mapper: impl FnOnce(I) -> O,
+ ) -> Self::WithPostInfo<O> {
+ ::pallet_evm_coder_substrate::execution::WithPostDispatchInfo {
+ data: mapper(v.data),
+ post_info: v.post_info,
+ }
+ }
+ fn with_default_post<V>(v: V) -> Self::WithPostInfo<V> {
+ ::pallet_evm_coder_substrate::execution::WithPostDispatchInfo {
+ data: v,
+ post_info: ::pallet_evm_coder_substrate::execution::PostDispatchInfo {
+ actual_weight: None,
+ },
+ }
+ }
+ }
+ };
+}
pallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth--- a/pallets/evm-coder-substrate/src/lib.rs
+++ b/pallets/evm-coder-substrate/src/lib.rs
@@ -16,10 +16,13 @@
#![cfg_attr(not(feature = "std"), no_std)]
+extern crate self as pallet_evm_coder_substrate;
+
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::format;
+use execution::PreDispatch;
use frame_support::dispatch::Weight;
use core::marker::PhantomData;
@@ -37,10 +40,14 @@
use sp_core::H160;
// #[cfg(feature = "runtime-benchmarks")]
// pub mod benchmarking;
+pub mod execution;
+pub use evm_coder::*;
+#[doc(hidden)]
+pub use spez::spez;
+
use evm_coder::{
abi::{AbiReader, AbiWrite, AbiWriter},
- execution,
types::{Msg, Value},
};
@@ -175,7 +182,7 @@
handle: &mut impl PrecompileHandle,
result: execution::Result<Option<AbiWriter>>,
) -> Option<PrecompileResult> {
- use evm_coder::execution::Error;
+ use execution::Error;
// We ignore error here, as it should not occur, as we have our own bookkeeping of gas
let _ = handle.record_cost(self.initial_gas - self.gas_left());
Some(match result {
@@ -200,7 +207,7 @@
}
pub fn dispatch_to_evm<T: Config>(err: DispatchError) -> execution::Error {
- use evm_coder::execution::Error as ExError;
+ use execution::Error as ExError;
match err {
DispatchError::Module(ModuleError { index, error, .. })
if index
@@ -231,15 +238,14 @@
}
/// Helper to simplify implementing bridge between evm-coder definitions and pallet-evm
-pub fn call<
+pub fn call<T, C, E, H>(handle: &mut H, mut e: E) -> Option<PrecompileResult>
+where
T: Config,
- C: evm_coder::Call + evm_coder::Weighted,
+ C: evm_coder::Call + PreDispatch,
E: evm_coder::Callable<C> + WithRecorder<T>,
H: PrecompileHandle,
->(
- handle: &mut H,
- mut e: E,
-) -> Option<PrecompileResult> {
+ execution::ResultWithPostInfo<AbiWriter>: From<ResultWithPostInfoOf<E, AbiWriter>>,
+{
let result = call_internal(
handle.context().caller,
&mut e,
@@ -249,16 +255,18 @@
e.into_recorder().evm_to_precompile_output(handle, result)
}
-fn call_internal<
- T: Config,
- C: evm_coder::Call + evm_coder::Weighted,
- E: evm_coder::Callable<C> + WithRecorder<T>,
->(
+fn call_internal<T, C, E>(
caller: H160,
e: &mut E,
value: Value,
input: &[u8],
-) -> execution::Result<Option<AbiWriter>> {
+) -> execution::Result<Option<AbiWriter>>
+where
+ T: Config,
+ C: evm_coder::Call + PreDispatch,
+ E: Contract + evm_coder::Callable<C> + WithRecorder<T>,
+ execution::ResultWithPostInfo<AbiWriter>: From<ResultWithPostInfoOf<E, AbiWriter>>,
+{
let (selector, mut reader) = AbiReader::new_call(input)?;
let call = C::parse(selector, &mut reader)?;
if call.is_none() {
@@ -267,15 +275,15 @@
}
let call = call.unwrap();
- let dispatch_info = call.weight();
+ let dispatch_info = call.dispatch_info();
e.recorder()
.consume_gas(T::GasWeightMapping::weight_to_gas(dispatch_info.weight))?;
- match e.call(Msg {
+ match execution::ResultWithPostInfo::from(e.call(Msg {
call,
caller,
value,
- }) {
+ })) {
Ok(v) => {
let unspent = v.post_info.calc_unspent(&dispatch_info);
e.recorder()
@@ -290,3 +298,26 @@
}
}
}
+
+#[cfg(test)]
+#[allow(dead_code)]
+mod tests {
+ use core::marker::PhantomData;
+
+ use evm_coder::ERC165Call;
+ use frame_support::weights::Weight;
+
+ use crate::execution::PreDispatch;
+
+ #[derive(PreDispatch)]
+ enum ExampleCall<T: super::Config> {
+ ERC165Call(ERC165Call, PhantomData<fn() -> T>),
+ OtherCall(ERC165Call),
+
+ #[weight(Weight::from_ref_time(a + b))]
+ Example {
+ a: u64,
+ b: u64,
+ },
+ }
+}
pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -20,7 +20,6 @@
use core::marker::PhantomData;
use evm_coder::{
abi::{AbiWriter, AbiType},
- execution::Result,
generate_stubgen, solidity_interface,
types::*,
ToLog,
@@ -30,7 +29,11 @@
ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
account::CrossAccountId,
};
-use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm};
+use pallet_evm_coder_substrate::{
+ SubstrateRecorder, WithRecorder, dispatch_to_evm,
+ execution::{Result, PreDispatch},
+ frontier_contract,
+};
use pallet_evm_transaction_payment::CallContext;
use sp_core::{H160, U256};
use up_data_structs::SponsorshipState;
@@ -42,6 +45,11 @@
use up_sponsorship::SponsorshipHandler;
use sp_std::vec::Vec;
+frontier_contract! {
+ macro_rules! ContractHelpers_result {...}
+ impl<T: Config> Contract for ContractHelpers<T> {...}
+}
+
/// Pallet events.
#[derive(ToLog)]
pub enum ContractHelpersEvents {
@@ -84,7 +92,7 @@
}
/// @title Magic contract, which allows users to reconfigure other contracts
-#[solidity_interface(name = ContractHelpers, events(ContractHelpersEvents))]
+#[solidity_interface(name = ContractHelpers, events(ContractHelpersEvents), enum(derive(PreDispatch)))]
impl<T: Config> ContractHelpers<T>
where
T::AccountId: AsRef<[u8; 32]>,
pallets/fungible/src/erc.rsdiffbeforeafterboth21use core::convert::TryInto;21use core::convert::TryInto;22use evm_coder::AbiCoder;22use evm_coder::AbiCoder;23use evm_coder::{23use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};24 abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,25 weight,26};27use up_data_structs::CollectionMode;24use up_data_structs::CollectionMode;28use pallet_common::{25use pallet_common::{33use sp_std::vec::Vec;30use sp_std::vec::Vec;34use pallet_evm::{account::CrossAccountId, PrecompileHandle};31use pallet_evm::{account::CrossAccountId, PrecompileHandle};35use pallet_evm_coder_substrate::{call, dispatch_to_evm};32use pallet_evm_coder_substrate::{33 call, dispatch_to_evm,34 execution::{PreDispatch, Result},35 frontier_contract,36};36use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};37use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};37use sp_core::{U256, Get};38use sp_core::{U256, Get};41 weights::WeightInfo,42 weights::WeightInfo,42};43};4445frontier_contract! {46 macro_rules! FungibleHandle_result {...}47 impl<T: Config> Contract for FungibleHandle<T> {...}48}434944#[derive(ToLog)]50#[derive(ToLog)]45pub enum ERC20Events {51pub enum ERC20Events {65 amount: U256,71 amount: U256,66}72}677368#[solidity_interface(name = ERC20, events(ERC20Events), expect_selector = 0x942e8b22)]74#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]69impl<T: Config> FungibleHandle<T> {75impl<T: Config> FungibleHandle<T> {70 fn name(&self) -> Result<String> {76 fn name(&self) -> Result<String> {71 Ok(decode_utf16(self.name.iter().copied())77 Ok(decode_utf16(self.name.iter().copied())145 }151 }146}152}147153148#[solidity_interface(name = ERC20Mintable)]154#[solidity_interface(name = ERC20Mintable, enum(derive(PreDispatch)), enum_attr(weight))]149impl<T: Config> FungibleHandle<T> {155impl<T: Config> FungibleHandle<T> {150 /// Mint tokens for `to` account.156 /// Mint tokens for `to` account.151 /// @param to account that will receive minted tokens157 /// @param to account that will receive minted tokens158 let budget = self164 let budget = self159 .recorder165 .recorder160 .weight_calls_budget(<StructureWeight<T>>::find_parent());166 .weight_calls_budget(<StructureWeight<T>>::find_parent());161 <Pallet<T>>::create_item(&self, &caller, (to, amount), &budget)167 <Pallet<T>>::create_item(self, &caller, (to, amount), &budget)162 .map_err(dispatch_to_evm::<T>)?;168 .map_err(dispatch_to_evm::<T>)?;163 Ok(true)169 Ok(true)164 }170 }165}171}166172167#[solidity_interface(name = ERC20UniqueExtensions)]173#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]168impl<T: Config> FungibleHandle<T>174impl<T: Config> FungibleHandle<T>169where175where170 T::AccountId: From<[u8; 32]>,176 T::AccountId: From<[u8; 32]>,181 }187 }182188183 /// @notice A description for the collection.189 /// @notice A description for the collection.184 fn description(&self) -> Result<String> {190 fn description(&self) -> String {185 Ok(decode_utf16(self.description.iter().copied())191 decode_utf16(self.description.iter().copied())186 .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))192 .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))187 .collect::<String>())193 .collect::<String>()188 }194 }189195190 #[weight(<SelfWeightOf<T>>::create_item())]196 #[weight(<SelfWeightOf<T>>::create_item())]278 })284 })279 .collect::<Result<_>>()?;285 .collect::<Result<_>>()?;280286281 <Pallet<T>>::create_multiple_items(&self, &caller, amounts, &budget)287 <Pallet<T>>::create_multiple_items(self, &caller, amounts, &budget)282 .map_err(dispatch_to_evm::<T>)?;288 .map_err(dispatch_to_evm::<T>)?;283 Ok(true)289 Ok(true)284 }290 }330 ERC20Mintable,336 ERC20Mintable,331 ERC20UniqueExtensions,337 ERC20UniqueExtensions,332 Collection(via(common_mut returns CollectionHandle<T>)),338 Collection(via(common_mut returns CollectionHandle<T>)),333 )339 ),340 enum(derive(PreDispatch))334)]341)]335impl<T: Config> FungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}342impl<T: Config> FungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}336343pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -24,16 +24,16 @@
char::{REPLACEMENT_CHARACTER, decode_utf16},
convert::TryInto,
};
-use evm_coder::{
- abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,
- weight,
-};
+use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
use frame_support::BoundedVec;
use up_data_structs::{
TokenId, PropertyPermission, PropertyKeyPermission, Property, CollectionId, PropertyKey,
CollectionPropertiesVec,
};
-use pallet_evm_coder_substrate::dispatch_to_evm;
+use pallet_evm_coder_substrate::{
+ dispatch_to_evm, frontier_contract,
+ execution::{Result, PreDispatch, Error},
+};
use sp_std::{vec::Vec, vec};
use pallet_common::{
CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
@@ -50,8 +50,13 @@
SelfWeightOf, weights::WeightInfo, TokenProperties,
};
+frontier_contract! {
+ macro_rules! NonfungibleHandle_result {...}
+ impl<T: Config> Contract for NonfungibleHandle<T> {...}
+}
+
/// @title A contract that allows to set and delete token properties and change token property permissions.
-#[solidity_interface(name = TokenProperties)]
+#[solidity_interface(name = TokenProperties, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> NonfungibleHandle<T> {
/// @notice Set permissions for token property.
/// @dev Throws error if `msg.sender` is not admin or owner of the collection.
@@ -59,8 +64,8 @@
/// @param isMutable Permission to mutate property.
/// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
/// @param tokenOwner Permission to mutate property by token owner if property is mutable.
+ #[solidity(hide)]
#[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]
- #[solidity(hide)]
fn set_token_property_permission(
&mut self,
caller: Caller,
@@ -293,7 +298,7 @@
/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
-#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f)]
+#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> NonfungibleHandle<T>
where
T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
@@ -301,14 +306,14 @@
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
#[solidity(hide, rename_selector = "name")]
- fn name_proxy(&self) -> Result<String> {
+ fn name_proxy(&self) -> String {
self.name()
}
/// @notice An abbreviated name for NFTs in this contract
/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
#[solidity(hide, rename_selector = "symbol")]
- fn symbol_proxy(&self) -> Result<String> {
+ fn symbol_proxy(&self) -> String {
self.symbol()
}
@@ -362,14 +367,14 @@
/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
-#[solidity_interface(name = ERC721Enumerable, expect_selector = 0x780e9d63)]
+#[solidity_interface(name = ERC721Enumerable, expect_selector = 0x780e9d63, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> NonfungibleHandle<T> {
/// @notice Enumerate valid NFTs
/// @param index A counter less than `totalSupply()`
/// @return The token identifier for the `index`th NFT,
/// (sort order not specified)
- fn token_by_index(&self, index: U256) -> Result<U256> {
- Ok(index)
+ fn token_by_index(&self, index: U256) -> U256 {
+ index
}
/// @dev Not implemented
@@ -389,7 +394,7 @@
/// @title ERC-721 Non-Fungible Token Standard
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-#[solidity_interface(name = ERC721, events(ERC721Events), expect_selector = 0x80ac58cd)]
+#[solidity_interface(name = ERC721, events(ERC721Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x80ac58cd)]
impl<T: Config> NonfungibleHandle<T> {
/// @notice Count all NFTs assigned to an owner
/// @dev NFTs assigned to the zero address are considered invalid, and this
@@ -516,7 +521,7 @@
}
/// @title ERC721 Token that can be irreversibly burned (destroyed).
-#[solidity_interface(name = ERC721Burnable)]
+#[solidity_interface(name = ERC721Burnable, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> NonfungibleHandle<T> {
/// @notice Burns a specific ERC721 token.
/// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
@@ -533,7 +538,7 @@
}
/// @title ERC721 minting logic.
-#[solidity_interface(name = ERC721UniqueMintable)]
+#[solidity_interface(name = ERC721UniqueMintable, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> NonfungibleHandle<T> {
/// @notice Function to mint a token.
/// @param to The new owner
@@ -698,28 +703,28 @@
}
/// @title Unique extensions for ERC721.
-#[solidity_interface(name = ERC721UniqueExtensions)]
+#[solidity_interface(name = ERC721UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> NonfungibleHandle<T>
where
T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
{
/// @notice A descriptive name for a collection of NFTs in this contract
- fn name(&self) -> Result<String> {
- Ok(decode_utf16(self.name.iter().copied())
+ fn name(&self) -> String {
+ decode_utf16(self.name.iter().copied())
.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
- .collect::<String>())
+ .collect::<String>()
}
/// @notice An abbreviated name for NFTs in this contract
- fn symbol(&self) -> Result<String> {
- Ok(String::from_utf8_lossy(&self.token_prefix).into())
+ fn symbol(&self) -> String {
+ String::from_utf8_lossy(&self.token_prefix).into()
}
/// @notice A description for the collection.
- fn description(&self) -> Result<String> {
- Ok(decode_utf16(self.description.iter().copied())
+ fn description(&self) -> String {
+ decode_utf16(self.description.iter().copied())
.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
- .collect::<String>())
+ .collect::<String>()
}
/// Returns the owner (in cross format) of the token.
@@ -1035,8 +1040,8 @@
}
/// @notice Returns collection helper contract address
- fn collection_helper_address(&self) -> Result<Address> {
- Ok(T::ContractAddress::get())
+ fn collection_helper_address(&self) -> Address {
+ T::ContractAddress::get()
}
}
@@ -1051,7 +1056,8 @@
ERC721Metadata(if(this.flags.erc721metadata)),
Collection(via(common_mut returns CollectionHandle<T>)),
TokenProperties,
- )
+ ),
+ enum(derive(PreDispatch)),
)]
impl<T: Config> NonfungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -25,10 +25,7 @@
char::{REPLACEMENT_CHARACTER, decode_utf16},
convert::TryInto,
};
-use evm_coder::{
- abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,
- weight,
-};
+use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
use frame_support::{BoundedBTreeMap, BoundedVec};
use pallet_common::{
CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
@@ -37,7 +34,11 @@
eth::{self, TokenUri},
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
-use pallet_evm_coder_substrate::{call, dispatch_to_evm};
+use pallet_evm_coder_substrate::{
+ call, dispatch_to_evm,
+ execution::{PreDispatch, Result, Error},
+ frontier_contract,
+};
use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
use sp_core::{H160, U256, Get};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};
@@ -51,10 +52,15 @@
TokenProperties, TokensMinted, TotalSupply, weights::WeightInfo,
};
+frontier_contract! {
+ macro_rules! RefungibleHandle_result {...}
+ impl<T: Config> Contract for RefungibleHandle<T> {...}
+}
+
pub const ADDRESS_FOR_PARTIALLY_OWNED_TOKENS: H160 = H160::repeat_byte(0xff);
/// @title A contract that allows to set and delete token properties and change token property permissions.
-#[solidity_interface(name = TokenProperties)]
+#[solidity_interface(name = TokenProperties, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> RefungibleHandle<T> {
/// @notice Set permissions for token property.
/// @dev Throws error if `msg.sender` is not admin or owner of the collection.
@@ -62,8 +68,8 @@
/// @param isMutable Permission to mutate property.
/// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
/// @param tokenOwner Permission to mutate property by token owner if property is mutable.
+ #[solidity(hide)]
#[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]
- #[solidity(hide)]
fn set_token_property_permission(
&mut self,
caller: Caller,
@@ -290,7 +296,7 @@
/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
-#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f)]
+#[solidity_interface(name = ERC721Metadata, enum(derive(PreDispatch)), expect_selector = 0x5b5e139f)]
impl<T: Config> RefungibleHandle<T>
where
T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
@@ -359,14 +365,14 @@
/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
-#[solidity_interface(name = ERC721Enumerable, expect_selector = 0x780e9d63)]
+#[solidity_interface(name = ERC721Enumerable, enum(derive(PreDispatch)), expect_selector = 0x780e9d63)]
impl<T: Config> RefungibleHandle<T> {
/// @notice Enumerate valid RFTs
/// @param index A counter less than `totalSupply()`
/// @return The token identifier for the `index`th NFT,
/// (sort order not specified)
- fn token_by_index(&self, index: U256) -> Result<U256> {
- Ok(index)
+ fn token_by_index(&self, index: U256) -> U256 {
+ index
}
/// Not implemented
@@ -386,7 +392,7 @@
/// @title ERC-721 Non-Fungible Token Standard
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-#[solidity_interface(name = ERC721, events(ERC721Events), expect_selector = 0x80ac58cd)]
+#[solidity_interface(name = ERC721, events(ERC721Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x80ac58cd)]
impl<T: Config> RefungibleHandle<T> {
/// @notice Count all RFTs assigned to an owner
/// @dev RFTs assigned to the zero address are considered invalid, and this
@@ -547,7 +553,7 @@
}
/// @title ERC721 Token that can be irreversibly burned (destroyed).
-#[solidity_interface(name = ERC721Burnable)]
+#[solidity_interface(name = ERC721Burnable, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> RefungibleHandle<T> {
/// @notice Burns a specific ERC721 token.
/// @dev Throws unless `msg.sender` is the current RFT owner, or an authorized
@@ -567,7 +573,7 @@
}
/// @title ERC721 minting logic.
-#[solidity_interface(name = ERC721UniqueMintable)]
+#[solidity_interface(name = ERC721UniqueMintable, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> RefungibleHandle<T> {
/// @notice Function to mint a token.
/// @param to The new owner
@@ -739,7 +745,7 @@
}
/// @title Unique extensions for ERC721.
-#[solidity_interface(name = ERC721UniqueExtensions)]
+#[solidity_interface(name = ERC721UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> RefungibleHandle<T>
where
T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
@@ -1120,7 +1126,8 @@
ERC721Metadata(if(this.flags.erc721metadata)),
Collection(via(common_mut returns CollectionHandle<T>)),
TokenProperties,
- )
+ ),
+ enum(derive(PreDispatch)),
)]
impl<T: Config> RefungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}
pallets/refungible/src/erc_token.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -24,40 +24,41 @@
convert::TryInto,
ops::Deref,
};
-use evm_coder::{
- abi::AbiType, ToLog, execution::*, generate_stubgen, solidity_interface, solidity, types::*,
- weight,
-};
+use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
use pallet_common::{
- CommonWeightInfo,
erc::{CommonEvmHandler, PrecompileResult},
eth::{collection_id_to_address, CrossAddress},
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
-use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};
+use pallet_evm_coder_substrate::{
+ call, dispatch_to_evm, WithRecorder, frontier_contract,
+ execution::{Result, PreDispatch},
+};
use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
use sp_std::vec::Vec;
use sp_core::U256;
use up_data_structs::TokenId;
-use crate::{
- Allowance, Balance, common::CommonWeights, Config, Pallet, RefungibleHandle, SelfWeightOf,
- TotalSupply, weights::WeightInfo,
-};
+use crate::{Allowance, Balance, Config, Pallet, RefungibleHandle, TotalSupply};
/// Refungible token handle contains information about token's collection and id
///
/// RefungibleTokenHandle doesn't check token's existance upon creation
pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);
-#[solidity_interface(name = ERC1633)]
+frontier_contract! {
+ macro_rules! RefungibleTokenHandle_result {...}
+ impl<T: Config> Contract for RefungibleTokenHandle<T> {...}
+}
+
+#[solidity_interface(name = ERC1633, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> RefungibleTokenHandle<T> {
- fn parent_token(&self) -> Result<Address> {
- Ok(collection_id_to_address(self.id))
+ fn parent_token(&self) -> Address {
+ collection_id_to_address(self.id)
}
- fn parent_token_id(&self) -> Result<U256> {
- Ok(self.1.into())
+ fn parent_token_id(&self) -> U256 {
+ self.1.into()
}
}
@@ -89,18 +90,18 @@
///
/// @dev Implementation of the basic standard token.
/// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
-#[solidity_interface(name = ERC20, events(ERC20Events))]
+#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> RefungibleTokenHandle<T> {
/// @return the name of the token.
- fn name(&self) -> Result<String> {
- Ok(decode_utf16(self.name.iter().copied())
+ fn name(&self) -> String {
+ decode_utf16(self.name.iter().copied())
.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
- .collect::<String>())
+ .collect::<String>()
}
/// @return the symbol of the token.
- fn symbol(&self) -> Result<String> {
- Ok(String::from_utf8_lossy(&self.token_prefix).into())
+ fn symbol(&self) -> String {
+ String::from_utf8_lossy(&self.token_prefix).into()
}
/// @dev Total number of tokens in existence
@@ -198,7 +199,7 @@
}
}
-#[solidity_interface(name = ERC20UniqueExtensions)]
+#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> RefungibleTokenHandle<T>
where
T::AccountId: From<[u8; 32]>,
@@ -361,7 +362,8 @@
#[solidity_interface(
name = UniqueRefungibleToken,
- is(ERC20, ERC20UniqueExtensions, ERC1633)
+ is(ERC20, ERC20UniqueExtensions, ERC1633),
+ enum(derive(PreDispatch)),
)]
impl<T: Config> RefungibleTokenHandle<T> where T::AccountId: From<[u8; 32]> {}
pallets/unique/src/eth/mod.rsdiffbeforeafterboth--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -18,9 +18,7 @@
use core::marker::PhantomData;
use ethereum as _;
-use evm_coder::{
- abi::AbiType, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight,
-};
+use evm_coder::{abi::AbiType, generate_stubgen, solidity_interface, types::*};
use frame_support::traits::Get;
use crate::Pallet;
@@ -32,7 +30,11 @@
Pallet as PalletCommon,
};
use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};
-use pallet_evm_coder_substrate::{dispatch_to_evm, SubstrateRecorder, WithRecorder};
+use pallet_evm_coder_substrate::{
+ dispatch_to_evm, SubstrateRecorder, WithRecorder,
+ execution::{PreDispatch, Result, Error},
+ frontier_contract,
+};
use up_data_structs::{
CollectionDescription, CollectionMode, CollectionName, CollectionTokenPrefix,
CreateCollectionData,
@@ -43,6 +45,10 @@
use alloc::format;
use sp_std::vec::Vec;
+frontier_contract! {
+ macro_rules! EvmCollectionHelpers_result {...}
+ impl<T: Config> Contract for EvmCollectionHelpers<T> {...}
+}
/// See [`CollectionHelpersCall`]
pub struct EvmCollectionHelpers<T: Config>(SubstrateRecorder<T>);
impl<T: Config> WithRecorder<T> for EvmCollectionHelpers<T> {
@@ -135,7 +141,7 @@
}
/// @title Contract, which allows users to operate with collections
-#[solidity_interface(name = CollectionHelpers, events(CollectionHelpersEvents))]
+#[solidity_interface(name = CollectionHelpers, events(CollectionHelpersEvents), enum(derive(PreDispatch)), enum_attr(weight))]
impl<T> EvmCollectionHelpers<T>
where
T: Config + pallet_common::Config + pallet_nonfungible::Config + pallet_refungible::Config,
@@ -183,9 +189,9 @@
/// @param description Informative description of the collection
/// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
/// @return address Address of the newly created collection
- #[weight(<SelfWeightOf<T>>::create_collection())]
#[deprecated(note = "mathod was renamed to `create_nft_collection`, prefer it instead")]
#[solidity(hide)]
+ #[weight(<SelfWeightOf<T>>::create_collection())]
fn create_nonfungible_collection(
&mut self,
caller: Caller,
runtime/tests/Cargo.tomldiffbeforeafterboth--- a/runtime/tests/Cargo.toml
+++ b/runtime/tests/Cargo.toml
@@ -40,5 +40,5 @@
parity-scale-codec = { version = "3.2.2", default-features = false, features = ["derive"] }
scale-info = "*"
-evm-coder = { default-features = false, path = "../../crates/evm-coder" }
+evm-coder = { workspace = true }
up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.37" }