diff --git a/Cargo.lock b/Cargo.lock index b3340b4471..162c215770 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.8.3" @@ -57,6 +72,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base16ct" version = "0.1.1" @@ -72,6 +102,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + [[package]] name = "beef" version = "0.5.2" @@ -84,6 +120,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bitvec" version = "1.0.1" @@ -165,7 +207,7 @@ version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "textwrap 0.11.0", "unicode-width", ] @@ -177,7 +219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "atty", - "bitflags", + "bitflags 1.3.2", "clap_derive", "clap_lex", "indexmap 1.9.2", @@ -215,7 +257,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -270,6 +312,22 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "cpufeatures" version = "0.2.5" @@ -526,6 +584,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "enumn" version = "0.1.6" @@ -543,6 +610,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "ethabi" version = "18.0.0" @@ -655,6 +732,12 @@ dependencies = [ "sha3", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "fe" version = "0.25.0" @@ -668,6 +751,9 @@ dependencies = [ "fs_extra", "include_dir", "indexmap 1.9.2", + "reqwest", + "serde", + "url", "walkdir", ] @@ -939,6 +1025,30 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fs_extra" version = "1.3.0" @@ -951,6 +1061,54 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "fxhash" version = "0.2.1" @@ -983,6 +1141,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "glob" version = "0.3.1" @@ -1000,6 +1164,25 @@ dependencies = [ "subtle", ] +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.2", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "1.8.2" @@ -1096,12 +1279,93 @@ dependencies = [ "digest", ] +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "id-arena" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "if_chain" version = "1.0.2" @@ -1212,6 +1476,12 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "itertools" version = "0.10.5" @@ -1269,9 +1539,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.139" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libm" @@ -1285,6 +1555,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + [[package]] name = "lock_api" version = "0.4.9" @@ -1342,6 +1618,50 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num" version = "0.4.0" @@ -1429,6 +1749,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -1441,6 +1770,50 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "openssl" +version = "0.10.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +dependencies = [ + "bitflags 2.4.1", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "os_str_bytes" version = "6.4.1" @@ -1503,7 +1876,7 @@ dependencies = [ "cloudabi", "instant", "libc", - "redox_syscall", + "redox_syscall 0.1.57", "smallvec", "winapi", ] @@ -1514,6 +1887,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + [[package]] name = "petgraph" version = "0.6.3" @@ -1524,6 +1903,24 @@ dependencies = [ "indexmap 1.9.2", ] +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "plotters" version = "0.3.4" @@ -1633,7 +2030,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f1b898011ce9595050a68e60f90bad083ff2987a695a42357134c8381fba70" dependencies = [ - "bitflags", + "bitflags 1.3.2", "byteorder", "lazy_static", "num-traits", @@ -1733,6 +2130,15 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.7.1" @@ -1750,6 +2156,44 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64 0.21.5", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "revm" version = "3.0.0" @@ -1857,8 +2301,8 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5" dependencies = [ - "base64", - "bitflags", + "base64 0.10.1", + "bitflags 1.3.2", "serde", ] @@ -1895,6 +2339,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62cc5760263ea229d367e7dff3c0cbf09e4797a125bd87059a6c095804f3b2d1" +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -1925,6 +2375,19 @@ dependencies = [ "semver 1.0.16", ] +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustversion" version = "1.0.11" @@ -1999,6 +2462,15 @@ dependencies = [ "syn", ] +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -2042,6 +2514,29 @@ dependencies = [ "cc", ] +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "0.9.0" @@ -2122,6 +2617,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha2" version = "0.10.6" @@ -2159,6 +2666,15 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.10.0" @@ -2174,6 +2690,26 @@ dependencies = [ "serde", ] +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "solc" version = "0.1.0" @@ -2253,12 +2789,46 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -2322,6 +2892,61 @@ dependencies = [ "serde_json", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.5", + "windows-sys", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml" version = "0.5.11" @@ -2365,6 +2990,31 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + [[package]] name = "triehash" version = "0.8.4" @@ -2375,6 +3025,12 @@ dependencies = [ "rlp", ] +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "typenum" version = "1.16.0" @@ -2405,12 +3061,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + [[package]] name = "unicode-ident" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.10.1" @@ -2423,6 +3094,23 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec1" version = "1.10.1" @@ -2458,6 +3146,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2595,6 +3292,72 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "winnow" version = "0.5.1" @@ -2604,6 +3367,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if 1.0.0", + "windows-sys", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/crates/driver/src/lib.rs b/crates/driver/src/lib.rs index a31b1f3307..3fa5182a45 100644 --- a/crates/driver/src/lib.rs +++ b/crates/driver/src/lib.rs @@ -26,8 +26,11 @@ pub struct CompiledModule { pub struct CompiledContract { pub json_abi: String, pub yul: String, + pub origin: ContractId, #[cfg(feature = "solc-backend")] pub bytecode: String, + #[cfg(feature = "solc-backend")] + pub runtime_bytecode: String, } #[cfg(feature = "solc-backend")] @@ -111,13 +114,14 @@ pub fn compile_single_file( path: &str, src: &str, with_bytecode: bool, + with_runtime_bytecode: bool, optimize: bool, ) -> Result { let module = ModuleId::new_standalone(db, path, src); let diags = module.diagnostics(db); if diags.is_empty() { - compile_module(db, module, with_bytecode, optimize) + compile_module(db, module, with_bytecode, with_runtime_bytecode, optimize) } else { Err(CompileError(diags)) } @@ -158,6 +162,7 @@ pub fn compile_ingot( db: &mut Db, build_files: &BuildFiles, with_bytecode: bool, + with_runtime_bytecode: bool, optimize: bool, ) -> Result { let ingot = IngotId::from_build_files(db, build_files); @@ -170,7 +175,13 @@ pub fn compile_ingot( let main_module = ingot .root_module(db) .expect("missing root module, with no diagnostic"); - compile_module(db, main_module, with_bytecode, optimize) + compile_module( + db, + main_module, + with_bytecode, + with_runtime_bytecode, + optimize, + ) } #[cfg(feature = "solc-backend")] @@ -220,7 +231,7 @@ fn compile_test(db: &mut Db, test: FunctionId, optimize: bool) -> CompiledTest { let yul_test = fe_codegen::yul::isel::lower_test(db, test) .to_string() .replace('"', "\\\""); - let bytecode = compile_to_evm("test", &yul_test, optimize); + let bytecode = compile_to_evm("test", &yul_test, optimize, false).bytecode; let events = db.codegen_abi_module_events(test.module(db)); CompiledTest::new(test.name(db), events, bytecode) } @@ -239,6 +250,7 @@ fn compile_module( db: &mut Db, module_id: ModuleId, with_bytecode: bool, + with_runtime_bytecode: bool, optimize: bool, ) -> Result { let mut contracts = IndexMap::default(); @@ -248,19 +260,28 @@ fn compile_module( let abi = db.codegen_abi_contract(contract); let yul_contract = compile_to_yul(db, contract); - let bytecode = if with_bytecode { + let (bytecode, runtime_bytecode) = if with_bytecode || with_runtime_bytecode { let deployable_name = db.codegen_contract_deployer_symbol_name(contract); - compile_to_evm(deployable_name.as_str(), &yul_contract, optimize) + let bytecode = compile_to_evm( + deployable_name.as_str(), + &yul_contract, + optimize, + with_runtime_bytecode, + ); + (bytecode.bytecode, bytecode.runtime_bytecode) } else { - "".to_string() + ("".to_string(), "".to_string()) }; contracts.insert( name.to_string(), + // Maybe put the ContractID here so we can trace it back to the source file CompiledContract { json_abi: serde_json::to_string_pretty(&abi).unwrap(), yul: yul_contract, + origin: contract, bytecode, + runtime_bytecode, }, ); } @@ -277,6 +298,7 @@ fn compile_module( db: &mut Db, module_id: ModuleId, _with_bytecode: bool, + _with_runtime_bytecode: bool, _optimize: bool, ) -> Result { let mut contracts = IndexMap::default(); @@ -290,6 +312,7 @@ fn compile_module( CompiledContract { json_abi: serde_json::to_string_pretty(&abi).unwrap(), yul: yul_contract, + origin: contract, }, ); } @@ -307,9 +330,14 @@ fn compile_to_yul(db: &mut Db, contract: ContractId) -> String { } #[cfg(feature = "solc-backend")] -fn compile_to_evm(name: &str, yul_object: &str, optimize: bool) -> String { - match fe_yulc::compile_single_contract(name, yul_object, optimize) { - Ok(contracts) => contracts, +fn compile_to_evm( + name: &str, + yul_object: &str, + optimize: bool, + verify_runtime_bytecode: bool, +) -> fe_yulc::ContractBytecode { + match fe_yulc::compile_single_contract(name, yul_object, optimize, verify_runtime_bytecode) { + Ok(bytecode) => bytecode, Err(error) => { for error in serde_json::from_str::(&error.0) diff --git a/crates/fe/Cargo.toml b/crates/fe/Cargo.toml index d770ddf760..c463feb4ef 100644 --- a/crates/fe/Cargo.toml +++ b/crates/fe/Cargo.toml @@ -15,6 +15,9 @@ solc-backend = ["fe-driver/solc-backend"] [dependencies] clap = {version="3.1.18", features = ["derive"]} +reqwest = { version = "0.11", features = ["json", "blocking"] } +serde = { version = "1", features = ["derive"] } +url = "2" fs_extra = "1.2.0" walkdir = "2" indexmap = "1.6.2" diff --git a/crates/fe/src/main.rs b/crates/fe/src/main.rs index 71f4781428..d4264273c4 100644 --- a/crates/fe/src/main.rs +++ b/crates/fe/src/main.rs @@ -27,6 +27,10 @@ fn main() { task::create_new_project(arg); } #[cfg(feature = "solc-backend")] + Commands::Verify(arg) => { + task::verify(arg); + } + #[cfg(feature = "solc-backend")] Commands::Test(arg) => { task::test(arg); } diff --git a/crates/fe/src/task/build.rs b/crates/fe/src/task/build.rs index 16ed066efd..dbc55e4767 100644 --- a/crates/fe/src/task/build.rs +++ b/crates/fe/src/task/build.rs @@ -16,6 +16,7 @@ enum Emit { Ast, LoweredAst, Bytecode, + RuntimeBytecode, Tokens, Yul, } @@ -45,6 +46,7 @@ pub struct BuildArgs { fn build_single_file(compile_arg: &BuildArgs) -> (String, CompiledModule) { let emit = &compile_arg.emit; let with_bytecode = emit.contains(&Emit::Bytecode); + let with_runtime_bytecode = emit.contains(&Emit::RuntimeBytecode); let input_path = &compile_arg.input_path; let optimize = compile_arg.optimize.unwrap_or(true); @@ -62,6 +64,7 @@ fn build_single_file(compile_arg: &BuildArgs) -> (String, CompiledModule) { input_path, &content, with_bytecode, + with_runtime_bytecode, optimize, ) { Ok(module) => module, @@ -77,6 +80,7 @@ fn build_single_file(compile_arg: &BuildArgs) -> (String, CompiledModule) { fn build_ingot(compile_arg: &BuildArgs) -> (String, CompiledModule) { let emit = &compile_arg.emit; let with_bytecode = emit.contains(&Emit::Bytecode); + let with_runtime_bytecode = emit.contains(&Emit::RuntimeBytecode); let input_path = &compile_arg.input_path; let optimize = compile_arg.optimize.unwrap_or(true); @@ -100,15 +104,20 @@ fn build_ingot(compile_arg: &BuildArgs) -> (String, CompiledModule) { } let mut db = fe_driver::Db::default(); - let compiled_module = - match fe_driver::compile_ingot(&mut db, &build_files, with_bytecode, optimize) { - Ok(module) => module, - Err(error) => { - eprintln!("Unable to compile {input_path}."); - print_diagnostics(&db, &error.0); - std::process::exit(1) - } - }; + let compiled_module = match fe_driver::compile_ingot( + &mut db, + &build_files, + with_bytecode, + with_runtime_bytecode, + optimize, + ) { + Ok(module) => module, + Err(error) => { + eprintln!("Unable to compile {input_path}."); + print_diagnostics(&db, &error.0); + std::process::exit(1) + } + }; // no file content for ingots ("".to_string(), compiled_module) @@ -202,6 +211,14 @@ fn write_compiled_module( let file_name = format!("{}.bin", &name); write_output(&contract_output_dir.join(file_name), &contract.bytecode)?; } + #[cfg(feature = "solc-backend")] + if targets.contains(&Emit::RuntimeBytecode) { + let file_name = format!("{}.runtime.bin", &name); + write_output( + &contract_output_dir.join(file_name), + &contract.runtime_bytecode, + )?; + } } Ok(()) diff --git a/crates/fe/src/task/mod.rs b/crates/fe/src/task/mod.rs index fba0986702..917279938f 100644 --- a/crates/fe/src/task/mod.rs +++ b/crates/fe/src/task/mod.rs @@ -3,6 +3,7 @@ mod check; mod new; #[cfg(feature = "solc-backend")] mod test; +mod verify; pub use build::{build, BuildArgs}; pub use check::{check, CheckArgs}; @@ -10,6 +11,8 @@ use clap::Subcommand; pub use new::{create_new_project, NewProjectArgs}; #[cfg(feature = "solc-backend")] pub use test::{test, TestArgs}; +#[cfg(feature = "solc-backend")] +pub use verify::{verify, VerifyArgs}; #[derive(Subcommand)] pub enum Commands { @@ -17,5 +20,7 @@ pub enum Commands { Check(CheckArgs), New(NewProjectArgs), #[cfg(feature = "solc-backend")] + Verify(VerifyArgs), + #[cfg(feature = "solc-backend")] Test(TestArgs), } diff --git a/crates/fe/src/task/verify.rs b/crates/fe/src/task/verify.rs new file mode 100644 index 0000000000..a363069254 --- /dev/null +++ b/crates/fe/src/task/verify.rs @@ -0,0 +1,161 @@ +#![cfg(feature = "solc-backend")] +use std::path::Path; + +use clap::Args; +use colored::Colorize; +use fe_common::utils::files::BuildFiles; +use fe_driver::{CompiledContract, CompiledModule, Db}; +use serde::Deserialize; +use url::Url; + +#[derive(Args)] +#[clap(about = "Verify any onchain contract against local available source code.")] +pub struct VerifyArgs { + #[clap(help("The onchain address of the contract to verify"))] + contract_address: String, + #[clap(help("The JSON-RPC URL of the network to verify against"))] + rpc_url: String, + #[clap(long, help("Print additional information"))] + verbose: bool, + #[clap(long, help("Verify against unoptimized bytecode"))] + unoptimized: bool, +} + +#[derive(Deserialize, Debug)] +struct Response { + result: String, +} + +fn build_ingot(db: &mut Db, optimize: bool) -> Result { + let input_path = "."; + + if !Path::new(input_path).exists() { + return Err(format!("Input directory does not exist: `{input_path}`.")); + } + + let build_files = match BuildFiles::load_fs(input_path) { + Ok(files) => files, + Err(err) => return Err(format!("Failed to load project files.\nError: {err}")), + }; + + let compiled_module = match fe_driver::compile_ingot(db, &build_files, true, true, optimize) { + Ok(module) => module, + Err(_) => return Err(format!("Unable to compile {input_path}.")), + }; + + Ok(compiled_module) +} + +fn validate_args(args: &VerifyArgs) -> Result<(), String> { + if !args.contract_address.starts_with("0x") { + return Err(format!( + "Invalid contract address: {}", + args.contract_address + )); + } + + if !args.contract_address.len() == 42 { + return Err(format!( + "Invalid contract address: {}", + args.contract_address + )); + } + if Url::parse(&args.rpc_url).is_err() { + return Err(format!("Invalid RPC URL: {}", args.rpc_url)); + } + Ok(()) +} + +fn request_bytecode(rpc_url: &str, contract_address: &str) -> Result { + let client = reqwest::blocking::Client::new(); + let res = client + .post(rpc_url) + .body(format!( + "{{ + \"jsonrpc\": \"2.0\", + \"id\": 0, + \"method\": \"eth_getCode\", + \"params\": [ + \"{contract_address}\", + \"latest\" + ] + }}" + )) + .send() + .map_err(|e| e.to_string())?; + + let response = res.json::().map_err(|err| err.to_string())?; + Ok(response.result) +} + +pub fn verify(args: VerifyArgs) { + if let Err(err) = do_work(args) { + eprintln!("{}", "Failed to verify contract.\n".bold()); + eprintln!("{}", err); + std::process::exit(1) + } +} + +fn do_work(args: VerifyArgs) -> Result<(), String> { + validate_args(&args)?; + let byte_code = request_bytecode(&args.rpc_url, &args.contract_address)?; + let bytecode = byte_code.strip_prefix("0x").unwrap_or(&byte_code); + + let mut db = fe_driver::Db::default(); + let compiled_module = build_ingot(&mut db, !args.unoptimized)?; + for (_, contract) in compiled_module.contracts { + if contract.runtime_bytecode == bytecode { + print_success(contract, &args, bytecode, &db); + return Ok(()); + } + } + eprintln!("{}", "No contract found with matching bytecode".bold()); + eprintln!("Note: If the contract was deployed with optimization disabled, try verifying with the `--unoptimized` flag."); + eprintln!( + "Note: Make sure to use the same compiler version as the one used to deploy the contract." + ); + Ok(()) +} + +fn print_success( + contract: CompiledContract, + args: &VerifyArgs, + bytecode: &str, + db: &fe_driver::Db, +) { + let bytecode_identifier = if bytecode.len() > 20 { + let start = &bytecode[..5]; + let end = &bytecode[bytecode.len() - 5..]; + format!("{}..{}", start, end) + } else { + // If the string is too short, just print it as it is + bytecode.to_string() + }; + + let contract_name = contract.origin.name(db); + let contract_path = contract.origin.span(db).file_id.path(db); + + println!("{}\n", "It's a match!✨".bold()); + + println!("{}", "Onchain contract:".bold()); + println!("Address: {}", args.contract_address); + println!("Bytecode: 0x{bytecode_identifier}"); + + println!("\n{}", "Local contract:".bold()); + println!("Contract name: {contract_name}"); + println!("Source file: {contract_path}"); + println!("Bytecode: 0x{bytecode_identifier}"); + + if !args.verbose { + println!( + "\n{}", + "Hint: Run with --verbose to see the contract's source code.".bold() + ); + } else { + println!("\n{}", "Source code, taken from: {contract_path}".bold()); + let contract_span = contract.origin.span(db); + let contract_source = contract_span.file_id.content(db); + let source = &contract_source[contract_span.start..contract_span.end]; + println!("{}", source) + } +} diff --git a/crates/test-utils/src/lib.rs b/crates/test-utils/src/lib.rs index d80e2b645c..22d3eb854a 100644 --- a/crates/test-utils/src/lib.rs +++ b/crates/test-utils/src/lib.rs @@ -341,6 +341,7 @@ pub fn deploy_contract( fixture, test_files::fixture(fixture), true, + false, true, ) { Ok(module) => module, @@ -376,7 +377,7 @@ pub fn deploy_contract_from_ingot( let files = test_files::fixture_dir_files("ingots"); let build_files = BuildFiles::load_static(files, path).expect("failed to load build files"); let mut db = driver::Db::default(); - let compiled_module = match driver::compile_ingot(&mut db, &build_files, true, true) { + let compiled_module = match driver::compile_ingot(&mut db, &build_files, true, false, true) { Ok(module) => module, Err(error) => { fe_common::diagnostics::print_diagnostics(&db, &error.0); @@ -587,12 +588,18 @@ pub fn compile_solidity_contract( #[allow(dead_code)] pub fn load_contract(address: H160, fixture: &str, contract_name: &str) -> ContractHarness { let mut db = driver::Db::default(); - let compiled_module = - driver::compile_single_file(&mut db, fixture, test_files::fixture(fixture), true, true) - .unwrap_or_else(|err| { - print_diagnostics(&db, &err.0); - panic!("failed to compile fixture: {fixture}"); - }); + let compiled_module = driver::compile_single_file( + &mut db, + fixture, + test_files::fixture(fixture), + true, + false, + true, + ) + .unwrap_or_else(|err| { + print_diagnostics(&db, &err.0); + panic!("failed to compile fixture: {fixture}"); + }); let compiled_contract = compiled_module .contracts .get(contract_name) @@ -712,9 +719,9 @@ impl ExecutionOutput { #[cfg(feature = "solc-backend")] fn execute_runtime_functions(executor: &mut Executor, runtime: &Runtime) -> (ExitReason, Vec) { let yul_code = runtime.to_yul().to_string().replace('"', "\\\""); - let bytecode = fe_yulc::compile_single_contract("Contract", &yul_code, false) + let contract_bytecode = fe_yulc::compile_single_contract("Contract", &yul_code, false, false) .expect("failed to compile Yul"); - let bytecode = hex::decode(bytecode).expect("failed to decode bytecode"); + let bytecode = hex::decode(contract_bytecode.bytecode).expect("failed to decode bytecode"); if let evm::Capture::Exit((reason, _, output)) = executor.create( address(DEFAULT_CALLER), diff --git a/crates/tests-legacy/src/crashes.rs b/crates/tests-legacy/src/crashes.rs index cd5de57760..fc3e291f5e 100644 --- a/crates/tests-legacy/src/crashes.rs +++ b/crates/tests-legacy/src/crashes.rs @@ -8,7 +8,7 @@ macro_rules! test_file { let mut db = fe_driver::Db::default(); let path = concat!("crashes/", stringify!($name), ".fe"); let src = test_files::fixture(path); - fe_driver::compile_single_file(&mut db, path, src, true, true).ok(); + fe_driver::compile_single_file(&mut db, path, src, true, false, true).ok(); } }; } diff --git a/crates/yulc/src/lib.rs b/crates/yulc/src/lib.rs index a98980f85f..b5c78ad0a9 100644 --- a/crates/yulc/src/lib.rs +++ b/crates/yulc/src/lib.rs @@ -3,16 +3,21 @@ use indexmap::map::IndexMap; #[derive(Debug)] pub struct YulcError(pub String); +pub struct ContractBytecode { + pub bytecode: String, + pub runtime_bytecode: String, +} + /// Compile a map of Yul contracts to a map of bytecode contracts. /// /// Returns a `contract_name -> hex_encoded_bytecode` map. pub fn compile( contracts: impl Iterator, impl AsRef)>, optimize: bool, -) -> Result, YulcError> { +) -> Result, YulcError> { contracts .map(|(name, yul_src)| { - compile_single_contract(name.as_ref(), yul_src.as_ref(), optimize) + compile_single_contract(name.as_ref(), yul_src.as_ref(), optimize, true) .map(|bytecode| (name.as_ref().to_string(), bytecode)) }) .collect() @@ -24,7 +29,8 @@ pub fn compile_single_contract( name: &str, yul_src: &str, optimize: bool, -) -> Result { + verify_runtime_bytecode: bool, +) -> Result { let solc_temp = include_str!("solc_temp.json"); let input = solc_temp .replace("{optimizer_enabled}", &optimize.to_string()) @@ -37,11 +43,22 @@ pub fn compile_single_contract( .to_string() .replace('"', ""); + let runtime_bytecode = output["contracts"]["input.yul"][name]["evm"]["deployedBytecode"] + ["object"] + .to_string() + .replace('"', ""); + if bytecode == "null" { return Err(YulcError(output.to_string())); } + if verify_runtime_bytecode && runtime_bytecode == "null" { + return Err(YulcError(output.to_string())); + } - Ok(bytecode) + Ok(ContractBytecode { + bytecode, + runtime_bytecode, + }) } #[cfg(not(feature = "solc-backend"))] @@ -50,7 +67,8 @@ pub fn compile_single_contract( _name: &str, _yul_src: &str, _optimize: bool, -) -> Result { + _verify_runtime_bytecode: bool, +) -> Result { // This is ugly, but required (as far as I can tell) to make // `cargo test --workspace` work without solc. panic!("fe-yulc requires 'solc-backend' feature") diff --git a/newsfragments/947.feature.md b/newsfragments/947.feature.md new file mode 100644 index 0000000000..f67137a493 --- /dev/null +++ b/newsfragments/947.feature.md @@ -0,0 +1,16 @@ +Give option to produce runtime bytecode as compilation artifact + +Previously, the compiler could only produce the bytecode that is used +for the deployment of the contract. Now it can also produce the runtime +bytecode which is the bytecode that is saved to storage. + +Being able to obtain the runtime bytecode is useful for contract +verification. + +To obtain the runtime bytecode use the `runtime-bytecode` option +of the `--emit` flag (multiple options allowed). + +Example Output: + +- mycontract.bin (bytecode for deployment) +- mycontract.runtime.bin (runtime bytecode) diff --git a/newsfragments/948.feature.md b/newsfragments/948.feature.md new file mode 100644 index 0000000000..7879e2d9a1 --- /dev/null +++ b/newsfragments/948.feature.md @@ -0,0 +1,29 @@ +New `verify` command to verify onchain contracts against local source code. + +People need to be able to verify that a deployed contract matches the source code +that the author claims was used to deploy it. Previously, there was no simple +way to achieve this. + +These are the steps to verify a contract with the `verify` command: + +1. Obtain the project's source code locally. +2. Ensure it is the same source code that was used to deploy the contract. (e.g. check out a specific tag) +2. From the project directory run `fe verify ` + +Example: + +```bash +$ fe verify 0xf0adbb9ed4135d1509ad039505bada942d18755f https://example-eth-mainnet-rpc.com +It's a match!✨ + +Onchain contract: +Address: 0xf0adbb9ed4135d1509ad039505bada942d18755f +Bytecode: 0x60008..76b90 + +Local contract: +Contract name: SimpleDAO +Source file: /home/work/ef/simple_dao/fe_contracts/simpledao/src/main.fe +Bytecode: 0x60008..76b90 + +Hint: Run with --verbose to see the contract's source code. +```