Compare commits
734 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
72671d6c88 | ||
|
2ba536f278 | ||
|
0d0a7fc1f5 | ||
|
77912ab35d | ||
|
fa394018c3 | ||
|
fe1f9c640e | ||
|
ab2d3957cb | ||
|
2b7ec23edc | ||
|
e3b36f736d | ||
|
cc7a14a61d | ||
|
3fb2f1db88 | ||
|
d2bfb2f737 | ||
|
b766268ff3 | ||
|
309a8de530 | ||
|
dc44f8ad91 | ||
|
586a7c54eb | ||
|
b0a986ffff | ||
|
020b59680e | ||
|
5a5e0b5bb3 | ||
|
6e8b9dff51 | ||
|
70cf104f19 | ||
|
85b1cb9013 | ||
|
0a69758468 | ||
|
5d88b74746 | ||
|
73d582d4b3 | ||
|
9bce5f91dc | ||
|
64a0f62700 | ||
|
b63a94031f | ||
|
dc68480f72 | ||
|
d083925bed | ||
|
481c7256cb | ||
|
99bfdf930a | ||
|
ba019e5a01 | ||
|
1041f071f0 | ||
|
91cc72bcd4 | ||
|
14aed39261 | ||
|
34c86d90be | ||
|
1cb04e84d9 | ||
|
16ae76cad7 | ||
|
ae36323edb | ||
|
e43968599e | ||
|
fdc6699159 | ||
|
1b8e792eb6 | ||
|
76e0d81354 | ||
|
737c1abbdf | ||
|
b3230b0bdc | ||
|
df03f1412d | ||
|
eff410eb74 | ||
|
26912e0ee2 | ||
|
88b8368932 | ||
|
c2362c3362 | ||
|
2cf23e15d8 | ||
|
925bfeb24b | ||
|
1ebdab43d8 | ||
|
37e18612c5 | ||
|
e847596e39 | ||
|
c965d6332c | ||
|
73b9077ab0 | ||
|
b1ead4af94 | ||
|
c5b81b66cd | ||
|
78b1f5acc2 | ||
|
589adee306 | ||
|
86ed964c6a | ||
|
1bb596096b | ||
|
a4d777643d | ||
|
38decf05dd | ||
|
ffd495bd89 | ||
|
b9db435684 | ||
|
bc6d10f11d | ||
|
8e9496eb8b | ||
|
60b18a13d2 | ||
|
af6d7793fb | ||
|
97f206ea89 | ||
|
ccf2896594 | ||
|
e57581e730 | ||
|
3d9f633bcd | ||
|
d0dc9e7af0 | ||
|
a442f0608a | ||
|
06b003b23c | ||
|
9ae42aab4c | ||
|
c703b5cd8c | ||
|
9adbced98e | ||
|
c96db51013 | ||
|
664baa9e6b | ||
|
36429e397c | ||
|
b17757ea17 | ||
|
a15ef59eec | ||
|
e8d050a1ce | ||
|
969aea6d33 | ||
|
ee21b03e6c | ||
|
d2f86ffb16 | ||
|
ad7932555d | ||
|
397a5543a4 | ||
|
0f5aacefa0 | ||
|
368ea01bb2 | ||
|
ef5f131862 | ||
|
2baf9d4d82 | ||
|
ec92685bcb | ||
|
18db62cf41 | ||
|
0c2fce579a | ||
|
69e5b634ea | ||
|
9f237d38a6 | ||
|
25fc3aa32f | ||
|
8031be1109 | ||
|
aaba5c408a | ||
|
f344dc164e | ||
|
310794089a | ||
|
342ba0324f | ||
|
579259d6e1 | ||
|
d0a5556fd0 | ||
|
f085572e24 | ||
|
ce423e5ae5 | ||
|
d8cc2c62f3 | ||
|
2a2a9d37ee | ||
|
b4d4b49dca | ||
|
de1a017ccb | ||
|
c50c9b2c43 | ||
|
339053f185 | ||
|
a59fc39f10 | ||
|
4020552e1d | ||
|
8407c8c615 | ||
|
b7d2c8bb0a | ||
|
3edf91adc8 | ||
|
ec240c6422 | ||
|
e357b8bc42 | ||
|
0fbc5cc7d3 | ||
|
96e7b4f46b | ||
|
65587d87c9 | ||
|
6d8b1374c5 | ||
|
e42242cd6f | ||
|
6c1bcb9a81 | ||
|
6f3a379557 | ||
|
e62bc30e9e | ||
|
f87bef2431 | ||
|
aecb11eff4 | ||
|
511712570b | ||
|
6574c10f25 | ||
|
ead0615ca3 | ||
|
2c70255617 | ||
|
ea7ee3d5fe | ||
|
451232985b | ||
|
80d0a979ac | ||
|
db5baebff8 | ||
|
0fa594e501 | ||
|
95beef4072 | ||
|
cdfc19b503 | ||
|
2e38798408 | ||
|
83fe3d4011 | ||
|
4fa48a6eb1 | ||
|
89407d253d | ||
|
b4407d90a5 | ||
|
548b033af6 | ||
|
964bdc711c | ||
|
957a9e742b | ||
|
dcbd645798 | ||
|
ab4f5f2983 | ||
|
ecd56e6129 | ||
|
927eddee84 | ||
|
f466e1ef5e | ||
|
ceb6587692 | ||
|
5b72c4f494 | ||
|
b2ce8898ea | ||
|
d268c3f5b3 | ||
|
c2670e4afb | ||
|
d9974bed71 | ||
|
ce1453b8f8 | ||
|
601104ea94 | ||
|
09628b7502 | ||
|
1acebf78ee | ||
|
f622a6c514 | ||
|
9206885bdd | ||
|
2a46e2fedc | ||
|
aba7d1769c | ||
|
86602852be | ||
|
5c7214cbe3 | ||
|
64427412c4 | ||
|
23fb9bc3a6 | ||
|
82cb5338a9 | ||
|
110e2a656d | ||
|
4fd5bbf50b | ||
|
2c82873a2c | ||
|
f3fc19080a | ||
|
4c4410e0c5 | ||
|
0ab0842c29 | ||
|
755110aed4 | ||
|
735326d50d | ||
|
ba3f9dd2a2 | ||
|
5e1e0e7752 | ||
|
a07f6c443a | ||
|
edceb4d2d1 | ||
|
96bb39d1b4 | ||
|
11be2f4881 | ||
|
e70e595ce7 | ||
|
dad2bf6472 | ||
|
490b90d0ab | ||
|
0afe025f19 | ||
|
bccfcd40a0 | ||
|
23955ba428 | ||
|
ae3b7625c9 | ||
|
ea724071b1 | ||
|
703fa6c8b5 | ||
|
1628678de2 | ||
|
ebc2bc9e23 | ||
|
3fc2eadbdb | ||
|
5b70830a64 | ||
|
16220db759 | ||
|
69c034b1c0 | ||
|
62723b7534 | ||
|
1ac883b84d | ||
|
e81f2bdbd6 | ||
|
8390a24e30 | ||
|
b29d8a429c | ||
|
c1ca2bf9d2 | ||
|
b583e9e64d | ||
|
919408901d | ||
|
09c30566eb | ||
|
ce0fbae00b | ||
|
b84af3f420 | ||
|
a9c8b4b4d1 | ||
|
27faacb72c | ||
|
58a4296989 | ||
|
29358806f4 | ||
|
5d7533b540 | ||
|
2f451a186b | ||
|
3599c8c6b9 | ||
|
30cd1a0fb4 | ||
|
29041c8101 | ||
|
c819243374 | ||
|
3bb492a28d | ||
|
8b64195d4b | ||
|
793adc8106 | ||
|
d12a981ba8 | ||
|
2cf03e3f0b | ||
|
87d0c84960 | ||
|
a4777937ed | ||
|
34d2383f28 | ||
|
b70477d795 | ||
|
1067232bbc | ||
|
92816eb6c5 | ||
|
dabecb600f | ||
|
45c2ffcd55 | ||
|
69ffcfc242 | ||
|
ea1327707b | ||
|
aca4c86a23 | ||
|
10670d6286 | ||
|
826fd90dcf | ||
|
f9a3c094a6 | ||
|
3b80aa2ea4 | ||
|
e8c4d0e324 | ||
|
b26090c288 | ||
|
08897b88c9 | ||
|
edd99b07fe | ||
|
fac7ca943b | ||
|
dc7cda18f0 | ||
|
3ecf968001 | ||
|
6b2939da31 | ||
|
399457d74b | ||
|
4752b31e6c | ||
|
381b610fe5 | ||
|
32e8297048 | ||
|
d4be1d9c2f | ||
|
712229a5c6 | ||
|
f50820fcae | ||
|
374a6fd50e | ||
|
ca8db58edd | ||
|
c2e97369d9 | ||
|
e45e6cc31d | ||
|
e6b1f5ccee | ||
|
4e113820c9 | ||
|
25f329e4a1 | ||
|
e87333f20f | ||
|
f8a1af8bd5 | ||
|
0713adde04 | ||
|
f4217bdc2c | ||
|
aa01223398 | ||
|
e44b8b9097 | ||
|
28573dc71b | ||
|
53c305ea80 | ||
|
b7abd9bba4 | ||
|
6c4e40bcef | ||
|
54c0ca99c3 | ||
|
d32aef3fea | ||
|
2f484431da | ||
|
8c5ecd1c01 | ||
|
74a38fc3d8 | ||
|
b1a773be2f | ||
|
facc38097d | ||
|
3aaa207162 | ||
|
0ea06e1c71 | ||
|
5e32a728fe | ||
|
51cd87c94d | ||
|
25be38905f | ||
|
dff774d82f | ||
|
8e35e8dd8e | ||
|
7ab730d410 | ||
|
811b8e565b | ||
|
64ef9d581b | ||
|
e6716e3208 | ||
|
25c78be73e | ||
|
c7372f3f22 | ||
|
09038ce4cb | ||
|
47969adf91 | ||
|
2769bb52f6 | ||
|
42a068b449 | ||
|
f1d2eda795 | ||
|
f15b826431 | ||
|
dcecf00e30 | ||
|
f5a531fd71 | ||
|
0e48e1251d | ||
|
f397b9a083 | ||
|
5c5f8e8dad | ||
|
00c2f511d3 | ||
|
c1df8ed563 | ||
|
6b061ba696 | ||
|
dd10334754 | ||
|
72a384f4fe | ||
|
4773b0b1e4 | ||
|
5306838920 | ||
|
a518310af9 | ||
|
824e59dec2 | ||
|
14d2ae2dfa | ||
|
d657e77f1e | ||
|
3eedc635c4 | ||
|
a0933fa80a | ||
|
ceab4dfee5 | ||
|
4449f07df4 | ||
|
cf106c44fe | ||
|
38468d03f4 | ||
|
2260c23ce1 | ||
|
8ca453f82e | ||
|
477b621f2e | ||
|
37506b1a90 | ||
|
b0419da654 | ||
|
5893e099fe | ||
|
28a1abf89a | ||
|
bb16f61e1c | ||
|
f09838a03d | ||
|
8c7404f639 | ||
|
1cc656c550 | ||
|
a089aefc05 | ||
|
6db4f182a5 | ||
|
a11b1c83f0 | ||
|
b24e4fcbfa | ||
|
4a1dbdaedb | ||
|
8c5304368d | ||
|
bcdb41f743 | ||
|
17aacfdb6a | ||
|
0ce5e4c94d | ||
|
02a07fdf46 | ||
|
a2a00850ca | ||
|
4af4e5c78f | ||
|
6ea033b7e3 | ||
|
9eaa5cebdb | ||
|
ab70c9cccb | ||
|
45bd6827d2 | ||
|
9f1f2a2a06 | ||
|
574d454be7 | ||
|
4c77bf57df | ||
|
e7f5303a39 | ||
|
7a34d34045 | ||
|
7460c997b7 | ||
|
ff2e4736fa | ||
|
33e7fc1cba | ||
|
d49ed7d66b | ||
|
aa9e25021d | ||
|
af74ab69c9 | ||
|
1250ee778d | ||
|
5640353603 | ||
|
8a41f4ac7e | ||
|
c8117ef75e | ||
|
5fcba53223 | ||
|
a334ab3525 | ||
|
9804085934 | ||
|
ccd80f9904 | ||
|
3f2cde9bd6 | ||
|
c5673278a7 | ||
|
678461e828 | ||
|
33bb833949 | ||
|
0a0c389541 | ||
|
c3a8b9cebb | ||
|
f07c8b1f51 | ||
|
de722d99bc | ||
|
edc5512b75 | ||
|
4b67dea8e2 | ||
|
a1b79de642 | ||
|
3c77d33db8 | ||
|
0f2bd3e8bd | ||
|
b730bde54d | ||
|
8366bd439b | ||
|
606fbd8fcc | ||
|
328f9c8f99 | ||
|
d5c3d34bf4 | ||
|
44a30e47ca | ||
|
4837d42361 | ||
|
a02a7206d8 | ||
|
3bec4c09be | ||
|
3bab14747e | ||
|
d370f53b7e | ||
|
0d0bcf628d | ||
|
4c4eadd893 | ||
|
75a0c486a8 | ||
|
c1720e62aa | ||
|
53626fc092 | ||
|
77af0b41df | ||
|
347c966f08 | ||
|
9a87b587d5 | ||
|
2da0a861ce | ||
|
cbd6495fb1 | ||
|
f32f35f8f1 | ||
|
4ccda14798 | ||
|
94d3747034 | ||
|
ccc2b8e2db | ||
|
44da8507b1 | ||
|
759732d310 | ||
|
41adba0eff | ||
|
34b13c1f89 | ||
|
050927b026 | ||
|
7c323a1faa | ||
|
29751849b5 | ||
|
a29f77369a | ||
|
d80fd1b572 | ||
|
41742c5410 | ||
|
102f18b2b0 | ||
|
766db7daa4 | ||
|
a00a2117c5 | ||
|
889f0721a2 | ||
|
0f40bcc06d | ||
|
bed4732e95 | ||
|
f2ddc997f0 | ||
|
385c48df73 | ||
|
dde579b434 | ||
|
1e63615206 | ||
|
1af6ca772d | ||
|
49cf49184a | ||
|
0cb279494a | ||
|
75960e6db8 | ||
|
8be32f2267 | ||
|
28a959295b | ||
|
778d6f4b26 | ||
|
7c870c95c5 | ||
|
6edec899c8 | ||
|
da7754c6db | ||
|
816f6ec175 | ||
|
302d46c1e6 | ||
|
3bcdc7bd9a | ||
|
14c25c386d | ||
|
a6c809fd19 | ||
|
53a02fc130 | ||
|
28c7fdae09 | ||
|
ba722b66cb | ||
|
4a8d6618f5 | ||
|
b95b96db4e | ||
|
cd5ae26e34 | ||
|
d0043d6753 | ||
|
ee92491aae | ||
|
1fb9a414c9 | ||
|
b75bddbd11 | ||
|
12bca24774 | ||
|
24d43dd1e6 | ||
|
c694a004be | ||
|
35a78f77bc | ||
|
f5b2044ed1 | ||
|
611e02c038 | ||
|
ded9ef17e8 | ||
|
2f78e9549a | ||
|
a297a68726 | ||
|
34da6c8811 | ||
|
61beb321b6 | ||
|
58555db423 | ||
|
f53c0375de | ||
|
a968f1a18c | ||
|
589688b236 | ||
|
e95cfa84bc | ||
|
3b2bb4ba50 | ||
|
ce27eecb93 | ||
|
67078afe4b | ||
|
a9949f1cd1 | ||
|
6cde589a03 | ||
|
e464a49b0b | ||
|
8ea890de53 | ||
|
4cf3661c3e | ||
|
a13c3f0d07 | ||
|
d8937d8a76 | ||
|
b99684d3f2 | ||
|
9b7eb4683b | ||
|
524db30f12 | ||
|
f78591c356 | ||
|
1e00672fbc | ||
|
927946c4f5 | ||
|
f4ab85da3e | ||
|
1fbc17ba05 | ||
|
2810119891 | ||
|
a77d4e281f | ||
|
29baf3b2ba | ||
|
64f57ac3c7 | ||
|
b85a95f52d | ||
|
8a14680851 | ||
|
ee1b50d345 | ||
|
8194acb3b7 | ||
|
3f04f00bdc | ||
|
07def48f45 | ||
|
421738b50d | ||
|
02e936ad82 | ||
|
c6aab84a0c | ||
|
9befe1d456 | ||
|
3458da9df3 | ||
|
5a776c722f | ||
|
719cce02b4 | ||
|
6d847e4e57 | ||
|
1a8be13c05 | ||
|
618211f82b | ||
|
345d0bcf13 | ||
|
07ac3874b6 | ||
|
71bea997aa | ||
|
3edcfce478 | ||
|
4264b5ae07 | ||
|
d478c7d81a | ||
|
cab88290c2 | ||
|
bc18af91bb | ||
|
8f63bb646c | ||
|
e1a9446f87 | ||
|
5d42bb5e38 | ||
|
f0c0df2d8c | ||
|
d08de34bd3 | ||
|
416e6f6604 | ||
|
593e207094 | ||
|
6bc6ae94a6 | ||
|
c1fffa892d | ||
|
46457cfc25 | ||
|
82bde40717 | ||
|
b30f89bcce | ||
|
41ce3feb0a | ||
|
802f895062 | ||
|
0bfcdaf794 | ||
|
8b4c1d3373 | ||
|
8757e0aa11 | ||
|
66fcd542bc | ||
|
fc7cd54849 | ||
|
5687f6e934 | ||
|
8dd6f77692 | ||
|
16d758b7f9 | ||
|
e29a68d374 | ||
|
a902c09cb7 | ||
|
f404eb0349 | ||
|
9e0a0af78c | ||
|
33b07c5dc6 | ||
|
d7ecee4f0a | ||
|
878862a924 | ||
|
26c769fe8e | ||
|
3d5bb3e87b | ||
|
9020efec58 | ||
|
2ea2a63102 | ||
|
be8752b5d3 | ||
|
8e5f8c8595 | ||
|
e6f099db92 | ||
|
f72e61ccbe | ||
|
a019f400d0 | ||
|
293690e5a4 | ||
|
7b634152bd | ||
|
a1fbf6b097 | ||
|
9d5b34b230 | ||
|
d9965a3d14 | ||
|
0037693c8d | ||
|
5e88d590c4 | ||
|
79d975a77d | ||
|
f2dc3d38a7 | ||
|
1a23b7a60a | ||
|
bca3fb8ffd | ||
|
4aa310034c | ||
|
ce9a7ee954 | ||
|
c0f92da860 | ||
|
c2a2fce8e7 | ||
|
25a41e3ac6 | ||
|
cd8636105d | ||
|
ccb64e9fa4 | ||
|
dce1e7b378 | ||
|
f12e368d67 | ||
|
c5ae22db86 | ||
|
58f3aa8c28 | ||
|
1468f5ac41 | ||
|
3e1e43f569 | ||
|
7974a3cf7c | ||
|
7375fc24c0 | ||
|
6f0941a510 | ||
|
5dbfa9409b | ||
|
0158de60be | ||
|
3fb1628358 | ||
|
2ca349c69a | ||
|
a0e62bbd3d | ||
|
0dd40d2ad2 | ||
|
e7ec40b1af | ||
|
afe1242c2f | ||
|
fac5666dc9 | ||
|
960889f532 | ||
|
acaa019785 | ||
|
6b73afae44 | ||
|
9a207ad27c | ||
|
6c58f31b4a | ||
|
aacbe72079 | ||
|
8c53b656e9 | ||
|
0aa85153e5 | ||
|
8b07e23975 | ||
|
d58c699478 | ||
|
812e26640c | ||
|
21c0f78650 | ||
|
529ffffbe1 | ||
|
d30ec3548f | ||
|
5327f4b4e3 | ||
|
f974dbc205 | ||
|
aeff485079 | ||
|
94ebcc9742 | ||
|
c95108169d | ||
|
ca55115ca5 | ||
|
817a57b365 | ||
|
9ace80c7ff | ||
|
f341cfbfb6 | ||
|
1ac3abfbb7 | ||
|
93c8120a24 | ||
|
0904bb3a3c | ||
|
983407762c | ||
|
43e2e3b28b | ||
|
b8e74ffc57 | ||
|
58c1cc6bde | ||
|
17bb4d8b03 | ||
|
8540fc8780 | ||
|
b6df64e4fd | ||
|
7dd6d40481 | ||
|
21823613bc | ||
|
1d8e0abd0a | ||
|
5f0f91974a | ||
|
ab74a268ae | ||
|
d4a08bda93 | ||
|
02b02f507d | ||
|
486be8f10d | ||
|
94ab0e3c53 | ||
|
103bf7a71f | ||
|
82817bfc3a | ||
|
6216842458 | ||
|
aba5ac5e2a | ||
|
5b5e853ea0 | ||
|
2e8d50eca2 | ||
|
1a83fa7ebc | ||
|
5b03c13f90 | ||
|
9445483d60 | ||
|
9a36438441 | ||
|
fa0d3a44a7 | ||
|
9efc422b48 | ||
|
38b5ae578b | ||
|
6c9fc53874 | ||
|
2c306ed32c | ||
|
ff61192eda | ||
|
37e507972c | ||
|
c2036081db | ||
|
d3d9d09f5e | ||
|
4064116df4 | ||
|
411431444e | ||
|
18b42dccd6 | ||
|
930c8c0753 | ||
|
13c0d93f81 | ||
|
45a3d8228d | ||
|
973eda17b4 | ||
|
23eb9c59bb | ||
|
228c355424 | ||
|
01b10e2515 | ||
|
07750ea23a | ||
|
e147654f92 | ||
|
8e652c3aff | ||
|
ceaa7b53da | ||
|
1a981af548 | ||
|
73183d3df9 | ||
|
bc3cbfa18d | ||
|
16bc4c6b5f | ||
|
1b0f7af707 | ||
|
0aefd15576 | ||
|
0384506e55 | ||
|
89c4ee6942 | ||
|
8b7879c7da | ||
|
7585cd9507 | ||
|
7cd589eee4 | ||
|
91b14174d8 | ||
|
e50d56517b | ||
|
a5166f0a19 | ||
|
627bbe2ea3 | ||
|
29e4becd73 | ||
|
59f9ab4dee | ||
|
3ac6edec5b | ||
|
695b250557 | ||
|
eec258c2d2 | ||
|
6bbef64034 | ||
|
96e2a6d3fe | ||
|
47aa1c65ae | ||
|
d33f2734b6 | ||
|
7b35f44622 | ||
|
a38549dc19 | ||
|
603f9f7208 | ||
|
db9c11a2a5 | ||
|
665bf29a84 | ||
|
048aabd3ca | ||
|
82fdc6fccc | ||
|
88e44ed5e2 | ||
|
a5c5e4602a | ||
|
e48d495fb7 | ||
|
7176925a87 | ||
|
98c011328a | ||
|
411841cbb5 | ||
|
8d91ccf028 | ||
|
821da895ea | ||
|
b3f35f703a | ||
|
f2bf23a067 | ||
|
acc01dadfc | ||
|
6a6bf303b5 | ||
|
8f1668ffb8 | ||
|
43431eb427 | ||
|
77640a57c9 | ||
|
558c39dad6 | ||
|
6f285ad197 | ||
|
dbf35f1c14 | ||
|
2b70b08d5f | ||
|
5c6e12b2c0 | ||
|
7ddb5e0c66 | ||
|
bc00063b2e | ||
|
f8880cad82 | ||
|
ddbef8f650 | ||
|
78608e8d17 | ||
|
e735ff1a95 | ||
|
da7dfeb0c5 | ||
|
b403085fa1 | ||
|
9b0556caa4 | ||
|
5b149adfcd | ||
|
72a17ceb71 | ||
|
1edfd73b37 | ||
|
7b8478a81b | ||
|
4ff310cc62 | ||
|
e89efe89a6 |
59
.circleci/compare_bytecode_reports.sh
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Compares bytecode reports generated by prepare_report.py/.js.
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity 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.
|
||||||
|
#
|
||||||
|
# solidity 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 solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2023 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
no_cli_platforms=(
|
||||||
|
emscripten
|
||||||
|
)
|
||||||
|
native_platforms=(
|
||||||
|
ubuntu2004-static
|
||||||
|
ubuntu
|
||||||
|
osx
|
||||||
|
windows
|
||||||
|
)
|
||||||
|
interfaces=(
|
||||||
|
cli
|
||||||
|
standard-json
|
||||||
|
)
|
||||||
|
|
||||||
|
for preset in "$@"; do
|
||||||
|
report_files=()
|
||||||
|
for platform in "${no_cli_platforms[@]}"; do
|
||||||
|
report_files+=("bytecode-report-${platform}-${preset}.txt")
|
||||||
|
done
|
||||||
|
for platform in "${native_platforms[@]}"; do
|
||||||
|
for interface in "${interfaces[@]}"; do
|
||||||
|
report_files+=("bytecode-report-${platform}-${interface}-${preset}.txt")
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Reports to compare:"
|
||||||
|
printf -- "- %s\n" "${report_files[@]}"
|
||||||
|
|
||||||
|
if ! diff --brief --report-identical-files --from-file "${report_files[@]}"; then
|
||||||
|
diff --unified=0 --report-identical-files --from-file "${report_files[@]}" | head --lines 50
|
||||||
|
zip "bytecode-reports-${preset}.zip" "${report_files[@]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
1613
.circleci/config.yml
@ -52,7 +52,8 @@ function validate_checksum {
|
|||||||
|
|
||||||
if [ ! -f /usr/local/lib/libz3.a ] # if this file does not exists (cache was not restored), rebuild dependencies
|
if [ ! -f /usr/local/lib/libz3.a ] # if this file does not exists (cache was not restored), rebuild dependencies
|
||||||
then
|
then
|
||||||
brew unlink python
|
brew update
|
||||||
|
brew upgrade
|
||||||
brew install boost
|
brew install boost
|
||||||
brew install cmake
|
brew install cmake
|
||||||
brew install wget
|
brew install wget
|
||||||
@ -61,11 +62,11 @@ then
|
|||||||
./scripts/install_obsolete_jsoncpp_1_7_4.sh
|
./scripts/install_obsolete_jsoncpp_1_7_4.sh
|
||||||
|
|
||||||
# z3
|
# z3
|
||||||
z3_version="4.11.2"
|
z3_version="4.12.1"
|
||||||
z3_dir="z3-${z3_version}-x64-osx-10.16"
|
z3_dir="z3-${z3_version}-x64-osx-10.16"
|
||||||
z3_package="${z3_dir}.zip"
|
z3_package="${z3_dir}.zip"
|
||||||
wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_package}"
|
wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_package}"
|
||||||
validate_checksum "$z3_package" a56b6c40d9251a963aabe1f15731dd88ad1cb801d0e7b16e45f8b232175e165c
|
validate_checksum "$z3_package" 7601f844de6d906235140d0f76cca58be7ac716f3e2c29c35845aa24b24f73b9
|
||||||
unzip "$z3_package"
|
unzip "$z3_package"
|
||||||
rm "$z3_package"
|
rm "$z3_package"
|
||||||
cp "${z3_dir}/bin/libz3.a" /usr/local/lib
|
cp "${z3_dir}/bin/libz3.a" /usr/local/lib
|
||||||
@ -74,10 +75,10 @@ then
|
|||||||
rm -r "$z3_dir"
|
rm -r "$z3_dir"
|
||||||
|
|
||||||
# evmone
|
# evmone
|
||||||
evmone_version="0.9.1"
|
evmone_version="0.10.0"
|
||||||
evmone_package="evmone-${evmone_version}-darwin-x86_64.tar.gz"
|
evmone_package="evmone-${evmone_version}-darwin-x86_64.tar.gz"
|
||||||
wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}"
|
wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}"
|
||||||
validate_checksum "$evmone_package" 70420a893a9b1036fcb63526b806d97658db8c373bcab1c3e8382594dc8593e4
|
validate_checksum "$evmone_package" 1b7773779287d7908baca6b8d556a98800cbd7d6e5c910b55fa507642bc0a15c
|
||||||
tar xzpf "$evmone_package" -C /usr/local
|
tar xzpf "$evmone_package" -C /usr/local
|
||||||
rm "$evmone_package"
|
rm "$evmone_package"
|
||||||
|
|
||||||
|
79
.circleci/parallel_bytecode_report.sh
Executable file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Splits all test source code into multiple files, generates bytecode and metadata
|
||||||
|
# for each file and combines it into a single report.txt file.
|
||||||
|
#
|
||||||
|
# The script is meant to be executed in CI on all supported platforms. All generated
|
||||||
|
# reports must be identical for a given compiler version.
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity 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.
|
||||||
|
#
|
||||||
|
# solidity 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 solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2023 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(( $# == 4 )) || { >&2 echo "Wrong number of arguments."; exit 1; }
|
||||||
|
label="$1"
|
||||||
|
binary_type="$2"
|
||||||
|
binary_path="$3" # This path must be absolute
|
||||||
|
preset="$4"
|
||||||
|
|
||||||
|
[[ $binary_type == native || $binary_type == solcjs ]] || { >&2 echo "Invalid binary type: ${binary_type}"; exit 1; }
|
||||||
|
|
||||||
|
# NOTE: Locale affects the order of the globbed files.
|
||||||
|
export LC_ALL=C
|
||||||
|
|
||||||
|
mkdir test-cases/
|
||||||
|
cd test-cases/
|
||||||
|
|
||||||
|
echo "Preparing input files"
|
||||||
|
python3 ../scripts/isolate_tests.py ../test/
|
||||||
|
|
||||||
|
# FIXME: These cases crash because of https://github.com/ethereum/solidity/issues/13583
|
||||||
|
rm ./*_bytecode_too_large_*.sol ./*_combined_too_large_*.sol
|
||||||
|
|
||||||
|
if [[ $binary_type == native ]]; then
|
||||||
|
interface=$(echo -e "standard-json\ncli" | circleci tests split)
|
||||||
|
echo "Selected interface: ${interface}"
|
||||||
|
|
||||||
|
echo "Generating bytecode reports"
|
||||||
|
python3 ../scripts/bytecodecompare/prepare_report.py \
|
||||||
|
"$binary_path" \
|
||||||
|
--interface "$interface" \
|
||||||
|
--preset "$preset" \
|
||||||
|
--report-file "../bytecode-report-${label}-${interface}-${preset}.txt"
|
||||||
|
else
|
||||||
|
echo "Installing solc-js"
|
||||||
|
git clone --depth 1 https://github.com/ethereum/solc-js.git solc-js
|
||||||
|
cp "$binary_path" solc-js/soljson.js
|
||||||
|
|
||||||
|
cd solc-js/
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
npm install ./solc-js/dist
|
||||||
|
|
||||||
|
cp ../scripts/bytecodecompare/prepare_report.js .
|
||||||
|
|
||||||
|
echo "Generating bytecode reports"
|
||||||
|
# shellcheck disable=SC2035
|
||||||
|
./prepare_report.js \
|
||||||
|
--preset "$preset" \
|
||||||
|
*.sol > "../bytecode-report-${label}-${preset}.txt"
|
||||||
|
fi
|
45
.circleci/parallel_cli_tests.py
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Slowest CLI tests, whose execution takes time on the order of minutes (as of June 2023).
|
||||||
|
# When adding/removing items here, remember to update `parallelism` value in jobs that run this script.
|
||||||
|
# TODO: We should switch to time-based splitting but that requires JUnit XML report support in cmdlineTests.sh.
|
||||||
|
tests_to_run_in_parallel = [
|
||||||
|
'~ast_import_export', # ~7 min
|
||||||
|
'~ast_export_with_stop_after_parsing', # ~4 min
|
||||||
|
'~soljson_via_fuzzer', # ~3 min
|
||||||
|
'~via_ir_equivalence', # ~1 min
|
||||||
|
'~compilation_tests', # ~1 min
|
||||||
|
'~documentation_examples', # ~1 min
|
||||||
|
'*', # This item represents all the remaining tests
|
||||||
|
]
|
||||||
|
|
||||||
|
# Ask CircleCI to select a subset of tests for this parallel execution.
|
||||||
|
# If `parallelism` in CI config is set correctly, we should get just one but we can handle any split.
|
||||||
|
selected_tests = subprocess.check_output(
|
||||||
|
['circleci', 'tests', 'split'],
|
||||||
|
input='\n'.join(tests_to_run_in_parallel),
|
||||||
|
encoding='ascii',
|
||||||
|
).strip().split('\n')
|
||||||
|
selected_tests = set(selected_tests) - {''}
|
||||||
|
excluded_tests = set(tests_to_run_in_parallel) - selected_tests
|
||||||
|
assert selected_tests.issubset(set(tests_to_run_in_parallel))
|
||||||
|
|
||||||
|
if len(selected_tests) == 0:
|
||||||
|
print("No tests to run.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if '*' in selected_tests:
|
||||||
|
filters = [arg for test_name in excluded_tests for arg in ['--exclude', test_name]]
|
||||||
|
else:
|
||||||
|
filters = list(selected_tests)
|
||||||
|
|
||||||
|
subprocess.run(
|
||||||
|
['test/cmdlineTests.sh'] + filters,
|
||||||
|
stdin=sys.stdin,
|
||||||
|
stdout=sys.stdout,
|
||||||
|
stderr=sys.stderr,
|
||||||
|
check=True,
|
||||||
|
)
|
@ -36,6 +36,7 @@ set -e
|
|||||||
|
|
||||||
OPTIMIZE=${OPTIMIZE:-"0"}
|
OPTIMIZE=${OPTIMIZE:-"0"}
|
||||||
EVM=${EVM:-"invalid"}
|
EVM=${EVM:-"invalid"}
|
||||||
|
CPUs=${CPUs:-3}
|
||||||
REPODIR="$(realpath "$(dirname "$0")/..")"
|
REPODIR="$(realpath "$(dirname "$0")/..")"
|
||||||
|
|
||||||
IFS=" " read -r -a BOOST_TEST_ARGS <<< "$BOOST_TEST_ARGS"
|
IFS=" " read -r -a BOOST_TEST_ARGS <<< "$BOOST_TEST_ARGS"
|
||||||
@ -67,7 +68,6 @@ get_logfile_basename() {
|
|||||||
# long-running test cases are next to each other.
|
# long-running test cases are next to each other.
|
||||||
CIRCLE_NODE_INDEX=$(((CIRCLE_NODE_INDEX + 23 * INDEX_SHIFT) % CIRCLE_NODE_TOTAL))
|
CIRCLE_NODE_INDEX=$(((CIRCLE_NODE_INDEX + 23 * INDEX_SHIFT) % CIRCLE_NODE_TOTAL))
|
||||||
|
|
||||||
CPUs=3
|
|
||||||
PIDs=()
|
PIDs=()
|
||||||
for run in $(seq 0 $((CPUs - 1)))
|
for run in $(seq 0 $((CPUs - 1)))
|
||||||
do
|
do
|
||||||
|
@ -31,8 +31,8 @@ REPODIR="$(realpath "$(dirname "$0")"/..)"
|
|||||||
# shellcheck source=scripts/common.sh
|
# shellcheck source=scripts/common.sh
|
||||||
source "${REPODIR}/scripts/common.sh"
|
source "${REPODIR}/scripts/common.sh"
|
||||||
|
|
||||||
EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london paris)
|
EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london paris shanghai)
|
||||||
DEFAULT_EVM=paris
|
DEFAULT_EVM=shanghai
|
||||||
[[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]]
|
[[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]]
|
||||||
OPTIMIZE_VALUES=(0 1)
|
OPTIMIZE_VALUES=(0 1)
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ Language: Cpp
|
|||||||
BasedOnStyle: LLVM
|
BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -4
|
AccessModifierOffset: -4
|
||||||
AlignAfterOpenBracket: AlwaysBreak
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
AlignEscapedNewlinesLeft: true
|
AlignEscapedNewlines: Left
|
||||||
AlwaysBreakAfterReturnType: None
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakTemplateDeclarations: Yes
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
BinPackArguments: false
|
BinPackArguments: false
|
||||||
|
7
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,5 +1,10 @@
|
|||||||
---
|
---
|
||||||
name: Bug Report
|
name: Bug Report
|
||||||
|
about: Problems, deficiencies, inaccuracies or crashes discovered on Solidity.
|
||||||
|
title: ''
|
||||||
|
labels: 'bug :bug:'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!--## Prerequisites
|
<!--## Prerequisites
|
||||||
@ -31,7 +36,7 @@ name: Bug Report
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Please provide a *minimal* source code example to trigger the bug you have found.
|
Please provide a *minimal* source code example to trigger the bug you have found.
|
||||||
Please also mention any command line flags that are necessary for triggering the bug.
|
Please also mention any command-line flags that are necessary for triggering the bug.
|
||||||
Provide as much information as necessary to reproduce the bug.
|
Provide as much information as necessary to reproduce the bug.
|
||||||
|
|
||||||
```solidity
|
```solidity
|
||||||
|
12
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,17 +1,5 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Bug Report
|
|
||||||
url: https://github.com/ethereum/solidity/issues/new?template=bug_report.md&projects=ethereum/solidity/43
|
|
||||||
about: Bug reports for the Solidity Compiler.
|
|
||||||
- name: Documentation Issue
|
|
||||||
url: https://github.com/ethereum/solidity/issues/new?template=documentation_issue.md&projects=ethereum/solidity/43
|
|
||||||
about: Solidity documentation.
|
|
||||||
- name: Feature Request
|
|
||||||
url: https://github.com/ethereum/solidity/issues/new?template=feature_request.md&projects=ethereum/solidity/43
|
|
||||||
about: Solidity language or infrastructure feature requests.
|
|
||||||
- name: Report a security vulnerability
|
|
||||||
url: https://github.com/ethereum/solidity/security/policy
|
|
||||||
about: Please review our security policy for more details.
|
|
||||||
- name: Initiate a language design or feedback discussion
|
- name: Initiate a language design or feedback discussion
|
||||||
url: https://forum.soliditylang.org
|
url: https://forum.soliditylang.org
|
||||||
about: Open a thread on the Solidity forum.
|
about: Open a thread on the Solidity forum.
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
---
|
---
|
||||||
name: Documentation Issue
|
name: Documentation Issue
|
||||||
|
about: Corrections, improvements or requests for new content on Solidity's documentation.
|
||||||
|
title: ''
|
||||||
|
labels: 'documentation :book:'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Page
|
## Page
|
||||||
|
6
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,5 +1,11 @@
|
|||||||
---
|
---
|
||||||
name: Feature Request
|
name: Feature Request
|
||||||
|
about: Ideas, comments or messages asking for a particular functionality to be added
|
||||||
|
to Solidity.
|
||||||
|
title: ''
|
||||||
|
labels: feature
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!--## Prerequisites
|
<!--## Prerequisites
|
||||||
|
5
.github/workflows/buildpack-deps.yml
vendored
@ -5,7 +5,8 @@ on:
|
|||||||
branches: [ develop ]
|
branches: [ develop ]
|
||||||
paths:
|
paths:
|
||||||
- 'scripts/docker/buildpack-deps/Dockerfile.emscripten'
|
- 'scripts/docker/buildpack-deps/Dockerfile.emscripten'
|
||||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz'
|
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz'
|
||||||
|
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2004'
|
||||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang'
|
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang'
|
||||||
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204'
|
- 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204'
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
image_variant: [emscripten, ubuntu1604.clang.ossfuzz, ubuntu2204.clang, ubuntu2204]
|
image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
18
.github/workflows/stale.yml
vendored
@ -10,8 +10,8 @@ permissions:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BEFORE_ISSUE_STALE: 334
|
BEFORE_ISSUE_STALE: 90
|
||||||
BEFORE_ISSUE_CLOSE: 0 #FIXME: change to 14 days
|
BEFORE_ISSUE_CLOSE: 7
|
||||||
BEFORE_PR_STALE: 14
|
BEFORE_PR_STALE: 14
|
||||||
BEFORE_PR_CLOSE: 7
|
BEFORE_PR_CLOSE: 7
|
||||||
|
|
||||||
@ -28,14 +28,13 @@ jobs:
|
|||||||
This issue has been marked as stale due to inactivity for the last ${{ env.BEFORE_ISSUE_STALE }} days.
|
This issue has been marked as stale due to inactivity for the last ${{ env.BEFORE_ISSUE_STALE }} days.
|
||||||
It will be automatically closed in ${{ env.BEFORE_ISSUE_CLOSE }} days.
|
It will be automatically closed in ${{ env.BEFORE_ISSUE_CLOSE }} days.
|
||||||
close-issue-message: |
|
close-issue-message: |
|
||||||
Hi everyone! This issue has been closed due to inactivity.
|
Hi everyone! This issue has been automatically closed due to inactivity.
|
||||||
If you think this issue is still relevant in the latest Solidity version and you have something to [contribute](https://docs.soliditylang.org/en/latest/contributing.html), feel free to reopen.
|
If you think this issue is still relevant in the latest Solidity version and you have something to [contribute](https://docs.soliditylang.org/en/latest/contributing.html), feel free to reopen.
|
||||||
However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the [forum](https://forum.soliditylang.org) instead.
|
However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the [forum](https://forum.soliditylang.org) instead.
|
||||||
any-of-issue-labels: stale # TODO: remove this when we're done with closing ancient issues
|
ascending: true
|
||||||
ascending: true # TODO: remove this when we're done with closing ancient issues
|
|
||||||
stale-issue-label: stale
|
stale-issue-label: stale
|
||||||
close-issue-label: closed-due-inactivity
|
close-issue-label: 'closed due inactivity'
|
||||||
exempt-issue-labels: 'bug :bug:,roadmap,selected-for-development,must have'
|
exempt-issue-labels: 'bug :bug:,epic,roadmap,selected for development,must have,must have eventually,smt'
|
||||||
stale-pr-message: |
|
stale-pr-message: |
|
||||||
This pull request is stale because it has been open for ${{ env.BEFORE_PR_STALE }} days with no activity.
|
This pull request is stale because it has been open for ${{ env.BEFORE_PR_STALE }} days with no activity.
|
||||||
It will be closed in ${{ env.BEFORE_PR_CLOSE }} days unless the `stale` label is removed.
|
It will be closed in ${{ env.BEFORE_PR_CLOSE }} days unless the `stale` label is removed.
|
||||||
@ -48,6 +47,5 @@ jobs:
|
|||||||
exempt-pr-labels: 'external contribution :star:,roadmap,epic'
|
exempt-pr-labels: 'external contribution :star:,roadmap,epic'
|
||||||
exempt-draft-pr: false
|
exempt-draft-pr: false
|
||||||
exempt-all-milestones: true
|
exempt-all-milestones: true
|
||||||
# remove-stale-when-updated: true # TODO: uncomment and remove the line below when we're done with closing ancient issues
|
remove-stale-when-updated: true
|
||||||
remove-issue-stale-when-updated: false
|
operations-per-run: 256
|
||||||
operations-per-run: 128
|
|
||||||
|
61
.github/workflows/triage.yml
vendored
@ -1,61 +0,0 @@
|
|||||||
name: Add new issues to triage column
|
|
||||||
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
ORGANIZATION: ethereum
|
|
||||||
REPOSITORY: solidity
|
|
||||||
PROJECT_NUMBER: 43
|
|
||||||
DRY_RUN: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
triage_issues:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: join(github.event.issue.labels) == ''
|
|
||||||
steps:
|
|
||||||
- name: Retrieve the content of all columns on the board
|
|
||||||
run: |
|
|
||||||
gh api graphql \
|
|
||||||
--raw-field owner="$ORGANIZATION" \
|
|
||||||
--field project_number="$PROJECT_NUMBER" \
|
|
||||||
--raw-field repository_name="$REPOSITORY" \
|
|
||||||
--raw-field query='
|
|
||||||
query($owner: String!, $repository_name: String!, $project_number: Int!) {
|
|
||||||
repository(owner: $owner, name: $repository_name) {
|
|
||||||
project(number: $project_number) {
|
|
||||||
columns(first: 10) {
|
|
||||||
nodes {
|
|
||||||
id,
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}' > project_columns.json
|
|
||||||
echo 'COLUMN_ID='$(jq '.data.repository.project.columns.nodes[] | select(.name == "Triage") | .id' project_columns.json) >> $GITHUB_ENV
|
|
||||||
echo 'COLUMN_NAME='$(jq '.data.repository.project.columns.nodes[] | select(.name == "Triage") | .name' project_columns.json) >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Add issue#${{ github.event.issue.number }} to Triage column
|
|
||||||
env:
|
|
||||||
ISSUE_ID: ${{ github.event.issue.node_id }}
|
|
||||||
run: |
|
|
||||||
echo "Adding issue: ${{ github.event.issue.number }} to column $COLUMN_NAME in project $PROJECT_NUMBER"
|
|
||||||
if [[ $DRY_RUN == "false" ]]; then
|
|
||||||
gh api graphql \
|
|
||||||
--silent \
|
|
||||||
--raw-field column=$COLUMN_ID \
|
|
||||||
--raw-field issue=$ISSUE_ID \
|
|
||||||
--raw-field query='
|
|
||||||
mutation($column: ID!, $issue: ID!) {
|
|
||||||
addProjectCard(input: {
|
|
||||||
projectColumnId: $column,
|
|
||||||
contentId: $issue
|
|
||||||
}) {
|
|
||||||
clientMutationId
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
fi
|
|
32
.github/workflows/welcome-external-pr.yml
vendored
@ -6,42 +6,16 @@ on:
|
|||||||
- opened
|
- opened
|
||||||
|
|
||||||
env:
|
env:
|
||||||
ORGANIZATION: Ethereum
|
|
||||||
DRY_RUN: false
|
DRY_RUN: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
comment-external-pr:
|
comment-external-pr:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Get organization members
|
# Note: this step requires that the INTERNAL_CONTRIBUTORS environment variable
|
||||||
id: get_members
|
# is already defined in the repository with the current json list of internal contributors.
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.READ_ORG }}
|
|
||||||
CONTRIBUTOR: ${{ github.event.pull_request.user.login }}
|
|
||||||
run: |
|
|
||||||
gh api graphql \
|
|
||||||
--raw-field organization="$ORGANIZATION" \
|
|
||||||
--raw-field query='
|
|
||||||
query($organization: String!) {
|
|
||||||
organization(login: $organization) {
|
|
||||||
team(slug: "Solidity") {
|
|
||||||
members(first: 100) {
|
|
||||||
nodes {
|
|
||||||
login
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}' > org_members.json
|
|
||||||
echo "CONTRIBUTOR_IS_ORG_MEMBER=$(
|
|
||||||
jq \
|
|
||||||
--arg contributor $CONTRIBUTOR \
|
|
||||||
'.data.organization.team.members | any(.nodes[].login; . == $contributor)' \
|
|
||||||
org_members.json
|
|
||||||
)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Comment on external contribution PR
|
- name: Comment on external contribution PR
|
||||||
if: ${{ steps.get_members.outputs.CONTRIBUTOR_IS_ORG_MEMBER == 'false' }}
|
if: "!contains(fromJSON(vars.INTERNAL_CONTRIBUTORS), github.event.pull_request.user.login)"
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
PR: ${{ github.event.pull_request.html_url }}
|
PR: ${{ github.event.pull_request.html_url }}
|
||||||
|
3
.gitignore
vendored
@ -27,6 +27,9 @@ __pycache__
|
|||||||
*.a
|
*.a
|
||||||
*.lib
|
*.lib
|
||||||
|
|
||||||
|
# ignore git mergetool backup files
|
||||||
|
*.orig
|
||||||
|
|
||||||
# Executables
|
# Executables
|
||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
|
18
.readthedocs.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
build:
|
||||||
|
os: ubuntu-22.04
|
||||||
|
tools:
|
||||||
|
python: "3.11"
|
||||||
|
|
||||||
|
sphinx:
|
||||||
|
builder: html
|
||||||
|
configuration: docs/conf.py
|
||||||
|
|
||||||
|
formats:
|
||||||
|
- pdf
|
||||||
|
- epub
|
||||||
|
|
||||||
|
python:
|
||||||
|
install:
|
||||||
|
- requirements: docs/requirements.txt
|
@ -1,11 +1,11 @@
|
|||||||
cmake_minimum_required(VERSION 3.13.0)
|
cmake_minimum_required(VERSION 3.13.0)
|
||||||
|
|
||||||
set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The the path to the cmake directory")
|
set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The path to the cmake directory")
|
||||||
list(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR})
|
list(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR})
|
||||||
|
|
||||||
# Set the build type, if none was specified.
|
# Set the build type, if none was specified.
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
if(EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||||
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
|
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
|
||||||
else()
|
else()
|
||||||
set(DEFAULT_BUILD_TYPE "Release")
|
set(DEFAULT_BUILD_TYPE "Release")
|
||||||
@ -21,7 +21,7 @@ include(EthPolicy)
|
|||||||
eth_policy()
|
eth_policy()
|
||||||
|
|
||||||
# project name and version should be set after cmake_policy CMP0048
|
# project name and version should be set after cmake_policy CMP0048
|
||||||
set(PROJECT_VERSION "0.8.18")
|
set(PROJECT_VERSION "0.8.22")
|
||||||
# OSX target needed in order to support std::visit
|
# OSX target needed in order to support std::visit
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14")
|
||||||
project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX)
|
project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX)
|
||||||
@ -66,16 +66,16 @@ include(EthUtils)
|
|||||||
|
|
||||||
# Create license.h from LICENSE.txt and template
|
# Create license.h from LICENSE.txt and template
|
||||||
# Converting to char array is required due to MSVC's string size limit.
|
# Converting to char array is required due to MSVC's string size limit.
|
||||||
file(READ ${CMAKE_SOURCE_DIR}/LICENSE.txt LICENSE_TEXT HEX)
|
file(READ ${PROJECT_SOURCE_DIR}/LICENSE.txt LICENSE_TEXT HEX)
|
||||||
string(REGEX MATCHALL ".." LICENSE_TEXT "${LICENSE_TEXT}")
|
string(REGEX MATCHALL ".." LICENSE_TEXT "${LICENSE_TEXT}")
|
||||||
string(REGEX REPLACE ";" ",\n\t0x" LICENSE_TEXT "${LICENSE_TEXT}")
|
string(REGEX REPLACE ";" ",\n\t0x" LICENSE_TEXT "${LICENSE_TEXT}")
|
||||||
set(LICENSE_TEXT "0x${LICENSE_TEXT}")
|
set(LICENSE_TEXT "0x${LICENSE_TEXT}")
|
||||||
|
|
||||||
configure_file("${CMAKE_SOURCE_DIR}/cmake/templates/license.h.in" include/license.h)
|
configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/license.h.in" include/license.h)
|
||||||
|
|
||||||
include(EthOptions)
|
include(EthOptions)
|
||||||
configure_project(TESTS)
|
configure_project(TESTS)
|
||||||
set(LATEST_Z3_VERSION "4.11.2")
|
set(LATEST_Z3_VERSION "4.12.1")
|
||||||
set(MINIMUM_Z3_VERSION "4.8.16")
|
set(MINIMUM_Z3_VERSION "4.8.16")
|
||||||
find_package(Z3)
|
find_package(Z3)
|
||||||
if (${Z3_FOUND})
|
if (${Z3_FOUND})
|
||||||
@ -140,6 +140,7 @@ add_subdirectory(libevmasm)
|
|||||||
add_subdirectory(libyul)
|
add_subdirectory(libyul)
|
||||||
add_subdirectory(libsolidity)
|
add_subdirectory(libsolidity)
|
||||||
add_subdirectory(libsolc)
|
add_subdirectory(libsolc)
|
||||||
|
add_subdirectory(libstdlib)
|
||||||
add_subdirectory(tools)
|
add_subdirectory(tools)
|
||||||
|
|
||||||
if (NOT EMSCRIPTEN)
|
if (NOT EMSCRIPTEN)
|
||||||
|
@ -51,11 +51,11 @@ To set indentation and tab width settings uniformly, the repository contains an
|
|||||||
## 1. Namespaces
|
## 1. Namespaces
|
||||||
|
|
||||||
1. No `using namespace` declarations in header files.
|
1. No `using namespace` declarations in header files.
|
||||||
2. Use `using namespace std;` in cpp files, but avoid importing namespaces from boost and others.
|
2. `using namespace solidity;` and other project local namespaces is fine in cpp files, and generally encouraged.
|
||||||
3. All symbols should be declared in a namespace except for final applications.
|
3. Avoid `using namespace` at file level for third party libraries, such as boost, ranges, etc.
|
||||||
4. Use anonymous namespaces for helpers whose scope is a cpp file only.
|
4. All symbols should be declared in a namespace except for final applications.
|
||||||
5. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore.
|
5. Use anonymous namespaces for helpers whose scope is a cpp file only.
|
||||||
6. Do not use `std::` qualifier in cpp files (see 2.), except for `std::move`, which will otherwise cause the `check_style` step to fail.
|
6. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore.
|
||||||
|
|
||||||
Only in the header:
|
Only in the header:
|
||||||
```cpp
|
```cpp
|
||||||
@ -66,16 +66,6 @@ std::tuple<float, float> meanAndSigma(std::vector<float> const& _v);
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Only in the cpp file:
|
|
||||||
```cpp
|
|
||||||
#include <cassert>
|
|
||||||
using namespace std;
|
|
||||||
tuple<float, float> myNamespace::meanAndSigma(vector<float> const& _v)
|
|
||||||
{
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Preprocessor
|
## 2. Preprocessor
|
||||||
|
|
||||||
1. File comment is always at top, and includes:
|
1. File comment is always at top, and includes:
|
||||||
@ -117,7 +107,7 @@ Use `solAssert` and `solUnimplementedAssert` generously to check assumptions tha
|
|||||||
1. {Typename} + {qualifiers} + {name}.
|
1. {Typename} + {qualifiers} + {name}.
|
||||||
2. Only one per line.
|
2. Only one per line.
|
||||||
3. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)).
|
3. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)).
|
||||||
4. Favour declarations close to use; don't habitually declare at top of scope ala C.
|
4. Favour declarations close to use; do not habitually declare at top of scope ala C.
|
||||||
5. Pass non-trivial parameters as const reference, unless the data is to be copied into the function, then either pass by const reference or by value and use std::move.
|
5. Pass non-trivial parameters as const reference, unless the data is to be copied into the function, then either pass by const reference or by value and use std::move.
|
||||||
6. If a function returns multiple values, use std::tuple (std::pair acceptable) or better introduce a struct type. Do not use */& arguments.
|
6. If a function returns multiple values, use std::tuple (std::pair acceptable) or better introduce a struct type. Do not use */& arguments.
|
||||||
7. Use parameters of pointer type only if ``nullptr`` is a valid argument, use references otherwise. Often, ``std::optional`` is better suited than a raw pointer.
|
7. Use parameters of pointer type only if ``nullptr`` is a valid argument, use references otherwise. Often, ``std::optional`` is better suited than a raw pointer.
|
||||||
|
119
Changelog.md
@ -1,3 +1,122 @@
|
|||||||
|
### 0.8.22 (unreleased)
|
||||||
|
|
||||||
|
Language Features:
|
||||||
|
* Allow defining events at file level.
|
||||||
|
|
||||||
|
|
||||||
|
Compiler Features:
|
||||||
|
* Parser: Remove the experimental error recovery mode (``--error-recovery`` / ``settings.parserErrorRecovery``).
|
||||||
|
* Yul Optimizer: If ``PUSH0`` is supported, favor zero literals over storing zero values in variables.
|
||||||
|
* Yul Optimizer: Run the ``Rematerializer`` and ``UnusedPruner`` steps at the end of the default clean-up sequence.
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* AST: Fix wrong initial ID for Yul nodes in the AST.
|
||||||
|
* Code Generator: Fix output from via-IR code generator being dependent on which files were discovered by import callback. In some cases, a different AST ID assignment would alter the order of functions in internal dispatch, resulting in superficially different but semantically equivalent bytecode.
|
||||||
|
* NatSpec: Fix internal error when requesting userdoc or devdoc for a contract that emits an event defined in a foreign contract or interface.
|
||||||
|
* SMTChecker: Fix encoding error that causes loops to unroll after completion.
|
||||||
|
* SMTChecker: Fix inconsistency on constant condition checks when ``while`` or ``for`` loops are unrolled before the condition check.
|
||||||
|
|
||||||
|
|
||||||
|
### 0.8.21 (2023-07-19)
|
||||||
|
|
||||||
|
Important Bugfixes:
|
||||||
|
* Code Generator: Always generate code for the expression in ``<expression>.selector`` in the legacy code generation pipeline.
|
||||||
|
* Yul Optimizer: Fix ``FullInliner`` step (``i``) not preserving the evaluation order of arguments passed into inlined functions in code that is not in expression-split form (i.e. when using a custom optimizer sequence in which the step not preceded by ``ExpressionSplitter`` (``x``)).
|
||||||
|
|
||||||
|
|
||||||
|
Language Features:
|
||||||
|
* Allow qualified access to events from other contracts.
|
||||||
|
* Relax restrictions on initialization of immutable variables. Reads and writes may now happen at any point at construction time outside of functions and modifiers. Explicit initialization is no longer mandatory.
|
||||||
|
|
||||||
|
|
||||||
|
Compiler Features:
|
||||||
|
* Commandline Interface: Add ``--ast-compact-json`` output in assembler mode.
|
||||||
|
* Commandline Interface: Add ``--ir-ast-json`` and ``--ir-optimized-ast-json`` outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR.
|
||||||
|
* Commandline Interface: Respect ``--optimize-yul`` and ``--no-optimize-yul`` in compiler mode and accept them in assembler mode as well. ``--optimize --no-optimize-yul`` combination now allows enabling EVM assembly optimizer without enabling Yul optimizer.
|
||||||
|
* EWasm: Remove EWasm backend.
|
||||||
|
* Parser: Introduce ``pragma experimental solidity``, which will enable an experimental language mode that in particular has no stability guarantees between non-breaking releases and is not suited for production use.
|
||||||
|
* SMTChecker: Add ``--model-checker-print-query`` CLI option and ``settings.modelChecker.printQuery`` JSON option to output the SMTChecker queries in the SMTLIB2 format. This requires using ``smtlib2`` solver only.
|
||||||
|
* Standard JSON Interface: Add ``ast`` file-level output for Yul input.
|
||||||
|
* Standard JSON Interface: Add ``irAst`` and ``irOptimizedAst`` contract-level outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR.
|
||||||
|
* Yul Optimizer: Remove experimental ``ReasoningBasedSimplifier`` optimization step.
|
||||||
|
* Yul Optimizer: Stack-to-memory mover is now enabled by default whenever possible for via IR code generation and pure Yul compilation.
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Code Generator: Disallow complex expressions whose results are types, built-ins, modules or some unassignable functions. The legacy code generation pipeline would not actually evaluate them, discarding any side-effects they might have.
|
||||||
|
* Code Generator: Fix not entirely deterministic order of functions in unoptimized Yul output. The choice of C++ compiler in some cases would result in different (but equivalent) bytecode (especially from native binaries vs emscripten binaries).
|
||||||
|
* Commandline Interface: Fix internal error when using ``--stop-after parsing`` and requesting some of the outputs that require full analysis or compilation.
|
||||||
|
* Commandline Interface: It is no longer possible to specify both ``--optimize-yul`` and ``--no-optimize-yul`` at the same time.
|
||||||
|
* SMTChecker: Fix encoding of side-effects inside ``if`` and ``ternary conditional``statements in the BMC engine.
|
||||||
|
* SMTChecker: Fix false negative when a verification target can be violated only by trusted external call from another public function.
|
||||||
|
* SMTChecker: Fix generation of invalid SMT-LIB2 scripts in BMC engine with trusted mode for external calls when CHC engine times out.
|
||||||
|
* SMTChecker: Fix internal error caused by incorrectly classifying external function call using function pointer as a public getter.
|
||||||
|
* SMTChecker: Fix internal error caused by using external identifier to encode member access to functions that take an internal function as a parameter.
|
||||||
|
* Standard JSON Interface: Fix an incomplete AST being returned when analysis is interrupted by certain kinds of fatal errors.
|
||||||
|
* Type Checker: Disallow using certain unassignable function types in complex expressions.
|
||||||
|
* Type Checker: Function declaration types referring to different declarations are no longer convertible to each other.
|
||||||
|
* Yul Optimizer: Ensure that the assignment of memory slots for variables moved to memory does not depend on AST IDs that may depend on whether additional files are included during compilation.
|
||||||
|
* Yul Optimizer: Fix ``FullInliner`` step not ignoring code that is not in expression-split form.
|
||||||
|
* Yul Optimizer: Fix optimized IR being unnecessarily passed through the Yul optimizer again before bytecode generation.
|
||||||
|
|
||||||
|
|
||||||
|
AST Changes:
|
||||||
|
* AST: Add the ``experimentalSolidity`` field to the ``SourceUnit`` nodes, which indicate whether the experimental parsing mode has been enabled via ``pragma experimental solidity``.
|
||||||
|
|
||||||
|
|
||||||
|
### 0.8.20 (2023-05-10)
|
||||||
|
|
||||||
|
Compiler Features:
|
||||||
|
* Assembler: Use ``push0`` for placing ``0`` on the stack for EVM versions starting from "Shanghai". This decreases the deployment and runtime costs.
|
||||||
|
* EVM: Set default EVM version to "Shanghai".
|
||||||
|
* EVM: Support for the EVM Version "Shanghai".
|
||||||
|
* NatSpec: Add support for NatSpec documentation in ``enum`` definitions.
|
||||||
|
* NatSpec: Add support for NatSpec documentation in ``struct`` definitions.
|
||||||
|
* NatSpec: Include NatSpec from events that are emitted by a contract but defined outside of it in userdoc and devdoc output.
|
||||||
|
* Optimizer: Re-implement simplified version of ``UnusedAssignEliminator`` and ``UnusedStoreEliminator``. It can correctly remove some unused assignments in deeply nested loops that were ignored by the old version.
|
||||||
|
* Parser: Unary plus is no longer recognized as a unary operator in the AST and triggers an error at the parsing stage (rather than later during the analysis).
|
||||||
|
* SMTChecker: Add CLI option ``--model-checker-bmc-loop-iterations`` and a JSON option ``settings.modelChecker.bmcLoopIterations`` that specify how many loop iterations the BMC engine should unroll. Note that false negatives are possible when unrolling loops. This is due to the possibility that bmc loop iteration setting is less than actual number of iterations needed to complete a loop.
|
||||||
|
* SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list.
|
||||||
|
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
|
||||||
|
* Standard JSON Interface: Add experimental support for importing ASTs via Standard JSON.
|
||||||
|
* Yul EVM Code Transform: If available, use ``push0`` instead of ``codesize`` to produce an arbitrary value on stack in order to create equal stack heights between branches.
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* ABI: Include events in the ABI that are emitted by a contract but defined outside of it.
|
||||||
|
* Immutables: Disallow initialization of immutables in try/catch statements.
|
||||||
|
* SMTChecker: Fix false positives in ternary operators that contain verification targets in its branches, directly or indirectly.
|
||||||
|
|
||||||
|
|
||||||
|
AST Changes:
|
||||||
|
* AST: Add the ``internalFunctionIDs`` field to the AST nodes of contracts containing IDs of functions that may be called via the internal dispatch. The field is a map from function AST IDs to internal dispatch function IDs. These IDs are always generated, but they are only used in via-IR code generation.
|
||||||
|
* AST: Add the ``usedEvents`` field to ``ContractDefinition`` which contains the AST IDs of all events emitted by the contract as well as all events defined and inherited by the contract.
|
||||||
|
|
||||||
|
|
||||||
|
### 0.8.19 (2023-02-22)
|
||||||
|
|
||||||
|
Language Features:
|
||||||
|
* Allow defining custom operators for user-defined value types via ``using {f as +} for T global`` syntax.
|
||||||
|
|
||||||
|
|
||||||
|
Compiler Features:
|
||||||
|
* SMTChecker: New trusted mode that assumes that any compile-time available code is the actual used code even in external calls. This can be used via the CLI option ``--model-checker-ext-calls trusted`` or the JSON field ``settings.modelChecker.extCalls: "trusted"``.
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Assembler: Avoid duplicating subassembly bytecode where possible.
|
||||||
|
* Code Generator: Avoid including references to the deployed label of referenced functions if they are called right away.
|
||||||
|
* ContractLevelChecker: Properly distinguish the case of missing base constructor arguments from having an unimplemented base function.
|
||||||
|
* SMTChecker: Fix internal error caused by unhandled ``z3`` expressions that come from the solver when bitwise operators are used.
|
||||||
|
* SMTChecker: Fix internal error when using the custom NatSpec annotation to abstract free functions.
|
||||||
|
* TypeChecker: Also allow external library functions in ``using for``.
|
||||||
|
|
||||||
|
|
||||||
|
AST Changes:
|
||||||
|
* AST: Add ``function`` field to ``UnaryOperation`` and ``BinaryOperation`` AST nodes. ``functionList`` in ``UsingForDirective`` AST nodes will now contain ``operator`` and ``definition`` members instead of ``function`` when the list entry defines an operator.
|
||||||
|
|
||||||
|
|
||||||
### 0.8.18 (2023-02-01)
|
### 0.8.18 (2023-02-01)
|
||||||
|
|
||||||
Language Features:
|
Language Features:
|
||||||
|
@ -3,23 +3,44 @@
|
|||||||
### Requirements
|
### Requirements
|
||||||
- [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js),
|
- [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js),
|
||||||
[solc-bin](https://github.com/ethereum/solc-bin), [homebrew-ethereum](https://github.com/ethereum/homebrew-ethereum),
|
[solc-bin](https://github.com/ethereum/solc-bin), [homebrew-ethereum](https://github.com/ethereum/homebrew-ethereum),
|
||||||
[solidity-blog](https://github.com/ethereum/solidity-blog) and [solidity-portal](https://github.com/ethereum/solidity-portal) repositories.
|
[solidity-website](https://github.com/ethereum/solidity-website).
|
||||||
- [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc).
|
- [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc).
|
||||||
- [ ] Lauchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and
|
- [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and
|
||||||
a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work).
|
a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work).
|
||||||
|
- [ ] Ubuntu/Debian dependencies of the PPA scripts: ``devscripts``, ``debhelper``, ``dput``, ``git``, ``wget``, ``ca-certificates``.
|
||||||
- [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [``solc`` package](https://www.npmjs.com/package/solc).
|
- [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [``solc`` package](https://www.npmjs.com/package/solc).
|
||||||
- [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang).
|
- [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang).
|
||||||
- [ ] [Reddit](https://www.reddit.com) account that is at least 10 days old with a minimum of 20 comment karma (``/r/ethereum`` requirements).
|
- [ ] [Reddit](https://www.reddit.com) account that is at least 10 days old with a minimum of 20 comment karma (``/r/ethereum`` requirements).
|
||||||
|
|
||||||
### Blog Post
|
### Pre-flight checks
|
||||||
- [ ] Create a post on [solidity-blog](https://github.com/ethereum/solidity-blog) in the ``Releases`` category and explain some of the new features or concepts.
|
At least a day before the release:
|
||||||
- [ ] Create a post on [solidity-blog](https://github.com/ethereum/solidity-blog) in the ``Security Alerts`` category in case of important bug(s).
|
- [ ] Run ``make linkcheck`` from within ``docs/`` and fix any broken links it finds.
|
||||||
|
Ignore false positives caused by ``href`` anchors and dummy links not meant to work.
|
||||||
|
- [ ] Double-check that [the most recent docs builds at readthedocs](https://readthedocs.org/projects/solidity/builds/) succeeded.
|
||||||
|
- [ ] Make sure that all merged PRs that should have changelog entries do have them.
|
||||||
|
- [ ] Rerun CI on the top commits of main branches in all repositories that do not have daily activity by creating a test branch or PR:
|
||||||
|
- [ ] ``solc-js``
|
||||||
|
- [ ] ``solc-bin`` (make sure the bytecode comparison check did run)
|
||||||
|
- [ ] ``homebrew-ethereum``
|
||||||
|
- [ ] (Optional) Create a prerelease in our Ubuntu PPA by following the steps in the PPA section below on ``develop`` rather than on a tag.
|
||||||
|
This is recommended especially when dealing with PPA for the first time, when we add a new Ubuntu version or when the PPA scripts were modified in this release cycle.
|
||||||
|
- [ ] Verify that the release tarball of ``solc-js`` works.
|
||||||
|
Bump version locally, add ``soljson.js`` from CI, build it, compare the file structure with the previous version, install it locally and try to use it.
|
||||||
|
|
||||||
### Documentation check
|
### Drafts
|
||||||
- [ ] Run ``make linkcheck`` from within ``docs/`` and fix any broken links it finds. Ignore false positives caused by ``href`` anchors and dummy links not meant to work.
|
At least a day before the release:
|
||||||
|
- [ ] Create a draft PR to sort the changelog.
|
||||||
|
- [ ] Create draft PRs to bump version in ``solidity`` and ``solc-js``.
|
||||||
|
- [ ] Create a draft of the release on github.
|
||||||
|
- [ ] Create a draft PR to update soliditylang.org.
|
||||||
|
- [ ] Create drafts of blog posts.
|
||||||
|
- [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements.
|
||||||
|
|
||||||
|
### Blog Post
|
||||||
|
- [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Releases`` category and explain some of the new features or concepts.
|
||||||
|
- [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Security Alerts`` category in case of important bug(s).
|
||||||
|
|
||||||
### Changelog
|
### Changelog
|
||||||
- [ ] Make sure that all merged PRs that should have changelog entries do have them.
|
|
||||||
- [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it.
|
- [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it.
|
||||||
- [ ] Update the changelog to include a release date.
|
- [ ] Update the changelog to include a release date.
|
||||||
- [ ] Run ``scripts/update_bugs_by_version.py`` to regenerate ``bugs_by_version.json`` from the changelog and ``bugs.json``.
|
- [ ] Run ``scripts/update_bugs_by_version.py`` to regenerate ``bugs_by_version.json`` from the changelog and ``bugs.json``.
|
||||||
@ -31,8 +52,10 @@
|
|||||||
- [ ] Create a [release on GitHub](https://github.com/ethereum/solidity/releases/new).
|
- [ ] Create a [release on GitHub](https://github.com/ethereum/solidity/releases/new).
|
||||||
Set the target to the ``develop`` branch and the tag to the new version, e.g. ``v0.8.5``.
|
Set the target to the ``develop`` branch and the tag to the new version, e.g. ``v0.8.5``.
|
||||||
Include the following warning: ``**The release is still in progress and the binaries may not yet be available from all sources.**``.
|
Include the following warning: ``**The release is still in progress and the binaries may not yet be available from all sources.**``.
|
||||||
Don't publish it yet - click the ``Save draft`` button instead.
|
Do not publish it yet - click the ``Save draft`` button instead.
|
||||||
- [ ] Thank voluntary contributors in the GitHub release notes (use ``git shortlog --summary --email v0.5.3..origin/develop``).
|
- [ ] Thank voluntary contributors in the GitHub release notes.
|
||||||
|
Use ``scripts/list_contributors.sh v<previous version>`` to get initial list of names.
|
||||||
|
Remove different variants of the same name manually before using the output.
|
||||||
- [ ] Check that all tests on the latest commit in ``develop`` are green.
|
- [ ] Check that all tests on the latest commit in ``develop`` are green.
|
||||||
- [ ] Click the ``Publish release`` button on the release page, creating the tag.
|
- [ ] Click the ``Publish release`` button on the release page, creating the tag.
|
||||||
- [ ] Wait for the CI runs on the tag itself.
|
- [ ] Wait for the CI runs on the tag itself.
|
||||||
@ -57,13 +80,17 @@
|
|||||||
|
|
||||||
### PPA
|
### PPA
|
||||||
- [ ] Create ``.release_ppa_auth`` at the root of your local Solidity checkout and set ``LAUNCHPAD_EMAIL`` and ``LAUNCHPAD_KEYID`` to your key's email and key id.
|
- [ ] Create ``.release_ppa_auth`` at the root of your local Solidity checkout and set ``LAUNCHPAD_EMAIL`` and ``LAUNCHPAD_KEYID`` to your key's email and key id.
|
||||||
- [ ] Double-check that the ``DISTRIBUTIONS`` list in ``scripts/release_ppa.sh`` and ``scripts/deps-ppa/static-z3.sh`` contains the most recent versions of Ubuntu.
|
- [ ] Double-check that the ``DISTRIBUTIONS`` list in ``scripts/release_ppa.sh`` and ``scripts/deps-ppa/static_z3.sh`` contains the most recent versions of Ubuntu.
|
||||||
- [ ] Make sure the [``~ethereum/cpp-build-deps`` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains ``libz3-static-dev builds`` for all current versions of Ubuntu.
|
- [ ] Make sure the [``~ethereum/cpp-build-deps`` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains ``libz3-static-dev builds`` for all current versions of Ubuntu.
|
||||||
If not, run ``scripts/deps-ppa/static-z3.sh`` and wait for the builds to succeed before continuing.
|
Note that it may be included in the ``z3-static`` multipackage (follow the ``View package details`` link to check).
|
||||||
|
If not present, run ``scripts/deps-ppa/static_z3.sh`` and wait for the builds to succeed before continuing.
|
||||||
- [ ] Run ``scripts/release_ppa.sh v$VERSION`` to create the PPA release.
|
- [ ] Run ``scripts/release_ppa.sh v$VERSION`` to create the PPA release.
|
||||||
- [ ] Wait for the [``~ethereum/ethereum-static`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static) build to be finished and published for *all platforms*.
|
This will create a single package containing static binary for older Ubuntu versions in the [``~ethereum/ethereum-static`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static)
|
||||||
|
and separate packages with dynamically-linked binaries for recent versions (those listed in ``DISTRIBUTIONS``) in the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum).
|
||||||
|
- [ ] Wait for the build to be finished and published for *all architectures* (currently we only build for ``amd64``, but we may add ``arm`` in the future).
|
||||||
**SERIOUSLY: DO NOT PROCEED EARLIER!!!**
|
**SERIOUSLY: DO NOT PROCEED EARLIER!!!**
|
||||||
*After* the static builds are *published*, copy the static package to the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum)
|
- [ ] *After* the package with the static build is *published*, use it to create packages for older Ubuntu versions.
|
||||||
|
Copy the static package to the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum)
|
||||||
for the destination series ``Trusty``, ``Xenial`` and ``Bionic`` while selecting ``Copy existing binaries``.
|
for the destination series ``Trusty``, ``Xenial`` and ``Bionic`` while selecting ``Copy existing binaries``.
|
||||||
|
|
||||||
### Release solc-js
|
### Release solc-js
|
||||||
@ -76,12 +103,15 @@
|
|||||||
### Post-release
|
### Post-release
|
||||||
- [ ] Make sure the documentation for the new release has been published successfully.
|
- [ ] Make sure the documentation for the new release has been published successfully.
|
||||||
Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default.
|
Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default.
|
||||||
- [ ] Remove "still in progress" warning from the release notes.
|
- [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases).
|
||||||
- [ ] Publish the blog posts.
|
- [ ] Merge the [blog posts](https://github.com/ethereum/solidity-website/pulls) related to the release.
|
||||||
- [ ] Create a commit to increase the version number on ``develop`` in ``CMakeLists.txt`` and add a new skeleton changelog entry.
|
- [ ] Create a commit to increase the version number on ``develop`` in ``CMakeLists.txt`` and add a new skeleton changelog entry.
|
||||||
- [ ] Announce on Twitter, including links to the release and the blog post.
|
- [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-website/blob/main/src/pages/index.tsx).
|
||||||
Use ``#xp`` at the end of the tweet to automatically cross post the announcement to Fosstodon.
|
- [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post.
|
||||||
|
- [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post.
|
||||||
- [ ] Share the announcement on Reddit in [``/r/ethdev``](https://reddit.com/r/ethdev/), cross-posted to [``/r/ethereum``](https://reddit.com/r/ethereum/).
|
- [ ] Share the announcement on Reddit in [``/r/ethdev``](https://reddit.com/r/ethdev/), cross-posted to [``/r/ethereum``](https://reddit.com/r/ethereum/).
|
||||||
- [ ] Share the announcement the [Solidity forum](https://forum.soliditylang.org) in the ``Announcements`` category.
|
- [ ] Share the announcement on the [Solidity forum](https://forum.soliditylang.org) in the ``Announcements`` category.
|
||||||
- [ ] Update the release information section on [soliditylang.org](https://github.com/ethereum/solidity-portal).
|
- [ ] Share the announcement on [Project Updates](https://discord.com/channels/420394352083337236/798974456704925696)
|
||||||
|
- [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im)
|
||||||
|
- [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org)
|
||||||
- [ ] Lean back, wait for bug reports and repeat from step 1 :).
|
- [ ] Lean back, wait for bug reports and repeat from step 1 :).
|
||||||
|
@ -102,7 +102,7 @@ The following points are all covered by the coding style but come up so often th
|
|||||||
already used elsewhere in the same expression.
|
already used elsewhere in the same expression.
|
||||||
- [ ] **Indent braces and parentheses in a way that makes nesting clear.**
|
- [ ] **Indent braces and parentheses in a way that makes nesting clear.**
|
||||||
- [ ] **Use `using namespace` only in `.cpp` files.** Use it for `std` and our own modules.
|
- [ ] **Use `using namespace` only in `.cpp` files.** Use it for `std` and our own modules.
|
||||||
Avoid unnecessary `std::` prefix in `.cpp` files (except for `std::move`).
|
Avoid unnecessary `std::` prefix in `.cpp` files (except for `std::move` and `std::forward`).
|
||||||
- [ ] **Use range-based loops and destructuring.**
|
- [ ] **Use range-based loops and destructuring.**
|
||||||
- [ ] **Include any headers you use directly,** even if they are implicitly included through other headers.
|
- [ ] **Include any headers you use directly,** even if they are implicitly included through other headers.
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ if(PEDANTIC)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Prevent the path of the source directory from ending up in the binary via __FILE__ macros.
|
# Prevent the path of the source directory from ending up in the binary via __FILE__ macros.
|
||||||
eth_add_cxx_compiler_flag_if_supported("-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=/solidity")
|
eth_add_cxx_compiler_flag_if_supported("-fmacro-prefix-map=${PROJECT_SOURCE_DIR}=/solidity")
|
||||||
|
|
||||||
# -Wpessimizing-move warns when a call to std::move would prevent copy elision
|
# -Wpessimizing-move warns when a call to std::move would prevent copy elision
|
||||||
# if the argument was not wrapped in a call. This happens when moving a local
|
# if the argument was not wrapped in a call. This happens when moving a local
|
||||||
@ -65,6 +65,13 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA
|
|||||||
if(WEXTRA_SEMI)
|
if(WEXTRA_SEMI)
|
||||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wextra-semi>)
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wextra-semi>)
|
||||||
endif()
|
endif()
|
||||||
|
# See https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=6b927b1297e66e26e62e722bf15c921dcbbd25b9
|
||||||
|
check_cxx_compiler_flag(-Wno-dangling-reference WNO_DANGLING_REFERENCE)
|
||||||
|
if (WNO_DANGLING_REFERENCE)
|
||||||
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-dangling-reference>)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
eth_add_cxx_compiler_flag_if_supported(-Wfinal-dtor-non-final-class)
|
eth_add_cxx_compiler_flag_if_supported(-Wfinal-dtor-non-final-class)
|
||||||
eth_add_cxx_compiler_flag_if_supported(-Wnewline-eof)
|
eth_add_cxx_compiler_flag_if_supported(-Wnewline-eof)
|
||||||
eth_add_cxx_compiler_flag_if_supported(-Wsuggest-destructor-override)
|
eth_add_cxx_compiler_flag_if_supported(-Wsuggest-destructor-override)
|
||||||
|
@ -2,11 +2,11 @@ include(FetchContent)
|
|||||||
|
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
fmtlib
|
fmtlib
|
||||||
PREFIX "${CMAKE_BINARY_DIR}/deps"
|
PREFIX "${PROJECT_BINARY_DIR}/deps"
|
||||||
DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/downloads"
|
DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads"
|
||||||
DOWNLOAD_NAME fmt-8.0.1.tar.gz
|
DOWNLOAD_NAME fmt-9.1.0.tar.gz
|
||||||
URL https://github.com/fmtlib/fmt/archive/8.0.1.tar.gz
|
URL https://github.com/fmtlib/fmt/archive/9.1.0.tar.gz
|
||||||
URL_HASH SHA256=b06ca3130158c625848f3fb7418f235155a4d389b2abc3a6245fb01cb0eb1e01
|
URL_HASH SHA256=5dea48d1fcddc3ec571ce2058e13910a0d4a6bab4cc09a809d8b1dd1c88ae6f2
|
||||||
)
|
)
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_LESS "3.14.0")
|
if (CMAKE_VERSION VERSION_LESS "3.14.0")
|
||||||
|
@ -6,7 +6,7 @@ else()
|
|||||||
set(JSONCPP_CMAKE_COMMAND ${CMAKE_COMMAND})
|
set(JSONCPP_CMAKE_COMMAND ${CMAKE_COMMAND})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(prefix "${CMAKE_BINARY_DIR}/deps")
|
set(prefix "${PROJECT_BINARY_DIR}/deps")
|
||||||
set(JSONCPP_LIBRARY "${prefix}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsoncpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
set(JSONCPP_LIBRARY "${prefix}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsoncpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
set(JSONCPP_INCLUDE_DIR "${prefix}/include")
|
set(JSONCPP_INCLUDE_DIR "${prefix}/include")
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ endif()
|
|||||||
|
|
||||||
ExternalProject_Add(jsoncpp-project
|
ExternalProject_Add(jsoncpp-project
|
||||||
PREFIX "${prefix}"
|
PREFIX "${prefix}"
|
||||||
DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/downloads"
|
DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads"
|
||||||
DOWNLOAD_NAME jsoncpp-1.9.3.tar.gz
|
DOWNLOAD_NAME jsoncpp-1.9.3.tar.gz
|
||||||
URL https://github.com/open-source-parsers/jsoncpp/archive/1.9.3.tar.gz
|
URL https://github.com/open-source-parsers/jsoncpp/archive/1.9.3.tar.gz
|
||||||
URL_HASH SHA256=8593c1d69e703563d94d8c12244e2e18893eeb9a8a9f8aa3d09a327aa45c8f7d
|
URL_HASH SHA256=8593c1d69e703563d94d8c12244e2e18893eeb9a8a9f8aa3d09a327aa45c8f7d
|
||||||
|
@ -6,12 +6,12 @@ else()
|
|||||||
set(RANGE_V3_CMAKE_COMMAND ${CMAKE_COMMAND})
|
set(RANGE_V3_CMAKE_COMMAND ${CMAKE_COMMAND})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(prefix "${CMAKE_BINARY_DIR}/deps")
|
set(prefix "${PROJECT_BINARY_DIR}/deps")
|
||||||
set(RANGE_V3_INCLUDE_DIR "${prefix}/include")
|
set(RANGE_V3_INCLUDE_DIR "${prefix}/include")
|
||||||
|
|
||||||
ExternalProject_Add(range-v3-project
|
ExternalProject_Add(range-v3-project
|
||||||
PREFIX "${prefix}"
|
PREFIX "${prefix}"
|
||||||
DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/downloads"
|
DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads"
|
||||||
DOWNLOAD_NAME range-v3-0.12.0.tar.gz
|
DOWNLOAD_NAME range-v3-0.12.0.tar.gz
|
||||||
URL https://github.com/ericniebler/range-v3/archive/0.12.0.tar.gz
|
URL https://github.com/ericniebler/range-v3/archive/0.12.0.tar.gz
|
||||||
URL_HASH SHA256=015adb2300a98edfceaf0725beec3337f542af4915cec4d0b89fa0886f4ba9cb
|
URL_HASH SHA256=015adb2300a98edfceaf0725beec3337f542af4915cec4d0b89fa0886f4ba9cb
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
// The generation of this file is defined in libyul/CMakeLists.txt.
|
|
||||||
// This file was generated by using the content of libyul/backends/wasm/polyfill/@EWASM_POLYFILL_NAME@.yul.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace solidity::yul::wasm::polyfill
|
|
||||||
{
|
|
||||||
|
|
||||||
static char const @EWASM_POLYFILL_NAME@[] = {
|
|
||||||
@EWASM_POLYFILL_CONTENT@, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace solidity::yul::wasm::polyfill
|
|
@ -137,7 +137,7 @@ For most of the topics the compiler will provide suggestions.
|
|||||||
``payable`` or create a new internal function for the program logic that
|
``payable`` or create a new internal function for the program logic that
|
||||||
uses ``msg.value``.
|
uses ``msg.value``.
|
||||||
|
|
||||||
* For clarity reasons, the command line interface now requires ``-`` if the
|
* For clarity reasons, the command-line interface now requires ``-`` if the
|
||||||
standard input is used as source.
|
standard input is used as source.
|
||||||
|
|
||||||
Deprecated Elements
|
Deprecated Elements
|
||||||
@ -147,18 +147,18 @@ This section lists changes that deprecate prior features or syntax. Note that
|
|||||||
many of these changes were already enabled in the experimental mode
|
many of these changes were already enabled in the experimental mode
|
||||||
``v0.5.0``.
|
``v0.5.0``.
|
||||||
|
|
||||||
Command Line and JSON Interfaces
|
Command-line and JSON Interfaces
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
* The command line option ``--formal`` (used to generate Why3 output for
|
* The command-line option ``--formal`` (used to generate Why3 output for
|
||||||
further formal verification) was deprecated and is now removed. A new
|
further formal verification) was deprecated and is now removed. A new
|
||||||
formal verification module, the SMTChecker, is enabled via ``pragma
|
formal verification module, the SMTChecker, is enabled via ``pragma
|
||||||
experimental SMTChecker;``.
|
experimental SMTChecker;``.
|
||||||
|
|
||||||
* The command line option ``--julia`` was renamed to ``--yul`` due to the
|
* The command-line option ``--julia`` was renamed to ``--yul`` due to the
|
||||||
renaming of the intermediate language ``Julia`` to ``Yul``.
|
renaming of the intermediate language ``Julia`` to ``Yul``.
|
||||||
|
|
||||||
* The ``--clone-bin`` and ``--combined-json clone-bin`` command line options
|
* The ``--clone-bin`` and ``--combined-json clone-bin`` command-line options
|
||||||
were removed.
|
were removed.
|
||||||
|
|
||||||
* Remappings with empty prefix are disallowed.
|
* Remappings with empty prefix are disallowed.
|
||||||
|
@ -12,7 +12,7 @@ For the full list check
|
|||||||
Changes the Compiler Might not Warn About
|
Changes the Compiler Might not Warn About
|
||||||
=========================================
|
=========================================
|
||||||
|
|
||||||
This section lists changes where the behaviour of your code might
|
This section lists changes where the behavior of your code might
|
||||||
change without the compiler telling you about it.
|
change without the compiler telling you about it.
|
||||||
|
|
||||||
* The resulting type of an exponentiation is the type of the base. It used to be the smallest type
|
* The resulting type of an exponentiation is the type of the base. It used to be the smallest type
|
||||||
@ -105,23 +105,23 @@ Interface Changes
|
|||||||
=================
|
=================
|
||||||
|
|
||||||
This section lists changes that are unrelated to the language itself, but that have an effect on the interfaces of
|
This section lists changes that are unrelated to the language itself, but that have an effect on the interfaces of
|
||||||
the compiler. These may change the way how you use the compiler on the command line, how you use its programmable
|
the compiler. These may change the way how you use the compiler on the command-line, how you use its programmable
|
||||||
interface, or how you analyze the output produced by it.
|
interface, or how you analyze the output produced by it.
|
||||||
|
|
||||||
New Error Reporter
|
New Error Reporter
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A new error reporter was introduced, which aims at producing more accessible error messages on the command line.
|
A new error reporter was introduced, which aims at producing more accessible error messages on the command-line.
|
||||||
It is enabled by default, but passing ``--old-reporter`` falls back to the the deprecated old error reporter.
|
It is enabled by default, but passing ``--old-reporter`` falls back to the deprecated old error reporter.
|
||||||
|
|
||||||
Metadata Hash Options
|
Metadata Hash Options
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The compiler now appends the `IPFS <https://ipfs.io/>`_ hash of the metadata file to the end of the bytecode by default
|
The compiler now appends the `IPFS <https://ipfs.io/>`_ hash of the metadata file to the end of the bytecode by default
|
||||||
(for details, see documentation on :doc:`contract metadata <metadata>`). Before 0.6.0, the compiler appended the
|
(for details, see documentation on :doc:`contract metadata <metadata>`). Before 0.6.0, the compiler appended the
|
||||||
`Swarm <https://ethersphere.github.io/swarm-home/>`_ hash by default, and in order to still support this behaviour,
|
`Swarm <https://ethersphere.github.io/swarm-home/>`_ hash by default, and in order to still support this behavior,
|
||||||
the new command line option ``--metadata-hash`` was introduced. It allows you to select the hash to be produced and
|
the new command-line option ``--metadata-hash`` was introduced. It allows you to select the hash to be produced and
|
||||||
appended, by passing either ``ipfs`` or ``swarm`` as value to the ``--metadata-hash`` command line option.
|
appended, by passing either ``ipfs`` or ``swarm`` as value to the ``--metadata-hash`` command-line option.
|
||||||
Passing the value ``none`` completely removes the hash.
|
Passing the value ``none`` completely removes the hash.
|
||||||
|
|
||||||
These changes can also be used via the :ref:`Standard JSON Interface<compiler-api>` and effect the metadata JSON generated by the compiler.
|
These changes can also be used via the :ref:`Standard JSON Interface<compiler-api>` and effect the metadata JSON generated by the compiler.
|
||||||
|
@ -10,18 +10,18 @@ For the full list check
|
|||||||
Silent Changes of the Semantics
|
Silent Changes of the Semantics
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
This section lists changes where existing code changes its behaviour without
|
This section lists changes where existing code changes its behavior without
|
||||||
the compiler notifying you about it.
|
the compiler notifying you about it.
|
||||||
|
|
||||||
* Arithmetic operations revert on underflow and overflow. You can use ``unchecked { ... }`` to use
|
* Arithmetic operations revert on underflow and overflow. You can use ``unchecked { ... }`` to use
|
||||||
the previous wrapping behaviour.
|
the previous wrapping behavior.
|
||||||
|
|
||||||
Checks for overflow are very common, so we made them the default to increase readability of code,
|
Checks for overflow are very common, so we made them the default to increase readability of code,
|
||||||
even if it comes at a slight increase of gas costs.
|
even if it comes at a slight increase of gas costs.
|
||||||
|
|
||||||
* ABI coder v2 is activated by default.
|
* ABI coder v2 is activated by default.
|
||||||
|
|
||||||
You can choose to use the old behaviour using ``pragma abicoder v1;``.
|
You can choose to use the old behavior using ``pragma abicoder v1;``.
|
||||||
The pragma ``pragma experimental ABIEncoderV2;`` is still valid, but it is deprecated and has no effect.
|
The pragma ``pragma experimental ABIEncoderV2;`` is still valid, but it is deprecated and has no effect.
|
||||||
If you want to be explicit, please use ``pragma abicoder v2;`` instead.
|
If you want to be explicit, please use ``pragma abicoder v2;`` instead.
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ New Restrictions
|
|||||||
|
|
||||||
This section lists changes that might cause existing contracts to not compile anymore.
|
This section lists changes that might cause existing contracts to not compile anymore.
|
||||||
|
|
||||||
* There are new restrictions related to explicit conversions of literals. The previous behaviour in
|
* There are new restrictions related to explicit conversions of literals. The previous behavior in
|
||||||
the following cases was likely ambiguous:
|
the following cases was likely ambiguous:
|
||||||
|
|
||||||
1. Explicit conversions from negative literals and literals larger than ``type(uint160).max`` to
|
1. Explicit conversions from negative literals and literals larger than ``type(uint160).max`` to
|
||||||
@ -106,7 +106,7 @@ This section lists changes that might cause existing contracts to not compile an
|
|||||||
|
|
||||||
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
||||||
|
|
||||||
These are low-level functions that were largely unused. Their behaviour can be accessed from inline assembly.
|
These are low-level functions that were largely unused. Their behavior can be accessed from inline assembly.
|
||||||
|
|
||||||
* ``enum`` definitions cannot contain more than 256 members.
|
* ``enum`` definitions cannot contain more than 256 members.
|
||||||
|
|
||||||
@ -173,4 +173,4 @@ How to update your code
|
|||||||
- Change ``msg.sender.transfer(x)`` to ``payable(msg.sender).transfer(x)`` or use a stored variable of ``address payable`` type.
|
- Change ``msg.sender.transfer(x)`` to ``payable(msg.sender).transfer(x)`` or use a stored variable of ``address payable`` type.
|
||||||
- Change ``x**y**z`` to ``(x**y)**z``.
|
- Change ``x**y**z`` to ``(x**y)**z``.
|
||||||
- Use inline assembly as a replacement for ``log0``, ..., ``log4``.
|
- Use inline assembly as a replacement for ``log0``, ..., ``log4``.
|
||||||
- Negate unsigned integers by subtracting them from the maximum value of the type and adding 1 (e.g. ``type(uint256).max - x + 1``, while ensuring that `x` is not zero)
|
- Negate unsigned integers by subtracting them from the maximum value of the type and adding 1 (e.g. ``type(uint256).max - x + 1``, while ensuring that ``x`` is not zero)
|
||||||
|
@ -34,7 +34,6 @@ help:
|
|||||||
@echo " epub to make an epub"
|
@echo " epub to make an epub"
|
||||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
|
||||||
@echo " text to make text files"
|
@echo " text to make text files"
|
||||||
@echo " man to make manual pages"
|
@echo " man to make manual pages"
|
||||||
@echo " texinfo to make Texinfo files"
|
@echo " texinfo to make Texinfo files"
|
||||||
@ -116,12 +115,6 @@ latexpdf:
|
|||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||||
|
|
||||||
latexpdfja:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
text:
|
text:
|
||||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||||
@echo
|
@echo
|
||||||
|
23
docs/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Solidity Language Docs
|
||||||
|
|
||||||
|
## Local environment setup
|
||||||
|
|
||||||
|
1. Install python https://www.python.org/downloads/
|
||||||
|
1. Install sphinx (the tool used to generate the docs) https://www.sphinx-doc.org/en/master/usage/installation.html
|
||||||
|
|
||||||
|
Go to `/docs` and run `./docs.sh` to install dependencies and build the project:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd docs
|
||||||
|
./docs.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
That will output the generated htmls under _build/
|
||||||
|
|
||||||
|
## Serve environment
|
||||||
|
|
||||||
|
```py
|
||||||
|
python3 -m http.server -d _build/html --cgi 8080
|
||||||
|
```
|
||||||
|
|
||||||
|
Visit dev server at http://localhost:8080
|
595
docs/_static/css/custom-dark.css
vendored
Normal file
@ -0,0 +1,595 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/* DARK MODE STYLING */
|
||||||
|
|
||||||
|
/* code directives */
|
||||||
|
|
||||||
|
:root[style*=dark] .method dt,
|
||||||
|
:root[style*=dark] .class dt,
|
||||||
|
:root[style*=dark] .data dt,
|
||||||
|
:root[style*=dark] .attribute dt,
|
||||||
|
:root[style*=dark] .function dt,
|
||||||
|
:root[style*=dark] .classmethod dt,
|
||||||
|
:root[style*=dark] .exception dt,
|
||||||
|
:root[style*=dark] .descclassname,
|
||||||
|
:root[style*=dark] .descname {
|
||||||
|
background-color: #2d2d2d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .rst-content dl:not(.docutils) dt {
|
||||||
|
background-color: #0008;
|
||||||
|
border-top: solid 3px #fff2;
|
||||||
|
border-left: solid 3px #fff2;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] em.property {
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tables */
|
||||||
|
|
||||||
|
:root[style*=dark] .rst-content table.docutils td {
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td {
|
||||||
|
background-color: #0002;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .rst-content pre {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* inlined code highlights */
|
||||||
|
|
||||||
|
:root[style*=dark] .xref,
|
||||||
|
:root[style*=dark] .py-meth {
|
||||||
|
color: #aaddff !important;
|
||||||
|
font-weight: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* highlight color search text */
|
||||||
|
|
||||||
|
:root[style*=dark] .rst-content .highlighted {
|
||||||
|
background: #ff5722;
|
||||||
|
box-shadow: 0 0 0 2px #f0978b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* notes, warnings, hints */
|
||||||
|
|
||||||
|
:root[style*=dark] .hint .admonition-title {
|
||||||
|
background: #2aa87c !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .warning .admonition-title {
|
||||||
|
background: #cc4444 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .admonition-title {
|
||||||
|
background: #3a7ca8 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .admonition,
|
||||||
|
:root[style*=dark] .note {
|
||||||
|
background-color: #0008 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* table of contents */
|
||||||
|
|
||||||
|
:root[style*=dark] .sidebar {
|
||||||
|
background-color: #191919 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .sidebar-title {
|
||||||
|
background-color: #2b2b2b !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .wy-menu-vertical code.docutils.literal.notranslate {
|
||||||
|
background: none !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
:root[style*=dark] .toc-backref {
|
||||||
|
color: grey !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight {
|
||||||
|
background: #0008;
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .c {
|
||||||
|
color: #888
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Comment */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .err {
|
||||||
|
color: #960050;
|
||||||
|
background-color: #1e0010
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Error */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .k {
|
||||||
|
color: #66d9ef
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Keyword */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .l {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .n {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .o {
|
||||||
|
color: #f92672
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Operator */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .p {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Punctuation */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .ch {
|
||||||
|
color: #888
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Comment.Hashbang */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .cm {
|
||||||
|
color: #888
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Comment.Multiline */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .cp {
|
||||||
|
color: #888
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Comment.Preproc */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .cpf {
|
||||||
|
color: #888
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Comment.PreprocFile */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .c1 {
|
||||||
|
color: #888
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Comment.Single */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .cs {
|
||||||
|
color: #888
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Comment.Special */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .gd {
|
||||||
|
color: #f92672
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Generic.Deleted */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .ge {
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Generic.Emph */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .gi {
|
||||||
|
color: #a6e22e
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Generic.Inserted */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .gs {
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Generic.Strong */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .gu {
|
||||||
|
color: #888
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Generic.Subheading */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .kc {
|
||||||
|
color: #66d9ef
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Keyword.Constant */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .kd {
|
||||||
|
color: #66d9ef
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Keyword.Declaration */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .kn {
|
||||||
|
color: #f92672
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Keyword.Namespace */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .kp {
|
||||||
|
color: #66d9ef
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Keyword.Pseudo */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .kr {
|
||||||
|
color: #66d9ef
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Keyword.Reserved */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .kt {
|
||||||
|
color: #66d9ef
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Keyword.Type */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .ld {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.Date */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .m {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.Number */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .s {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .na {
|
||||||
|
color: #a6e22e
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Attribute */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nb {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Builtin */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nc {
|
||||||
|
color: #a6e22e
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Class */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .no {
|
||||||
|
color: #66d9ef
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Constant */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nd {
|
||||||
|
color: #a6e22e
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Decorator */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .ni {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Entity */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .ne {
|
||||||
|
color: #a6e22e
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Exception */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nf {
|
||||||
|
color: #a6e22e
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Function */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nl {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Label */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nn {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Namespace */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nx {
|
||||||
|
color: #a6e22e
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Other */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .py {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Property */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nt {
|
||||||
|
color: #f92672
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Tag */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .nv {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Variable */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .ow {
|
||||||
|
color: #f92672
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Operator.Word */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .w {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Text.Whitespace */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .mb {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.Number.Bin */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .mf {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.Number.Float */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .mh {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.Number.Hex */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .mi {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.Number.Integer */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .mo {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.Number.Oct */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .sa {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Affix */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .sb {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Backtick */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .sc {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Char */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .dl {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Delimiter */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .sd {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Doc */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .s2 {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Double */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .se {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Escape */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .sh {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Heredoc */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .si {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Interpol */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .sx {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Other */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .sr {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Regex */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .s1 {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Single */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .ss {
|
||||||
|
color: #e6db74
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Literal.String.Symbol */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .bp {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Builtin.Pseudo */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .fm {
|
||||||
|
color: #a6e22e
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Function.Magic */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .vc {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Variable.Class */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .vg {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Variable.Global */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .vi {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Variable.Instance */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .vm {
|
||||||
|
color: #f8f8f2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Name.Variable.Magic */
|
||||||
|
|
||||||
|
:root[style*=dark] .highlight .il {
|
||||||
|
color: #ae81ff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Grammar */
|
||||||
|
|
||||||
|
:root[style*=dark] .railroad-diagram {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .railroad-diagram path {
|
||||||
|
stroke: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .railroad-diagram rect {
|
||||||
|
stroke: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] .a4 .sig-name {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
850
docs/_static/css/custom.css
vendored
@ -1,23 +1,185 @@
|
|||||||
pre {
|
/* ROOT DECLARATIONS */
|
||||||
white-space: pre-wrap; /* css-3 */
|
:root {
|
||||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
/* Text */
|
||||||
white-space: -pre-wrap; /* Opera 4-6 */
|
--color-a: #2B247C;
|
||||||
white-space: -o-pre-wrap; /* Opera 7 */
|
--color-b: #672AC8;
|
||||||
word-wrap: break-word;
|
--color-c: #5554D9;
|
||||||
|
--color-d: #9F94E8;
|
||||||
|
--color-e: #AEC0F1;
|
||||||
|
--color-f: #E6E3EC;
|
||||||
|
/* Background */
|
||||||
|
|
||||||
|
--white: #FAF8FF;
|
||||||
|
--black: #110C4E;
|
||||||
|
--menu-bg: #2B247C06;
|
||||||
|
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||||
|
|
||||||
|
--navHeight: 4.5rem;
|
||||||
|
--sideWidth: 300px;
|
||||||
|
--maxWidth: 80rem;
|
||||||
|
--desktopInlinePadding: 2rem;
|
||||||
|
--mobileInlinePadding: 1rem;
|
||||||
|
--currentVersionHeight: 45px;
|
||||||
|
|
||||||
|
text-rendering: geometricPrecision;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wy-table-responsive table td, .wy-table-responsive table th {
|
a,
|
||||||
|
button {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*=dark] {
|
||||||
|
--color-a: #E6E3EC !important;
|
||||||
|
--color-b: #AEC0F1 !important;
|
||||||
|
--color-c: #9F94E8 !important;
|
||||||
|
--color-d: #5554D9 !important;
|
||||||
|
--color-e: #672AC8 !important;
|
||||||
|
--color-f: #2B247C !important;
|
||||||
|
|
||||||
|
--white: #110C4E !important;
|
||||||
|
--black: #FAF8FF !important;
|
||||||
|
--menu-bg: #E6E3EC06 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
.unified-header::before,
|
||||||
|
.wy-nav-side,
|
||||||
|
.rst-versions,
|
||||||
|
code,
|
||||||
|
div,
|
||||||
|
input[type=text],
|
||||||
|
a,
|
||||||
|
.wy-grid-for-nav {
|
||||||
|
transition: background 150ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
.wy-grid-for-nav {
|
||||||
|
background-color: var(--color-f) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "Overpass", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--color-c);
|
||||||
|
}
|
||||||
|
|
||||||
|
a, section {
|
||||||
|
scroll-margin-top: calc(var(--navHeight) + 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin-block: 2rem;
|
||||||
|
border-color: var(--color-d) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* HEADER STYLES */
|
||||||
|
h1 {
|
||||||
|
font-family: 'Overpass', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 44px;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
line-height: 1.1;
|
||||||
|
text-wrap: balance;
|
||||||
|
margin-top: 4rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
section:first-of-type h1:first-of-type {
|
||||||
|
font-family: 'Overpass mono', monospace;
|
||||||
|
font-size: 48px;
|
||||||
|
margin-top: 3rem;
|
||||||
|
margin-bottom: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: 'Overpass', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 38px;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
line-height: 46px;
|
||||||
|
text-wrap: balance;
|
||||||
|
margin-top: 4rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
*:not([role=navigation])>p[role=heading]>span,
|
||||||
|
h3 {
|
||||||
|
font-family: 'Overpass', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 32px;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
line-height: 46px;
|
||||||
|
text-wrap: balance;
|
||||||
|
margin-top: 4rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-family: 'Overpass', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 32px;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
line-height: 46px;
|
||||||
|
text-wrap: balance;
|
||||||
|
margin-top: 3rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-family: 'Overpass', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
line-height: 1.4;
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-family: 'Overpass', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
line-height: 1.4;
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.pre,
|
||||||
|
pre {
|
||||||
|
/* css-3 */
|
||||||
|
white-space: pre-wrap;
|
||||||
|
/* Mozilla, since 1999 */
|
||||||
|
white-space: -moz-pre-wrap;
|
||||||
|
/* Opera 4-6 */
|
||||||
|
white-space: -pre-wrap;
|
||||||
|
/* Opera 7 */
|
||||||
|
white-space: -o-pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-family: 'Overpass Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
small,
|
||||||
|
small * {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-table-responsive table td,
|
||||||
|
.wy-table-responsive table th {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rst-content table.docutils td {
|
.rst-content table.docutils td {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* links */
|
/* links */
|
||||||
.rst-content a:not(:visited) {
|
|
||||||
color: #002fa7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rst-content .highlighted {
|
.rst-content .highlighted {
|
||||||
background: #eac545;
|
background: #eac545;
|
||||||
}
|
}
|
||||||
@ -27,60 +189,638 @@ pre {
|
|||||||
background: #fafafa;
|
background: #fafafa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wy-side-nav-search img.logo {
|
|
||||||
width: 100px !important;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wy-side-nav-search > a {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* project version (displayed under project logo) */
|
/* project version (displayed under project logo) */
|
||||||
.wy-side-nav-search .version {
|
.wy-side-nav-search>div.version {
|
||||||
color: #272525 !important;
|
color: var(--color-b);
|
||||||
}
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
/* menu section headers */
|
text-align: start;
|
||||||
.wy-menu .caption {
|
|
||||||
color: #65afff !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link to Remix IDE shown next to code snippets */
|
/* Link to Remix IDE shown next to code snippets */
|
||||||
p.remix-link-container {
|
.rst-content p.remix-link-container {
|
||||||
position: relative;
|
|
||||||
right: -100%; /* Positioned next to the the top-right corner of the code block following it. */
|
|
||||||
}
|
|
||||||
|
|
||||||
a.remix-link {
|
|
||||||
position: absolute; /* Remove it from normal flow not to affect the original position of the snippet. */
|
|
||||||
top: 0.5em;
|
|
||||||
width: 3.236em; /* Size of the margin (= right-side padding in .wy-nav-content in the current theme). */
|
|
||||||
}
|
|
||||||
|
|
||||||
a.remix-link .link-icon {
|
|
||||||
background: url("../img/solid-share-arrow.svg") no-repeat;
|
|
||||||
display: block;
|
display: block;
|
||||||
width: 1.5em;
|
text-align: right;
|
||||||
height: 1.5em;
|
margin: 0;
|
||||||
margin: auto;
|
line-height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.remix-link .link-text {
|
.rst-content .remix-link-container a.remix-link {
|
||||||
display: none; /* Visible only on hover. */
|
font-size: 0.7em;
|
||||||
width: 3.3em; /* Narrow enough to get two lines of text. */
|
padding: 0.1em 0.5em;
|
||||||
margin: auto;
|
background: transparent;
|
||||||
text-align: center;
|
color: var(--color-a) !important;
|
||||||
font-size: 0.8em;
|
border: 1px solid var(--color-a);
|
||||||
line-height: normal;
|
text-decoration: none;
|
||||||
color: black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a.remix-link:hover {
|
.rst-content div.highlight-solidity,
|
||||||
|
.rst-content div.highlight-yul {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CUSTOMIZATION UPDATES */
|
||||||
|
|
||||||
|
.wy-nav-content-wrap,
|
||||||
|
.wy-nav-content {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-side-nav-search {
|
||||||
|
background-color: transparent !important;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
box-shadow: 0 4 4 0 var(--color-a);
|
||||||
|
border-bottom: 1px solid var(--color-d) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-side-nav-search svg {
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-nav-top {
|
||||||
|
background-color: transparent !important;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-nav-top a {
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-breadcrumbs a.icon-home:before {
|
||||||
|
content: "Documentation";
|
||||||
|
font-family: "Overpass", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-content table.docutils thead {
|
||||||
|
color: var(--color-a);
|
||||||
|
}
|
||||||
|
|
||||||
|
code.docutils.literal.notranslate {
|
||||||
|
padding: 2px 4px;
|
||||||
|
font-size: 0.875em;
|
||||||
|
font-family: "Overpass Mono", monospace;
|
||||||
|
background: var(--white);
|
||||||
|
color: var(--color-c);
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt code.docutils.literal.notranslate {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-nav-content {
|
||||||
|
color: var(--color-a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .rst-content a:not(:visited) { */
|
||||||
|
/* color: var(--color-b) !important; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
.rst-content a:visited {
|
||||||
|
color: var(--color-c) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-content a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-content a:where(:focus, :focus-visible, :hover) {
|
||||||
|
color: var(--color-d) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-side-scroll a {
|
||||||
|
color: var(--color-a);
|
||||||
|
background: transparent;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 125%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-menu-vertical li.current a,
|
||||||
|
.wy-menu-vertical li.current li a,
|
||||||
|
.wy-menu-vertical li.current li a code {
|
||||||
|
border: none;
|
||||||
|
color: var(--color-a);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.current ul,
|
||||||
|
.wy-menu-vertical li.current a:hover,
|
||||||
|
.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,
|
||||||
|
.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,
|
||||||
|
.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,
|
||||||
|
.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,
|
||||||
|
.wy-menu-vertical li.current {
|
||||||
|
background: var(--menu-bg) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-menu.wy-menu-vertical>ul {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-menu.wy-menu-vertical>p {
|
||||||
|
color: var(--color-c);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-menu-vertical li.on a,
|
||||||
|
.wy-menu-vertical li.current>a {
|
||||||
|
background: var(--menu-bg) !important;
|
||||||
|
border-bottom: 0px !important;
|
||||||
|
border-top: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
border-radius: 0;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-breadcrumbs-aside a,
|
||||||
|
.wy-breadcrumbs-aside a:visited,
|
||||||
|
a.fa.fa-github,
|
||||||
|
a.fa.fa-github:visited,
|
||||||
|
a.fa.fa-github:not(:visited),
|
||||||
|
a.btn.btn-neutral:visited,
|
||||||
|
a.btn.btn-neutral:not(:visited),
|
||||||
|
a.btn.btn-neutral {
|
||||||
|
background: transparent !important;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
border: 2px solid var(--color-a) !important;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-content .remix-link-container a.remix-link:hover,
|
||||||
|
.wy-breadcrumbs-aside a:hover,
|
||||||
|
a.fa.fa-github:hover,
|
||||||
|
a.btn.btn-neutral:hover {
|
||||||
|
background: var(--white) !important;
|
||||||
|
color: var(--color-b) !important;
|
||||||
|
border-color: var(--color-b) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer .rst-footer-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customization for the unified layout
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Site wrapper, and two children: header and rest */
|
||||||
|
.unified-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
inset: 0;
|
||||||
|
max-width: var(--maxWidth);
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Site header */
|
||||||
|
.unified-header {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
inset-inline: 0;
|
||||||
|
z-index: 99999;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .inner-header {
|
||||||
|
display: flex;
|
||||||
|
margin-inline: auto;
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--maxWidth);
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-inline: var(--desktopInlinePadding);
|
||||||
|
padding-block: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
opacity: 95%;
|
||||||
|
background: var(--color-f);
|
||||||
|
z-index: -1;
|
||||||
|
backdrop-filter: blur(3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .home-link {
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
width: 25px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .home-link:hover .solidity-logo {
|
||||||
|
transform: scale(1.1);
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header img.solidity-logo {
|
||||||
|
transform: scale(1);
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .nav-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .nav-bar .nav-button-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .nav-link {
|
||||||
|
display: inline-block;
|
||||||
|
padding-inline: 8px;
|
||||||
|
padding-block: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: 'Overpass Mono', monospace;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--color-a);
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
font-weight: 400;
|
||||||
|
box-sizing: content-box;
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .nav-link.active {
|
||||||
|
background: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .nav-link:hover {
|
||||||
|
color: var(--color-c);
|
||||||
|
border-bottom: 1px solid var(--color-c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rest: Flex-row, with two children: side bar, and content */
|
||||||
|
.unified-wrapper .wy-grid-for-nav {
|
||||||
|
position: relative !important;
|
||||||
|
display: flex;
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First child: Side bar */
|
||||||
|
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side {
|
||||||
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: var(--color-f);
|
||||||
|
color: var(--color-a);
|
||||||
|
padding-bottom: unset !important;
|
||||||
|
z-index: 10 !important;
|
||||||
|
min-height: unset !important;
|
||||||
|
width: var(--sideWidth) !important;
|
||||||
|
top: var(--navHeight);
|
||||||
|
bottom: 0;
|
||||||
|
left: auto;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll {
|
||||||
|
position: static !important;
|
||||||
|
width: unset !important;
|
||||||
|
overflow: unset !important;
|
||||||
|
height: unset !important;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll .wy-side-nav-search {
|
||||||
|
margin: 0 !important;
|
||||||
|
width: var(--sideWidth) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-nav-side,
|
||||||
|
.wy-side-scroll,
|
||||||
|
.wy-side-nav-search,
|
||||||
|
.my-menu {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-nav-side input[type=text] {
|
||||||
|
font-family: "Overpass", sans-serif;
|
||||||
|
border-radius: 0;
|
||||||
|
border-color: var(--color-d);
|
||||||
|
background: var(--white);
|
||||||
|
box-shadow: none;
|
||||||
|
color: var(--color-a);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-nav-side input[type=text]::placeholder {
|
||||||
|
font-family: "Overpass", sans-serif;
|
||||||
|
color: var(--color-e);
|
||||||
|
font-size: 16px;
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second child: Content */
|
||||||
|
.unified-wrapper .wy-grid-for-nav .wy-nav-content {
|
||||||
|
width: 100%;
|
||||||
|
max-width: unset !important; /* override */
|
||||||
|
padding-inline: var(--desktopInlinePadding);
|
||||||
|
margin-inline-start: var(--sideWidth);
|
||||||
|
margin-top: var(--navHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-wrapper .wy-grid-for-nav .wy-nav-content .rst-content {
|
||||||
|
max-width: min(70ch, calc(100vw - 2 * var(--desktopInlinePadding) - var(--sideWidth)));
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-wrapper.menu-open .backdrop {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.remix-link:hover .link-text {
|
.unified-wrapper .wy-nav-side,
|
||||||
display: block;
|
.unified-wrapper .rst-versions {
|
||||||
|
left: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.unified-wrapper .backdrop {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 200ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
h2 {
|
||||||
|
margin-top: 3rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: 3rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu closed styles */
|
||||||
|
.unified-header .nav-link {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-header .inner-header {
|
||||||
|
padding-inline: var(--mobileInlinePadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
transition: transform 200ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu open styles */
|
||||||
|
.unified-wrapper.menu-open nav.wy-nav-side {
|
||||||
|
transform: translateX(0);
|
||||||
|
transition: transform 200ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-wrapper.menu-open .rst-versions {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-wrapper.menu-open .backdrop {
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 200ms ease-in-out;
|
||||||
|
z-index: 5;
|
||||||
|
background: #0006;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.skip-to-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-nav-content {
|
||||||
|
margin-inline-start: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-content {
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-side-scroll {
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.search .context {
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-versions {
|
||||||
|
background: var(--color-f);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-versions.shift-up {
|
||||||
|
height: unset !important;
|
||||||
|
max-height: unset !important;
|
||||||
|
overflow-y: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-content dl:not(.docutils) dt {
|
||||||
|
color: var(--color-a);
|
||||||
|
background-color: #fff8;
|
||||||
|
border-top: solid 3px #0002;
|
||||||
|
border-inline-start: solid 3px #0002;
|
||||||
|
padding: 2px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-versions .rst-current-version {
|
||||||
|
border-color: var(--color-d) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-current-version *,
|
||||||
|
.rst-current-version .fa:before,
|
||||||
|
.rst-current-version .fa-element {
|
||||||
|
color: var(--color-b) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-current-version dt,
|
||||||
|
.rst-current-version dd,
|
||||||
|
.rst-current-version dd a,
|
||||||
|
.rst-other-versions dl:last-of-type dt,
|
||||||
|
.rst-other-versions dl:last-of-type dd,
|
||||||
|
.rst-other-versions dl:last-of-type dd a {
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-other-versions {
|
||||||
|
background: var(--white) !important;
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
max-height: calc(100vh - var(--navHeight) - var(--currentVersionHeight));
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-other-versions a {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: var(--color-c) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-other-versions dt {
|
||||||
|
color: var(--color-a) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-other-versions dl {
|
||||||
|
margin-bottom: 1.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-other-versions dl:last-of-type {
|
||||||
|
margin-top: 2rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bottom Search */
|
||||||
|
.wy-nav-side input[type=text],
|
||||||
|
.rst-other-versions dl:last-of-type dd {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-other-versions dl:last-of-type dt {
|
||||||
|
color: var(--color-b) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-other-versions dl:last-of-type div[style*=padding],
|
||||||
|
.rst-other-versions dl dd:first-of-type a {
|
||||||
|
padding-inline-start: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.toctree-expand {
|
||||||
|
color: var(--black) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light/dark color mode toggle 🌓 */
|
||||||
|
button.color-toggle {
|
||||||
|
display: inline-flex;
|
||||||
|
appearance: none;
|
||||||
|
-webkit-box-align: center;
|
||||||
|
align-items: center;
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
justify-content: center;
|
||||||
|
user-select: none;
|
||||||
|
outline: none;
|
||||||
|
height: 28px;
|
||||||
|
width: 28px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 6px;
|
||||||
|
margin: 6px;
|
||||||
|
transition-duration: 200ms;
|
||||||
|
transition-property: background-color,
|
||||||
|
color,
|
||||||
|
fill,
|
||||||
|
stroke,
|
||||||
|
opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.color-toggle:focus-visible {
|
||||||
|
outline: 2px solid var(--color-c);
|
||||||
|
color: var(--color-c);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.color-toggle:hover {
|
||||||
|
color: var(--color-c);
|
||||||
|
background: #0002;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.color-toggle .color-toggle-icon {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 1em;
|
||||||
|
-webkit-flex-shrink: 0;
|
||||||
|
-ms-flex-negative: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
/* color: var(--color-a); */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
button.mobile-menu-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
nav.wy-nav-top {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.mobile-menu-button {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-results .search li:first-child,
|
||||||
|
#search-results .search li {
|
||||||
|
border-color: var(--color-d);
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-results .search li:last-child {
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forum-link::after {
|
||||||
|
content: ' ↗';
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: 'Overpass Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-breadcrumbs>li {
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-breadcrumbs-aside a {
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: "'Overpass'", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.skip-to-content:visited,
|
||||||
|
a.skip-to-content:not(:visited),
|
||||||
|
a.skip-to-content {
|
||||||
|
display: block;
|
||||||
|
pointer-events: none;
|
||||||
|
width: fit-content;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 200ms ease-in-out;
|
||||||
|
padding: 2px 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-inline-end: auto;
|
||||||
|
margin-inline-start: 1.5rem;
|
||||||
|
color: var(--color-a);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.skip-to-content:focus {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 200ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
scroll-margin-top: 6rem;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
635
docs/_static/css/dark.css
vendored
@ -1,635 +0,0 @@
|
|||||||
/* links */
|
|
||||||
|
|
||||||
.rst-content a:not(:visited) {
|
|
||||||
color: #aaddff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* code directives */
|
|
||||||
|
|
||||||
.method dt,
|
|
||||||
.class dt,
|
|
||||||
.data dt,
|
|
||||||
.attribute dt,
|
|
||||||
.function dt,
|
|
||||||
.classmethod dt,
|
|
||||||
.exception dt,
|
|
||||||
.descclassname,
|
|
||||||
.descname {
|
|
||||||
background-color: #2d2d2d !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rst-content dl:not(.docutils) dt {
|
|
||||||
color: #aaddff;
|
|
||||||
background-color: #2d2d2d;
|
|
||||||
border-top: solid 3px #525252;
|
|
||||||
border-left: solid 3px #525252;
|
|
||||||
}
|
|
||||||
|
|
||||||
em.property {
|
|
||||||
color: #888888;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* tables */
|
|
||||||
|
|
||||||
.rst-content table.docutils thead {
|
|
||||||
color: #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rst-content table.docutils td {
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td {
|
|
||||||
background-color: #5a5a5a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rst-content pre {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* inlined code highlights */
|
|
||||||
|
|
||||||
.xref,
|
|
||||||
.py-meth,
|
|
||||||
.rst-content a code {
|
|
||||||
color: #aaddff !important;
|
|
||||||
font-weight: normal !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rst-content code {
|
|
||||||
color: #eee !important;
|
|
||||||
font-weight: normal !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
code.literal {
|
|
||||||
background-color: #2d2d2d !important;
|
|
||||||
border: 1px solid #6d6d6d !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
code.docutils.literal.notranslate {
|
|
||||||
color: #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* highlight color search text */
|
|
||||||
|
|
||||||
.rst-content .highlighted {
|
|
||||||
background: #ff5722;
|
|
||||||
box-shadow: 0 0 0 2px #f0978b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* notes, warnings, hints */
|
|
||||||
|
|
||||||
.hint .admonition-title {
|
|
||||||
background: #2aa87c !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning .admonition-title {
|
|
||||||
background: #cc4444 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.admonition-title {
|
|
||||||
background: #3a7ca8 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.admonition,
|
|
||||||
.note {
|
|
||||||
background-color: #2d2d2d !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* table of contents */
|
|
||||||
|
|
||||||
.wy-nav-content-wrap {
|
|
||||||
background-color: rgba(0, 0, 0, 0.6) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
background-color: #191919 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-title {
|
|
||||||
background-color: #2b2b2b !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wy-menu-vertical a {
|
|
||||||
color: #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wy-menu-vertical code.docutils.literal.notranslate {
|
|
||||||
color: #404040;
|
|
||||||
background: none !important;
|
|
||||||
border: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wy-nav-content {
|
|
||||||
background: #3c3c3c;
|
|
||||||
color: #dddddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wy-menu-vertical li.on a,
|
|
||||||
.wy-menu-vertical li.current>a {
|
|
||||||
background: #a3a3a3;
|
|
||||||
border-bottom: 0px !important;
|
|
||||||
border-top: 0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wy-menu-vertical li.current {
|
|
||||||
background: #b3b3b3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toc-backref {
|
|
||||||
color: grey !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlight .hll {
|
|
||||||
background-color: #49483e
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlight {
|
|
||||||
background: #222;
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlight .c {
|
|
||||||
color: #888
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Comment */
|
|
||||||
|
|
||||||
.highlight .err {
|
|
||||||
color: #960050;
|
|
||||||
background-color: #1e0010
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Error */
|
|
||||||
|
|
||||||
.highlight .k {
|
|
||||||
color: #66d9ef
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Keyword */
|
|
||||||
|
|
||||||
.highlight .l {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal */
|
|
||||||
|
|
||||||
.highlight .n {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name */
|
|
||||||
|
|
||||||
.highlight .o {
|
|
||||||
color: #f92672
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Operator */
|
|
||||||
|
|
||||||
.highlight .p {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Punctuation */
|
|
||||||
|
|
||||||
.highlight .ch {
|
|
||||||
color: #888
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Comment.Hashbang */
|
|
||||||
|
|
||||||
.highlight .cm {
|
|
||||||
color: #888
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Comment.Multiline */
|
|
||||||
|
|
||||||
.highlight .cp {
|
|
||||||
color: #888
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Comment.Preproc */
|
|
||||||
|
|
||||||
.highlight .cpf {
|
|
||||||
color: #888
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Comment.PreprocFile */
|
|
||||||
|
|
||||||
.highlight .c1 {
|
|
||||||
color: #888
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Comment.Single */
|
|
||||||
|
|
||||||
.highlight .cs {
|
|
||||||
color: #888
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Comment.Special */
|
|
||||||
|
|
||||||
.highlight .gd {
|
|
||||||
color: #f92672
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Generic.Deleted */
|
|
||||||
|
|
||||||
.highlight .ge {
|
|
||||||
font-style: italic
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Generic.Emph */
|
|
||||||
|
|
||||||
.highlight .gi {
|
|
||||||
color: #a6e22e
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Generic.Inserted */
|
|
||||||
|
|
||||||
.highlight .gs {
|
|
||||||
font-weight: bold
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Generic.Strong */
|
|
||||||
|
|
||||||
.highlight .gu {
|
|
||||||
color: #888
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Generic.Subheading */
|
|
||||||
|
|
||||||
.highlight .kc {
|
|
||||||
color: #66d9ef
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Keyword.Constant */
|
|
||||||
|
|
||||||
.highlight .kd {
|
|
||||||
color: #66d9ef
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Keyword.Declaration */
|
|
||||||
|
|
||||||
.highlight .kn {
|
|
||||||
color: #f92672
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Keyword.Namespace */
|
|
||||||
|
|
||||||
.highlight .kp {
|
|
||||||
color: #66d9ef
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Keyword.Pseudo */
|
|
||||||
|
|
||||||
.highlight .kr {
|
|
||||||
color: #66d9ef
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Keyword.Reserved */
|
|
||||||
|
|
||||||
.highlight .kt {
|
|
||||||
color: #66d9ef
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Keyword.Type */
|
|
||||||
|
|
||||||
.highlight .ld {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.Date */
|
|
||||||
|
|
||||||
.highlight .m {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.Number */
|
|
||||||
|
|
||||||
.highlight .s {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String */
|
|
||||||
|
|
||||||
.highlight .na {
|
|
||||||
color: #a6e22e
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Attribute */
|
|
||||||
|
|
||||||
.highlight .nb {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Builtin */
|
|
||||||
|
|
||||||
.highlight .nc {
|
|
||||||
color: #a6e22e
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Class */
|
|
||||||
|
|
||||||
.highlight .no {
|
|
||||||
color: #66d9ef
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Constant */
|
|
||||||
|
|
||||||
.highlight .nd {
|
|
||||||
color: #a6e22e
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Decorator */
|
|
||||||
|
|
||||||
.highlight .ni {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Entity */
|
|
||||||
|
|
||||||
.highlight .ne {
|
|
||||||
color: #a6e22e
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Exception */
|
|
||||||
|
|
||||||
.highlight .nf {
|
|
||||||
color: #a6e22e
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Function */
|
|
||||||
|
|
||||||
.highlight .nl {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Label */
|
|
||||||
|
|
||||||
.highlight .nn {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Namespace */
|
|
||||||
|
|
||||||
.highlight .nx {
|
|
||||||
color: #a6e22e
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Other */
|
|
||||||
|
|
||||||
.highlight .py {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Property */
|
|
||||||
|
|
||||||
.highlight .nt {
|
|
||||||
color: #f92672
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Tag */
|
|
||||||
|
|
||||||
.highlight .nv {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Variable */
|
|
||||||
|
|
||||||
.highlight .ow {
|
|
||||||
color: #f92672
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Operator.Word */
|
|
||||||
|
|
||||||
.highlight .w {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Text.Whitespace */
|
|
||||||
|
|
||||||
.highlight .mb {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.Number.Bin */
|
|
||||||
|
|
||||||
.highlight .mf {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.Number.Float */
|
|
||||||
|
|
||||||
.highlight .mh {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.Number.Hex */
|
|
||||||
|
|
||||||
.highlight .mi {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.Number.Integer */
|
|
||||||
|
|
||||||
.highlight .mo {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.Number.Oct */
|
|
||||||
|
|
||||||
.highlight .sa {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Affix */
|
|
||||||
|
|
||||||
.highlight .sb {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Backtick */
|
|
||||||
|
|
||||||
.highlight .sc {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Char */
|
|
||||||
|
|
||||||
.highlight .dl {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Delimiter */
|
|
||||||
|
|
||||||
.highlight .sd {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Doc */
|
|
||||||
|
|
||||||
.highlight .s2 {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Double */
|
|
||||||
|
|
||||||
.highlight .se {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Escape */
|
|
||||||
|
|
||||||
.highlight .sh {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Heredoc */
|
|
||||||
|
|
||||||
.highlight .si {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Interpol */
|
|
||||||
|
|
||||||
.highlight .sx {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Other */
|
|
||||||
|
|
||||||
.highlight .sr {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Regex */
|
|
||||||
|
|
||||||
.highlight .s1 {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Single */
|
|
||||||
|
|
||||||
.highlight .ss {
|
|
||||||
color: #e6db74
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.String.Symbol */
|
|
||||||
|
|
||||||
.highlight .bp {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Builtin.Pseudo */
|
|
||||||
|
|
||||||
.highlight .fm {
|
|
||||||
color: #a6e22e
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Function.Magic */
|
|
||||||
|
|
||||||
.highlight .vc {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Variable.Class */
|
|
||||||
|
|
||||||
.highlight .vg {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Variable.Global */
|
|
||||||
|
|
||||||
.highlight .vi {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Variable.Instance */
|
|
||||||
|
|
||||||
.highlight .vm {
|
|
||||||
color: #f8f8f2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name.Variable.Magic */
|
|
||||||
|
|
||||||
.highlight .il {
|
|
||||||
color: #ae81ff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Literal.Number.Integer.Long */
|
|
||||||
|
|
||||||
|
|
||||||
/* Link to Remix IDE shown over code snippets */
|
|
||||||
a.remix-link {
|
|
||||||
filter: invert(1); /* The icon is black. In dark mode we want it white. */
|
|
||||||
}
|
|
2
docs/_static/css/fonts.css
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import url("https://fonts.cdnfonts.com/css/overpass");
|
||||||
|
@import url("https://fonts.cdnfonts.com/css/overpass-mono");
|
399
docs/_static/css/pygments.css
vendored
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
pre {
|
||||||
|
line-height: 125%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.linenos .normal {
|
||||||
|
color: inherit;
|
||||||
|
background-color: transparent;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.linenos {
|
||||||
|
color: inherit;
|
||||||
|
background-color: transparent;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.linenos .special {
|
||||||
|
color: #000000;
|
||||||
|
background-color: #ffffc0;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.linenos.special {
|
||||||
|
color: #000000;
|
||||||
|
background-color: #ffffc0;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight .hll {
|
||||||
|
background-color: #ffffcc
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
background: #eeffcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight .c {
|
||||||
|
color: #408090;
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment */
|
||||||
|
.highlight .err {
|
||||||
|
border: 1px solid #FF0000
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error */
|
||||||
|
.highlight .k {
|
||||||
|
color: #007020;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keyword */
|
||||||
|
.highlight .o {
|
||||||
|
color: #666666
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Operator */
|
||||||
|
.highlight .ch {
|
||||||
|
color: #408090;
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment.Hashbang */
|
||||||
|
.highlight .cm {
|
||||||
|
color: #408090;
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment.Multiline */
|
||||||
|
.highlight .cp {
|
||||||
|
color: #007020
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment.Preproc */
|
||||||
|
.highlight .cpf {
|
||||||
|
color: #408090;
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment.PreprocFile */
|
||||||
|
.highlight .c1 {
|
||||||
|
color: #408090;
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment.Single */
|
||||||
|
.highlight .cs {
|
||||||
|
color: #408090;
|
||||||
|
background-color: #fff0f0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment.Special */
|
||||||
|
.highlight .gd {
|
||||||
|
color: #A00000
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Deleted */
|
||||||
|
.highlight .ge {
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Emph */
|
||||||
|
.highlight .gr {
|
||||||
|
color: #FF0000
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Error */
|
||||||
|
.highlight .gh {
|
||||||
|
color: #000080;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Heading */
|
||||||
|
.highlight .gi {
|
||||||
|
color: #00A000
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Inserted */
|
||||||
|
.highlight .go {
|
||||||
|
color: #333333
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Output */
|
||||||
|
.highlight .gp {
|
||||||
|
color: #c65d09;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Prompt */
|
||||||
|
.highlight .gs {
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Strong */
|
||||||
|
.highlight .gu {
|
||||||
|
color: #800080;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Subheading */
|
||||||
|
.highlight .gt {
|
||||||
|
color: #0044DD
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic.Traceback */
|
||||||
|
.highlight .kc {
|
||||||
|
color: #007020;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keyword.Constant */
|
||||||
|
.highlight .kd {
|
||||||
|
color: #007020;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keyword.Declaration */
|
||||||
|
.highlight .kn {
|
||||||
|
color: #007020;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keyword.Namespace */
|
||||||
|
.highlight .kp {
|
||||||
|
color: #007020
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keyword.Pseudo */
|
||||||
|
.highlight .kr {
|
||||||
|
color: #007020;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keyword.Reserved */
|
||||||
|
.highlight .kt {
|
||||||
|
color: #902000
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keyword.Type */
|
||||||
|
.highlight .m {
|
||||||
|
color: #208050
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.Number */
|
||||||
|
.highlight .s {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String */
|
||||||
|
.highlight .na {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Attribute */
|
||||||
|
.highlight .nb {
|
||||||
|
color: #007020
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Builtin */
|
||||||
|
.highlight .nc {
|
||||||
|
color: #0e84b5;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Class */
|
||||||
|
.highlight .no {
|
||||||
|
color: #60add5
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Constant */
|
||||||
|
.highlight .nd {
|
||||||
|
color: #555555;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Decorator */
|
||||||
|
.highlight .ni {
|
||||||
|
color: #d55537;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Entity */
|
||||||
|
.highlight .ne {
|
||||||
|
color: #007020
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Exception */
|
||||||
|
.highlight .nf {
|
||||||
|
color: #06287e
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Function */
|
||||||
|
.highlight .nl {
|
||||||
|
color: #002070;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Label */
|
||||||
|
.highlight .nn {
|
||||||
|
color: #0e84b5;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Namespace */
|
||||||
|
.highlight .nt {
|
||||||
|
color: #062873;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Tag */
|
||||||
|
.highlight .nv {
|
||||||
|
color: #bb60d5
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Variable */
|
||||||
|
.highlight .ow {
|
||||||
|
color: #007020;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Operator.Word */
|
||||||
|
.highlight .w {
|
||||||
|
color: #bbbbbb
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text.Whitespace */
|
||||||
|
.highlight .mb {
|
||||||
|
color: #208050
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.Number.Bin */
|
||||||
|
.highlight .mf {
|
||||||
|
color: #208050
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.Number.Float */
|
||||||
|
.highlight .mh {
|
||||||
|
color: #208050
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.Number.Hex */
|
||||||
|
.highlight .mi {
|
||||||
|
color: #208050
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.Number.Integer */
|
||||||
|
.highlight .mo {
|
||||||
|
color: #208050
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.Number.Oct */
|
||||||
|
.highlight .sa {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Affix */
|
||||||
|
.highlight .sb {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Backtick */
|
||||||
|
.highlight .sc {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Char */
|
||||||
|
.highlight .dl {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Delimiter */
|
||||||
|
.highlight .sd {
|
||||||
|
color: #4070a0;
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Doc */
|
||||||
|
.highlight .s2 {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Double */
|
||||||
|
.highlight .se {
|
||||||
|
color: #4070a0;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Escape */
|
||||||
|
.highlight .sh {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Heredoc */
|
||||||
|
.highlight .si {
|
||||||
|
color: #70a0d0;
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Interpol */
|
||||||
|
.highlight .sx {
|
||||||
|
color: #c65d09
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Other */
|
||||||
|
.highlight .sr {
|
||||||
|
color: #235388
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Regex */
|
||||||
|
.highlight .s1 {
|
||||||
|
color: #4070a0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Single */
|
||||||
|
.highlight .ss {
|
||||||
|
color: #517918
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.String.Symbol */
|
||||||
|
.highlight .bp {
|
||||||
|
color: #007020
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Builtin.Pseudo */
|
||||||
|
.highlight .fm {
|
||||||
|
color: #06287e
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Function.Magic */
|
||||||
|
.highlight .vc {
|
||||||
|
color: #bb60d5
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Variable.Class */
|
||||||
|
.highlight .vg {
|
||||||
|
color: #bb60d5
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Variable.Global */
|
||||||
|
.highlight .vi {
|
||||||
|
color: #bb60d5
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Variable.Instance */
|
||||||
|
.highlight .vm {
|
||||||
|
color: #bb60d5
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name.Variable.Magic */
|
||||||
|
.highlight .il {
|
||||||
|
color: #208050
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Literal.Number.Integer.Long */
|
15
docs/_static/css/toggle.css
vendored
@ -9,6 +9,13 @@ input[type=checkbox] {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
background-color: var(--color-f);
|
||||||
|
border-top: 1px solid var(--color-c);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-caret-down,
|
||||||
|
.fa-book {
|
||||||
|
color: var(--color-a) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rst-versions .rst-current-version .fa-book,
|
.rst-versions .rst-current-version .fa-book,
|
||||||
@ -76,8 +83,6 @@ html.transition *:after {
|
|||||||
transition-delay: 0 !important;
|
transition-delay: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav.wy-nav-side {
|
.wy-menu-vertical a:hover {
|
||||||
/* The default padding of 2em is too small and the "Keyword Index" link gets obscured
|
background-color: #0002;
|
||||||
* by the version toggle. */
|
}
|
||||||
padding-bottom: 3em;
|
|
||||||
}
|
|
BIN
docs/_static/img/favicon.ico
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
3
docs/_static/img/hamburger-dark.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="#E6E3EC" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
|
||||||
|
<path d="M 3 5 A 1.0001 1.0001 0 1 0 3 7 L 21 7 A 1.0001 1.0001 0 1 0 21 5 L 3 5 z M 3 11 A 1.0001 1.0001 0 1 0 3 13 L 21 13 A 1.0001 1.0001 0 1 0 21 11 L 3 11 z M 3 17 A 1.0001 1.0001 0 1 0 3 19 L 21 19 A 1.0001 1.0001 0 1 0 21 17 L 3 17 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 413 B |
3
docs/_static/img/hamburger-light.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="24px" height="24px" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
|
||||||
|
<path fill="#2B247C" d="M 3 5 A 1.0001 1.0001 0 1 0 3 7 L 21 7 A 1.0001 1.0001 0 1 0 21 5 L 3 5 z M 3 11 A 1.0001 1.0001 0 1 0 3 13 L 21 13 A 1.0001 1.0001 0 1 0 21 11 L 3 11 z M 3 17 A 1.0001 1.0001 0 1 0 3 19 L 21 19 A 1.0001 1.0001 0 1 0 21 17 L 3 17 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 437 B |
8
docs/_static/img/logo-dark.svg
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<svg width="100" height="160" viewBox="0 0 100 160" fill="#E6E3EC" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
|
||||||
|
<path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
|
||||||
|
<path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
|
||||||
|
<path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
|
||||||
|
<path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
|
||||||
|
<path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 574 B |
8
docs/_static/img/logo.svg
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<svg width="100" height="160" viewBox="0 0 100 160" fill="#2B247C" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
|
||||||
|
<path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
|
||||||
|
<path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
|
||||||
|
<path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
|
||||||
|
<path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
|
||||||
|
<path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 574 B |
3
docs/_static/img/moon.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="#2B247C" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
|
||||||
|
<path d="M21.4,13.7C20.6,13.9,19.8,14,19,14c-5,0-9-4-9-9c0-0.8,0.1-1.6,0.3-2.4c0.1-0.3,0-0.7-0.3-1 c-0.3-0.3-0.6-0.4-1-0.3C4.3,2.7,1,7.1,1,12c0,6.1,4.9,11,11,11c4.9,0,9.3-3.3,10.6-8.1c0.1-0.3,0-0.7-0.3-1 C22.1,13.7,21.7,13.6,21.4,13.7z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 408 B |
13
docs/_static/img/sun.svg
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
|
||||||
|
<g stroke-linejoin="round" stroke-linecap="round" stroke-width="2" fill="none" stroke="#E6E3EC">
|
||||||
|
<circle cx="12" cy="12" r="5" />
|
||||||
|
<path d="M12 1v2" />
|
||||||
|
<path d="M12 21v2" />
|
||||||
|
<path d="M4.22 4.22l1.42 1.42" />
|
||||||
|
<path d="M18.36 18.36l1.42 1.42" />
|
||||||
|
<path d="M1 12h2" />
|
||||||
|
<path d="M21 12h2" />
|
||||||
|
<path d="M4.22 19.78l1.42-1.42" />
|
||||||
|
<path d="M18.36 5.64l1.42-1.42" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 554 B |
38
docs/_static/js/constants.js
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Site URL
|
||||||
|
const SITE_URL = "https://docs.soliditylang.org"
|
||||||
|
const { origin, pathname } = location;
|
||||||
|
const pathSplit = pathname.split("/");
|
||||||
|
const rootPath = origin.includes(SITE_URL) && pathSplit.length > 3 ? pathSplit.splice(1, 2).join("/") : ''
|
||||||
|
const ROOT_URL = `${origin}/${rootPath}`;
|
||||||
|
|
||||||
|
// Color mode constants
|
||||||
|
const [DARK, LIGHT] = ["dark", "light"];
|
||||||
|
const LIGHT_LOGO_PATH = `${ROOT_URL}/_static/img/logo.svg`;
|
||||||
|
const DARK_LOGO_PATH = `${ROOT_URL}/_static/img/logo-dark.svg`;
|
||||||
|
const SUN_ICON_PATH = `${ROOT_URL}/_static/img/sun.svg`;
|
||||||
|
const MOON_ICON_PATH = `${ROOT_URL}/_static/img/moon.svg`;
|
||||||
|
const LIGHT_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-light.svg`;
|
||||||
|
const DARK_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-dark.svg`;
|
||||||
|
const COLOR_TOGGLE_ICON_CLASS = "color-toggle-icon";
|
||||||
|
const SOLIDITY_LOGO_CLASS = "solidity-logo";
|
||||||
|
const LS_COLOR_SCHEME = "color-scheme";
|
||||||
|
|
||||||
|
// Solidity navigation constants
|
||||||
|
const SOLIDITY_HOME_URL = "https://soliditylang.org";
|
||||||
|
const BLOG_URL = `${SOLIDITY_HOME_URL}/blog`;
|
||||||
|
const DOCS_URL = "/";
|
||||||
|
const USE_CASES_PATH = `${SOLIDITY_HOME_URL}/use-cases`;
|
||||||
|
const CONTRIBUTE_PATH = `/en/latest/contributing.html`;
|
||||||
|
const ABOUT_PATH = `${SOLIDITY_HOME_URL}/about`;
|
||||||
|
const FORUM_URL = "https://forum.soliditylang.org/";
|
||||||
|
const NAV_LINKS = [
|
||||||
|
{ name: "Blog", href: BLOG_URL },
|
||||||
|
{ name: "Documentation", href: DOCS_URL },
|
||||||
|
{ name: "Use cases", href: USE_CASES_PATH },
|
||||||
|
{ name: "Contribute", href: CONTRIBUTE_PATH },
|
||||||
|
{ name: "About", href: ABOUT_PATH },
|
||||||
|
{ name: "Forum", href: FORUM_URL },
|
||||||
|
];
|
||||||
|
|
||||||
|
const MOBILE_MENU_TOGGLE_CLASS = "shift";
|
||||||
|
const WRAPPER_CLASS = "unified-wrapper";
|
250
docs/_static/js/initialize.js
vendored
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
const getLogoSrc = (isDark) => (isDark ? DARK_LOGO_PATH : LIGHT_LOGO_PATH);
|
||||||
|
|
||||||
|
const getModeIconSrc = (isDark) => (isDark ? SUN_ICON_PATH : MOON_ICON_PATH);
|
||||||
|
|
||||||
|
const getMenuIconSrc = (isDark) =>
|
||||||
|
isDark ? DARK_HAMBURGER_PATH : LIGHT_HAMBURGER_PATH;
|
||||||
|
|
||||||
|
function addFooterNote() {
|
||||||
|
const contentInfo = document.querySelector("div[role=contentinfo]");
|
||||||
|
const footerNote = document.createElement("p");
|
||||||
|
footerNote.classList.add("footer-note");
|
||||||
|
footerNote.innerHTML =
|
||||||
|
'Customized with ❤️ by the <a href="https://ethereum.org/" target="_blank">ethereum.org</a> team.';
|
||||||
|
contentInfo.parentNode.insertBefore(footerNote, contentInfo.nextSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rearrangeDom() {
|
||||||
|
const bodyDivs = document.querySelectorAll("body>div");
|
||||||
|
bodyDivs.forEach((div) => div.remove());
|
||||||
|
const wrapperDiv = document.createElement("div");
|
||||||
|
wrapperDiv.classList.add(WRAPPER_CLASS);
|
||||||
|
bodyDivs.forEach((div) => wrapperDiv.appendChild(div));
|
||||||
|
document.body.prepend(wrapperDiv);
|
||||||
|
|
||||||
|
const rstVersions = document.querySelector(".rst-versions");
|
||||||
|
rstVersions.remove();
|
||||||
|
const wyNavSide = document.querySelector("nav.wy-nav-side");
|
||||||
|
wyNavSide.appendChild(rstVersions);
|
||||||
|
const backdrop = document.createElement("div");
|
||||||
|
backdrop.classList.add("backdrop");
|
||||||
|
wrapperDiv.appendChild(backdrop);
|
||||||
|
|
||||||
|
const content = document.querySelector(".wy-nav-content");
|
||||||
|
content.id = "content";
|
||||||
|
const oldWrap = document.querySelector("section.wy-nav-content-wrap");
|
||||||
|
oldWrap.remove();
|
||||||
|
document.querySelector(".wy-grid-for-nav").appendChild(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildHeader() {
|
||||||
|
const isDarkMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK;
|
||||||
|
|
||||||
|
const header = document.createElement("div");
|
||||||
|
header.classList.add("unified-header");
|
||||||
|
document.querySelector(`.${WRAPPER_CLASS}`).prepend(header);
|
||||||
|
|
||||||
|
const innerHeader = document.createElement("div");
|
||||||
|
innerHeader.classList.add("inner-header");
|
||||||
|
header.appendChild(innerHeader);
|
||||||
|
|
||||||
|
const homeLink = document.createElement("a");
|
||||||
|
homeLink.classList.add("home-link");
|
||||||
|
homeLink.href = SOLIDITY_HOME_URL;
|
||||||
|
homeLink.ariaLabel = "Solidity home";
|
||||||
|
innerHeader.appendChild(homeLink);
|
||||||
|
|
||||||
|
const logo = document.createElement("img");
|
||||||
|
logo.classList.add(SOLIDITY_LOGO_CLASS);
|
||||||
|
logo.src = getLogoSrc(isDarkMode);
|
||||||
|
logo.alt = "Solidity logo";
|
||||||
|
homeLink.appendChild(logo);
|
||||||
|
|
||||||
|
const skipToContent = document.createElement("a");
|
||||||
|
skipToContent.classList.add("skip-to-content");
|
||||||
|
skipToContent.href = "#content";
|
||||||
|
skipToContent.innerText = "{skip to content}";
|
||||||
|
innerHeader.appendChild(skipToContent);
|
||||||
|
|
||||||
|
const navBar = document.createElement("nav");
|
||||||
|
navBar.classList.add("nav-bar");
|
||||||
|
innerHeader.appendChild(navBar);
|
||||||
|
|
||||||
|
const linkElements = NAV_LINKS.map(({ name, href }) => {
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.classList.add("nav-link");
|
||||||
|
link.setAttribute("key", name);
|
||||||
|
link.setAttribute("href", href);
|
||||||
|
link.setAttribute("aria-label", name);
|
||||||
|
if (href === FORUM_URL) {
|
||||||
|
link.classList.add("forum-link");
|
||||||
|
link.setAttribute("target", "_blank");
|
||||||
|
link.setAttribute("rel", "noopener noreferrer");
|
||||||
|
}
|
||||||
|
link.innerText = name;
|
||||||
|
return link;
|
||||||
|
});
|
||||||
|
linkElements.forEach((link) => navBar.appendChild(link));
|
||||||
|
|
||||||
|
// Flex wrapper for color mode and mobile menu buttons
|
||||||
|
const navButtonContainer = document.createElement("div");
|
||||||
|
navButtonContainer.classList.add("nav-button-container");
|
||||||
|
navBar.appendChild(navButtonContainer);
|
||||||
|
|
||||||
|
// Build color toggle
|
||||||
|
const toggleIcon = document.createElement("img");
|
||||||
|
toggleIcon.classList.add(COLOR_TOGGLE_ICON_CLASS);
|
||||||
|
toggleIcon.src = getModeIconSrc(isDarkMode);
|
||||||
|
toggleIcon.alt = "Color mode toggle icon";
|
||||||
|
toggleIcon.setAttribute("aria-hidden", "true");
|
||||||
|
toggleIcon.setAttribute("key", "toggle icon");
|
||||||
|
const colorModeButton = document.createElement("button");
|
||||||
|
colorModeButton.classList.add("color-toggle");
|
||||||
|
colorModeButton.setAttribute("type", "button");
|
||||||
|
colorModeButton.setAttribute("aria-label", "Toggle light dark mode");
|
||||||
|
colorModeButton.setAttribute("key", "color mode button");
|
||||||
|
colorModeButton.addEventListener("click", toggleColorMode);
|
||||||
|
colorModeButton.appendChild(toggleIcon);
|
||||||
|
navButtonContainer.appendChild(colorModeButton);
|
||||||
|
|
||||||
|
// Build mobile hamburger menu
|
||||||
|
const menuIcon = document.createElement("img");
|
||||||
|
menuIcon.classList.add(COLOR_TOGGLE_ICON_CLASS);
|
||||||
|
menuIcon.src = getMenuIconSrc(isDarkMode);
|
||||||
|
menuIcon.alt = "Toggle menu";
|
||||||
|
menuIcon.setAttribute("aria-hidden", "true");
|
||||||
|
menuIcon.setAttribute("key", "menu icon");
|
||||||
|
const menuButton = document.createElement("button");
|
||||||
|
menuButton.classList.add("color-toggle");
|
||||||
|
menuButton.classList.add("mobile-menu-button");
|
||||||
|
menuButton.setAttribute("type", "button");
|
||||||
|
menuButton.setAttribute("aria-label", "Toggle menu");
|
||||||
|
menuButton.setAttribute("key", "menu button");
|
||||||
|
menuButton.addEventListener("click", toggleMenu);
|
||||||
|
menuButton.appendChild(menuIcon);
|
||||||
|
navButtonContainer.appendChild(menuButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateActiveNavLink = () => {
|
||||||
|
const navLinks = document.querySelectorAll(".unified-header .nav-link");
|
||||||
|
navLinks.forEach((link) => {
|
||||||
|
const href = link.getAttribute("href");
|
||||||
|
if (document.documentURI.includes("contributing.html")) {
|
||||||
|
link.classList[href.includes("contributing.html") ? "add" : "remove"](
|
||||||
|
"active"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
link.classList[document.documentURI.includes(href) ? "add" : "remove"](
|
||||||
|
"active"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener("locationchange", updateActiveNavLink);
|
||||||
|
|
||||||
|
function updateGitHubEditPath() {
|
||||||
|
// Replaces the version number in the GitHub edit path with "develop"
|
||||||
|
const gitHubEditAnchor = document.querySelector(".wy-breadcrumbs-aside > a");
|
||||||
|
const url = new URL(gitHubEditAnchor.href);
|
||||||
|
const split = url.pathname.split("/");
|
||||||
|
const versionIndex = split.indexOf("blob") + 1;
|
||||||
|
split[versionIndex] = "develop";
|
||||||
|
url.pathname = split.join("/");
|
||||||
|
gitHubEditAnchor.setAttribute("href", url.toString());
|
||||||
|
gitHubEditAnchor.setAttribute("target", "_blank");
|
||||||
|
gitHubEditAnchor.setAttribute("rel", "noopener noreferrer");
|
||||||
|
}
|
||||||
|
|
||||||
|
function initialize() {
|
||||||
|
// Rearrange DOM elements for styling
|
||||||
|
rearrangeDom();
|
||||||
|
|
||||||
|
// Check localStorage for existing color scheme preference
|
||||||
|
var prefersDark = localStorage.getItem(LS_COLOR_SCHEME) == DARK;
|
||||||
|
// Check link for search param "color"... it may be "light" or "dark"
|
||||||
|
var urlParams = new URLSearchParams(window.location.search);
|
||||||
|
if (urlParams.size > 0) {
|
||||||
|
// This is used for color mode continuity between the main Solidity Lang site and the docs
|
||||||
|
var colorSchemeParam = urlParams.get("color");
|
||||||
|
// If present, overwrite prefersDark accordingly
|
||||||
|
if (colorSchemeParam) {
|
||||||
|
prefersDark = colorSchemeParam == DARK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove "color" search param from URL
|
||||||
|
const { location, title } = document;
|
||||||
|
const { pathname, origin, search, hash } = location;
|
||||||
|
const newSearchParams = new URLSearchParams(search);
|
||||||
|
newSearchParams.delete("color");
|
||||||
|
const sanitizedSearch =
|
||||||
|
newSearchParams.size < 1 ? "" : "?" + newSearchParams.toString();
|
||||||
|
window.history.replaceState(
|
||||||
|
origin,
|
||||||
|
title,
|
||||||
|
pathname + sanitizedSearch + hash
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case none existed, establish localStorage color scheme preference
|
||||||
|
var mode = prefersDark ? DARK : LIGHT;
|
||||||
|
localStorage.setItem(LS_COLOR_SCHEME, mode);
|
||||||
|
|
||||||
|
// Select the root element and set the style attribute to denote color-scheme attribute
|
||||||
|
document
|
||||||
|
.querySelector(":root")
|
||||||
|
.setAttribute("style", `--color-scheme: ${mode}`);
|
||||||
|
|
||||||
|
// Remove old input and RTD logo anchor element
|
||||||
|
document.querySelector("input[name=mode]").remove();
|
||||||
|
document.querySelector("label[for=switch]").remove();
|
||||||
|
document.querySelector(".wy-side-nav-search > a").remove();
|
||||||
|
|
||||||
|
// Add footer note
|
||||||
|
addFooterNote();
|
||||||
|
|
||||||
|
// Build header
|
||||||
|
buildHeader();
|
||||||
|
|
||||||
|
// Close menu
|
||||||
|
toggleMenu({ force: false });
|
||||||
|
|
||||||
|
// Update active nav link
|
||||||
|
updateActiveNavLink();
|
||||||
|
|
||||||
|
// Update GitHub edit path to direct to `develop` branch
|
||||||
|
updateGitHubEditPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", initialize);
|
||||||
|
|
||||||
|
const handleClick = (e) => {
|
||||||
|
if (e.target.closest(".backdrop")) {
|
||||||
|
toggleMenu({ force: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.target.closest("a")) {
|
||||||
|
const target = e.target.closest("a");
|
||||||
|
const href = target.getAttribute("href");
|
||||||
|
if (href.includes(SOLIDITY_HOME_URL)) {
|
||||||
|
const url = new URL(href);
|
||||||
|
const params = new URLSearchParams(url.search);
|
||||||
|
params.set("color", localStorage.getItem(LS_COLOR_SCHEME));
|
||||||
|
url.search = params.toString();
|
||||||
|
target.setAttribute("href", url.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener("click", handleClick);
|
||||||
|
|
||||||
|
const handleKeyDown = (e) => {
|
||||||
|
if (e.metaKey && e.key === "k") {
|
||||||
|
document.querySelector("#rtd-search-form input").focus();
|
||||||
|
} else if (e.key === "Escape") {
|
||||||
|
toggleMenu({ force: false });
|
||||||
|
}
|
||||||
|
if (e.metaKey && e.code === "Backslash") {
|
||||||
|
toggleColorMode();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener("keydown", handleKeyDown);
|
78
docs/_static/js/toggle.js
vendored
@ -1,39 +1,47 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
function toggleColorMode() {
|
||||||
|
// Check localStorage for previous color scheme preference, assign the opposite
|
||||||
|
var newMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK ? LIGHT : DARK;
|
||||||
|
|
||||||
function toggleCssMode(isDay) {
|
// Update localStorage with new color scheme preference
|
||||||
var mode = (isDay ? "Day" : "Night");
|
localStorage.setItem(LS_COLOR_SCHEME, newMode);
|
||||||
localStorage.setItem("css-mode", mode);
|
|
||||||
|
|
||||||
var url_root = DOCUMENTATION_OPTIONS.URL_ROOT == "./" ? "" : DOCUMENTATION_OPTIONS.URL_ROOT;
|
// Update the root element with the new color scheme preference
|
||||||
var daysheet = $(`link[href="${url_root}_static/pygments.css"]`)[0].sheet;
|
document
|
||||||
daysheet.disabled = !isDay;
|
.querySelector(":root")
|
||||||
|
.setAttribute("style", `--color-scheme: ${newMode}`);
|
||||||
|
|
||||||
var nightsheet = $(`link[href="${url_root}_static/css/dark.css"]`)[0];
|
// Update logo
|
||||||
if (!isDay && nightsheet === undefined) {
|
document
|
||||||
var element = document.createElement("link");
|
.querySelector(`img.${SOLIDITY_LOGO_CLASS}`)
|
||||||
element.setAttribute("rel", "stylesheet");
|
.setAttribute("src", newMode === LIGHT ? LIGHT_LOGO_PATH : DARK_LOGO_PATH);
|
||||||
element.setAttribute("type", "text/css");
|
|
||||||
element.setAttribute("href", `${url_root}_static/css/dark.css`);
|
// Update color mode toggle icon
|
||||||
document.getElementsByTagName("head")[0].appendChild(element);
|
document
|
||||||
return;
|
.querySelector(`img.${COLOR_TOGGLE_ICON_CLASS}`)
|
||||||
}
|
.setAttribute("src", newMode === LIGHT ? MOON_ICON_PATH : SUN_ICON_PATH);
|
||||||
if (nightsheet !== undefined) {
|
|
||||||
nightsheet.sheet.disabled = isDay;
|
// Update hamburger menu icon color
|
||||||
}
|
document
|
||||||
|
.querySelector("button.mobile-menu-button img")
|
||||||
|
.setAttribute(
|
||||||
|
"src",
|
||||||
|
newMode === LIGHT ? LIGHT_HAMBURGER_PATH : DARK_HAMBURGER_PATH
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMenu(options = {}) {
|
||||||
|
const handleClassToggle = ({ classList }, className) => {
|
||||||
|
if (typeof options.force !== "undefined") {
|
||||||
|
classList.toggle(className, options.force);
|
||||||
|
} else {
|
||||||
|
classList.toggle(className);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
var initial = localStorage.getItem("css-mode") != "Night";
|
document
|
||||||
var checkbox = document.querySelector('input[name=mode]');
|
.querySelectorAll('[data-toggle="rst-versions"]')
|
||||||
|
.forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));
|
||||||
toggleCssMode(initial);
|
document
|
||||||
checkbox.checked = initial;
|
.querySelectorAll('[data-toggle="wy-nav-shift"]')
|
||||||
|
.forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));
|
||||||
checkbox.addEventListener('change', function() {
|
handleClassToggle(document.querySelector(`.${WRAPPER_CLASS}`), "menu-open");
|
||||||
document.documentElement.classList.add('transition');
|
}
|
||||||
window.setTimeout(() => {
|
|
||||||
document.documentElement.classList.remove('transition');
|
|
||||||
}, 1000)
|
|
||||||
toggleCssMode(this.checked);
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
|
@ -563,7 +563,7 @@ A function description is a JSON object with the fields:
|
|||||||
blockchain state <pure-functions>`), ``view`` (:ref:`specified to not modify the blockchain
|
blockchain state <pure-functions>`), ``view`` (:ref:`specified to not modify the blockchain
|
||||||
state <view-functions>`), ``nonpayable`` (function does not accept Ether - the default) and ``payable`` (function accepts Ether).
|
state <view-functions>`), ``nonpayable`` (function does not accept Ether - the default) and ``payable`` (function accepts Ether).
|
||||||
|
|
||||||
Constructor and fallback function never have ``name`` or ``outputs``. Fallback function doesn't have ``inputs`` either.
|
Constructor, receive, and fallback never have ``name`` or ``outputs``. Receive and fallback do not have ``inputs`` either.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Sending non-zero Ether to non-payable function will revert the transaction.
|
Sending non-zero Ether to non-payable function will revert the transaction.
|
||||||
@ -581,7 +581,7 @@ An event description is a JSON object with fairly similar fields:
|
|||||||
* ``name``: the name of the parameter.
|
* ``name``: the name of the parameter.
|
||||||
* ``type``: the canonical type of the parameter (more below).
|
* ``type``: the canonical type of the parameter (more below).
|
||||||
* ``components``: used for tuple types (more below).
|
* ``components``: used for tuple types (more below).
|
||||||
* ``indexed``: ``true`` if the field is part of the log's topics, ``false`` if it one of the log's data segment.
|
* ``indexed``: ``true`` if the field is part of the log's topics, ``false`` if it is one of the log's data segments.
|
||||||
|
|
||||||
- ``anonymous``: ``true`` if the event was declared as ``anonymous``.
|
- ``anonymous``: ``true`` if the event was declared as ``anonymous``.
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ visual diff of the assembly before and after a change is often very enlightening
|
|||||||
|
|
||||||
Consider the following contract (named, say ``contract.sol``):
|
Consider the following contract (named, say ``contract.sol``):
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.5.0 <0.9.0;
|
pragma solidity >=0.5.0 <0.9.0;
|
||||||
|
@ -362,7 +362,7 @@ in memory is automatically considered memory-safe and does not need to be annota
|
|||||||
.. warning::
|
.. warning::
|
||||||
It is your responsibility to make sure that the assembly actually satisfies the memory model. If you annotate
|
It is your responsibility to make sure that the assembly actually satisfies the memory model. If you annotate
|
||||||
an assembly block as memory-safe, but violate one of the memory assumptions, this **will** lead to incorrect and
|
an assembly block as memory-safe, but violate one of the memory assumptions, this **will** lead to incorrect and
|
||||||
undefined behaviour that cannot easily be discovered by testing.
|
undefined behavior that cannot easily be discovered by testing.
|
||||||
|
|
||||||
In case you are developing a library that is meant to be compatible across multiple versions
|
In case you are developing a library that is meant to be compatible across multiple versions
|
||||||
of Solidity, you can use a special comment to annotate an assembly block as memory-safe:
|
of Solidity, you can use a special comment to annotate an assembly block as memory-safe:
|
||||||
@ -375,4 +375,4 @@ of Solidity, you can use a special comment to annotate an assembly block as memo
|
|||||||
}
|
}
|
||||||
|
|
||||||
Note that we will disallow the annotation via comment in a future breaking release; so, if you are not concerned with
|
Note that we will disallow the annotation via comment in a future breaking release; so, if you are not concerned with
|
||||||
backwards-compatibility with older compiler versions, prefer using the dialect string.
|
backward-compatibility with older compiler versions, prefer using the dialect string.
|
||||||
|
@ -67,7 +67,7 @@ When using the Solidity logo, please respect the Solidity logo guidelines.
|
|||||||
Solidity Logo Guidelines
|
Solidity Logo Guidelines
|
||||||
========================
|
========================
|
||||||
|
|
||||||
.. image:: logo.svg
|
.. image:: solidity_logo.svg
|
||||||
:width: 256
|
:width: 256
|
||||||
|
|
||||||
*(Right click on the logo to download it.)*
|
*(Right click on the logo to download it.)*
|
||||||
|
@ -1,4 +1,30 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"uid": "SOL-2023-2",
|
||||||
|
"name": "FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"summary": "Optimizer sequences containing FullInliner do not preserve the evaluation order of arguments of inlined function calls in code that is not in expression-split form.",
|
||||||
|
"description": "Function call arguments in Yul are evaluated right to left. This order matters when the argument expressions have side-effects, and changing it may change contract behavior. FullInliner is an optimizer step that can replace a function call with the body of that function. The transformation involves assigning argument expressions to temporary variables, which imposes an explicit evaluation order. FullInliner was written with the assumption that this order does not necessarily have to match usual argument evaluation order because the argument expressions have no side-effects. In most circumstances this assumption is true because the default optimization step sequence contains the ExpressionSplitter step. ExpressionSplitter ensures that the code is in *expression-split form*, which means that function calls cannot appear nested inside expressions, and all function call arguments have to be variables. The assumption is, however, not guaranteed to be true in general. Version 0.6.7 introduced a setting allowing users to specify an arbitrary optimization step sequence, making it possible for the FullInliner to actually encounter argument expressions with side-effects, which can result in behavior differences between optimized and unoptimized bytecode. Contracts compiled without optimization or with the default optimization sequence are not affected. To trigger the bug the user has to explicitly choose compiler settings that contain a sequence with FullInliner step not preceded by ExpressionSplitter.",
|
||||||
|
"link": "https://blog.soliditylang.org/2023/07/19/full-inliner-non-expression-split-argument-evaluation-order-bug/",
|
||||||
|
"introduced": "0.6.7",
|
||||||
|
"fixed": "0.8.21",
|
||||||
|
"severity": "low",
|
||||||
|
"conditions": {
|
||||||
|
"yulOptimizer": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "SOL-2023-1",
|
||||||
|
"name": "MissingSideEffectsOnSelectorAccess",
|
||||||
|
"summary": "Accessing the ``.selector`` member on complex expressions leaves the expression unevaluated in the legacy code generation.",
|
||||||
|
"description": "When accessing the ``.selector`` member on an expression with side-effects, like an assignment, a function call or a conditional, the expression would not be evaluated in the legacy code generation. This would happen in expressions where the functions used in the expression were all known at compilation time, regardless of whether the whole expression could be evaluated at compilation time or not. Note that the code generated by the IR pipeline was unaffected and would behave as expected.",
|
||||||
|
"link": "https://blog.soliditylang.org/2023/07/19/missing-side-effects-on-selector-access-bug/",
|
||||||
|
"introduced": "0.6.2",
|
||||||
|
"fixed": "0.8.21",
|
||||||
|
"severity": "low",
|
||||||
|
"conditions": {
|
||||||
|
"viaIR": false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"uid": "SOL-2022-7",
|
"uid": "SOL-2022-7",
|
||||||
"name": "StorageWriteRemovalBeforeConditionalTermination",
|
"name": "StorageWriteRemovalBeforeConditionalTermination",
|
||||||
|
@ -68,7 +68,7 @@ conditions
|
|||||||
If no conditions are given, assume that the bug is present.
|
If no conditions are given, assume that the bug is present.
|
||||||
check
|
check
|
||||||
This field contains different checks that report whether the smart contract
|
This field contains different checks that report whether the smart contract
|
||||||
contains the bug or not. The first type of check are Javascript regular
|
contains the bug or not. The first type of check are JavaScript regular
|
||||||
expressions that are to be matched against the source code ("source-regex")
|
expressions that are to be matched against the source code ("source-regex")
|
||||||
if the bug is present. If there is no match, then the bug is very likely
|
if the bug is present. If there is no match, then the bug is very likely
|
||||||
not present. If there is a match, the bug might be present. For improved
|
not present. If there is a match, the bug might be present. For improved
|
||||||
|
@ -1422,6 +1422,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.10": {
|
"0.6.10": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1436,6 +1438,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.11": {
|
"0.6.11": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1450,6 +1454,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.12": {
|
"0.6.12": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1464,6 +1470,7 @@
|
|||||||
},
|
},
|
||||||
"0.6.2": {
|
"0.6.2": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||||
@ -1481,6 +1488,7 @@
|
|||||||
},
|
},
|
||||||
"0.6.3": {
|
"0.6.3": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||||
@ -1498,6 +1506,7 @@
|
|||||||
},
|
},
|
||||||
"0.6.4": {
|
"0.6.4": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||||
@ -1515,6 +1524,7 @@
|
|||||||
},
|
},
|
||||||
"0.6.5": {
|
"0.6.5": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||||
@ -1532,6 +1542,7 @@
|
|||||||
},
|
},
|
||||||
"0.6.6": {
|
"0.6.6": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||||
@ -1548,6 +1559,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.7": {
|
"0.6.7": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||||
@ -1564,6 +1577,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.8": {
|
"0.6.8": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"NestedCalldataArrayAbiReencodingSizeValidation",
|
"NestedCalldataArrayAbiReencodingSizeValidation",
|
||||||
@ -1577,6 +1592,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.9": {
|
"0.6.9": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1592,6 +1609,8 @@
|
|||||||
},
|
},
|
||||||
"0.7.0": {
|
"0.7.0": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1606,6 +1625,8 @@
|
|||||||
},
|
},
|
||||||
"0.7.1": {
|
"0.7.1": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1621,6 +1642,8 @@
|
|||||||
},
|
},
|
||||||
"0.7.2": {
|
"0.7.2": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1635,6 +1658,8 @@
|
|||||||
},
|
},
|
||||||
"0.7.3": {
|
"0.7.3": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1648,6 +1673,8 @@
|
|||||||
},
|
},
|
||||||
"0.7.4": {
|
"0.7.4": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1660,6 +1687,8 @@
|
|||||||
},
|
},
|
||||||
"0.7.5": {
|
"0.7.5": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1672,6 +1701,8 @@
|
|||||||
},
|
},
|
||||||
"0.7.6": {
|
"0.7.6": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1684,6 +1715,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.0": {
|
"0.8.0": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1696,6 +1729,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.1": {
|
"0.8.1": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1708,6 +1743,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.10": {
|
"0.8.10": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1717,6 +1754,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.11": {
|
"0.8.11": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1727,6 +1766,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.12": {
|
"0.8.12": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1737,6 +1778,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.13": {
|
"0.8.13": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"StorageWriteRemovalBeforeConditionalTermination",
|
"StorageWriteRemovalBeforeConditionalTermination",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
@ -1748,6 +1791,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.14": {
|
"0.8.14": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"StorageWriteRemovalBeforeConditionalTermination",
|
"StorageWriteRemovalBeforeConditionalTermination",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
@ -1757,6 +1802,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.15": {
|
"0.8.15": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"StorageWriteRemovalBeforeConditionalTermination",
|
"StorageWriteRemovalBeforeConditionalTermination",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup"
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup"
|
||||||
],
|
],
|
||||||
@ -1764,20 +1811,37 @@
|
|||||||
},
|
},
|
||||||
"0.8.16": {
|
"0.8.16": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"StorageWriteRemovalBeforeConditionalTermination"
|
"StorageWriteRemovalBeforeConditionalTermination"
|
||||||
],
|
],
|
||||||
"released": "2022-08-08"
|
"released": "2022-08-08"
|
||||||
},
|
},
|
||||||
"0.8.17": {
|
"0.8.17": {
|
||||||
"bugs": [],
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess"
|
||||||
|
],
|
||||||
"released": "2022-09-08"
|
"released": "2022-09-08"
|
||||||
},
|
},
|
||||||
"0.8.18": {
|
"0.8.18": {
|
||||||
"bugs": [],
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess"
|
||||||
|
],
|
||||||
"released": "2023-02-01"
|
"released": "2023-02-01"
|
||||||
},
|
},
|
||||||
|
"0.8.19": {
|
||||||
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess"
|
||||||
|
],
|
||||||
|
"released": "2023-02-22"
|
||||||
|
},
|
||||||
"0.8.2": {
|
"0.8.2": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1788,8 +1852,21 @@
|
|||||||
],
|
],
|
||||||
"released": "2021-03-02"
|
"released": "2021-03-02"
|
||||||
},
|
},
|
||||||
|
"0.8.20": {
|
||||||
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess"
|
||||||
|
],
|
||||||
|
"released": "2023-05-10"
|
||||||
|
},
|
||||||
|
"0.8.21": {
|
||||||
|
"bugs": [],
|
||||||
|
"released": "2023-07-19"
|
||||||
|
},
|
||||||
"0.8.3": {
|
"0.8.3": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1801,6 +1878,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.4": {
|
"0.8.4": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1811,6 +1890,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.5": {
|
"0.8.5": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1821,6 +1902,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.6": {
|
"0.8.6": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1831,6 +1914,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.7": {
|
"0.8.7": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1841,6 +1926,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.8": {
|
"0.8.8": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
@ -1852,6 +1939,8 @@
|
|||||||
},
|
},
|
||||||
"0.8.9": {
|
"0.8.9": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"FullInlinerNonExpressionSplitArgumentEvaluationOrder",
|
||||||
|
"MissingSideEffectsOnSelectorAccess",
|
||||||
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
"AbiReencodingHeadOverflowWithStaticArrayCleanup",
|
||||||
"DirtyBytesArrayToStorage",
|
"DirtyBytesArrayToStorage",
|
||||||
"DataLocationChangeInInternalOverride",
|
"DataLocationChangeInInternalOverride",
|
||||||
|
@ -2,16 +2,17 @@
|
|||||||
Cheatsheet
|
Cheatsheet
|
||||||
**********
|
**********
|
||||||
|
|
||||||
.. index:: operator; precedence
|
.. index:: operator;precedence
|
||||||
|
|
||||||
Order of Precedence of Operators
|
Order of Precedence of Operators
|
||||||
================================
|
================================
|
||||||
|
|
||||||
.. include:: types/operator-precedence-table.rst
|
.. include:: types/operator-precedence-table.rst
|
||||||
|
|
||||||
.. index:: assert, block, coinbase, difficulty, prevrandao, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, gas price, origin, revert, require, keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, codehash, send
|
.. index:: abi;decode, abi;encode, abi;encodePacked, abi;encodeWithSelector, abi;encodeCall, abi;encodeWithSignature
|
||||||
|
|
||||||
Global Variables
|
ABI Encoding and Decoding Functions
|
||||||
================
|
===================================
|
||||||
|
|
||||||
- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI <ABI>`-decodes
|
- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI <ABI>`-decodes
|
||||||
the provided data. The types are given in parentheses as second argument.
|
the provided data. The types are given in parentheses as second argument.
|
||||||
@ -25,10 +26,37 @@ Global Variables
|
|||||||
tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))``
|
tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))``
|
||||||
- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent
|
- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent
|
||||||
to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``
|
to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``
|
||||||
|
|
||||||
|
.. index:: bytes;concat, string;concat
|
||||||
|
|
||||||
|
Members of ``bytes`` and ``string``
|
||||||
|
====================================
|
||||||
|
|
||||||
- ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of
|
- ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of
|
||||||
arguments to one byte array<bytes-concat>`
|
arguments to one byte array<bytes-concat>`
|
||||||
|
|
||||||
- ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of
|
- ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of
|
||||||
arguments to one string array<string-concat>`
|
arguments to one string array<string-concat>`
|
||||||
|
|
||||||
|
.. index:: address;balance, address;codehash, address;send, address;code, address;transfer
|
||||||
|
|
||||||
|
Members of ``address``
|
||||||
|
======================
|
||||||
|
|
||||||
|
- ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei
|
||||||
|
- ``<address>.code`` (``bytes memory``): code at the :ref:`address` (can be empty)
|
||||||
|
- ``<address>.codehash`` (``bytes32``): the codehash of the :ref:`address`
|
||||||
|
- ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`,
|
||||||
|
returns ``false`` on failure
|
||||||
|
- ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure
|
||||||
|
|
||||||
|
.. index:: blockhash, block, block;basefree, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp
|
||||||
|
.. index:: gasleft, msg;data, msg;sender, msg;sig, msg;value, tx;gasprice, tx;origin
|
||||||
|
|
||||||
|
Block and Transaction Properties
|
||||||
|
================================
|
||||||
|
|
||||||
|
- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
|
||||||
- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_)
|
- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_)
|
||||||
- ``block.chainid`` (``uint``): current chain id
|
- ``block.chainid`` (``uint``): current chain id
|
||||||
- ``block.coinbase`` (``address payable``): current block miner's address
|
- ``block.coinbase`` (``address payable``): current block miner's address
|
||||||
@ -44,6 +72,12 @@ Global Variables
|
|||||||
- ``msg.value`` (``uint``): number of wei sent with the message
|
- ``msg.value`` (``uint``): number of wei sent with the message
|
||||||
- ``tx.gasprice`` (``uint``): gas price of the transaction
|
- ``tx.gasprice`` (``uint``): gas price of the transaction
|
||||||
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
|
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
|
||||||
|
|
||||||
|
.. index:: assert, require, revert
|
||||||
|
|
||||||
|
Validations and Assertions
|
||||||
|
==========================
|
||||||
|
|
||||||
- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error)
|
- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error)
|
||||||
- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use
|
- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use
|
||||||
for malformed input or error in external component)
|
for malformed input or error in external component)
|
||||||
@ -51,7 +85,12 @@ Global Variables
|
|||||||
condition is ``false`` (use for malformed input or error in external component). Also provide error message.
|
condition is ``false`` (use for malformed input or error in external component). Also provide error message.
|
||||||
- ``revert()``: abort execution and revert state changes
|
- ``revert()``: abort execution and revert state changes
|
||||||
- ``revert(string memory message)``: abort execution and revert state changes providing an explanatory string
|
- ``revert(string memory message)``: abort execution and revert state changes providing an explanatory string
|
||||||
- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
|
|
||||||
|
.. index:: cryptography, keccak256, sha256, ripemd160, ecrecover, addmod, mulmod
|
||||||
|
|
||||||
|
Mathematical and Cryptographic Functions
|
||||||
|
========================================
|
||||||
|
|
||||||
- ``keccak256(bytes memory) returns (bytes32)``: compute the Keccak-256 hash of the input
|
- ``keccak256(bytes memory) returns (bytes32)``: compute the Keccak-256 hash of the input
|
||||||
- ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input
|
- ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input
|
||||||
- ``ripemd160(bytes memory) returns (bytes20)``: compute the RIPEMD-160 hash of the input
|
- ``ripemd160(bytes memory) returns (bytes20)``: compute the RIPEMD-160 hash of the input
|
||||||
@ -61,15 +100,21 @@ Global Variables
|
|||||||
arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
|
arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
|
||||||
- ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed
|
- ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed
|
||||||
with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
|
with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.
|
||||||
|
|
||||||
|
.. index:: this, super, selfdestruct
|
||||||
|
|
||||||
|
Contract-related
|
||||||
|
================
|
||||||
|
|
||||||
- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` or ``address payable``
|
- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` or ``address payable``
|
||||||
- ``super``: the contract one level higher in the inheritance hierarchy
|
- ``super``: a contract one level higher in the inheritance hierarchy
|
||||||
- ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given address
|
- ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given address
|
||||||
- ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei
|
|
||||||
- ``<address>.code`` (``bytes memory``): code at the :ref:`address` (can be empty)
|
.. index:: type;name, type;creationCode, type;runtimeCode, type;interfaceId, type;min, type;max
|
||||||
- ``<address>.codehash`` (``bytes32``): the codehash of the :ref:`address`
|
|
||||||
- ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`,
|
Type Information
|
||||||
returns ``false`` on failure
|
================
|
||||||
- ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure
|
|
||||||
- ``type(C).name`` (``string``): the name of the contract
|
- ``type(C).name`` (``string``): the name of the contract
|
||||||
- ``type(C).creationCode`` (``bytes memory``): creation bytecode of the given contract, see :ref:`Type Information<meta-type>`.
|
- ``type(C).creationCode`` (``bytes memory``): creation bytecode of the given contract, see :ref:`Type Information<meta-type>`.
|
||||||
- ``type(C).runtimeCode`` (``bytes memory``): runtime bytecode of the given contract, see :ref:`Type Information<meta-type>`.
|
- ``type(C).runtimeCode`` (``bytes memory``): runtime bytecode of the given contract, see :ref:`Type Information<meta-type>`.
|
||||||
@ -105,11 +150,11 @@ Modifiers
|
|||||||
- ``view`` for functions: Disallows modification of state.
|
- ``view`` for functions: Disallows modification of state.
|
||||||
- ``payable`` for functions: Allows them to receive Ether together with a call.
|
- ``payable`` for functions: Allows them to receive Ether together with a call.
|
||||||
- ``constant`` for state variables: Disallows assignment (except initialisation), does not occupy storage slot.
|
- ``constant`` for state variables: Disallows assignment (except initialisation), does not occupy storage slot.
|
||||||
- ``immutable`` for state variables: Allows exactly one assignment at construction time and is constant afterwards. Is stored in code.
|
- ``immutable`` for state variables: Allows assignment at construction time and is constant when deployed. Is stored in code.
|
||||||
- ``anonymous`` for events: Does not store event signature as topic.
|
- ``anonymous`` for events: Does not store event signature as topic.
|
||||||
- ``indexed`` for event parameters: Stores the parameter as topic.
|
- ``indexed`` for event parameters: Stores the parameter as topic.
|
||||||
- ``virtual`` for functions and modifiers: Allows the function's or modifier's
|
- ``virtual`` for functions and modifiers: Allows the function's or modifier's
|
||||||
behaviour to be changed in derived contracts.
|
behavior to be changed in derived contracts.
|
||||||
- ``override``: States that this function, modifier or public state variable changes
|
- ``override``: States that this function, modifier or public state variable changes
|
||||||
the behaviour of a function or modifier in a base contract.
|
the behavior of a function or modifier in a base contract.
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ introduces a potential security risk. You may read
|
|||||||
more about this on the :ref:`security_considerations` page.
|
more about this on the :ref:`security_considerations` page.
|
||||||
|
|
||||||
The following is an example of the withdrawal pattern in practice in
|
The following is an example of the withdrawal pattern in practice in
|
||||||
a contract where the goal is to send the most money to the
|
a contract where the goal is to send the most of some compensation, e.g. Ether, to the
|
||||||
contract in order to become the "richest", inspired by
|
contract in order to become the "richest", inspired by
|
||||||
`King of the Ether <https://www.kingoftheether.com/>`_.
|
`King of the Ether <https://www.kingoftheether.com/>`_.
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ you receive the funds of the person who is now the richest.
|
|||||||
address public richest;
|
address public richest;
|
||||||
uint public mostSent;
|
uint public mostSent;
|
||||||
|
|
||||||
mapping (address => uint) pendingWithdrawals;
|
mapping(address => uint) pendingWithdrawals;
|
||||||
|
|
||||||
/// The amount of Ether sent was not higher than
|
/// The amount of Ether sent was not higher than
|
||||||
/// the currently highest amount.
|
/// the currently highest amount.
|
||||||
@ -55,7 +55,7 @@ you receive the funds of the person who is now the richest.
|
|||||||
function withdraw() public {
|
function withdraw() public {
|
||||||
uint amount = pendingWithdrawals[msg.sender];
|
uint amount = pendingWithdrawals[msg.sender];
|
||||||
// Remember to zero the pending refund before
|
// Remember to zero the pending refund before
|
||||||
// sending to prevent re-entrancy attacks
|
// sending to prevent reentrancy attacks
|
||||||
pendingWithdrawals[msg.sender] = 0;
|
pendingWithdrawals[msg.sender] = 0;
|
||||||
payable(msg.sender).transfer(amount);
|
payable(msg.sender).transfer(amount);
|
||||||
}
|
}
|
||||||
|
13
docs/conf.py
@ -31,7 +31,10 @@ def setup(sphinx):
|
|||||||
sphinx.add_lexer('Solidity', SolidityLexer)
|
sphinx.add_lexer('Solidity', SolidityLexer)
|
||||||
sphinx.add_lexer('Yul', YulLexer)
|
sphinx.add_lexer('Yul', YulLexer)
|
||||||
|
|
||||||
|
sphinx.add_css_file('css/fonts.css')
|
||||||
sphinx.add_css_file('css/custom.css')
|
sphinx.add_css_file('css/custom.css')
|
||||||
|
sphinx.add_css_file('css/custom-dark.css')
|
||||||
|
sphinx.add_css_file('css/pygments.css')
|
||||||
|
|
||||||
# -- General configuration ------------------------------------------------
|
# -- General configuration ------------------------------------------------
|
||||||
|
|
||||||
@ -45,6 +48,7 @@ extensions = [
|
|||||||
'sphinx_a4doc',
|
'sphinx_a4doc',
|
||||||
'html_extra_template_renderer',
|
'html_extra_template_renderer',
|
||||||
'remix_code_links',
|
'remix_code_links',
|
||||||
|
'sphinx.ext.imgconverter',
|
||||||
]
|
]
|
||||||
|
|
||||||
a4_base_path = os.path.dirname(__file__) + '/grammar'
|
a4_base_path = os.path.dirname(__file__) + '/grammar'
|
||||||
@ -131,7 +135,6 @@ html_theme = 'sphinx_rtd_theme'
|
|||||||
# documentation.
|
# documentation.
|
||||||
html_theme_options = {
|
html_theme_options = {
|
||||||
'logo_only': True,
|
'logo_only': True,
|
||||||
'style_nav_header_background': '#65afff',
|
|
||||||
'display_version': True,
|
'display_version': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,12 +150,12 @@ html_theme_options = {
|
|||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top
|
# The name of an image file (relative to this directory) to place at the top
|
||||||
# of the sidebar.
|
# of the sidebar.
|
||||||
html_logo = "logo.svg"
|
# html_logo = "logo.svg"
|
||||||
|
|
||||||
# The name of an image file (within the static path) to use as favicon of the
|
# The name of an image file (within the static path) to use as favicon of the
|
||||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
# pixels large.
|
# pixels large.
|
||||||
html_favicon = "_static/img/favicon.png"
|
html_favicon = "_static/img/favicon.ico"
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
@ -161,7 +164,7 @@ html_static_path = ['_static']
|
|||||||
|
|
||||||
html_css_files = ["css/toggle.css"]
|
html_css_files = ["css/toggle.css"]
|
||||||
|
|
||||||
html_js_files = ["js/toggle.js"]
|
html_js_files = ["js/constants.js", "js/initialize.js", "js/toggle.js"]
|
||||||
|
|
||||||
# Add any extra paths that contain custom files (such as robots.txt or
|
# Add any extra paths that contain custom files (such as robots.txt or
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
# .htaccess) here, relative to this directory. These files are copied
|
||||||
@ -209,7 +212,7 @@ html_extra_templates = {
|
|||||||
#html_show_sourcelink = True
|
#html_show_sourcelink = True
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||||
#html_show_sphinx = True
|
html_show_sphinx = False
|
||||||
|
|
||||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||||
#html_show_copyright = True
|
#html_show_copyright = True
|
||||||
|
@ -30,19 +30,23 @@ Not all types for constants and immutables are implemented at this time. The onl
|
|||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.7.4;
|
pragma solidity ^0.8.21;
|
||||||
|
|
||||||
uint constant X = 32**22 + 8;
|
uint constant X = 32**22 + 8;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
string constant TEXT = "abc";
|
string constant TEXT = "abc";
|
||||||
bytes32 constant MY_HASH = keccak256("abc");
|
bytes32 constant MY_HASH = keccak256("abc");
|
||||||
uint immutable decimals;
|
uint immutable decimals = 18;
|
||||||
uint immutable maxBalance;
|
uint immutable maxBalance;
|
||||||
address immutable owner = msg.sender;
|
address immutable owner = msg.sender;
|
||||||
|
|
||||||
constructor(uint decimals_, address ref) {
|
constructor(uint decimals_, address ref) {
|
||||||
decimals = decimals_;
|
if (decimals_ != 0)
|
||||||
|
// Immutables are only immutable when deployed.
|
||||||
|
// At construction time they can be assigned to any number of times.
|
||||||
|
decimals = decimals_;
|
||||||
|
|
||||||
// Assignments to immutables can even access the environment.
|
// Assignments to immutables can even access the environment.
|
||||||
maxBalance = ref.balance;
|
maxBalance = ref.balance;
|
||||||
}
|
}
|
||||||
@ -74,25 +78,34 @@ Immutable
|
|||||||
=========
|
=========
|
||||||
|
|
||||||
Variables declared as ``immutable`` are a bit less restricted than those
|
Variables declared as ``immutable`` are a bit less restricted than those
|
||||||
declared as ``constant``: Immutable variables can be assigned an arbitrary
|
declared as ``constant``: Immutable variables can be assigned a
|
||||||
value in the constructor of the contract or at the point of their declaration.
|
value at construction time.
|
||||||
They can be assigned only once and can, from that point on, be read even during
|
The value can be changed at any time before deployment and then it becomes permanent.
|
||||||
construction time.
|
|
||||||
|
One additional restriction is that immutables can only be assigned to inside expressions for which
|
||||||
|
there is no possibility of being executed after creation.
|
||||||
|
This excludes all modifier definitions and functions other than constructors.
|
||||||
|
|
||||||
|
There are no restrictions on reading immutable variables.
|
||||||
|
The read is even allowed to happen before the variable is written to for the first time because variables in
|
||||||
|
Solidity always have a well-defined initial value.
|
||||||
|
For this reason it is also allowed to never explicitly assign a value to an immutable.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
When accessing immutables at construction time, please keep the :ref:`initialization order
|
||||||
|
<state-variable-initialization-order>` in mind.
|
||||||
|
Even if you provide an explicit initializer, some expressions may end up being evaluated before
|
||||||
|
that initializer, especially when they are at a different level in inheritance hierarchy.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Before Solidity 0.8.21 initialization of immutable variables was more restrictive.
|
||||||
|
Such variables had to be initialized exactly once at construction time and could not be read
|
||||||
|
before then.
|
||||||
|
|
||||||
The contract creation code generated by the compiler will modify the
|
The contract creation code generated by the compiler will modify the
|
||||||
contract's runtime code before it is returned by replacing all references
|
contract's runtime code before it is returned by replacing all references
|
||||||
to immutables with the values assigned to them. This is important if
|
to immutables with the values assigned to them. This is important if
|
||||||
you are comparing the
|
you are comparing the
|
||||||
runtime code generated by the compiler with the one actually stored in the
|
runtime code generated by the compiler with the one actually stored in the
|
||||||
blockchain.
|
blockchain. The compiler outputs where these immutables are located in the deployed bytecode
|
||||||
|
in the ``immutableReferences`` field of the :ref:`compiler JSON standard output <compiler-api>`.
|
||||||
.. note::
|
|
||||||
Immutables that are assigned at their declaration are only considered
|
|
||||||
initialized once the constructor of the contract is executing.
|
|
||||||
This means you cannot initialize immutables inline with a value
|
|
||||||
that depends on another immutable. You can do this, however,
|
|
||||||
inside the constructor of the contract.
|
|
||||||
|
|
||||||
This is a safeguard against different interpretations about the order
|
|
||||||
of state variable initialization and constructor execution, especially
|
|
||||||
with regards to inheritance.
|
|
||||||
|
@ -9,9 +9,10 @@ Events
|
|||||||
Solidity events give an abstraction on top of the EVM's logging functionality.
|
Solidity events give an abstraction on top of the EVM's logging functionality.
|
||||||
Applications can subscribe and listen to these events through the RPC interface of an Ethereum client.
|
Applications can subscribe and listen to these events through the RPC interface of an Ethereum client.
|
||||||
|
|
||||||
Events are inheritable members of contracts. When you call them, they cause the
|
Events can be defined at file level or as inheritable members of contracts (including interfaces and libraries).
|
||||||
|
When you call them, they cause the
|
||||||
arguments to be stored in the transaction's log - a special data structure
|
arguments to be stored in the transaction's log - a special data structure
|
||||||
in the blockchain. These logs are associated with the address of the contract,
|
in the blockchain. These logs are associated with the address of the contract that emitted them,
|
||||||
are incorporated into the blockchain, and stay there as long as a block is
|
are incorporated into the blockchain, and stay there as long as a block is
|
||||||
accessible (forever as of now, but this might
|
accessible (forever as of now, but this might
|
||||||
change with Serenity). The Log and its event data is not accessible from within
|
change with Serenity). The Log and its event data is not accessible from within
|
||||||
@ -151,6 +152,6 @@ The output of the above looks like the following (trimmed):
|
|||||||
Additional Resources for Understanding Events
|
Additional Resources for Understanding Events
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
- `Javascript documentation <https://github.com/web3/web3.js/blob/1.x/docs/web3-eth-contract.rst#events>`_
|
- `JavaScript documentation <https://github.com/web3/web3.js/blob/1.x/docs/web3-eth-contract.rst#events>`_
|
||||||
- `Example usage of events <https://github.com/ethchange/smart-exchange/blob/master/lib/contracts/SmartExchange.sol>`_
|
- `Example usage of events <https://github.com/ethchange/smart-exchange/blob/master/lib/contracts/SmartExchange.sol>`_
|
||||||
- `How to access them in js <https://github.com/ethchange/smart-exchange/blob/master/lib/exchange_transactions.js>`_
|
- `How to access them in js <https://github.com/ethchange/smart-exchange/blob/master/lib/exchange_transactions.js>`_
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
Function Modifiers
|
Function Modifiers
|
||||||
******************
|
******************
|
||||||
|
|
||||||
Modifiers can be used to change the behaviour of functions in a declarative way.
|
Modifiers can be used to change the behavior of functions in a declarative way.
|
||||||
For example,
|
For example,
|
||||||
you can use a modifier to automatically check a condition prior to executing the function.
|
you can use a modifier to automatically check a condition prior to executing the function.
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ if they are marked ``virtual``. For details, please see
|
|||||||
}
|
}
|
||||||
|
|
||||||
contract Register is priced, destructible {
|
contract Register is priced, destructible {
|
||||||
mapping (address => bool) registeredAddresses;
|
mapping(address => bool) registeredAddresses;
|
||||||
uint price;
|
uint price;
|
||||||
|
|
||||||
constructor(uint initialPrice) { price = initialPrice; }
|
constructor(uint initialPrice) { price = initialPrice; }
|
||||||
@ -132,7 +132,7 @@ variables are set to their :ref:`default values<default-value>` just as if the f
|
|||||||
body.
|
body.
|
||||||
|
|
||||||
The ``_`` symbol can appear in the modifier multiple times. Each occurrence is replaced with
|
The ``_`` symbol can appear in the modifier multiple times. Each occurrence is replaced with
|
||||||
the function body.
|
the function body, and the function returns the return value of the final occurrence.
|
||||||
|
|
||||||
Arbitrary expressions are allowed for modifier arguments and in this context,
|
Arbitrary expressions are allowed for modifier arguments and in this context,
|
||||||
all symbols visible from the function are visible in the modifier. Symbols
|
all symbols visible from the function are visible in the modifier. Symbols
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.. index:: ! functions
|
.. index:: ! functions, ! function;free
|
||||||
|
|
||||||
.. _functions:
|
.. _functions:
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ Reverting a state change is not considered a "state modification", as only chang
|
|||||||
state made previously in code that did not have the ``view`` or ``pure`` restriction
|
state made previously in code that did not have the ``view`` or ``pure`` restriction
|
||||||
are reverted and that code has the option to catch the ``revert`` and not pass it on.
|
are reverted and that code has the option to catch the ``revert`` and not pass it on.
|
||||||
|
|
||||||
This behaviour is also in line with the ``STATICCALL`` opcode.
|
This behavior is also in line with the ``STATICCALL`` opcode.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
It is not possible to prevent functions from reading the state at the level
|
It is not possible to prevent functions from reading the state at the level
|
||||||
@ -277,7 +277,7 @@ This behaviour is also in line with the ``STATICCALL`` opcode.
|
|||||||
Special Functions
|
Special Functions
|
||||||
=================
|
=================
|
||||||
|
|
||||||
.. index:: ! receive ether function, function;receive ! receive
|
.. index:: ! receive ether function, function;receive, ! receive
|
||||||
|
|
||||||
.. _receive-ether-function:
|
.. _receive-ether-function:
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ Details are given in the following example.
|
|||||||
// accessed externally via `this`, though.
|
// accessed externally via `this`, though.
|
||||||
contract Destructible is Owned {
|
contract Destructible is Owned {
|
||||||
// The keyword `virtual` means that the function can change
|
// The keyword `virtual` means that the function can change
|
||||||
// its behaviour in derived classes ("overriding").
|
// its behavior in derived classes ("overriding").
|
||||||
function destroy() virtual public {
|
function destroy() virtual public {
|
||||||
if (msg.sender == owner) selfdestruct(owner);
|
if (msg.sender == owner) selfdestruct(owner);
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ Details are given in the following example.
|
|||||||
|
|
||||||
// Here, we only specify `override` and not `virtual`.
|
// Here, we only specify `override` and not `virtual`.
|
||||||
// This means that contracts deriving from `PriceFeed`
|
// This means that contracts deriving from `PriceFeed`
|
||||||
// cannot change the behaviour of `destroy` anymore.
|
// cannot change the behavior of `destroy` anymore.
|
||||||
function destroy() public override(Destructible, Named) { Named.destroy(); }
|
function destroy() public override(Destructible, Named) { Named.destroy(); }
|
||||||
function get() public view returns(uint r) { return info; }
|
function get() public view returns(uint r) { return info; }
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ and ends at a contract mentioning a function with that signature
|
|||||||
that does not override.
|
that does not override.
|
||||||
|
|
||||||
If you do not mark a function that overrides as ``virtual``, derived
|
If you do not mark a function that overrides as ``virtual``, derived
|
||||||
contracts can no longer change the behaviour of that function.
|
contracts can no longer change the behavior of that function.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -436,11 +436,11 @@ You can use internal parameters in a constructor (for example storage pointers).
|
|||||||
the contract has to be marked :ref:`abstract <abstract-contract>`, because these parameters
|
the contract has to be marked :ref:`abstract <abstract-contract>`, because these parameters
|
||||||
cannot be assigned valid values from outside but only through the constructors of derived contracts.
|
cannot be assigned valid values from outside but only through the constructors of derived contracts.
|
||||||
|
|
||||||
.. warning ::
|
.. warning::
|
||||||
Prior to version 0.4.22, constructors were defined as functions with the same name as the contract.
|
Prior to version 0.4.22, constructors were defined as functions with the same name as the contract.
|
||||||
This syntax was deprecated and is not allowed anymore in version 0.5.0.
|
This syntax was deprecated and is not allowed anymore in version 0.5.0.
|
||||||
|
|
||||||
.. warning ::
|
.. warning::
|
||||||
Prior to version 0.7.0, you had to specify the visibility of constructors as either
|
Prior to version 0.7.0, you had to specify the visibility of constructors as either
|
||||||
``internal`` or ``public``.
|
``internal`` or ``public``.
|
||||||
|
|
||||||
@ -487,7 +487,7 @@ One way is directly in the inheritance list (``is Base(7)``). The other is in
|
|||||||
the way a modifier is invoked as part of
|
the way a modifier is invoked as part of
|
||||||
the derived constructor (``Base(y * y)``). The first way to
|
the derived constructor (``Base(y * y)``). The first way to
|
||||||
do it is more convenient if the constructor argument is a
|
do it is more convenient if the constructor argument is a
|
||||||
constant and defines the behaviour of the contract or
|
constant and defines the behavior of the contract or
|
||||||
describes it. The second way has to be used if the
|
describes it. The second way has to be used if the
|
||||||
constructor arguments of the base depend on those of the
|
constructor arguments of the base depend on those of the
|
||||||
derived contract. Arguments have to be given either in the
|
derived contract. Arguments have to be given either in the
|
||||||
|
@ -65,7 +65,7 @@ inheritance.
|
|||||||
Types defined inside interfaces and other contract-like structures
|
Types defined inside interfaces and other contract-like structures
|
||||||
can be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``.
|
can be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``.
|
||||||
|
|
||||||
.. warning:
|
.. warning::
|
||||||
|
|
||||||
Interfaces have supported ``enum`` types since :doc:`Solidity version 0.5.0 <050-breaking-changes>`, make
|
Interfaces have supported ``enum`` types since :doc:`Solidity version 0.5.0 <050-breaking-changes>`, make
|
||||||
sure the pragma version specifies this version as a minimum.
|
sure the pragma version specifies this version as a minimum.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.. index:: ! using for, library
|
.. index:: ! using for, library, ! operator;user-defined, function;free
|
||||||
|
|
||||||
.. _using-for:
|
.. _using-for:
|
||||||
|
|
||||||
@ -6,37 +6,87 @@
|
|||||||
Using For
|
Using For
|
||||||
*********
|
*********
|
||||||
|
|
||||||
The directive ``using A for B;`` can be used to attach
|
The directive ``using A for B`` can be used to attach
|
||||||
functions (``A``) as member functions to any type (``B``).
|
functions (``A``) as operators to user-defined value types
|
||||||
These functions will receive the object they are called on
|
or as member functions to any type (``B``).
|
||||||
|
The member functions receive the object they are called on
|
||||||
as their first parameter (like the ``self`` variable in Python).
|
as their first parameter (like the ``self`` variable in Python).
|
||||||
|
The operator functions receive operands as parameters.
|
||||||
|
|
||||||
It is valid either at file level or inside a contract,
|
It is valid either at file level or inside a contract,
|
||||||
at contract level.
|
at contract level.
|
||||||
|
|
||||||
The first part, ``A``, can be one of:
|
The first part, ``A``, can be one of:
|
||||||
|
|
||||||
- A list of file-level or library functions (e.g. ``using {f, g, h, L.t} for uint;``) -
|
- A list of functions, optionally with an operator name assigned (e.g.
|
||||||
only those functions will be attached to the type as member functions.
|
``using {f, g as +, h, L.t} for uint``).
|
||||||
Note that private library functions can only be specified when ``using for`` is inside the library.
|
If no operator is specified, the function can be either a library function or a free function and
|
||||||
- The name of a library (e.g. ``using L for uint;``) -
|
is attached to the type as a member function.
|
||||||
all non-private functions of the library are attached to the type.
|
Otherwise it must be a free function and it becomes the definition of that operator on the type.
|
||||||
|
- The name of a library (e.g. ``using L for uint``) -
|
||||||
|
all non-private functions of the library are attached to the type
|
||||||
|
as member functions
|
||||||
|
|
||||||
At file level, the second part, ``B``, has to be an explicit type (without data location specifier).
|
At file level, the second part, ``B``, has to be an explicit type (without data location specifier).
|
||||||
Inside contracts, you can also use ``*`` in place of the type (e.g. ``using L for *;``),
|
Inside contracts, you can also use ``*`` in place of the type (e.g. ``using L for *;``),
|
||||||
which has the effect that all functions of the library ``L``
|
which has the effect that all functions of the library ``L``
|
||||||
are attached to *all* types.
|
are attached to *all* types.
|
||||||
|
|
||||||
If you specify a library, *all* functions in the library get attached,
|
If you specify a library, *all* non-private functions in the library get attached,
|
||||||
even those where the type of the first parameter does not
|
even those where the type of the first parameter does not
|
||||||
match the type of the object. The type is checked at the
|
match the type of the object. The type is checked at the
|
||||||
point the function is called and function overload
|
point the function is called and function overload
|
||||||
resolution is performed.
|
resolution is performed.
|
||||||
|
|
||||||
If you use a list of functions (e.g. ``using {f, g, h, L.t} for uint;``),
|
If you use a list of functions (e.g. ``using {f, g, h, L.t} for uint``),
|
||||||
then the type (``uint``) has to be implicitly convertible to the
|
then the type (``uint``) has to be implicitly convertible to the
|
||||||
first parameter of each of these functions. This check is
|
first parameter of each of these functions. This check is
|
||||||
performed even if none of these functions are called.
|
performed even if none of these functions are called.
|
||||||
|
Note that private library functions can only be specified when ``using for`` is inside a library.
|
||||||
|
|
||||||
|
If you define an operator (e.g. ``using {f as +} for T``), then the type (``T``) must be a
|
||||||
|
:ref:`user-defined value type <user-defined-value-types>` and the definition must be a ``pure`` function.
|
||||||
|
Operator definitions must be global.
|
||||||
|
The following operators can be defined this way:
|
||||||
|
|
||||||
|
+------------+----------+---------------------------------------------+
|
||||||
|
| Category | Operator | Possible signatures |
|
||||||
|
+============+==========+=============================================+
|
||||||
|
| Bitwise | ``&`` | ``function (T, T) pure returns (T)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``|`` | ``function (T, T) pure returns (T)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``^`` | ``function (T, T) pure returns (T)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``~`` | ``function (T) pure returns (T)`` |
|
||||||
|
+------------+----------+---------------------------------------------+
|
||||||
|
| Arithmetic | ``+`` | ``function (T, T) pure returns (T)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``-`` | ``function (T, T) pure returns (T)`` |
|
||||||
|
| + +---------------------------------------------+
|
||||||
|
| | | ``function (T) pure returns (T)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``*`` | ``function (T, T) pure returns (T)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``/`` | ``function (T, T) pure returns (T)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``%`` | ``function (T, T) pure returns (T)`` |
|
||||||
|
+------------+----------+---------------------------------------------+
|
||||||
|
| Comparison | ``==`` | ``function (T, T) pure returns (bool)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``!=`` | ``function (T, T) pure returns (bool)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``<`` | ``function (T, T) pure returns (bool)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``<=`` | ``function (T, T) pure returns (bool)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``>`` | ``function (T, T) pure returns (bool)`` |
|
||||||
|
| +----------+---------------------------------------------+
|
||||||
|
| | ``>=`` | ``function (T, T) pure returns (bool)`` |
|
||||||
|
+------------+----------+---------------------------------------------+
|
||||||
|
|
||||||
|
Note that unary and binary ``-`` need separate definitions.
|
||||||
|
The compiler will choose the right definition based on how the operator is invoked.
|
||||||
|
|
||||||
The ``using A for B;`` directive is active only within the current
|
The ``using A for B;`` directive is active only within the current
|
||||||
scope (either the contract or the current module/source unit),
|
scope (either the contract or the current module/source unit),
|
||||||
@ -46,7 +96,7 @@ outside of the contract or module in which it is used.
|
|||||||
When the directive is used at file level and applied to a
|
When the directive is used at file level and applied to a
|
||||||
user-defined type which was defined at file level in the same file,
|
user-defined type which was defined at file level in the same file,
|
||||||
the word ``global`` can be added at the end. This will have the
|
the word ``global`` can be added at the end. This will have the
|
||||||
effect that the functions are attached to the type everywhere
|
effect that the functions and operators are attached to the type everywhere
|
||||||
the type is available (including other files), not only in the
|
the type is available (including other files), not only in the
|
||||||
scope of the using statement.
|
scope of the using statement.
|
||||||
|
|
||||||
@ -150,3 +200,37 @@ if you pass memory or value types, a copy will be performed, even in case of the
|
|||||||
``self`` variable. The only situation where no copy will be performed
|
``self`` variable. The only situation where no copy will be performed
|
||||||
is when storage reference variables are used or when internal library
|
is when storage reference variables are used or when internal library
|
||||||
functions are called.
|
functions are called.
|
||||||
|
|
||||||
|
Another example shows how to define a custom operator for a user-defined type:
|
||||||
|
|
||||||
|
.. code-block:: solidity
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
pragma solidity ^0.8.19;
|
||||||
|
|
||||||
|
type UFixed16x2 is uint16;
|
||||||
|
|
||||||
|
using {
|
||||||
|
add as +,
|
||||||
|
div as /
|
||||||
|
} for UFixed16x2 global;
|
||||||
|
|
||||||
|
uint32 constant SCALE = 100;
|
||||||
|
|
||||||
|
function add(UFixed16x2 a, UFixed16x2 b) pure returns (UFixed16x2) {
|
||||||
|
return UFixed16x2.wrap(UFixed16x2.unwrap(a) + UFixed16x2.unwrap(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
function div(UFixed16x2 a, UFixed16x2 b) pure returns (UFixed16x2) {
|
||||||
|
uint32 a32 = UFixed16x2.unwrap(a);
|
||||||
|
uint32 b32 = UFixed16x2.unwrap(b);
|
||||||
|
uint32 result32 = a32 * SCALE / b32;
|
||||||
|
require(result32 <= type(uint16).max, "Divide overflow");
|
||||||
|
return UFixed16x2.wrap(uint16(a32 * SCALE / b32));
|
||||||
|
}
|
||||||
|
|
||||||
|
contract Math {
|
||||||
|
function avg(UFixed16x2 a, UFixed16x2 b) public pure returns (UFixed16x2) {
|
||||||
|
return (a + b) / UFixed16x2.wrap(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -200,12 +200,12 @@ The next example is more complex:
|
|||||||
struct Data {
|
struct Data {
|
||||||
uint a;
|
uint a;
|
||||||
bytes3 b;
|
bytes3 b;
|
||||||
mapping (uint => uint) map;
|
mapping(uint => uint) map;
|
||||||
uint[3] c;
|
uint[3] c;
|
||||||
uint[] d;
|
uint[] d;
|
||||||
bytes e;
|
bytes e;
|
||||||
}
|
}
|
||||||
mapping (uint => mapping(bool => Data[])) public data;
|
mapping(uint => mapping(bool => Data[])) public data;
|
||||||
}
|
}
|
||||||
|
|
||||||
It generates a function of the following form. The mapping and arrays (with the
|
It generates a function of the following form. The mapping and arrays (with the
|
||||||
|
@ -28,11 +28,11 @@ Team Calls
|
|||||||
==========
|
==========
|
||||||
|
|
||||||
If you have issues or pull requests to discuss, or are interested in hearing what
|
If you have issues or pull requests to discuss, or are interested in hearing what
|
||||||
the team and contributors are working on, you can join our public team calls:
|
the team and contributors are working on, you can join our public team call:
|
||||||
|
|
||||||
- Mondays and Wednesdays at 3PM CET/CEST.
|
- Wednesdays at 3PM CET/CEST.
|
||||||
|
|
||||||
Both calls take place on `Jitsi <https://meet.soliditylang.org/>`_.
|
The call takes place on `Jitsi <https://meet.soliditylang.org/>`_.
|
||||||
|
|
||||||
How to Report Issues
|
How to Report Issues
|
||||||
====================
|
====================
|
||||||
@ -45,7 +45,7 @@ reporting issues, please mention the following details:
|
|||||||
* Source code (if applicable).
|
* Source code (if applicable).
|
||||||
* Operating system.
|
* Operating system.
|
||||||
* Steps to reproduce the issue.
|
* Steps to reproduce the issue.
|
||||||
* Actual vs. expected behaviour.
|
* Actual vs. expected behavior.
|
||||||
|
|
||||||
Reducing the source code that caused the issue to a bare minimum is always
|
Reducing the source code that caused the issue to a bare minimum is always
|
||||||
very helpful, and sometimes even clarifies a misunderstanding.
|
very helpful, and sometimes even clarifies a misunderstanding.
|
||||||
@ -93,8 +93,7 @@ Prerequisites
|
|||||||
|
|
||||||
For running all compiler tests you may want to optionally install a few
|
For running all compiler tests you may want to optionally install a few
|
||||||
dependencies (`evmone <https://github.com/ethereum/evmone/releases>`_,
|
dependencies (`evmone <https://github.com/ethereum/evmone/releases>`_,
|
||||||
`libz3 <https://github.com/Z3Prover/z3>`_, and
|
`libz3 <https://github.com/Z3Prover/z3>`_).
|
||||||
`libhera <https://github.com/ewasm/hera>`_).
|
|
||||||
|
|
||||||
On macOS systems, some of the testing scripts expect GNU coreutils to be installed.
|
On macOS systems, some of the testing scripts expect GNU coreutils to be installed.
|
||||||
This can be easiest accomplished using Homebrew: ``brew install coreutils``.
|
This can be easiest accomplished using Homebrew: ``brew install coreutils``.
|
||||||
@ -115,7 +114,7 @@ Running ``build/test/soltest`` or its wrapper ``scripts/soltest.sh`` is sufficie
|
|||||||
|
|
||||||
The ``./scripts/tests.sh`` script executes most Solidity tests automatically,
|
The ``./scripts/tests.sh`` script executes most Solidity tests automatically,
|
||||||
including those bundled into the `Boost C++ Test Framework <https://www.boost.org/doc/libs/release/libs/test/doc/html/index.html>`_
|
including those bundled into the `Boost C++ Test Framework <https://www.boost.org/doc/libs/release/libs/test/doc/html/index.html>`_
|
||||||
application ``soltest`` (or its wrapper ``scripts/soltest.sh``), as well as command line tests and
|
application ``soltest`` (or its wrapper ``scripts/soltest.sh``), as well as command-line tests and
|
||||||
compilation tests.
|
compilation tests.
|
||||||
|
|
||||||
The test system automatically tries to discover the location of
|
The test system automatically tries to discover the location of
|
||||||
@ -129,13 +128,7 @@ for the ``evmone`` shared object can be specified via the ``ETH_EVMONE`` environ
|
|||||||
If you do not have it installed, you can skip these tests by passing the ``--no-semantic-tests``
|
If you do not have it installed, you can skip these tests by passing the ``--no-semantic-tests``
|
||||||
flag to ``scripts/soltest.sh``.
|
flag to ``scripts/soltest.sh``.
|
||||||
|
|
||||||
Running Ewasm tests is disabled by default and can be explicitly enabled
|
The ``evmone`` library should both end with the file name
|
||||||
via ``./scripts/soltest.sh --ewasm`` and requires `hera <https://github.com/ewasm/hera>`_
|
|
||||||
to be found by ``soltest``.
|
|
||||||
The mechanism for locating the ``hera`` library is the same as for ``evmone``, except that the
|
|
||||||
variable for specifying an explicit location is called ``ETH_HERA``.
|
|
||||||
|
|
||||||
The ``evmone`` and ``hera`` libraries should both end with the file name
|
|
||||||
extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS.
|
extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS.
|
||||||
|
|
||||||
For running SMT tests, the ``libz3`` library must be installed and locatable
|
For running SMT tests, the ``libz3`` library must be installed and locatable
|
||||||
@ -146,7 +139,7 @@ SMT tests by exporting ``SMT_FLAGS=--no-smt`` before running ``./scripts/tests.s
|
|||||||
running ``./scripts/soltest.sh --no-smt``.
|
running ``./scripts/soltest.sh --no-smt``.
|
||||||
These tests are ``libsolidity/smtCheckerTests`` and ``libsolidity/smtCheckerTestsJSON``.
|
These tests are ``libsolidity/smtCheckerTests`` and ``libsolidity/smtCheckerTestsJSON``.
|
||||||
|
|
||||||
.. note ::
|
.. note::
|
||||||
|
|
||||||
To get a list of all unit tests run by Soltest, run ``./build/test/soltest --list_content=HRF``.
|
To get a list of all unit tests run by Soltest, run ``./build/test/soltest --list_content=HRF``.
|
||||||
|
|
||||||
@ -167,7 +160,7 @@ See especially:
|
|||||||
- `run_test (-t) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/run_test.html>`_ to run specific tests cases, and
|
- `run_test (-t) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/run_test.html>`_ to run specific tests cases, and
|
||||||
- `report-level (-r) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/report_level.html>`_ give a more detailed report.
|
- `report-level (-r) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/report_level.html>`_ give a more detailed report.
|
||||||
|
|
||||||
.. note ::
|
.. note::
|
||||||
|
|
||||||
Those working in a Windows environment wanting to run the above basic sets
|
Those working in a Windows environment wanting to run the above basic sets
|
||||||
without libz3. Using Git Bash, you use: ``./build/test/Release/soltest.exe -- --no-smt``.
|
without libz3. Using Git Bash, you use: ``./build/test/Release/soltest.exe -- --no-smt``.
|
||||||
@ -175,6 +168,7 @@ See especially:
|
|||||||
|
|
||||||
If you want to debug using GDB, make sure you build differently than the "usual".
|
If you want to debug using GDB, make sure you build differently than the "usual".
|
||||||
For example, you could run the following command in your ``build`` folder:
|
For example, you could run the following command in your ``build`` folder:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
@ -245,7 +239,7 @@ provides a way to edit, update or skip the current contract file, or quit the ap
|
|||||||
|
|
||||||
It offers several options for failing tests:
|
It offers several options for failing tests:
|
||||||
|
|
||||||
- ``edit``: ``isoltest`` tries to open the contract in an editor so you can adjust it. It either uses the editor given on the command line (as ``isoltest --editor /path/to/editor``), in the environment variable ``EDITOR`` or just ``/usr/bin/editor`` (in that order).
|
- ``edit``: ``isoltest`` tries to open the contract in an editor so you can adjust it. It either uses the editor given on the command-line (as ``isoltest --editor /path/to/editor``), in the environment variable ``EDITOR`` or just ``/usr/bin/editor`` (in that order).
|
||||||
- ``update``: Updates the expectations for contract under test. This updates the annotations by removing unmet expectations and adding missing expectations. The test is then run again.
|
- ``update``: Updates the expectations for contract under test. This updates the annotations by removing unmet expectations and adding missing expectations. The test is then run again.
|
||||||
- ``skip``: Skips the execution of this particular test.
|
- ``skip``: Skips the execution of this particular test.
|
||||||
- ``quit``: Quits ``isoltest``.
|
- ``quit``: Quits ``isoltest``.
|
||||||
@ -275,6 +269,62 @@ and re-run the test. It now passes again:
|
|||||||
Do not put more than one contract into a single file, unless you are testing inheritance or cross-contract calls.
|
Do not put more than one contract into a single file, unless you are testing inheritance or cross-contract calls.
|
||||||
Each file should test one aspect of your new feature.
|
Each file should test one aspect of your new feature.
|
||||||
|
|
||||||
|
Command-line Tests
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Our suite of end-to-end command-line tests checks the behaviour of the compiler binary as a whole
|
||||||
|
in various scenarios.
|
||||||
|
These tests are located in `test/cmdlineTests/ <https://github.com/ethereum/solidity/tree/develop/test/cmdlineTests>`_,
|
||||||
|
one per subdirectory, and can be executed using the ``cmdlineTests.sh`` script.
|
||||||
|
|
||||||
|
By default the script runs all available tests.
|
||||||
|
You can also provide one or more `file name patterns <https://www.gnu.org/software/bash/manual/bash.html#Filename-Expansion>`_,
|
||||||
|
in which case only the tests matching at least one pattern will be executed.
|
||||||
|
It is also possible to exclude files matching a specific pattern by prefixing it with ``--exclude``.
|
||||||
|
|
||||||
|
By default the script assumes that a ``solc`` binary is available inside the ``build/`` subdirectory
|
||||||
|
inside the working copy.
|
||||||
|
If you build the compiler outside of the source tree, you can use the ``SOLIDITY_BUILD_DIR`` environment
|
||||||
|
variable to specify a different location for the build directory.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
export SOLIDITY_BUILD_DIR=~/solidity/build/
|
||||||
|
test/cmdlineTests.sh "standard_*" "*_yul_*" --exclude "standard_yul_*"
|
||||||
|
|
||||||
|
The commands above will run tests from directories starting with ``test/cmdlineTests/standard_`` and
|
||||||
|
subdirectories of ``test/cmdlineTests/`` that have ``_yul_`` somewhere in the name,
|
||||||
|
but no test whose name starts with ``standard_yul_`` will be executed.
|
||||||
|
It will also assume that the file ``solidity/build/solc/solc`` inside your home directory is the
|
||||||
|
compiler binary (unless you are on Windows -- then ``solidity/build/solc/Release/solc.exe``).
|
||||||
|
|
||||||
|
There are several kinds of command-line tests:
|
||||||
|
|
||||||
|
- *Standard JSON test*: contains at least an ``input.json`` file.
|
||||||
|
In general may contain:
|
||||||
|
|
||||||
|
- ``input.json``: input file to be passed to the ``--standard-json`` option on the command line.
|
||||||
|
- ``output.json``: expected Standard JSON output.
|
||||||
|
- ``args``: extra command-line arguments passed to ``solc``.
|
||||||
|
|
||||||
|
- *CLI test*: contains at least an ``input.*`` file (other than ``input.json``).
|
||||||
|
In general may contain:
|
||||||
|
|
||||||
|
- ``input.*``: a single input file, whose name will be supplied to ``solc`` on the command line.
|
||||||
|
Usually ``input.sol`` or ``input.yul``.
|
||||||
|
- ``args``: extra command-line arguments passed to ``solc``.
|
||||||
|
- ``stdin``: content to be passed to ``solc`` via standard input.
|
||||||
|
- ``output``: expected content of the standard output.
|
||||||
|
- ``err``: expected content of the standard error output.
|
||||||
|
- ``exit``: expected exit code. If not provided, zero is expected.
|
||||||
|
|
||||||
|
- *Script test*: contains a ``test.*`` file.
|
||||||
|
In general may contain:
|
||||||
|
|
||||||
|
- ``test.*``: a single script to run, usually ``test.sh`` or ``test.py``.
|
||||||
|
The script must be executable.
|
||||||
|
|
||||||
Running the Fuzzer via AFL
|
Running the Fuzzer via AFL
|
||||||
==========================
|
==========================
|
||||||
@ -356,7 +406,7 @@ The AFL documentation states that the corpus (the initial input files) should no
|
|||||||
too large. The files themselves should not be larger than 1 kB and there should be
|
too large. The files themselves should not be larger than 1 kB and there should be
|
||||||
at most one input file per functionality, so better start with a small number of.
|
at most one input file per functionality, so better start with a small number of.
|
||||||
There is also a tool called ``afl-cmin`` that can trim input files
|
There is also a tool called ``afl-cmin`` that can trim input files
|
||||||
that result in similar behaviour of the binary.
|
that result in similar behavior of the binary.
|
||||||
|
|
||||||
Now run the fuzzer (the ``-m`` extends the size of memory to 60 MB):
|
Now run the fuzzer (the ``-m`` extends the size of memory to 60 MB):
|
||||||
|
|
||||||
@ -403,13 +453,12 @@ contributions to Solidity.
|
|||||||
English Language
|
English Language
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Use English, with British English spelling preferred, unless using project or brand names. Try to reduce the usage of
|
Use International English, unless using project or brand names. Try to reduce the usage of
|
||||||
local slang and references, making your language as clear to all readers as possible. Below are some references to help:
|
local slang and references, making your language as clear to all readers as possible.
|
||||||
|
Below are some references to help:
|
||||||
|
|
||||||
* `Simplified technical English <https://en.wikipedia.org/wiki/Simplified_Technical_English>`_
|
* `Simplified technical English <https://en.wikipedia.org/wiki/Simplified_Technical_English>`_
|
||||||
* `International English <https://en.wikipedia.org/wiki/International_English>`_
|
* `International English <https://en.wikipedia.org/wiki/International_English>`_
|
||||||
* `British English spelling <https://web.archive.org/web/20220324094038/https://www.lexico.com/grammar/british-and-spelling>`_
|
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -173,7 +173,6 @@ parameters from the function declaration, but can be in arbitrary order.
|
|||||||
function set(uint key, uint value) public {
|
function set(uint key, uint value) public {
|
||||||
data[key] = value;
|
data[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Omitted Names in Function Definitions
|
Omitted Names in Function Definitions
|
||||||
@ -366,13 +365,13 @@ i.e. the following is not valid: ``(x, uint y) = (1, 2);``
|
|||||||
.. warning::
|
.. warning::
|
||||||
Be careful when assigning to multiple variables at the same time when
|
Be careful when assigning to multiple variables at the same time when
|
||||||
reference types are involved, because it could lead to unexpected
|
reference types are involved, because it could lead to unexpected
|
||||||
copying behaviour.
|
copying behavior.
|
||||||
|
|
||||||
Complications for Arrays and Structs
|
Complications for Arrays and Structs
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
The semantics of assignments are more complicated for non-value types like arrays and structs,
|
The semantics of assignments are more complicated for non-value types like arrays and structs,
|
||||||
including ``bytes`` and ``string``, see :ref:`Data location and assignment behaviour <data-location-assignment>` for details.
|
including ``bytes`` and ``string``, see :ref:`Data location and assignment behavior <data-location-assignment>` for details.
|
||||||
|
|
||||||
In the example below the call to ``g(x)`` has no effect on ``x`` because it creates
|
In the example below the call to ``g(x)`` has no effect on ``x`` because it creates
|
||||||
an independent copy of the storage value in memory. However, ``h(x)`` successfully modifies ``x``
|
an independent copy of the storage value in memory. However, ``h(x)`` successfully modifies ``x``
|
||||||
@ -511,7 +510,7 @@ additional checks.
|
|||||||
Since Solidity 0.8.0, all arithmetic operations revert on over- and underflow by default,
|
Since Solidity 0.8.0, all arithmetic operations revert on over- and underflow by default,
|
||||||
thus making the use of these libraries unnecessary.
|
thus making the use of these libraries unnecessary.
|
||||||
|
|
||||||
To obtain the previous behaviour, an ``unchecked`` block can be used:
|
To obtain the previous behavior, an ``unchecked`` block can be used:
|
||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
@ -651,7 +650,7 @@ in the following situations:
|
|||||||
|
|
||||||
For the following cases, the error data from the external call
|
For the following cases, the error data from the external call
|
||||||
(if provided) is forwarded. This means that it can either cause
|
(if provided) is forwarded. This means that it can either cause
|
||||||
an `Error` or a `Panic` (or whatever else was given):
|
an ``Error`` or a ``Panic`` (or whatever else was given):
|
||||||
|
|
||||||
#. If a ``.transfer()`` fails.
|
#. If a ``.transfer()`` fails.
|
||||||
#. If you call a function via a message call but it does not finish
|
#. If you call a function via a message call but it does not finish
|
||||||
@ -686,7 +685,7 @@ and ``assert`` for internal error checking.
|
|||||||
addr.transfer(msg.value / 2);
|
addr.transfer(msg.value / 2);
|
||||||
// Since transfer throws an exception on failure and
|
// Since transfer throws an exception on failure and
|
||||||
// cannot call back here, there should be no way for us to
|
// cannot call back here, there should be no way for us to
|
||||||
// still have half of the money.
|
// still have half of the Ether.
|
||||||
assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);
|
assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);
|
||||||
return address(this).balance;
|
return address(this).balance;
|
||||||
}
|
}
|
||||||
@ -720,7 +719,7 @@ The ``revert`` statement takes a custom error as direct argument without parenth
|
|||||||
|
|
||||||
revert CustomError(arg1, arg2);
|
revert CustomError(arg1, arg2);
|
||||||
|
|
||||||
For backwards-compatibility reasons, there is also the ``revert()`` function, which uses parentheses
|
For backward-compatibility reasons, there is also the ``revert()`` function, which uses parentheses
|
||||||
and accepts a string:
|
and accepts a string:
|
||||||
|
|
||||||
revert();
|
revert();
|
||||||
|
@ -16,11 +16,11 @@ Simple Open Auction
|
|||||||
===================
|
===================
|
||||||
|
|
||||||
The general idea of the following simple auction contract is that everyone can
|
The general idea of the following simple auction contract is that everyone can
|
||||||
send their bids during a bidding period. The bids already include sending money
|
send their bids during a bidding period. The bids already include sending some compensation,
|
||||||
/ Ether in order to bind the bidders to their bid. If the highest bid is
|
e.g. Ether, in order to bind the bidders to their bid. If the highest bid is
|
||||||
raised, the previous highest bidder gets their money back. After the end of
|
raised, the previous highest bidder gets their Ether back. After the end of
|
||||||
the bidding period, the contract has to be called manually for the beneficiary
|
the bidding period, the contract has to be called manually for the beneficiary
|
||||||
to receive their money - contracts cannot activate themselves.
|
to receive their Ether - contracts cannot activate themselves.
|
||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
@ -92,19 +92,19 @@ to receive their money - contracts cannot activate themselves.
|
|||||||
revert AuctionAlreadyEnded();
|
revert AuctionAlreadyEnded();
|
||||||
|
|
||||||
// If the bid is not higher, send the
|
// If the bid is not higher, send the
|
||||||
// money back (the revert statement
|
// Ether back (the revert statement
|
||||||
// will revert all changes in this
|
// will revert all changes in this
|
||||||
// function execution including
|
// function execution including
|
||||||
// it having received the money).
|
// it having received the Ether).
|
||||||
if (msg.value <= highestBid)
|
if (msg.value <= highestBid)
|
||||||
revert BidNotHighEnough(highestBid);
|
revert BidNotHighEnough(highestBid);
|
||||||
|
|
||||||
if (highestBid != 0) {
|
if (highestBid != 0) {
|
||||||
// Sending back the money by simply using
|
// Sending back the Ether by simply using
|
||||||
// highestBidder.send(highestBid) is a security risk
|
// highestBidder.send(highestBid) is a security risk
|
||||||
// because it could execute an untrusted contract.
|
// because it could execute an untrusted contract.
|
||||||
// It is always safer to let the recipients
|
// It is always safer to let the recipients
|
||||||
// withdraw their money themselves.
|
// withdraw their Ether themselves.
|
||||||
pendingReturns[highestBidder] += highestBid;
|
pendingReturns[highestBidder] += highestBid;
|
||||||
}
|
}
|
||||||
highestBidder = msg.sender;
|
highestBidder = msg.sender;
|
||||||
@ -182,7 +182,7 @@ the contract checks that the hash value is the same as the one provided during
|
|||||||
the bidding period.
|
the bidding period.
|
||||||
|
|
||||||
Another challenge is how to make the auction **binding and blind** at the same
|
Another challenge is how to make the auction **binding and blind** at the same
|
||||||
time: The only way to prevent the bidder from just not sending the money after
|
time: The only way to prevent the bidder from just not sending the Ether after
|
||||||
they won the auction is to make them send it together with the bid. Since value
|
they won the auction is to make them send it together with the bid. Since value
|
||||||
transfers cannot be blinded in Ethereum, anyone can see the value.
|
transfers cannot be blinded in Ethereum, anyone can see the value.
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ Packing arguments
|
|||||||
Now that we have identified what information to include in the signed message,
|
Now that we have identified what information to include in the signed message,
|
||||||
we are ready to put the message together, hash it, and sign it. For simplicity,
|
we are ready to put the message together, hash it, and sign it. For simplicity,
|
||||||
we concatenate the data. The `ethereumjs-abi <https://github.com/ethereumjs/ethereumjs-abi>`_
|
we concatenate the data. The `ethereumjs-abi <https://github.com/ethereumjs/ethereumjs-abi>`_
|
||||||
library provides a function called ``soliditySHA3`` that mimics the behaviour of
|
library provides a function called ``soliditySHA3`` that mimics the behavior of
|
||||||
Solidity's ``keccak256`` function applied to arguments encoded using ``abi.encodePacked``.
|
Solidity's ``keccak256`` function applied to arguments encoded using ``abi.encodePacked``.
|
||||||
Here is a JavaScript function that creates the proper signature for the ``ReceiverPays`` example:
|
Here is a JavaScript function that creates the proper signature for the ``ReceiverPays`` example:
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ Modular Contracts
|
|||||||
A modular approach to building your contracts helps you reduce the complexity
|
A modular approach to building your contracts helps you reduce the complexity
|
||||||
and improve the readability which will help to identify bugs and vulnerabilities
|
and improve the readability which will help to identify bugs and vulnerabilities
|
||||||
during development and code review.
|
during development and code review.
|
||||||
If you specify and control the behaviour of each module in isolation, the
|
If you specify and control the behavior of each module in isolation, the
|
||||||
interactions you have to consider are only those between the module specifications
|
interactions you have to consider are only those between the module specifications
|
||||||
and not every other moving part of the contract.
|
and not every other moving part of the contract.
|
||||||
In the example below, the contract uses the ``move`` method
|
In the example below, the contract uses the ``move`` method
|
||||||
@ -34,7 +34,7 @@ and the sum of all balances is an invariant across the lifetime of the contract.
|
|||||||
contract Token {
|
contract Token {
|
||||||
mapping(address => uint256) balances;
|
mapping(address => uint256) balances;
|
||||||
using Balances for *;
|
using Balances for *;
|
||||||
mapping(address => mapping (address => uint256)) allowed;
|
mapping(address => mapping(address => uint256)) allowed;
|
||||||
|
|
||||||
event Transfer(address from, address to, uint amount);
|
event Transfer(address from, address to, uint amount);
|
||||||
event Approval(address owner, address spender, uint amount);
|
event Approval(address owner, address spender, uint amount);
|
||||||
|
@ -6,18 +6,18 @@ Safe Remote Purchase
|
|||||||
|
|
||||||
Purchasing goods remotely currently requires multiple parties that need to trust each other.
|
Purchasing goods remotely currently requires multiple parties that need to trust each other.
|
||||||
The simplest configuration involves a seller and a buyer. The buyer would like to receive
|
The simplest configuration involves a seller and a buyer. The buyer would like to receive
|
||||||
an item from the seller and the seller would like to get money (or an equivalent)
|
an item from the seller and the seller would like to get some compensation, e.g. Ether,
|
||||||
in return. The problematic part is the shipment here: There is no way to determine for
|
in return. The problematic part is the shipment here: There is no way to determine for
|
||||||
sure that the item arrived at the buyer.
|
sure that the item arrived at the buyer.
|
||||||
|
|
||||||
There are multiple ways to solve this problem, but all fall short in one or the other way.
|
There are multiple ways to solve this problem, but all fall short in one or the other way.
|
||||||
In the following example, both parties have to put twice the value of the item into the
|
In the following example, both parties have to put twice the value of the item into the
|
||||||
contract as escrow. As soon as this happened, the money will stay locked inside
|
contract as escrow. As soon as this happened, the Ether will stay locked inside
|
||||||
the contract until the buyer confirms that they received the item. After that,
|
the contract until the buyer confirms that they received the item. After that,
|
||||||
the buyer is returned the value (half of their deposit) and the seller gets three
|
the buyer is returned the value (half of their deposit) and the seller gets three
|
||||||
times the value (their deposit plus the value). The idea behind
|
times the value (their deposit plus the value). The idea behind
|
||||||
this is that both parties have an incentive to resolve the situation or otherwise
|
this is that both parties have an incentive to resolve the situation or otherwise
|
||||||
their money is locked forever.
|
their Ether is locked forever.
|
||||||
|
|
||||||
This contract of course does not solve the problem, but gives an overview of how
|
This contract of course does not solve the problem, but gives an overview of how
|
||||||
you can use state machine-like constructs inside a contract.
|
you can use state machine-like constructs inside a contract.
|
||||||
|
@ -22,23 +22,16 @@ def remix_code_url(source_code, language, solidity_version):
|
|||||||
# NOTE: base64 encoded data may contain +, = and / characters. Remix seems to handle them just
|
# NOTE: base64 encoded data may contain +, = and / characters. Remix seems to handle them just
|
||||||
# fine without any escaping.
|
# fine without any escaping.
|
||||||
base64_encoded_source = base64.b64encode(source_code.encode('utf-8')).decode('ascii')
|
base64_encoded_source = base64.b64encode(source_code.encode('utf-8')).decode('ascii')
|
||||||
return f"https://remix.ethereum.org/?language={language}&version={solidity_version}&code={base64_encoded_source}"
|
return f"https://remix.ethereum.org/?#language={language}&version={solidity_version}&code={base64_encoded_source}"
|
||||||
|
|
||||||
|
|
||||||
def build_remix_link_node(url):
|
def build_remix_link_node(url):
|
||||||
link_icon_node = docutils.nodes.inline()
|
reference_node = docutils.nodes.reference('', 'open in Remix', internal=False, refuri=url, target='_blank')
|
||||||
link_icon_node.set_class('link-icon')
|
|
||||||
|
|
||||||
link_text_node = docutils.nodes.inline(text="open in Remix")
|
|
||||||
link_text_node.set_class('link-text')
|
|
||||||
|
|
||||||
reference_node = docutils.nodes.reference('', '', internal=False, refuri=url)
|
|
||||||
reference_node.set_class('remix-link')
|
reference_node.set_class('remix-link')
|
||||||
reference_node += [link_icon_node, link_text_node]
|
|
||||||
|
|
||||||
paragraph_node = docutils.nodes.paragraph()
|
paragraph_node = docutils.nodes.paragraph()
|
||||||
paragraph_node.set_class('remix-link-container')
|
paragraph_node.set_class('remix-link-container')
|
||||||
paragraph_node += reference_node
|
paragraph_node.append(reference_node)
|
||||||
return paragraph_node
|
return paragraph_node
|
||||||
|
|
||||||
|
|
||||||
@ -49,22 +42,24 @@ def insert_remix_link(app, doctree, solidity_version):
|
|||||||
for literal_block_node in doctree.traverse(docutils.nodes.literal_block):
|
for literal_block_node in doctree.traverse(docutils.nodes.literal_block):
|
||||||
assert 'language' in literal_block_node.attributes
|
assert 'language' in literal_block_node.attributes
|
||||||
language = literal_block_node.attributes['language'].lower()
|
language = literal_block_node.attributes['language'].lower()
|
||||||
if language in ['solidity', 'yul']:
|
if language not in ['solidity', 'yul']:
|
||||||
text_nodes = list(literal_block_node.traverse(docutils.nodes.Text))
|
continue
|
||||||
assert len(text_nodes) == 1
|
|
||||||
|
|
||||||
remix_url = remix_code_url(text_nodes[0], language, solidity_version)
|
text_nodes = list(literal_block_node.traverse(docutils.nodes.Text))
|
||||||
url_length = len(remix_url.encode('utf-8'))
|
assert len(text_nodes) == 1
|
||||||
if url_length > MAX_SAFE_URL_LENGTH:
|
|
||||||
logger.warning(
|
|
||||||
"Remix URL generated from the code snippet exceeds the maximum safe URL length "
|
|
||||||
" (%d > %d bytes).",
|
|
||||||
url_length,
|
|
||||||
MAX_SAFE_URL_LENGTH,
|
|
||||||
location=(literal_block_node.source, literal_block_node.line),
|
|
||||||
)
|
|
||||||
|
|
||||||
insert_node_before(literal_block_node, build_remix_link_node(remix_url))
|
remix_url = remix_code_url(text_nodes[0], language, solidity_version)
|
||||||
|
url_length = len(remix_url.encode('utf-8'))
|
||||||
|
if url_length > MAX_SAFE_URL_LENGTH:
|
||||||
|
logger.warning(
|
||||||
|
"Remix URL generated from the code snippet exceeds the maximum safe URL length "
|
||||||
|
" (%d > %d bytes).",
|
||||||
|
url_length,
|
||||||
|
MAX_SAFE_URL_LENGTH,
|
||||||
|
location=(literal_block_node.source, literal_block_node.line),
|
||||||
|
)
|
||||||
|
|
||||||
|
insert_node_before(literal_block_node, build_remix_link_node(remix_url))
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
@ -62,7 +62,7 @@ New: 'new';
|
|||||||
/**
|
/**
|
||||||
* Unit denomination for numbers.
|
* Unit denomination for numbers.
|
||||||
*/
|
*/
|
||||||
NumberUnit: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years';
|
SubDenomination: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years';
|
||||||
Override: 'override';
|
Override: 'override';
|
||||||
Payable: 'payable';
|
Payable: 'payable';
|
||||||
Pragma: 'pragma' -> pushMode(PragmaMode);
|
Pragma: 'pragma' -> pushMode(PragmaMode);
|
||||||
@ -90,6 +90,7 @@ Try: 'try';
|
|||||||
Type: 'type';
|
Type: 'type';
|
||||||
Ufixed: 'ufixed' | ('ufixed' [1-9][0-9]+ 'x' [1-9][0-9]+);
|
Ufixed: 'ufixed' | ('ufixed' [1-9][0-9]+ 'x' [1-9][0-9]+);
|
||||||
Unchecked: 'unchecked';
|
Unchecked: 'unchecked';
|
||||||
|
Unicode: 'unicode';
|
||||||
/**
|
/**
|
||||||
* Sized unsigned integer types.
|
* Sized unsigned integer types.
|
||||||
* uint is an alias of uint256.
|
* uint is an alias of uint256.
|
||||||
@ -198,9 +199,7 @@ fragment EscapeSequence:
|
|||||||
/**
|
/**
|
||||||
* A single quoted string literal allowing arbitrary unicode characters.
|
* A single quoted string literal allowing arbitrary unicode characters.
|
||||||
*/
|
*/
|
||||||
UnicodeStringLiteral:
|
UnicodeStringLiteral: 'unicode' (('"' DoubleQuotedUnicodeStringCharacter* '"') | ('\'' SingleQuotedUnicodeStringCharacter* '\''));
|
||||||
'unicode"' DoubleQuotedUnicodeStringCharacter* '"'
|
|
||||||
| 'unicode\'' SingleQuotedUnicodeStringCharacter* '\'';
|
|
||||||
//@doc:inline
|
//@doc:inline
|
||||||
fragment DoubleQuotedUnicodeStringCharacter: ~["\r\n\\] | EscapeSequence;
|
fragment DoubleQuotedUnicodeStringCharacter: ~["\r\n\\] | EscapeSequence;
|
||||||
//@doc:inline
|
//@doc:inline
|
||||||
@ -222,6 +221,14 @@ fragment EvenHexDigits: HexCharacter HexCharacter ('_'? HexCharacter HexCharacte
|
|||||||
//@doc:inline
|
//@doc:inline
|
||||||
fragment HexCharacter: [0-9A-Fa-f];
|
fragment HexCharacter: [0-9A-Fa-f];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scanned but not used by any rule, i.e, disallowed.
|
||||||
|
* solc parser considers number starting with '0', not immediately followed by '.' or 'x' as
|
||||||
|
* octal, even if non octal digits '8' and '9' are present.
|
||||||
|
*/
|
||||||
|
OctalNumber: '0' DecimalDigits ('.' DecimalDigits)?;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A decimal number literal consists of decimal digits that may be delimited by underscores and
|
* A decimal number literal consists of decimal digits that may be delimited by underscores and
|
||||||
* an optional positive or negative exponent.
|
* an optional positive or negative exponent.
|
||||||
@ -232,6 +239,12 @@ DecimalNumber: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? D
|
|||||||
fragment DecimalDigits: [0-9] ('_'? [0-9])* ;
|
fragment DecimalDigits: [0-9] ('_'? [0-9])* ;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is needed to avoid successfully parsing a number followed by a string with no whitespace between.
|
||||||
|
*/
|
||||||
|
DecimalNumberFollowedByIdentifier: DecimalNumber Identifier;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An identifier in solidity has to start with a letter, a dollar-sign or an underscore and
|
* An identifier in solidity has to start with a letter, a dollar-sign or an underscore and
|
||||||
* may additionally contain numbers after the first symbol.
|
* may additionally contain numbers after the first symbol.
|
||||||
|
@ -22,6 +22,7 @@ sourceUnit: (
|
|||||||
| enumDefinition
|
| enumDefinition
|
||||||
| userDefinedValueTypeDefinition
|
| userDefinedValueTypeDefinition
|
||||||
| errorDefinition
|
| errorDefinition
|
||||||
|
| eventDefinition
|
||||||
)* EOF;
|
)* EOF;
|
||||||
|
|
||||||
//@doc: inline
|
//@doc: inline
|
||||||
@ -152,7 +153,7 @@ stateMutability: Pure | View | Payable;
|
|||||||
*/
|
*/
|
||||||
overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=identifierPath)* RParen)?;
|
overrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=identifierPath)* RParen)?;
|
||||||
/**
|
/**
|
||||||
* The definition of contract, library and interface functions.
|
* The definition of contract, library, interface or free functions.
|
||||||
* Depending on the context in which the function is defined, further restrictions may apply,
|
* Depending on the context in which the function is defined, further restrictions may apply,
|
||||||
* e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block.
|
* e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block.
|
||||||
*/
|
*/
|
||||||
@ -161,7 +162,7 @@ locals[
|
|||||||
boolean visibilitySet = false,
|
boolean visibilitySet = false,
|
||||||
boolean mutabilitySet = false,
|
boolean mutabilitySet = false,
|
||||||
boolean virtualSet = false,
|
boolean virtualSet = false,
|
||||||
boolean overrideSpecifierSet = false
|
boolean overrideSpecifierSet = false,
|
||||||
]
|
]
|
||||||
:
|
:
|
||||||
Function (identifier | Fallback | Receive)
|
Function (identifier | Fallback | Receive)
|
||||||
@ -175,6 +176,7 @@ locals[
|
|||||||
)*
|
)*
|
||||||
(Returns LParen returnParameters=parameterList RParen)?
|
(Returns LParen returnParameters=parameterList RParen)?
|
||||||
(Semicolon | body=block);
|
(Semicolon | body=block);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The definition of a modifier.
|
* The definition of a modifier.
|
||||||
* Note that within the body block of a modifier, the underscore cannot be used as identifier,
|
* Note that within the body block of a modifier, the underscore cannot be used as identifier,
|
||||||
@ -311,11 +313,31 @@ errorDefinition:
|
|||||||
LParen (parameters+=errorParameter (Comma parameters+=errorParameter)*)? RParen
|
LParen (parameters+=errorParameter (Comma parameters+=errorParameter)*)? RParen
|
||||||
Semicolon;
|
Semicolon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operators that users are allowed to implement for some types with `using for`.
|
||||||
|
*/
|
||||||
|
userDefinableOperator:
|
||||||
|
BitAnd
|
||||||
|
| BitNot
|
||||||
|
| BitOr
|
||||||
|
| BitXor
|
||||||
|
| Add
|
||||||
|
| Div
|
||||||
|
| Mod
|
||||||
|
| Mul
|
||||||
|
| Sub
|
||||||
|
| Equal
|
||||||
|
| GreaterThan
|
||||||
|
| GreaterThanOrEqual
|
||||||
|
| LessThan
|
||||||
|
| LessThanOrEqual
|
||||||
|
| NotEqual;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Using directive to attach library functions and free functions to types.
|
* Using directive to attach library functions and free functions to types.
|
||||||
* Can occur within contracts and libraries and at the file level.
|
* Can occur within contracts and libraries and at the file level.
|
||||||
*/
|
*/
|
||||||
usingDirective: Using (identifierPath | (LBrace identifierPath (Comma identifierPath)* RBrace)) For (Mul | typeName) Global? Semicolon;
|
usingDirective: Using (identifierPath | (LBrace identifierPath (As userDefinableOperator)? (Comma identifierPath (As userDefinableOperator)?)* RBrace)) For (Mul | typeName) Global? Semicolon;
|
||||||
/**
|
/**
|
||||||
* A type name can be an elementary type, a function type, a mapping type, a user-defined type
|
* A type name can be an elementary type, a function type, a mapping type, a user-defined type
|
||||||
* (e.g. a contract or struct) or an array type.
|
* (e.g. a contract or struct) or an array type.
|
||||||
@ -347,7 +369,7 @@ dataLocation: Memory | Storage | Calldata;
|
|||||||
*/
|
*/
|
||||||
expression:
|
expression:
|
||||||
expression LBrack index=expression? RBrack # IndexAccess
|
expression LBrack index=expression? RBrack # IndexAccess
|
||||||
| expression LBrack start=expression? Colon end=expression? RBrack # IndexRangeAccess
|
| expression LBrack startIndex=expression? Colon endIndex=expression? RBrack # IndexRangeAccess
|
||||||
| expression Period (identifier | Address) # MemberAccess
|
| expression Period (identifier | Address) # MemberAccess
|
||||||
| expression LBrace (namedArgument (Comma namedArgument)*)? RBrace # FunctionCallOptions
|
| expression LBrace (namedArgument (Comma namedArgument)*)? RBrace # FunctionCallOptions
|
||||||
| expression callArgumentList # FunctionCall
|
| expression callArgumentList # FunctionCall
|
||||||
@ -368,12 +390,13 @@ expression:
|
|||||||
| expression Or expression # OrOperation
|
| expression Or expression # OrOperation
|
||||||
|<assoc=right> expression Conditional expression Colon expression # Conditional
|
|<assoc=right> expression Conditional expression Colon expression # Conditional
|
||||||
|<assoc=right> expression assignOp expression # Assignment
|
|<assoc=right> expression assignOp expression # Assignment
|
||||||
| New typeName # NewExpression
|
| New typeName # NewExpr
|
||||||
| tupleExpression # Tuple
|
| tupleExpression # Tuple
|
||||||
| inlineArrayExpression # InlineArray
|
| inlineArrayExpression # InlineArray
|
||||||
| (
|
| (
|
||||||
identifier
|
identifier
|
||||||
| literal
|
| literal
|
||||||
|
| literalWithSubDenomination
|
||||||
| elementaryTypeName[false]
|
| elementaryTypeName[false]
|
||||||
) # PrimaryExpression
|
) # PrimaryExpression
|
||||||
;
|
;
|
||||||
@ -392,6 +415,9 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack;
|
|||||||
identifier: Identifier | From | Error | Revert | Global;
|
identifier: Identifier | From | Error | Revert | Global;
|
||||||
|
|
||||||
literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
|
literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
|
||||||
|
|
||||||
|
literalWithSubDenomination: numberLiteral SubDenomination;
|
||||||
|
|
||||||
booleanLiteral: True | False;
|
booleanLiteral: True | False;
|
||||||
/**
|
/**
|
||||||
* A full string literal consists of either one or several consecutive quoted strings.
|
* A full string literal consists of either one or several consecutive quoted strings.
|
||||||
@ -409,7 +435,8 @@ unicodeStringLiteral: UnicodeStringLiteral+;
|
|||||||
/**
|
/**
|
||||||
* Number literals can be decimal or hexadecimal numbers with an optional unit.
|
* Number literals can be decimal or hexadecimal numbers with an optional unit.
|
||||||
*/
|
*/
|
||||||
numberLiteral: (DecimalNumber | HexNumber) NumberUnit?;
|
numberLiteral: DecimalNumber | HexNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A curly-braced block of statements. Opens its own scope.
|
* A curly-braced block of statements. Opens its own scope.
|
||||||
*/
|
*/
|
||||||
|
@ -1,38 +1,35 @@
|
|||||||
Solidity
|
Solidity
|
||||||
========
|
========
|
||||||
|
|
||||||
Solidity is an object-oriented, high-level language for implementing smart
|
Solidity is an object-oriented, high-level language for implementing smart contracts.
|
||||||
contracts. Smart contracts are programs which govern the behaviour of accounts
|
Smart contracts are programs that govern the behavior of accounts within the Ethereum state.
|
||||||
within the Ethereum state.
|
|
||||||
|
|
||||||
Solidity is a `curly-bracket language <https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages>`_ designed to target the Ethereum Virtual Machine (EVM).
|
Solidity is a `curly-bracket language <https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages>`_ designed to target the Ethereum Virtual Machine (EVM).
|
||||||
It is influenced by C++, Python and JavaScript. You can find more details about which languages Solidity has been inspired by in the :doc:`language influences <language-influences>` section.
|
It is influenced by C++, Python, and JavaScript.
|
||||||
|
You can find more details about which languages Solidity has been inspired by in the :doc:`language influences <language-influences>` section.
|
||||||
|
|
||||||
Solidity is statically typed, supports inheritance, libraries and complex
|
Solidity is statically typed, supports inheritance, libraries, and complex user-defined types, among other features.
|
||||||
user-defined types among other features.
|
|
||||||
|
|
||||||
With Solidity you can create contracts for uses such as voting, crowdfunding, blind auctions,
|
With Solidity, you can create contracts for uses such as voting, crowdfunding, blind auctions, and multi-signature wallets.
|
||||||
and multi-signature wallets.
|
|
||||||
|
|
||||||
When deploying contracts, you should use the latest released
|
When deploying contracts, you should use the latest released version of Solidity.
|
||||||
version of Solidity. Apart from exceptional cases, only the latest version receives
|
Apart from exceptional cases, only the latest version receives
|
||||||
`security fixes <https://github.com/ethereum/solidity/security/policy#supported-versions>`_.
|
`security fixes <https://github.com/ethereum/solidity/security/policy#supported-versions>`_.
|
||||||
Furthermore, breaking changes as well as
|
Furthermore, breaking changes, as well as new features, are introduced regularly.
|
||||||
new features are introduced regularly. We currently use
|
We currently use a 0.y.z version number `to indicate this fast pace of change <https://semver.org/#spec-item-4>`_.
|
||||||
a 0.y.z version number `to indicate this fast pace of change <https://semver.org/#spec-item-4>`_.
|
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
Solidity recently released the 0.8.x version that introduced a lot of breaking
|
Solidity recently released the 0.8.x version that introduced a lot of breaking changes.
|
||||||
changes. Make sure you read :doc:`the full list <080-breaking-changes>`.
|
Make sure you read :doc:`the full list <080-breaking-changes>`.
|
||||||
|
|
||||||
Ideas for improving Solidity or this documentation are always welcome,
|
Ideas for improving Solidity or this documentation are always welcome,
|
||||||
read our :doc:`contributors guide <contributing>` for more details.
|
read our :doc:`contributors guide <contributing>` for more details.
|
||||||
|
|
||||||
.. Hint::
|
.. Hint::
|
||||||
|
|
||||||
You can download this documentation as PDF, HTML or Epub by clicking on the versions
|
You can download this documentation as PDF, HTML or Epub
|
||||||
flyout menu in the bottom-left corner and selecting the preferred download format.
|
by clicking on the versions flyout menu in the bottom-left corner and selecting the preferred download format.
|
||||||
|
|
||||||
|
|
||||||
Getting Started
|
Getting Started
|
||||||
@ -40,8 +37,7 @@ Getting Started
|
|||||||
|
|
||||||
**1. Understand the Smart Contract Basics**
|
**1. Understand the Smart Contract Basics**
|
||||||
|
|
||||||
If you are new to the concept of smart contracts we recommend you to get started by digging
|
If you are new to the concept of smart contracts, we recommend you to get started by digging into the "Introduction to Smart Contracts" section, which covers the following:
|
||||||
into the "Introduction to Smart Contracts" section, which covers:
|
|
||||||
|
|
||||||
* :ref:`A simple example smart contract <simple-smart-contract>` written in Solidity.
|
* :ref:`A simple example smart contract <simple-smart-contract>` written in Solidity.
|
||||||
* :ref:`Blockchain Basics <blockchain-basics>`.
|
* :ref:`Blockchain Basics <blockchain-basics>`.
|
||||||
@ -59,29 +55,27 @@ simply choose your preferred option and follow the steps outlined on the :ref:`i
|
|||||||
|
|
||||||
.. hint::
|
.. hint::
|
||||||
You can try out code examples directly in your browser with the
|
You can try out code examples directly in your browser with the
|
||||||
`Remix IDE <https://remix.ethereum.org>`_. Remix is a web browser based IDE
|
`Remix IDE <https://remix.ethereum.org>`_.
|
||||||
that allows you to write, deploy and administer Solidity smart contracts, without
|
Remix is a web browser-based IDE that allows you to write, deploy and administer Solidity smart contracts,
|
||||||
the need to install Solidity locally.
|
without the need to install Solidity locally.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
As humans write software, it can have bugs. You should follow established
|
As humans write software, it can have bugs.
|
||||||
software development best-practices when writing your smart contracts. This
|
Therefore, you should follow established software development best practices when writing your smart contracts.
|
||||||
includes code review, testing, audits, and correctness proofs. Smart contract
|
This includes code review, testing, audits, and correctness proofs.
|
||||||
users are sometimes more confident with code than their authors, and
|
Smart contract users are sometimes more confident with code than their authors,
|
||||||
blockchains and smart contracts have their own unique issues to
|
and blockchains and smart contracts have their own unique issues to watch out for,
|
||||||
watch out for, so before working on production code, make sure you read the
|
so before working on production code, make sure you read the :ref:`security_considerations` section.
|
||||||
:ref:`security_considerations` section.
|
|
||||||
|
|
||||||
**4. Learn More**
|
**4. Learn More**
|
||||||
|
|
||||||
If you want to learn more about building decentralized applications on Ethereum, the
|
If you want to learn more about building decentralized applications on Ethereum,
|
||||||
`Ethereum Developer Resources <https://ethereum.org/en/developers/>`_
|
the `Ethereum Developer Resources <https://ethereum.org/en/developers/>`_ can help you with further general documentation around Ethereum,
|
||||||
can help you with further general documentation around Ethereum, and a wide selection of tutorials,
|
and a wide selection of tutorials, tools, and development frameworks.
|
||||||
tools and development frameworks.
|
|
||||||
|
|
||||||
If you have any questions, you can try searching for answers or asking on the
|
If you have any questions, you can try searching for answers or asking on the
|
||||||
`Ethereum StackExchange <https://ethereum.stackexchange.com/>`_, or
|
`Ethereum StackExchange <https://ethereum.stackexchange.com/>`_,
|
||||||
our `Gitter channel <https://gitter.im/ethereum/solidity/>`_.
|
or our `Gitter channel <https://gitter.im/ethereum/solidity>`_.
|
||||||
|
|
||||||
.. _translations:
|
.. _translations:
|
||||||
|
|
||||||
@ -89,8 +83,8 @@ Translations
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
Community contributors help translate this documentation into several languages.
|
Community contributors help translate this documentation into several languages.
|
||||||
Note that they have varying degrees of completeness and up-to-dateness. The English
|
Note that they have varying degrees of completeness and up-to-dateness.
|
||||||
version stands as a reference.
|
The English version stands as a reference.
|
||||||
|
|
||||||
You can switch between languages by clicking on the flyout menu in the bottom-left corner
|
You can switch between languages by clicking on the flyout menu in the bottom-left corner
|
||||||
and selecting the preferred language.
|
and selecting the preferred language.
|
||||||
@ -107,8 +101,8 @@ and selecting the preferred language.
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
We set up a GitHub organization and translation workflow to help streamline the
|
We set up a GitHub organization and translation workflow to help streamline the community efforts.
|
||||||
community efforts. Please refer to the translation guide in the `solidity-docs org <https://github.com/solidity-docs>`_
|
Please refer to the translation guide in the `solidity-docs org <https://github.com/solidity-docs>`_
|
||||||
for information on how to start a new language or contribute to the community translations.
|
for information on how to start a new language or contribute to the community translations.
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
@ -121,8 +115,8 @@ Contents
|
|||||||
:caption: Basics
|
:caption: Basics
|
||||||
|
|
||||||
introduction-to-smart-contracts.rst
|
introduction-to-smart-contracts.rst
|
||||||
installing-solidity.rst
|
|
||||||
solidity-by-example.rst
|
solidity-by-example.rst
|
||||||
|
installing-solidity.rst
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
@ -161,21 +155,31 @@ Contents
|
|||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Additional Material
|
:caption: Advisory content
|
||||||
|
|
||||||
|
security-considerations.rst
|
||||||
|
bugs.rst
|
||||||
050-breaking-changes.rst
|
050-breaking-changes.rst
|
||||||
060-breaking-changes.rst
|
060-breaking-changes.rst
|
||||||
070-breaking-changes.rst
|
070-breaking-changes.rst
|
||||||
080-breaking-changes.rst
|
080-breaking-changes.rst
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Additional Material
|
||||||
|
|
||||||
natspec-format.rst
|
natspec-format.rst
|
||||||
security-considerations.rst
|
|
||||||
smtchecker.rst
|
smtchecker.rst
|
||||||
resources.rst
|
|
||||||
path-resolution.rst
|
|
||||||
yul.rst
|
yul.rst
|
||||||
|
path-resolution.rst
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Resources
|
||||||
|
|
||||||
style-guide.rst
|
style-guide.rst
|
||||||
common-patterns.rst
|
common-patterns.rst
|
||||||
bugs.rst
|
resources.rst
|
||||||
contributing.rst
|
contributing.rst
|
||||||
brand-guide.rst
|
|
||||||
language-influences.rst
|
language-influences.rst
|
||||||
|
brand-guide.rst
|
||||||
|
@ -10,12 +10,12 @@ Versioning
|
|||||||
==========
|
==========
|
||||||
|
|
||||||
Solidity versions follow `Semantic Versioning <https://semver.org>`_. In
|
Solidity versions follow `Semantic Versioning <https://semver.org>`_. In
|
||||||
addition, patch level releases with major release 0 (i.e. 0.x.y) will not
|
addition, patch-level releases with major release 0 (i.e. 0.x.y) will not
|
||||||
contain breaking changes. That means code that compiles with version 0.x.y
|
contain breaking changes. That means code that compiles with version 0.x.y
|
||||||
can be expected to compile with 0.x.z where z > y.
|
can be expected to compile with 0.x.z where z > y.
|
||||||
|
|
||||||
In addition to releases, we provide **nightly development builds** with the
|
In addition to releases, we provide **nightly development builds** to make
|
||||||
intention of making it easy for developers to try out upcoming features and
|
it easy for developers to try out upcoming features and
|
||||||
provide early feedback. Note, however, that while the nightly builds are usually
|
provide early feedback. Note, however, that while the nightly builds are usually
|
||||||
very stable, they contain bleeding-edge code from the development branch and are
|
very stable, they contain bleeding-edge code from the development branch and are
|
||||||
not guaranteed to be always working. Despite our best efforts, they might
|
not guaranteed to be always working. Despite our best efforts, they might
|
||||||
@ -33,12 +33,12 @@ Remix
|
|||||||
|
|
||||||
`Access Remix online <https://remix.ethereum.org/>`_, you do not need to install anything.
|
`Access Remix online <https://remix.ethereum.org/>`_, you do not need to install anything.
|
||||||
If you want to use it without connection to the Internet, go to
|
If you want to use it without connection to the Internet, go to
|
||||||
https://github.com/ethereum/remix-live/tree/gh-pages and download the ``.zip`` file as
|
https://github.com/ethereum/remix-live/tree/gh-pages#readme and follow the instructions on that page.
|
||||||
explained on that page. Remix is also a convenient option for testing nightly builds
|
Remix is also a convenient option for testing nightly builds
|
||||||
without installing multiple Solidity versions.
|
without installing multiple Solidity versions.
|
||||||
|
|
||||||
Further options on this page detail installing commandline Solidity compiler software
|
Further options on this page detail installing command-line Solidity compiler software
|
||||||
on your computer. Choose a commandline compiler if you are working on a larger contract
|
on your computer. Choose a command-line compiler if you are working on a larger contract
|
||||||
or if you require more compilation options.
|
or if you require more compilation options.
|
||||||
|
|
||||||
.. _solcjs:
|
.. _solcjs:
|
||||||
@ -54,7 +54,7 @@ the full-featured compiler, ``solc``. The usage of ``solcjs`` is documented insi
|
|||||||
`repository <https://github.com/ethereum/solc-js>`_.
|
`repository <https://github.com/ethereum/solc-js>`_.
|
||||||
|
|
||||||
Note: The solc-js project is derived from the C++
|
Note: The solc-js project is derived from the C++
|
||||||
`solc` by using Emscripten which means that both use the same compiler source code.
|
`solc` by using Emscripten, which means that both use the same compiler source code.
|
||||||
`solc-js` can be used in JavaScript projects directly (such as Remix).
|
`solc-js` can be used in JavaScript projects directly (such as Remix).
|
||||||
Please refer to the solc-js repository for instructions.
|
Please refer to the solc-js repository for instructions.
|
||||||
|
|
||||||
@ -64,18 +64,18 @@ Please refer to the solc-js repository for instructions.
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The commandline executable is named ``solcjs``.
|
The command-line executable is named ``solcjs``.
|
||||||
|
|
||||||
The commandline options of ``solcjs`` are not compatible with ``solc`` and tools (such as ``geth``)
|
The command-line options of ``solcjs`` are not compatible with ``solc`` and tools (such as ``geth``)
|
||||||
expecting the behaviour of ``solc`` will not work with ``solcjs``.
|
expecting the behavior of ``solc`` will not work with ``solcjs``.
|
||||||
|
|
||||||
Docker
|
Docker
|
||||||
======
|
======
|
||||||
|
|
||||||
Docker images of Solidity builds are available using the ``solc`` image from the ``ethereum`` organisation.
|
Docker images of Solidity builds are available using the ``solc`` image from the ``ethereum`` organization.
|
||||||
Use the ``stable`` tag for the latest released version, and ``nightly`` for potentially unstable changes in the develop branch.
|
Use the ``stable`` tag for the latest released version, and ``nightly`` for potentially unstable changes in the develop branch.
|
||||||
|
|
||||||
The Docker image runs the compiler executable, so you can pass all compiler arguments to it.
|
The Docker image runs the compiler executable so that you can pass all compiler arguments to it.
|
||||||
For example, the command below pulls the stable version of the ``solc`` image (if you do not have it already),
|
For example, the command below pulls the stable version of the ``solc`` image (if you do not have it already),
|
||||||
and runs it in a new container, passing the ``--help`` argument.
|
and runs it in a new container, passing the ``--help`` argument.
|
||||||
|
|
||||||
@ -83,13 +83,13 @@ and runs it in a new container, passing the ``--help`` argument.
|
|||||||
|
|
||||||
docker run ethereum/solc:stable --help
|
docker run ethereum/solc:stable --help
|
||||||
|
|
||||||
You can also specify release build versions in the tag, for example, for the 0.5.4 release.
|
For example, You can specify release build versions in the tag for the 0.5.4 release.
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
docker run ethereum/solc:0.5.4 --help
|
docker run ethereum/solc:0.5.4 --help
|
||||||
|
|
||||||
To use the Docker image to compile Solidity files on the host machine mount a
|
To use the Docker image to compile Solidity files on the host machine, mount a
|
||||||
local folder for input and output, and specify the contract to compile. For example.
|
local folder for input and output, and specify the contract to compile. For example.
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
@ -97,7 +97,7 @@ local folder for input and output, and specify the contract to compile. For exam
|
|||||||
docker run -v /local/path:/sources ethereum/solc:stable -o /sources/output --abi --bin /sources/Contract.sol
|
docker run -v /local/path:/sources ethereum/solc:stable -o /sources/output --abi --bin /sources/Contract.sol
|
||||||
|
|
||||||
You can also use the standard JSON interface (which is recommended when using the compiler with tooling).
|
You can also use the standard JSON interface (which is recommended when using the compiler with tooling).
|
||||||
When using this interface it is not necessary to mount any directories as long as the JSON input is
|
When using this interface, it is not necessary to mount any directories as long as the JSON input is
|
||||||
self-contained (i.e. it does not refer to any external files that would have to be
|
self-contained (i.e. it does not refer to any external files that would have to be
|
||||||
:ref:`loaded by the import callback <initial-vfs-content-standard-json-with-import-callback>`).
|
:ref:`loaded by the import callback <initial-vfs-content-standard-json-with-import-callback>`).
|
||||||
|
|
||||||
@ -130,13 +130,15 @@ The nightly version can be installed using these commands:
|
|||||||
sudo apt-get install solc
|
sudo apt-get install solc
|
||||||
|
|
||||||
Furthermore, some Linux distributions provide their own packages. These packages are not directly
|
Furthermore, some Linux distributions provide their own packages. These packages are not directly
|
||||||
maintained by us, but usually kept up-to-date by the respective package maintainers.
|
maintained by us but usually kept up-to-date by the respective package maintainers.
|
||||||
|
|
||||||
For example, Arch Linux has packages for the latest development version:
|
For example, Arch Linux has packages for the latest development version as AUR packages: `solidity <https://aur.archlinux.org/packages/solidity>`_
|
||||||
|
and `solidity-bin <https://aur.archlinux.org/packages/solidity-bin>`_.
|
||||||
|
|
||||||
.. code-block:: bash
|
.. note::
|
||||||
|
|
||||||
pacman -S solidity
|
Please be aware that `AUR <https://wiki.archlinux.org/title/Arch_User_Repository>`_ packages
|
||||||
|
are user-produced content and unofficial packages. Exercise caution when using them.
|
||||||
|
|
||||||
There is also a `snap package <https://snapcraft.io/solc>`_, however, it is **currently unmaintained**.
|
There is also a `snap package <https://snapcraft.io/solc>`_, however, it is **currently unmaintained**.
|
||||||
It is installable in all the `supported Linux distros <https://snapcraft.io/docs/core/install>`_. To
|
It is installable in all the `supported Linux distros <https://snapcraft.io/docs/core/install>`_. To
|
||||||
@ -212,12 +214,12 @@ out-of-the-box but it is also meant to be friendly to third-party tools:
|
|||||||
HTTPS without any authentication, rate limiting or the need to use git.
|
HTTPS without any authentication, rate limiting or the need to use git.
|
||||||
- Content is served with correct `Content-Type` headers and lenient CORS configuration so that it
|
- Content is served with correct `Content-Type` headers and lenient CORS configuration so that it
|
||||||
can be directly loaded by tools running in the browser.
|
can be directly loaded by tools running in the browser.
|
||||||
- Binaries do not require installation or unpacking (with the exception of older Windows builds
|
- Binaries do not require installation or unpacking (exception for older Windows builds
|
||||||
bundled with necessary DLLs).
|
bundled with necessary DLLs).
|
||||||
- We strive for a high level of backwards-compatibility. Files, once added, are not removed or moved
|
- We strive for a high level of backward-compatibility. Files, once added, are not removed or moved
|
||||||
without providing a symlink/redirect at the old location. They are also never modified
|
without providing a symlink/redirect at the old location. They are also never modified
|
||||||
in place and should always match the original checksum. The only exception would be broken or
|
in place and should always match the original checksum. The only exception would be broken or
|
||||||
unusable files with a potential to cause more harm than good if left as is.
|
unusable files with the potential to cause more harm than good if left as is.
|
||||||
- Files are served over both HTTP and HTTPS. As long as you obtain the file list in a secure way
|
- Files are served over both HTTP and HTTPS. As long as you obtain the file list in a secure way
|
||||||
(via git, HTTPS, IPFS or just have it cached locally) and verify hashes of the binaries
|
(via git, HTTPS, IPFS or just have it cached locally) and verify hashes of the binaries
|
||||||
after downloading them, you do not have to use HTTPS for the binaries themselves.
|
after downloading them, you do not have to use HTTPS for the binaries themselves.
|
||||||
@ -228,7 +230,7 @@ that we do not rename them if the naming convention changes and we do not add bu
|
|||||||
that were not supported at the time of release. This only happens in ``solc-bin``.
|
that were not supported at the time of release. This only happens in ``solc-bin``.
|
||||||
|
|
||||||
The ``solc-bin`` repository contains several top-level directories, each representing a single platform.
|
The ``solc-bin`` repository contains several top-level directories, each representing a single platform.
|
||||||
Each one contains a ``list.json`` file listing the available binaries. For example in
|
Each one includes a ``list.json`` file listing the available binaries. For example in
|
||||||
``emscripten-wasm32/list.json`` you will find the following information about version 0.7.4:
|
``emscripten-wasm32/list.json`` you will find the following information about version 0.7.4:
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
@ -259,7 +261,7 @@ This means that:
|
|||||||
- The file might in future be available on Swarm at `16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1`_.
|
- The file might in future be available on Swarm at `16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1`_.
|
||||||
- You can verify the integrity of the binary by comparing its keccak256 hash to
|
- You can verify the integrity of the binary by comparing its keccak256 hash to
|
||||||
``0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3``. The hash can be computed
|
``0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3``. The hash can be computed
|
||||||
on the command line using ``keccak256sum`` utility provided by `sha3sum`_ or `keccak256() function
|
on the command-line using ``keccak256sum`` utility provided by `sha3sum`_ or `keccak256() function
|
||||||
from ethereumjs-util`_ in JavaScript.
|
from ethereumjs-util`_ in JavaScript.
|
||||||
- You can also verify the integrity of the binary by comparing its sha256 hash to
|
- You can also verify the integrity of the binary by comparing its sha256 hash to
|
||||||
``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2``.
|
``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2``.
|
||||||
@ -310,7 +312,6 @@ This means that:
|
|||||||
|
|
||||||
Building from Source
|
Building from Source
|
||||||
====================
|
====================
|
||||||
|
|
||||||
Prerequisites - All Operating Systems
|
Prerequisites - All Operating Systems
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
@ -322,7 +323,7 @@ The following are dependencies for all builds of Solidity:
|
|||||||
| `CMake`_ (version 3.21.3+ on | Cross-platform build file generator. |
|
| `CMake`_ (version 3.21.3+ on | Cross-platform build file generator. |
|
||||||
| Windows, 3.13+ otherwise) | |
|
| Windows, 3.13+ otherwise) | |
|
||||||
+-----------------------------------+-------------------------------------------------------+
|
+-----------------------------------+-------------------------------------------------------+
|
||||||
| `Boost`_ (version 1.77 on | C++ libraries. |
|
| `Boost`_ (version 1.77+ on | C++ libraries. |
|
||||||
| Windows, 1.65+ otherwise) | |
|
| Windows, 1.65+ otherwise) | |
|
||||||
+-----------------------------------+-------------------------------------------------------+
|
+-----------------------------------+-------------------------------------------------------+
|
||||||
| `Git`_ | Command-line tool for retrieving source code. |
|
| `Git`_ | Command-line tool for retrieving source code. |
|
||||||
@ -341,7 +342,7 @@ The following are dependencies for all builds of Solidity:
|
|||||||
.. note::
|
.. note::
|
||||||
Solidity versions prior to 0.5.10 can fail to correctly link against Boost versions 1.70+.
|
Solidity versions prior to 0.5.10 can fail to correctly link against Boost versions 1.70+.
|
||||||
A possible workaround is to temporarily rename ``<Boost install path>/lib/cmake/Boost-1.70.0``
|
A possible workaround is to temporarily rename ``<Boost install path>/lib/cmake/Boost-1.70.0``
|
||||||
prior to running the cmake command to configure solidity.
|
prior to running the cmake command to configure Solidity.
|
||||||
|
|
||||||
Starting from 0.5.10 linking against Boost 1.70+ should work without manual intervention.
|
Starting from 0.5.10 linking against Boost 1.70+ should work without manual intervention.
|
||||||
|
|
||||||
@ -379,7 +380,7 @@ Prerequisites - macOS
|
|||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
For macOS builds, ensure that you have the latest version of
|
For macOS builds, ensure that you have the latest version of
|
||||||
`Xcode installed <https://developer.apple.com/xcode/download/>`_.
|
`Xcode installed <https://developer.apple.com/xcode/resources/>`_.
|
||||||
This contains the `Clang C++ compiler <https://en.wikipedia.org/wiki/Clang>`_, the
|
This contains the `Clang C++ compiler <https://en.wikipedia.org/wiki/Clang>`_, the
|
||||||
`Xcode IDE <https://en.wikipedia.org/wiki/Xcode>`_ and other Apple development
|
`Xcode IDE <https://en.wikipedia.org/wiki/Xcode>`_ and other Apple development
|
||||||
tools that are required for building C++ applications on OS X.
|
tools that are required for building C++ applications on OS X.
|
||||||
@ -409,7 +410,7 @@ You need to install the following dependencies for Windows builds of Solidity:
|
|||||||
+-----------------------------------+-------------------------------------------------------+
|
+-----------------------------------+-------------------------------------------------------+
|
||||||
| `Visual Studio 2019`_ (Optional) | C++ compiler and dev environment. |
|
| `Visual Studio 2019`_ (Optional) | C++ compiler and dev environment. |
|
||||||
+-----------------------------------+-------------------------------------------------------+
|
+-----------------------------------+-------------------------------------------------------+
|
||||||
| `Boost`_ (version 1.77) | C++ libraries. |
|
| `Boost`_ (version 1.77+) | C++ libraries. |
|
||||||
+-----------------------------------+-------------------------------------------------------+
|
+-----------------------------------+-------------------------------------------------------+
|
||||||
|
|
||||||
If you already have one IDE and only need the compiler and libraries,
|
If you already have one IDE and only need the compiler and libraries,
|
||||||
@ -429,7 +430,7 @@ in Visual Studio 2019 Build Tools or Visual Studio 2019:
|
|||||||
* C++/CLI support
|
* C++/CLI support
|
||||||
|
|
||||||
.. _Visual Studio 2019: https://www.visualstudio.com/vs/
|
.. _Visual Studio 2019: https://www.visualstudio.com/vs/
|
||||||
.. _Visual Studio 2019 Build Tools: https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019
|
.. _Visual Studio 2019 Build Tools: https://visualstudio.microsoft.com/vs/older-downloads/#visual-studio-2019-and-other-products
|
||||||
|
|
||||||
We have a helper script which you can use to install all required external dependencies:
|
We have a helper script which you can use to install all required external dependencies:
|
||||||
|
|
||||||
@ -449,7 +450,7 @@ To clone the source code, execute the following command:
|
|||||||
git clone --recursive https://github.com/ethereum/solidity.git
|
git clone --recursive https://github.com/ethereum/solidity.git
|
||||||
cd solidity
|
cd solidity
|
||||||
|
|
||||||
If you want to help developing Solidity,
|
If you want to help develop Solidity,
|
||||||
you should fork Solidity and add your personal fork as a second remote:
|
you should fork Solidity and add your personal fork as a second remote:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
@ -457,7 +458,7 @@ you should fork Solidity and add your personal fork as a second remote:
|
|||||||
git remote add personal git@github.com:[username]/solidity.git
|
git remote add personal git@github.com:[username]/solidity.git
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
This method will result in a prerelease build leading to e.g. a flag
|
This method will result in a pre-release build leading to e.g. a flag
|
||||||
being set in each bytecode produced by such a compiler.
|
being set in each bytecode produced by such a compiler.
|
||||||
If you want to re-build a released Solidity compiler, then
|
If you want to re-build a released Solidity compiler, then
|
||||||
please use the source tarball on the github release page:
|
please use the source tarball on the github release page:
|
||||||
@ -527,7 +528,7 @@ If you are interested what CMake options are available run ``cmake .. -LH``.
|
|||||||
SMT Solvers
|
SMT Solvers
|
||||||
-----------
|
-----------
|
||||||
Solidity can be built against SMT solvers and will do so by default if
|
Solidity can be built against SMT solvers and will do so by default if
|
||||||
they are found in the system. Each solver can be disabled by a `cmake` option.
|
they are found in the system. Each solver can be disabled by a ``cmake`` option.
|
||||||
|
|
||||||
*Note: In some cases, this can also be a potential workaround for build failures.*
|
*Note: In some cases, this can also be a potential workaround for build failures.*
|
||||||
|
|
||||||
@ -580,4 +581,4 @@ Example:
|
|||||||
4. A breaking change is introduced --> version is bumped to 0.5.0.
|
4. A breaking change is introduced --> version is bumped to 0.5.0.
|
||||||
5. The 0.5.0 release is made.
|
5. The 0.5.0 release is made.
|
||||||
|
|
||||||
This behaviour works well with the :ref:`version pragma <version_pragma>`.
|
This behavior works well with the :ref:`version pragma <version_pragma>`.
|
||||||
|
@ -208,7 +208,7 @@ of types), arrays have its ``base`` type, and structs list their ``members`` in
|
|||||||
the same format as the top-level ``storage`` (see :ref:`above
|
the same format as the top-level ``storage`` (see :ref:`above
|
||||||
<storage-layout-top-level>`).
|
<storage-layout-top-level>`).
|
||||||
|
|
||||||
.. note ::
|
.. note::
|
||||||
The JSON output format of a contract's storage layout is still considered experimental
|
The JSON output format of a contract's storage layout is still considered experimental
|
||||||
and is subject to change in non-breaking releases of Solidity.
|
and is subject to change in non-breaking releases of Solidity.
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ value and reference types, types that are encoded packed, and nested types.
|
|||||||
uint y;
|
uint y;
|
||||||
S s;
|
S s;
|
||||||
address addr;
|
address addr;
|
||||||
mapping (uint => mapping (address => bool)) map;
|
mapping(uint => mapping(address => bool)) map;
|
||||||
uint[] array;
|
uint[] array;
|
||||||
string s1;
|
string s1;
|
||||||
bytes b1;
|
bytes b1;
|
||||||
|
@ -27,7 +27,7 @@ optimized Yul IR for a Solidity source. Similarly, one can use ``solc --strict-a
|
|||||||
for a stand-alone Yul mode.
|
for a stand-alone Yul mode.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The `peephole optimizer <https://en.wikipedia.org/wiki/Peephole_optimization>`_ and the inliner are always
|
The `peephole optimizer <https://en.wikipedia.org/wiki/Peephole_optimization>`_ is always
|
||||||
enabled by default and can only be turned off via the :ref:`Standard JSON <compiler-api>`.
|
enabled by default and can only be turned off via the :ref:`Standard JSON <compiler-api>`.
|
||||||
|
|
||||||
You can find more details on both optimizer modules and their optimization steps below.
|
You can find more details on both optimizer modules and their optimization steps below.
|
||||||
@ -316,7 +316,6 @@ Abbreviation Full name
|
|||||||
``L`` :ref:`load-resolver`
|
``L`` :ref:`load-resolver`
|
||||||
``M`` :ref:`loop-invariant-code-motion`
|
``M`` :ref:`loop-invariant-code-motion`
|
||||||
``r`` :ref:`redundant-assign-eliminator`
|
``r`` :ref:`redundant-assign-eliminator`
|
||||||
``R`` :ref:`reasoning-based-simplifier` - highly experimental
|
|
||||||
``m`` :ref:`rematerialiser`
|
``m`` :ref:`rematerialiser`
|
||||||
``V`` :ref:`SSA-reverser`
|
``V`` :ref:`SSA-reverser`
|
||||||
``a`` :ref:`SSA-transform`
|
``a`` :ref:`SSA-transform`
|
||||||
@ -330,10 +329,6 @@ Abbreviation Full name
|
|||||||
Some steps depend on properties ensured by ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter``.
|
Some steps depend on properties ensured by ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter``.
|
||||||
For this reason the Yul optimizer always applies them before applying any steps supplied by the user.
|
For this reason the Yul optimizer always applies them before applying any steps supplied by the user.
|
||||||
|
|
||||||
The ReasoningBasedSimplifier is an optimizer step that is currently not enabled
|
|
||||||
in the default set of steps. It uses an SMT solver to simplify arithmetic expressions
|
|
||||||
and boolean conditions. It has not received thorough testing or validation yet and can produce
|
|
||||||
non-reproducible results, so please use with care!
|
|
||||||
|
|
||||||
Selecting Optimizations
|
Selecting Optimizations
|
||||||
-----------------------
|
-----------------------
|
||||||
@ -343,7 +338,7 @@ You can override this sequence and supply your own using the ``--yul-optimizatio
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOc'
|
solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOcmu'
|
||||||
|
|
||||||
The order of steps is significant and affects the quality of the output.
|
The order of steps is significant and affects the quality of the output.
|
||||||
Moreover, applying a step may uncover new optimization opportunities for others that were already applied,
|
Moreover, applying a step may uncover new optimization opportunities for others that were already applied,
|
||||||
@ -575,7 +570,7 @@ It is not applied to loop iteration-condition, because the loop control flow doe
|
|||||||
this "outlining" of the inner expressions in all cases. We can sidestep this limitation by applying
|
this "outlining" of the inner expressions in all cases. We can sidestep this limitation by applying
|
||||||
:ref:`for-loop-condition-into-body` to move the iteration condition into loop body.
|
:ref:`for-loop-condition-into-body` to move the iteration condition into loop body.
|
||||||
|
|
||||||
The final program should be in a form such that (with the exception of loop conditions)
|
The final program should be in an *expression-split form*, where (with the exception of loop conditions)
|
||||||
function calls cannot appear nested inside expressions
|
function calls cannot appear nested inside expressions
|
||||||
and all function call arguments have to be variables.
|
and all function call arguments have to be variables.
|
||||||
|
|
||||||
@ -826,10 +821,10 @@ if the common subexpression eliminator was run right before it.
|
|||||||
|
|
||||||
.. _expression-simplifier:
|
.. _expression-simplifier:
|
||||||
|
|
||||||
Expression Simplifier
|
ExpressionSimplifier
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The Expression Simplifier uses the Dataflow Analyzer and makes use
|
The ExpressionSimplifier uses the Dataflow Analyzer and makes use
|
||||||
of a list of equivalence transforms on expressions like ``X + 0 -> X``
|
of a list of equivalence transforms on expressions like ``X + 0 -> X``
|
||||||
to simplify the code.
|
to simplify the code.
|
||||||
|
|
||||||
@ -863,22 +858,6 @@ Works best if the code is in SSA form.
|
|||||||
|
|
||||||
Prerequisite: Disambiguator, ForLoopInitRewriter.
|
Prerequisite: Disambiguator, ForLoopInitRewriter.
|
||||||
|
|
||||||
.. _reasoning-based-simplifier:
|
|
||||||
|
|
||||||
ReasoningBasedSimplifier
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
This optimizer uses SMT solvers to check whether ``if`` conditions are constant.
|
|
||||||
|
|
||||||
- If ``constraints AND condition`` is UNSAT, the condition is never true and the whole body can be removed.
|
|
||||||
- If ``constraints AND NOT condition`` is UNSAT, the condition is always true and can be replaced by ``1``.
|
|
||||||
|
|
||||||
The simplifications above can only be applied if the condition is movable.
|
|
||||||
|
|
||||||
It is only effective on the EVM dialect, but safe to use on other dialects.
|
|
||||||
|
|
||||||
Prerequisite: Disambiguator, SSATransform.
|
|
||||||
|
|
||||||
Statement-Scale Simplifications
|
Statement-Scale Simplifications
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
@ -1213,7 +1192,7 @@ This component can only be used on sources with unique names.
|
|||||||
FullInliner
|
FullInliner
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
The Full Inliner replaces certain calls of certain functions
|
The FullInliner replaces certain calls of certain functions
|
||||||
by the function's body. This is not very helpful in most cases, because
|
by the function's body. This is not very helpful in most cases, because
|
||||||
it just increases the code size but does not have a benefit. Furthermore,
|
it just increases the code size but does not have a benefit. Furthermore,
|
||||||
code is usually very expensive and we would often rather have shorter
|
code is usually very expensive and we would often rather have shorter
|
||||||
@ -1237,6 +1216,11 @@ we can run the optimizer on this specialized function. If it
|
|||||||
results in heavy gains, the specialized function is kept,
|
results in heavy gains, the specialized function is kept,
|
||||||
otherwise the original function is used instead.
|
otherwise the original function is used instead.
|
||||||
|
|
||||||
|
FunctionHoister and ExpressionSplitter are recommended as prerequisites since they make the step
|
||||||
|
more efficient, but are not required for correctness.
|
||||||
|
In particular, function calls with other function calls as arguments are not inlined, but running
|
||||||
|
ExpressionSplitter beforehand ensures that there are no such calls in the input.
|
||||||
|
|
||||||
Cleanup
|
Cleanup
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@ -1279,8 +1263,8 @@ This is a tiny step that helps in reversing the effects of the SSA transform
|
|||||||
if it is combined with the Common Subexpression Eliminator and the
|
if it is combined with the Common Subexpression Eliminator and the
|
||||||
Unused Pruner.
|
Unused Pruner.
|
||||||
|
|
||||||
The SSA form we generate is detrimental to code generation on the EVM and
|
The SSA form we generate is detrimental to code generation
|
||||||
WebAssembly alike because it generates many local variables. It would
|
because it produces many local variables. It would
|
||||||
be better to just re-use existing variables with assignments instead of
|
be better to just re-use existing variables with assignments instead of
|
||||||
fresh variable declarations.
|
fresh variable declarations.
|
||||||
|
|
||||||
@ -1398,15 +1382,3 @@ into
|
|||||||
}
|
}
|
||||||
|
|
||||||
The LiteralRematerialiser should be run before this step.
|
The LiteralRematerialiser should be run before this step.
|
||||||
|
|
||||||
|
|
||||||
WebAssembly specific
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
MainFunction
|
|
||||||
^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Changes the topmost block to be a function with a specific name ("main") which has no
|
|
||||||
inputs nor outputs.
|
|
||||||
|
|
||||||
Depends on the Function Grouper.
|
|
||||||
|
@ -26,7 +26,7 @@ that are not part of the original input but are referenced from the source
|
|||||||
mappings. These source files together with their identifiers can be
|
mappings. These source files together with their identifiers can be
|
||||||
obtained via ``output['contracts'][sourceName][contractName]['evm']['bytecode']['generatedSources']``.
|
obtained via ``output['contracts'][sourceName][contractName]['evm']['bytecode']['generatedSources']``.
|
||||||
|
|
||||||
.. note ::
|
.. note::
|
||||||
In the case of instructions that are not associated with any particular source file,
|
In the case of instructions that are not associated with any particular source file,
|
||||||
the source mapping assigns an integer identifier of ``-1``. This may happen for
|
the source mapping assigns an integer identifier of ``-1``. This may happen for
|
||||||
bytecode sections stemming from compiler-generated inline assembly statements.
|
bytecode sections stemming from compiler-generated inline assembly statements.
|
||||||
|
@ -91,7 +91,7 @@ registering with a username and password, all you need is an Ethereum keypair.
|
|||||||
// The keyword "public" makes variables
|
// The keyword "public" makes variables
|
||||||
// accessible from other contracts
|
// accessible from other contracts
|
||||||
address public minter;
|
address public minter;
|
||||||
mapping (address => uint) public balances;
|
mapping(address => uint) public balances;
|
||||||
|
|
||||||
// Events allow clients to react to specific
|
// Events allow clients to react to specific
|
||||||
// contract changes you declare
|
// contract changes you declare
|
||||||
@ -151,7 +151,7 @@ You do not need to do this, the compiler figures it out for you.
|
|||||||
|
|
||||||
.. index:: mapping
|
.. index:: mapping
|
||||||
|
|
||||||
The next line, ``mapping (address => uint) public balances;`` also
|
The next line, ``mapping(address => uint) public balances;`` also
|
||||||
creates a public state variable, but it is a more complex datatype.
|
creates a public state variable, but it is a more complex datatype.
|
||||||
The :ref:`mapping <mapping-types>` type maps addresses to :ref:`unsigned integers <integers>`.
|
The :ref:`mapping <mapping-types>` type maps addresses to :ref:`unsigned integers <integers>`.
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ the source account is also not modified.
|
|||||||
Furthermore, a transaction is always cryptographically signed by the sender (creator).
|
Furthermore, a transaction is always cryptographically signed by the sender (creator).
|
||||||
This makes it straightforward to guard access to specific modifications of the
|
This makes it straightforward to guard access to specific modifications of the
|
||||||
database. In the example of the electronic currency, a simple check ensures that
|
database. In the example of the electronic currency, a simple check ensures that
|
||||||
only the person holding the keys to the account can transfer money from it.
|
only the person holding the keys to the account can transfer some compensation, e.g. Ether, from it.
|
||||||
|
|
||||||
.. index:: ! block
|
.. index:: ! block
|
||||||
|
|
||||||
@ -300,9 +300,9 @@ and then they will be executed and distributed among all participating nodes.
|
|||||||
If two transactions contradict each other, the one that ends up being second will
|
If two transactions contradict each other, the one that ends up being second will
|
||||||
be rejected and not become part of the block.
|
be rejected and not become part of the block.
|
||||||
|
|
||||||
These blocks form a linear sequence in time and that is where the word "blockchain"
|
These blocks form a linear sequence in time, and that is where the word "blockchain" derives from.
|
||||||
derives from. Blocks are added to the chain in rather regular intervals - for
|
Blocks are added to the chain at regular intervals, although these intervals may be subject to change in the future.
|
||||||
Ethereum this is roughly every 17 seconds.
|
For the most up-to-date information, it is recommended to monitor the network, for example, on `Etherscan <https://etherscan.io/chart/blocktime>`_.
|
||||||
|
|
||||||
As part of the "order selection mechanism" (which is called "mining") it may happen that
|
As part of the "order selection mechanism" (which is called "mining") it may happen that
|
||||||
blocks are reverted from time to time, but only at the "tip" of the chain. The more
|
blocks are reverted from time to time, but only at the "tip" of the chain. The more
|
||||||
@ -564,7 +564,7 @@ contracts, the Ether is forever lost.
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a
|
From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a
|
||||||
deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behaviour
|
deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior
|
||||||
as stated in `EIP-6049 <https://eips.ethereum.org/EIPS/eip-6049>`_.
|
as stated in `EIP-6049 <https://eips.ethereum.org/EIPS/eip-6049>`_.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
@ -591,7 +591,7 @@ Precompiled Contracts
|
|||||||
There is a small set of contract addresses that are special:
|
There is a small set of contract addresses that are special:
|
||||||
The address range between ``1`` and (including) ``8`` contains
|
The address range between ``1`` and (including) ``8`` contains
|
||||||
"precompiled contracts" that can be called as any other contract
|
"precompiled contracts" that can be called as any other contract
|
||||||
but their behaviour (and their gas consumption) is not defined
|
but their behavior (and their gas consumption) is not defined
|
||||||
by EVM code stored at that address (they do not contain code)
|
by EVM code stored at that address (they do not contain code)
|
||||||
but instead is implemented in the EVM execution environment itself.
|
but instead is implemented in the EVM execution environment itself.
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@ The IR-based code generator was introduced with an aim to not only allow
|
|||||||
code generation to be more transparent and auditable but also
|
code generation to be more transparent and auditable but also
|
||||||
to enable more powerful optimization passes that span across functions.
|
to enable more powerful optimization passes that span across functions.
|
||||||
|
|
||||||
You can enable it on the command line using ``--via-ir``
|
You can enable it on the command-line using ``--via-ir``
|
||||||
or with the option ``{"viaIR": true}`` in standard-json and we
|
or with the option ``{"viaIR": true}`` in standard-json and we
|
||||||
encourage everyone to try it out!
|
encourage everyone to try it out!
|
||||||
|
|
||||||
For several reasons, there are tiny semantic differences between the old
|
For several reasons, there are tiny semantic differences between the old
|
||||||
and the IR-based code generator, mostly in areas where we would not
|
and the IR-based code generator, mostly in areas where we would not
|
||||||
expect people to rely on this behaviour anyway.
|
expect people to rely on this behavior anyway.
|
||||||
This section highlights the main differences between the old and the IR-based codegen.
|
This section highlights the main differences between the old and the IR-based codegen.
|
||||||
|
|
||||||
Semantic Only Changes
|
Semantic Only Changes
|
||||||
@ -30,6 +30,8 @@ Semantic Only Changes
|
|||||||
This section lists the changes that are semantic-only, thus potentially
|
This section lists the changes that are semantic-only, thus potentially
|
||||||
hiding new and different behavior in existing code.
|
hiding new and different behavior in existing code.
|
||||||
|
|
||||||
|
.. _state-variable-initialization-order:
|
||||||
|
|
||||||
- The order of state variable initialization has changed in case of inheritance.
|
- The order of state variable initialization has changed in case of inheritance.
|
||||||
|
|
||||||
The order used to be:
|
The order used to be:
|
||||||
@ -174,8 +176,8 @@ hiding new and different behavior in existing code.
|
|||||||
|
|
||||||
The function ``preincr_u8(1)`` returns the following values:
|
The function ``preincr_u8(1)`` returns the following values:
|
||||||
|
|
||||||
- Old code generator: 3 (``1 + 2``) but the return value is unspecified in general
|
- Old code generator: ``3`` (``1 + 2``) but the return value is unspecified in general
|
||||||
- New code generator: 4 (``2 + 2``) but the return value is not guaranteed
|
- New code generator: ``4`` (``2 + 2``) but the return value is not guaranteed
|
||||||
|
|
||||||
.. index:: ! evaluation order; function arguments
|
.. index:: ! evaluation order; function arguments
|
||||||
|
|
||||||
@ -247,7 +249,7 @@ hiding new and different behavior in existing code.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The function `f()` behaves as follows:
|
The function ``f()`` behaves as follows:
|
||||||
|
|
||||||
- Old code generator: runs out of gas while zeroing the array contents after the large memory allocation
|
- Old code generator: runs out of gas while zeroing the array contents after the large memory allocation
|
||||||
- New code generator: reverts due to free memory pointer overflow (does not run out of gas)
|
- New code generator: reverts due to free memory pointer overflow (does not run out of gas)
|
||||||
|
@ -1,27 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<svg width="100" height="160" viewBox="0 0 100 160" fill="#2B247C" xmlns="http://www.w3.org/2000/svg">
|
||||||
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
|
||||||
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
<path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
|
||||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1300px" height="1300px"
|
<path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
|
||||||
viewBox="0 0 1300 1300" enable-background="new 0 0 1300 1300" xml:space="preserve">
|
<path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
|
||||||
<title>Vector 1</title>
|
<path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
|
||||||
<desc>Created with Sketch.</desc>
|
|
||||||
<g id="Page-1" sketch:type="MSPage">
|
|
||||||
<g id="solidity" transform="translate(402.000000, 118.000000)" sketch:type="MSLayerGroup">
|
|
||||||
<g id="Group" sketch:type="MSShapeGroup">
|
|
||||||
<path id="Shape" opacity="0.45" enable-background="new " d="M371.772,135.308L241.068,367.61H-20.158l130.614-232.302
|
|
||||||
H371.772"/>
|
|
||||||
<path id="Shape_1_" opacity="0.6" enable-background="new " d="M241.068,367.61h261.318L371.772,135.308H110.456
|
|
||||||
L241.068,367.61z"/>
|
|
||||||
<path id="Shape_2_" opacity="0.8" enable-background="new " d="M110.456,599.822L241.068,367.61L110.456,135.308
|
|
||||||
L-20.158,367.61L110.456,599.822z"/>
|
|
||||||
<path id="Shape_3_" opacity="0.45" enable-background="new " d="M111.721,948.275l130.704-232.303h261.318L373.038,948.275
|
|
||||||
H111.721"/>
|
|
||||||
<path id="Shape_4_" opacity="0.6" enable-background="new " d="M242.424,715.973H-18.893l130.613,232.303h261.317
|
|
||||||
L242.424,715.973z"/>
|
|
||||||
<path id="Shape_5_" opacity="0.8" enable-background="new " d="M373.038,483.761L242.424,715.973l130.614,232.303
|
|
||||||
l130.704-232.303L373.038,483.761z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 574 B |
@ -28,6 +28,7 @@ if "%1" == "help" (
|
|||||||
echo. devhelp to make HTML files and a Devhelp project
|
echo. devhelp to make HTML files and a Devhelp project
|
||||||
echo. epub to make an epub
|
echo. epub to make an epub
|
||||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||||
|
echo. latexpdf to make LaTeX files and run them through pdflatex
|
||||||
echo. text to make text files
|
echo. text to make text files
|
||||||
echo. man to make manual pages
|
echo. man to make manual pages
|
||||||
echo. texinfo to make Texinfo files
|
echo. texinfo to make Texinfo files
|
||||||
@ -155,16 +156,6 @@ if "%1" == "latexpdf" (
|
|||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "latexpdfja" (
|
|
||||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
|
||||||
cd %BUILDDIR%/latex
|
|
||||||
make all-pdf-ja
|
|
||||||
cd %BUILDDIR%/..
|
|
||||||
echo.
|
|
||||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
|
||||||
goto end
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "text" (
|
if "%1" == "text" (
|
||||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
|
@ -6,18 +6,19 @@ Contract Metadata
|
|||||||
|
|
||||||
.. index:: metadata, contract verification
|
.. index:: metadata, contract verification
|
||||||
|
|
||||||
The Solidity compiler automatically generates a JSON file, the contract
|
The Solidity compiler automatically generates a JSON file.
|
||||||
metadata, that contains information about the compiled contract. You can use
|
The file contains two kinds of information about the compiled contract:
|
||||||
this file to query the compiler version, the sources used, the ABI and NatSpec
|
|
||||||
documentation to more safely interact with the contract and verify its source
|
- How to interact with the contract: ABI, and NatSpec documentation.
|
||||||
code.
|
- How to reproduce the compilation and verify a deployed contract:
|
||||||
|
compiler version, compiler settings, and source files used.
|
||||||
|
|
||||||
The compiler appends by default the IPFS hash of the metadata file to the end
|
The compiler appends by default the IPFS hash of the metadata file to the end
|
||||||
of the bytecode (for details, see below) of each contract, so that you can
|
of the runtime bytecode (not necessarily the creation bytecode) of each contract,
|
||||||
retrieve the file in an authenticated way without having to resort to a
|
so that, if published, you can retrieve the file in an authenticated way without
|
||||||
centralized data provider. The other available options are the Swarm hash and
|
having to resort to a centralized data provider. The other available options are
|
||||||
not appending the metadata hash to the bytecode. These can be configured via
|
the Swarm hash and not appending the metadata hash to the bytecode. These can be
|
||||||
the :ref:`Standard JSON Interface<compiler-api>`.
|
configured via the :ref:`Standard JSON Interface<compiler-api>`.
|
||||||
|
|
||||||
You have to publish the metadata file to IPFS, Swarm, or another service so
|
You have to publish the metadata file to IPFS, Swarm, or another service so
|
||||||
that others can access it. You create the file by using the ``solc --metadata``
|
that others can access it. You create the file by using the ``solc --metadata``
|
||||||
@ -30,108 +31,50 @@ shall match with the one contained in the bytecode.
|
|||||||
|
|
||||||
The metadata file has the following format. The example below is presented in a
|
The metadata file has the following format. The example below is presented in a
|
||||||
human-readable way. Properly formatted metadata should use quotes correctly,
|
human-readable way. Properly formatted metadata should use quotes correctly,
|
||||||
reduce whitespace to a minimum and sort the keys of all objects to arrive at a
|
reduce whitespace to a minimum, and sort the keys of all objects in alphabetical order
|
||||||
unique formatting. Comments are not permitted and used here only for
|
to arrive at a canonical formatting. Comments are not permitted and are used here only for
|
||||||
explanatory purposes.
|
explanatory purposes.
|
||||||
|
|
||||||
.. code-block:: javascript
|
.. code-block:: javascript
|
||||||
|
|
||||||
{
|
{
|
||||||
// Required: The version of the metadata format
|
|
||||||
"version": "1",
|
|
||||||
// Required: Source code language, basically selects a "sub-version"
|
|
||||||
// of the specification
|
|
||||||
"language": "Solidity",
|
|
||||||
// Required: Details about the compiler, contents are specific
|
// Required: Details about the compiler, contents are specific
|
||||||
// to the language.
|
// to the language.
|
||||||
"compiler": {
|
"compiler": {
|
||||||
// Required for Solidity: Version of the compiler
|
|
||||||
"version": "0.8.2+commit.661d1103",
|
|
||||||
// Optional: Hash of the compiler binary which produced this output
|
// Optional: Hash of the compiler binary which produced this output
|
||||||
"keccak256": "0x123..."
|
"keccak256": "0x123...",
|
||||||
},
|
// Required for Solidity: Version of the compiler
|
||||||
// Required: Compilation source files/source units, keys are file paths
|
"version": "0.8.2+commit.661d1103"
|
||||||
"sources":
|
|
||||||
{
|
|
||||||
"myDirectory/myFile.sol": {
|
|
||||||
// Required: keccak256 hash of the source file
|
|
||||||
"keccak256": "0x123...",
|
|
||||||
// Required (unless "content" is used, see below): Sorted URL(s)
|
|
||||||
// to the source file, protocol is more or less arbitrary, but an
|
|
||||||
// IPFS URL is recommended
|
|
||||||
"urls": [ "bzz-raw://7d7a...", "dweb:/ipfs/QmN..." ],
|
|
||||||
// Optional: SPDX license identifier as given in the source file
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"destructible": {
|
|
||||||
// Required: keccak256 hash of the source file
|
|
||||||
"keccak256": "0x234...",
|
|
||||||
// Required (unless "url" is used): literal contents of the source file
|
|
||||||
"content": "contract destructible is owned { function destroy() { if (msg.sender == owner) selfdestruct(owner); } }"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Required: Compiler settings
|
|
||||||
"settings":
|
|
||||||
{
|
|
||||||
// Required for Solidity: Sorted list of import remappings
|
|
||||||
"remappings": [ ":g=/dir" ],
|
|
||||||
// Optional: Optimizer settings. The fields "enabled" and "runs" are deprecated
|
|
||||||
// and are only given for backwards-compatibility.
|
|
||||||
"optimizer": {
|
|
||||||
"enabled": true,
|
|
||||||
"runs": 500,
|
|
||||||
"details": {
|
|
||||||
// peephole defaults to "true"
|
|
||||||
"peephole": true,
|
|
||||||
// inliner defaults to "true"
|
|
||||||
"inliner": true,
|
|
||||||
// jumpdestRemover defaults to "true"
|
|
||||||
"jumpdestRemover": true,
|
|
||||||
"orderLiterals": false,
|
|
||||||
"deduplicate": false,
|
|
||||||
"cse": false,
|
|
||||||
"constantOptimizer": false,
|
|
||||||
"yul": true,
|
|
||||||
// Optional: Only present if "yul" is "true"
|
|
||||||
"yulDetails": {
|
|
||||||
"stackAllocation": false,
|
|
||||||
"optimizerSteps": "dhfoDgvulfnTUtnIf..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
// Reflects the setting used in the input json, defaults to "true"
|
|
||||||
"appendCBOR": true,
|
|
||||||
// Reflects the setting used in the input json, defaults to "false"
|
|
||||||
"useLiteralContent": true,
|
|
||||||
// Reflects the setting used in the input json, defaults to "ipfs"
|
|
||||||
"bytecodeHash": "ipfs"
|
|
||||||
},
|
|
||||||
// Required for Solidity: File path and the name of the contract or library this
|
|
||||||
// metadata is created for.
|
|
||||||
"compilationTarget": {
|
|
||||||
"myDirectory/myFile.sol": "MyContract"
|
|
||||||
},
|
|
||||||
// Required for Solidity: Addresses for libraries used
|
|
||||||
"libraries": {
|
|
||||||
"MyLib": "0x123123..."
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
// Required: Source code language, basically selects a "sub-version"
|
||||||
|
// of the specification
|
||||||
|
"language": "Solidity",
|
||||||
// Required: Generated information about the contract.
|
// Required: Generated information about the contract.
|
||||||
"output":
|
"output": {
|
||||||
{
|
|
||||||
// Required: ABI definition of the contract. See "Contract ABI Specification"
|
// Required: ABI definition of the contract. See "Contract ABI Specification"
|
||||||
"abi": [/* ... */],
|
"abi": [/* ... */],
|
||||||
// Required: NatSpec developer documentation of the contract.
|
// Required: NatSpec developer documentation of the contract. See https://docs.soliditylang.org/en/latest/natspec-format.html for details.
|
||||||
"devdoc": {
|
"devdoc": {
|
||||||
"version": 1 // NatSpec version
|
|
||||||
"kind": "dev",
|
|
||||||
// Contents of the @author NatSpec field of the contract
|
// Contents of the @author NatSpec field of the contract
|
||||||
"author": "John Doe",
|
"author": "John Doe",
|
||||||
// Contents of the @title NatSpec field of the contract
|
|
||||||
"title": "MyERC20: an example ERC20"
|
|
||||||
// Contents of the @dev NatSpec field of the contract
|
// Contents of the @dev NatSpec field of the contract
|
||||||
"details": "Interface of the ERC20 standard as defined in the EIP. See https://eips.ethereum.org/EIPS/eip-20 for details",
|
"details": "Interface of the ERC20 standard as defined in the EIP. See https://eips.ethereum.org/EIPS/eip-20 for details",
|
||||||
|
"errors": {
|
||||||
|
"MintToZeroAddress()" : {
|
||||||
|
"details": "Cannot mint to zero address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"Transfer(address,address,uint256)": {
|
||||||
|
"details": "Emitted when `value` tokens are moved from one account (`from`) toanother (`to`).",
|
||||||
|
"params": {
|
||||||
|
"from": "The sender address",
|
||||||
|
"to": "The receiver address",
|
||||||
|
"value": "The token amount"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kind": "dev",
|
||||||
"methods": {
|
"methods": {
|
||||||
"transfer(address,uint256)": {
|
"transfer(address,uint256)": {
|
||||||
// Contents of the @dev NatSpec field of the method
|
// Contents of the @dev NatSpec field of the method
|
||||||
@ -140,7 +83,7 @@ explanatory purposes.
|
|||||||
"params": {
|
"params": {
|
||||||
"_value": "The amount tokens to be transferred",
|
"_value": "The amount tokens to be transferred",
|
||||||
"_to": "The receiver address"
|
"_to": "The receiver address"
|
||||||
}
|
},
|
||||||
// Contents of the @return NatSpec field.
|
// Contents of the @return NatSpec field.
|
||||||
"returns": {
|
"returns": {
|
||||||
// Return var name (here "success") if exists. "_0" as key if return var is unnamed
|
// Return var name (here "success") if exists. "_0" as key if return var is unnamed
|
||||||
@ -153,34 +96,104 @@ explanatory purposes.
|
|||||||
// Contents of the @dev NatSpec field of the state variable
|
// Contents of the @dev NatSpec field of the state variable
|
||||||
"details": "Must be set during contract creation. Can then only be changed by the owner"
|
"details": "Must be set during contract creation. Can then only be changed by the owner"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
"events": {
|
// Contents of the @title NatSpec field of the contract
|
||||||
"Transfer(address,address,uint256)": {
|
"title": "MyERC20: an example ERC20",
|
||||||
"details": "Emitted when `value` tokens are moved from one account (`from`) toanother (`to`)."
|
|
||||||
"params": {
|
|
||||||
"from": "The sender address"
|
|
||||||
"to": "The receiver address"
|
|
||||||
"value": "The token amount"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Required: NatSpec user documentation of the contract
|
|
||||||
"userdoc": {
|
|
||||||
"version": 1 // NatSpec version
|
"version": 1 // NatSpec version
|
||||||
|
},
|
||||||
|
// Required: NatSpec user documentation of the contract. See "NatSpec Format"
|
||||||
|
"userdoc": {
|
||||||
|
"errors": {
|
||||||
|
"ApprovalCallerNotOwnerNorApproved()": [
|
||||||
|
{
|
||||||
|
"notice": "The caller must own the token or be an approved operator."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"Transfer(address,address,uint256)": {
|
||||||
|
"notice": "`_value` tokens have been moved from `from` to `to`"
|
||||||
|
}
|
||||||
|
},
|
||||||
"kind": "user",
|
"kind": "user",
|
||||||
"methods": {
|
"methods": {
|
||||||
"transfer(address,uint256)": {
|
"transfer(address,uint256)": {
|
||||||
"notice": "Transfers `_value` tokens to address `_to`"
|
"notice": "Transfers `_value` tokens to address `_to`"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"events": {
|
"version": 1 // NatSpec version
|
||||||
"Transfer(address,address,uint256)": {
|
|
||||||
"notice": "`_value` tokens have been moved from `from` to `to`"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
// Required: Compiler settings. Reflects the settings in the JSON input during compilation.
|
||||||
|
// Check the documentation of standard JSON input's "settings" field
|
||||||
|
"settings": {
|
||||||
|
// Required for Solidity: File path and the name of the contract or library this
|
||||||
|
// metadata is created for.
|
||||||
|
"compilationTarget": {
|
||||||
|
"myDirectory/myFile.sol": "MyContract"
|
||||||
|
},
|
||||||
|
// Required for Solidity.
|
||||||
|
"evmVersion": "london",
|
||||||
|
// Required for Solidity: Addresses for libraries used.
|
||||||
|
"libraries": {
|
||||||
|
"MyLib": "0x123123..."
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
// Reflects the setting used in the input json, defaults to "true"
|
||||||
|
"appendCBOR": true,
|
||||||
|
// Reflects the setting used in the input json, defaults to "ipfs"
|
||||||
|
"bytecodeHash": "ipfs",
|
||||||
|
// Reflects the setting used in the input json, defaults to "false"
|
||||||
|
"useLiteralContent": true
|
||||||
|
},
|
||||||
|
// Optional: Optimizer settings. The fields "enabled" and "runs" are deprecated
|
||||||
|
// and are only given for backward-compatibility.
|
||||||
|
"optimizer": {
|
||||||
|
"details": {
|
||||||
|
"constantOptimizer": false,
|
||||||
|
"cse": false,
|
||||||
|
"deduplicate": false,
|
||||||
|
// inliner defaults to "false"
|
||||||
|
"inliner": false,
|
||||||
|
// jumpdestRemover defaults to "true"
|
||||||
|
"jumpdestRemover": true,
|
||||||
|
"orderLiterals": false,
|
||||||
|
// peephole defaults to "true"
|
||||||
|
"peephole": true,
|
||||||
|
"yul": true,
|
||||||
|
// Optional: Only present if "yul" is "true"
|
||||||
|
"yulDetails": {
|
||||||
|
"optimizerSteps": "dhfoDgvulfnTUtnIf...",
|
||||||
|
"stackAllocation": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enabled": true,
|
||||||
|
"runs": 500
|
||||||
|
},
|
||||||
|
// Required for Solidity: Sorted list of import remappings.
|
||||||
|
"remappings": [ ":g=/dir" ]
|
||||||
|
},
|
||||||
|
// Required: Compilation source files/source units, keys are file paths
|
||||||
|
"sources": {
|
||||||
|
"destructible": {
|
||||||
|
// Required (unless "url" is used): literal contents of the source file
|
||||||
|
"content": "contract destructible is owned { function destroy() { if (msg.sender == owner) selfdestruct(owner); } }",
|
||||||
|
// Required: keccak256 hash of the source file
|
||||||
|
"keccak256": "0x234..."
|
||||||
|
},
|
||||||
|
"myDirectory/myFile.sol": {
|
||||||
|
// Required: keccak256 hash of the source file
|
||||||
|
"keccak256": "0x123...",
|
||||||
|
// Optional: SPDX license identifier as given in the source file
|
||||||
|
"license": "MIT",
|
||||||
|
// Required (unless "content" is used, see above): Sorted URL(s)
|
||||||
|
// to the source file, protocol is more or less arbitrary, but an
|
||||||
|
// IPFS URL is recommended
|
||||||
|
"urls": [ "bzz-raw://7d7a...", "dweb:/ipfs/QmN..." ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Required: The version of the metadata format
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
@ -200,26 +213,35 @@ explanatory purposes.
|
|||||||
Encoding of the Metadata Hash in the Bytecode
|
Encoding of the Metadata Hash in the Bytecode
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
Because we might support other ways to retrieve the metadata file in the future,
|
The compiler currently by default appends the
|
||||||
the mapping ``{"ipfs": <IPFS hash>, "solc": <compiler version>}`` is stored
|
`IPFS hash (in CID v0) <https://docs.ipfs.tech/concepts/content-addressing/#version-0-v0>`_
|
||||||
`CBOR <https://tools.ietf.org/html/rfc7049>`_-encoded. Since the mapping might
|
of the canonical metadata file and the compiler version to the end of the bytecode.
|
||||||
contain more keys (see below) and the beginning of that
|
Optionally, a Swarm hash instead of the IPFS, or an experimental flag is used.
|
||||||
encoding is not easy to find, its length is added in a two-byte big-endian
|
Below are all the possible fields:
|
||||||
encoding. The current version of the Solidity compiler usually adds the following
|
|
||||||
to the end of the deployed bytecode
|
|
||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: javascript
|
||||||
|
|
||||||
0xa2
|
{
|
||||||
0x64 'i' 'p' 'f' 's' 0x58 0x22 <34 bytes IPFS hash>
|
"ipfs": "<metadata hash>",
|
||||||
0x64 's' 'o' 'l' 'c' 0x43 <3 byte version encoding>
|
// If "bytecodeHash" was "bzzr1" in compiler settings not "ipfs" but "bzzr1"
|
||||||
0x00 0x33
|
"bzzr1": "<metadata hash>",
|
||||||
|
// Previous versions were using "bzzr0" instead of "bzzr1"
|
||||||
|
"bzzr0": "<metadata hash>",
|
||||||
|
// If any experimental features that affect code generation are used
|
||||||
|
"experimental": true,
|
||||||
|
"solc": "<compiler version>"
|
||||||
|
}
|
||||||
|
|
||||||
So in order to retrieve the data, the end of the deployed bytecode can be checked
|
Because we might support other ways to retrieve the
|
||||||
to match that pattern and the IPFS hash can be used to retrieve the file (if pinned/published).
|
metadata file in the future, this information is stored
|
||||||
|
`CBOR <https://tools.ietf.org/html/rfc7049>`_-encoded. The last two bytes in the bytecode
|
||||||
|
indicate the length of the CBOR encoded information. By looking at this length, the
|
||||||
|
relevant part of the bytecode can be decoded with a CBOR decoder.
|
||||||
|
|
||||||
|
Check the `Metadata Playground <https://playground.sourcify.dev/>`_ to see it in action.
|
||||||
|
|
||||||
Whereas release builds of solc use a 3 byte encoding of the version as shown
|
Whereas release builds of solc use a 3 byte encoding of the version as shown
|
||||||
above (one byte each for major, minor and patch version number), prerelease builds
|
above (one byte each for major, minor and patch version number), pre-release builds
|
||||||
will instead use a complete version string including commit hash and build date.
|
will instead use a complete version string including commit hash and build date.
|
||||||
|
|
||||||
The commandline flag ``--no-cbor-metadata`` can be used to skip metadata
|
The commandline flag ``--no-cbor-metadata`` can be used to skip metadata
|
||||||
@ -228,17 +250,9 @@ boolean field ``settings.metadata.appendCBOR`` in Standard JSON input can be set
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The CBOR mapping can also contain other keys, so it is better to fully
|
The CBOR mapping can also contain other keys, so it is better to fully
|
||||||
decode the data instead of relying on it starting with ``0xa264``.
|
decode the data by looking at the end of the bytecode for the CBOR length,
|
||||||
For example, if any experimental features that affect code generation
|
and to use a proper CBOR parser. Do not rely on it starting with ``0xa264``
|
||||||
are used, the mapping will also contain ``"experimental": true``.
|
or ``0xa2 0x64 'i' 'p' 'f' 's'``.
|
||||||
|
|
||||||
.. note::
|
|
||||||
The compiler currently uses the IPFS hash of the metadata by default, but
|
|
||||||
it may also use the bzzr1 hash or some other hash in the future, so do
|
|
||||||
not rely on this sequence to start with ``0xa2 0x64 'i' 'p' 'f' 's'``. We
|
|
||||||
might also add additional data to this CBOR structure, so the best option
|
|
||||||
is to use a proper CBOR parser.
|
|
||||||
|
|
||||||
|
|
||||||
Usage for Automatic Interface Generation and NatSpec
|
Usage for Automatic Interface Generation and NatSpec
|
||||||
====================================================
|
====================================================
|
||||||
@ -252,24 +266,27 @@ is JSON-decoded into a structure like above.
|
|||||||
The component can then use the ABI to automatically generate a rudimentary
|
The component can then use the ABI to automatically generate a rudimentary
|
||||||
user interface for the contract.
|
user interface for the contract.
|
||||||
|
|
||||||
Furthermore, the wallet can use the NatSpec user documentation to display a human-readable confirmation message to the user
|
Furthermore, the wallet can use the NatSpec user documentation to display a
|
||||||
whenever they interact with the contract, together with requesting
|
human-readable confirmation message to the user whenever they interact with
|
||||||
authorization for the transaction signature.
|
the contract, together with requesting authorization for the transaction signature.
|
||||||
|
|
||||||
For additional information, read :doc:`Ethereum Natural Language Specification (NatSpec) format <natspec-format>`.
|
For additional information, read :doc:`Ethereum Natural Language Specification (NatSpec) format <natspec-format>`.
|
||||||
|
|
||||||
Usage for Source Code Verification
|
Usage for Source Code Verification
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
In order to verify the compilation, sources can be retrieved from IPFS/Swarm
|
If pinned/published, it is possible to retrieve the metadata of the contract from IPFS/Swarm.
|
||||||
via the link in the metadata file.
|
The metadata file also contains the URLs or the IPFS hashes of the source files, as well as
|
||||||
The compiler of the correct version (which is checked to be part of the "official" compilers)
|
the compilation settings, i.e. everything needed to reproduce a compilation.
|
||||||
is invoked on that input with the specified settings. The resulting
|
|
||||||
bytecode is compared to the data of the creation transaction or ``CREATE`` opcode data.
|
|
||||||
This automatically verifies the metadata since its hash is part of the bytecode.
|
|
||||||
Excess data corresponds to the constructor input data, which should be decoded
|
|
||||||
according to the interface and presented to the user.
|
|
||||||
|
|
||||||
In the repository `sourcify <https://github.com/ethereum/sourcify>`_
|
With this information it is then possible to verify the source code of a contract by
|
||||||
(`npm package <https://www.npmjs.com/package/source-verify>`_) you can see
|
reproducing the compilation, and comparing the bytecode from the compilation with
|
||||||
example code that shows how to use this feature.
|
the bytecode of the deployed contract.
|
||||||
|
|
||||||
|
This automatically verifies the metadata since its hash is part of the bytecode, as well
|
||||||
|
as the source codes, because their hashes are part of the metadata. Any change in the files
|
||||||
|
or settings would result in a different metadata hash. The metadata here serves
|
||||||
|
as a fingerprint of the whole compilation.
|
||||||
|
|
||||||
|
`Sourcify <https://sourcify.dev>`_ makes use of this feature for "full/perfect verification",
|
||||||
|
as well as pinning the files publicly on IPFS to be accessed with the metadata hash.
|
||||||
|
@ -58,7 +58,7 @@ The following example shows a contract and a function using all available tags.
|
|||||||
|
|
||||||
This may change in the future.
|
This may change in the future.
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.8.2 < 0.9.0;
|
pragma solidity >=0.8.2 < 0.9.0;
|
||||||
|
@ -139,7 +139,7 @@ The initial content of the VFS depends on how you invoke the compiler:
|
|||||||
|
|
||||||
#. **Standard input**
|
#. **Standard input**
|
||||||
|
|
||||||
On the command line it is also possible to provide the source by sending it to compiler's
|
On the command-line it is also possible to provide the source by sending it to compiler's
|
||||||
standard input:
|
standard input:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
@ -253,6 +253,7 @@ The compiler resolves the import into a source unit name based on the import pat
|
|||||||
#. We start with the source unit name of the importing source unit.
|
#. We start with the source unit name of the importing source unit.
|
||||||
#. The last path segment with preceding slashes is removed from the resolved name.
|
#. The last path segment with preceding slashes is removed from the resolved name.
|
||||||
#. Then, for every segment in the import path, starting from the leftmost one:
|
#. Then, for every segment in the import path, starting from the leftmost one:
|
||||||
|
|
||||||
- If the segment is ``.``, it is skipped.
|
- If the segment is ``.``, it is skipped.
|
||||||
- If the segment is ``..``, the last path segment with preceding slashes is removed from the resolved name.
|
- If the segment is ``..``, the last path segment with preceding slashes is removed from the resolved name.
|
||||||
- Otherwise, the segment (preceded by a single slash if the resolved name is not empty), is appended to the resolved name.
|
- Otherwise, the segment (preceded by a single slash if the resolved name is not empty), is appended to the resolved name.
|
||||||
@ -344,13 +345,13 @@ of the compiler.
|
|||||||
CLI Path Normalization and Stripping
|
CLI Path Normalization and Stripping
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
On the command line the compiler behaves just as you would expect from any other program:
|
On the command-line the compiler behaves just as you would expect from any other program:
|
||||||
it accepts paths in a format native to the platform and relative paths are relative to the current
|
it accepts paths in a format native to the platform and relative paths are relative to the current
|
||||||
working directory.
|
working directory.
|
||||||
The source unit names assigned to files whose paths are specified on the command line, however,
|
The source unit names assigned to files whose paths are specified on the command-line, however,
|
||||||
should not change just because the project is being compiled on a different platform or because the
|
should not change just because the project is being compiled on a different platform or because the
|
||||||
compiler happens to have been invoked from a different directory.
|
compiler happens to have been invoked from a different directory.
|
||||||
To achieve this, paths to source files coming from the command line must be converted to a canonical
|
To achieve this, paths to source files coming from the command-line must be converted to a canonical
|
||||||
form, and, if possible, made relative to the base path or one of the include paths.
|
form, and, if possible, made relative to the base path or one of the include paths.
|
||||||
|
|
||||||
The normalization rules are as follows:
|
The normalization rules are as follows:
|
||||||
@ -407,7 +408,7 @@ The resulting file path becomes the source unit name.
|
|||||||
Prior to version 0.8.8, CLI path stripping was not performed and the only normalization applied
|
Prior to version 0.8.8, CLI path stripping was not performed and the only normalization applied
|
||||||
was the conversion of path separators.
|
was the conversion of path separators.
|
||||||
When working with older versions of the compiler it is recommended to invoke the compiler from
|
When working with older versions of the compiler it is recommended to invoke the compiler from
|
||||||
the base path and to only use relative paths on the command line.
|
the base path and to only use relative paths on the command-line.
|
||||||
|
|
||||||
.. index:: ! allowed paths, ! --allow-paths, remapping; target
|
.. index:: ! allowed paths, ! --allow-paths, remapping; target
|
||||||
.. _allowed-paths:
|
.. _allowed-paths:
|
||||||
@ -420,7 +421,7 @@ locations that are considered safe by default:
|
|||||||
|
|
||||||
- Outside of Standard JSON mode:
|
- Outside of Standard JSON mode:
|
||||||
|
|
||||||
- The directories containing input files listed on the command line.
|
- The directories containing input files listed on the command-line.
|
||||||
- The directories used as :ref:`remapping <import-remapping>` targets.
|
- The directories used as :ref:`remapping <import-remapping>` targets.
|
||||||
If the target is not a directory (i.e does not end with ``/``, ``/.`` or ``/..``) the directory
|
If the target is not a directory (i.e does not end with ``/``, ``/.`` or ``/..``) the directory
|
||||||
containing the target is used instead.
|
containing the target is used instead.
|
||||||
@ -514,7 +515,7 @@ you can use the following in your source file:
|
|||||||
|
|
||||||
The compiler will look for the file in the VFS under ``dapp-bin/library/math.sol``.
|
The compiler will look for the file in the VFS under ``dapp-bin/library/math.sol``.
|
||||||
If the file is not available there, the source unit name will be passed to the Host Filesystem
|
If the file is not available there, the source unit name will be passed to the Host Filesystem
|
||||||
Loader, which will then look in ``/project/dapp-bin/library/iterable_mapping.sol``.
|
Loader, which will then look in ``/project/dapp-bin/library/math.sol``.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
@ -550,7 +551,7 @@ you checked out to ``/project/dapp-bin_old``, then you can run:
|
|||||||
This means that all imports in ``module2`` point to the old version but imports in ``module1``
|
This means that all imports in ``module2`` point to the old version but imports in ``module1``
|
||||||
point to the new version.
|
point to the new version.
|
||||||
|
|
||||||
Here are the detailed rules governing the behaviour of remappings:
|
Here are the detailed rules governing the behavior of remappings:
|
||||||
|
|
||||||
#. **Remappings only affect the translation between import paths and source unit names.**
|
#. **Remappings only affect the translation between import paths and source unit names.**
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ Integrated (Ethereum) Development Environments
|
|||||||
Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine.
|
Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine.
|
||||||
|
|
||||||
* `Dapp <https://dapp.tools/>`_
|
* `Dapp <https://dapp.tools/>`_
|
||||||
Tool for building, testing and deploying smart contracts from the command line.
|
Tool for building, testing and deploying smart contracts from the command-line.
|
||||||
|
|
||||||
* `Embark <https://framework.embarklabs.io/>`_
|
* `Embark <https://framework.embarklabs.io/>`_
|
||||||
Developer platform for building and deploying decentralized applications.
|
Developer platform for building and deploying decentralized applications.
|
||||||
@ -71,7 +71,7 @@ Editor Integrations
|
|||||||
|
|
||||||
* Visual Studio Code (VS Code)
|
* Visual Studio Code (VS Code)
|
||||||
|
|
||||||
* `Ethereum Remix Visual Studio Code extension <https://marketplace.visualstudio.com/items?itemName=RemixProject.ethereum-remix>`_
|
* `Ethereum Remix Visual Studio Code extension <https://github.com/ethereum/remix-vscode>`_
|
||||||
Ethereum Remix extension pack for VS Code
|
Ethereum Remix extension pack for VS Code
|
||||||
|
|
||||||
* `Solidity Visual Studio Code extension, by Juan Blanco <https://juan.blanco.ws/solidity-contracts-in-visual-studio-code/>`_
|
* `Solidity Visual Studio Code extension, by Juan Blanco <https://juan.blanco.ws/solidity-contracts-in-visual-studio-code/>`_
|
||||||
@ -113,9 +113,6 @@ Solidity Tools
|
|||||||
* `leafleth <https://github.com/clemlak/leafleth>`_
|
* `leafleth <https://github.com/clemlak/leafleth>`_
|
||||||
A documentation generator for Solidity smart-contracts.
|
A documentation generator for Solidity smart-contracts.
|
||||||
|
|
||||||
* `PIET <https://piet.slock.it/>`_
|
|
||||||
A tool to develop, audit and use Solidity smart contracts through a simple graphical interface.
|
|
||||||
|
|
||||||
* `Scaffold-ETH <https://github.com/scaffold-eth/scaffold-eth>`_
|
* `Scaffold-ETH <https://github.com/scaffold-eth/scaffold-eth>`_
|
||||||
Forkable Ethereum development stack focused on fast product iterations.
|
Forkable Ethereum development stack focused on fast product iterations.
|
||||||
|
|
||||||
|
@ -7,28 +7,28 @@ Security Considerations
|
|||||||
While it is usually quite easy to build software that works as expected,
|
While it is usually quite easy to build software that works as expected,
|
||||||
it is much harder to check that nobody can use it in a way that was **not** anticipated.
|
it is much harder to check that nobody can use it in a way that was **not** anticipated.
|
||||||
|
|
||||||
In Solidity, this is even more important because you can use smart contracts
|
In Solidity, this is even more important because you can use smart contracts to handle tokens or,
|
||||||
to handle tokens or, possibly, even more valuable things. Furthermore, every
|
possibly, even more valuable things.
|
||||||
execution of a smart contract happens in public and, in addition to that,
|
Furthermore, every execution of a smart contract happens in public and,
|
||||||
the source code is often available.
|
in addition to that, the source code is often available.
|
||||||
|
|
||||||
Of course you always have to consider how much is at stake:
|
Of course, you always have to consider how much is at stake:
|
||||||
You can compare a smart contract with a web service that is open to the
|
You can compare a smart contract with a web service that is open to the public
|
||||||
public (and thus, also to malicious actors) and perhaps even open source.
|
(and thus, also to malicious actors) and perhaps even open-source.
|
||||||
If you only store your grocery list on that web service, you might not have
|
If you only store your grocery list on that web service, you might not have to take too much care,
|
||||||
to take too much care, but if you manage your bank account using that web service,
|
but if you manage your bank account using that web service, you should be more careful.
|
||||||
you should be more careful.
|
|
||||||
|
|
||||||
This section will list some pitfalls and general security recommendations but
|
This section will list some pitfalls and general security recommendations
|
||||||
can, of course, never be complete. Also, keep in mind that even if your smart
|
but can, of course, never be complete.
|
||||||
contract code is bug-free, the compiler or the platform itself might have a
|
Also, keep in mind that even if your smart contract code is bug-free,
|
||||||
bug. A list of some publicly known security-relevant bugs of the compiler can
|
the compiler or the platform itself might have a bug.
|
||||||
be found in the :ref:`list of known bugs<known_bugs>`, which is also
|
A list of some publicly known security-relevant bugs of the compiler can be found
|
||||||
machine-readable. Note that there is a bug bounty program that covers the code
|
in the :ref:`list of known bugs<known_bugs>`, which is also machine-readable.
|
||||||
generator of the Solidity compiler.
|
Note that there is a `Bug Bounty Program <https://ethereum.org/en/bug-bounty/>`_
|
||||||
|
that covers the code generator of the Solidity compiler.
|
||||||
|
|
||||||
As always, with open source documentation, please help us extend this section
|
As always, with open-source documentation,
|
||||||
(especially, some examples would not hurt)!
|
please help us extend this section (especially, some examples would not hurt)!
|
||||||
|
|
||||||
NOTE: In addition to the list below, you can find more security recommendations and best practices
|
NOTE: In addition to the list below, you can find more security recommendations and best practices
|
||||||
`in Guy Lando's knowledge list <https://github.com/guylando/KnowledgeLists/blob/master/EthereumSmartContracts.md>`_ and
|
`in Guy Lando's knowledge list <https://github.com/guylando/KnowledgeLists/blob/master/EthereumSmartContracts.md>`_ and
|
||||||
@ -41,20 +41,18 @@ Pitfalls
|
|||||||
Private Information and Randomness
|
Private Information and Randomness
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
Everything you use in a smart contract is publicly visible, even
|
Everything you use in a smart contract is publicly visible,
|
||||||
local variables and state variables marked ``private``.
|
even local variables and state variables marked ``private``.
|
||||||
|
|
||||||
Using random numbers in smart contracts is quite tricky if you do not want
|
Using random numbers in smart contracts is quite tricky if you do not want block builders to be able to cheat.
|
||||||
block builders to be able to cheat.
|
|
||||||
|
|
||||||
Re-Entrancy
|
Reentrancy
|
||||||
===========
|
==========
|
||||||
|
|
||||||
Any interaction from a contract (A) with another contract (B) and any transfer
|
Any interaction from a contract (A) with another contract (B)
|
||||||
of Ether hands over control to that contract (B). This makes it possible for B
|
and any transfer of Ether hands over control to that contract (B).
|
||||||
to call back into A before this interaction is completed. To give an example,
|
This makes it possible for B to call back into A before this interaction is completed.
|
||||||
the following code contains a bug (it is just a snippet and not a
|
To give an example, the following code contains a bug (it is just a snippet and not a complete contract):
|
||||||
complete contract):
|
|
||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
@ -72,12 +70,12 @@ complete contract):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The problem is not too serious here because of the limited gas as part
|
The problem is not too serious here because of the limited gas as part of ``send``,
|
||||||
of ``send``, but it still exposes a weakness: Ether transfer can always
|
but it still exposes a weakness:
|
||||||
include code execution, so the recipient could be a contract that calls
|
Ether transfer can always include code execution,
|
||||||
back into ``withdraw``. This would let it get multiple refunds and
|
so the recipient could be a contract that calls back into ``withdraw``.
|
||||||
basically retrieve all the Ether in the contract. In particular, the
|
This would let it get multiple refunds and, basically, retrieve all the Ether in the contract.
|
||||||
following contract will allow an attacker to refund multiple times
|
In particular, the following contract will allow an attacker to refund multiple times
|
||||||
as it uses ``call`` which forwards all remaining gas by default:
|
as it uses ``call`` which forwards all remaining gas by default:
|
||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
@ -97,8 +95,7 @@ as it uses ``call`` which forwards all remaining gas by default:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
To avoid re-entrancy, you can use the Checks-Effects-Interactions pattern as
|
To avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demonstrated below:
|
||||||
demonstrated below:
|
|
||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
@ -116,58 +113,58 @@ demonstrated below:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The Checks-Effects-Interactions pattern ensures that all code paths through a contract complete all required checks
|
The Checks-Effects-Interactions pattern ensures that all code paths through a contract
|
||||||
of the supplied parameters before modifying the contract's state (Checks); only then it makes any changes to the state (Effects);
|
complete all required checks of the supplied parameters before modifying the contract's state (Checks);
|
||||||
it may make calls to functions in other contracts *after* all planned state changes have been written to
|
only then it makes any changes to the state (Effects);
|
||||||
storage (Interactions). This is a common foolproof way to prevent *re-entrancy attacks*, where an externally called
|
it may make calls to functions in other contracts
|
||||||
malicious contract is able to double-spend an allowance, double-withdraw a balance, among other things, by using logic that calls back into the
|
*after* all planned state changes have been written to storage (Interactions).
|
||||||
original contract before it has finalized its transaction.
|
This is a common foolproof way to prevent *reentrancy attacks*,
|
||||||
|
where an externally called malicious contract can double-spend an allowance,
|
||||||
|
double-withdraw a balance, among other things,
|
||||||
|
by using logic that calls back into the original contract before it has finalized its transaction.
|
||||||
|
|
||||||
Note that re-entrancy is not only an effect of Ether transfer but of any
|
Note that reentrancy is not only an effect of Ether transfer
|
||||||
function call on another contract. Furthermore, you also have to take
|
but of any function call on another contract.
|
||||||
multi-contract situations into account. A called contract could modify the
|
Furthermore, you also have to take multi-contract situations into account.
|
||||||
state of another contract you depend on.
|
A called contract could modify the state of another contract you depend on.
|
||||||
|
|
||||||
Gas Limit and Loops
|
Gas Limit and Loops
|
||||||
===================
|
===================
|
||||||
|
|
||||||
Loops that do not have a fixed number of iterations, for example, loops that depend on storage values, have to be used carefully:
|
Loops that do not have a fixed number of iterations, for example,
|
||||||
Due to the block gas limit, transactions can only consume a certain amount of gas. Either explicitly or just due to
|
loops that depend on storage values, have to be used carefully:
|
||||||
normal operation, the number of iterations in a loop can grow beyond the block gas limit which can cause the complete
|
Due to the block gas limit, transactions can only consume a certain amount of gas.
|
||||||
contract to be stalled at a certain point. This may not apply to ``view`` functions that are only executed
|
Either explicitly or just due to normal operation,
|
||||||
to read data from the blockchain. Still, such functions may be called by other contracts as part of on-chain operations
|
the number of iterations in a loop can grow beyond the block gas limit
|
||||||
and stall those. Please be explicit about such cases in the documentation of your contracts.
|
which can cause the complete contract to be stalled at a certain point.
|
||||||
|
This may not apply to ``view`` functions that are only executed to read data from the blockchain.
|
||||||
|
Still, such functions may be called by other contracts as part of on-chain operations and stall those.
|
||||||
|
Please be explicit about such cases in the documentation of your contracts.
|
||||||
|
|
||||||
Sending and Receiving Ether
|
Sending and Receiving Ether
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
- Neither contracts nor "external accounts" are currently able to prevent that someone sends them Ether.
|
- Neither contracts nor "external accounts" are currently able to prevent someone from sending them Ether.
|
||||||
Contracts can react on and reject a regular transfer, but there are ways
|
Contracts can react on and reject a regular transfer, but there are ways to move Ether without creating a message call.
|
||||||
to move Ether without creating a message call. One way is to simply "mine to"
|
One way is to simply "mine to" the contract address and the second way is using ``selfdestruct(x)``.
|
||||||
the contract address and the second way is using ``selfdestruct(x)``.
|
|
||||||
|
|
||||||
- If a contract receives Ether (without a function being called),
|
- If a contract receives Ether (without a function being called), either the :ref:`receive Ether <receive-ether-function>`
|
||||||
either the :ref:`receive Ether <receive-ether-function>`
|
|
||||||
or the :ref:`fallback <fallback-function>` function is executed.
|
or the :ref:`fallback <fallback-function>` function is executed.
|
||||||
If it does not have a receive nor a fallback function, the Ether will be
|
If it does not have a ``receive`` nor a ``fallback`` function, the Ether will be rejected (by throwing an exception).
|
||||||
rejected (by throwing an exception). During the execution of one of these
|
During the execution of one of these functions, the contract can only rely on the "gas stipend" it is passed (2300 gas)
|
||||||
functions, the contract can only rely on the "gas stipend" it is passed (2300
|
being available to it at that time.
|
||||||
gas) being available to it at that time. This stipend is not enough to modify
|
This stipend is not enough to modify storage (do not take this for granted though, the stipend might change with future hard forks).
|
||||||
storage (do not take this for granted though, the stipend might change with
|
To be sure that your contract can receive Ether in that way, check the gas requirements of the receive and fallback functions
|
||||||
future hard forks). To be sure that your contract can receive Ether in that
|
|
||||||
way, check the gas requirements of the receive and fallback functions
|
|
||||||
(for example in the "details" section in Remix).
|
(for example in the "details" section in Remix).
|
||||||
|
|
||||||
- There is a way to forward more gas to the receiving contract using
|
- There is a way to forward more gas to the receiving contract using ``addr.call{value: x}("")``.
|
||||||
``addr.call{value: x}("")``. This is essentially the same as ``addr.transfer(x)``,
|
This is essentially the same as ``addr.transfer(x)``, only that it forwards all remaining gas
|
||||||
only that it forwards all remaining gas and opens up the ability for the
|
and opens up the ability for the recipient to perform more expensive actions
|
||||||
recipient to perform more expensive actions (and it returns a failure code
|
(and it returns a failure code instead of automatically propagating the error).
|
||||||
instead of automatically propagating the error). This might include calling back
|
This might include calling back into the sending contract or other state changes you might not have thought of.
|
||||||
into the sending contract or other state changes you might not have thought of.
|
|
||||||
So it allows for great flexibility for honest users but also for malicious actors.
|
So it allows for great flexibility for honest users but also for malicious actors.
|
||||||
|
|
||||||
- Use the most precise units to represent the wei amount as possible, as you lose
|
- Use the most precise units to represent the Wei amount as possible, as you lose any that is rounded due to a lack of precision.
|
||||||
any that is rounded due to a lack of precision.
|
|
||||||
|
|
||||||
- If you want to send Ether using ``address.transfer``, there are certain details to be aware of:
|
- If you want to send Ether using ``address.transfer``, there are certain details to be aware of:
|
||||||
|
|
||||||
@ -191,24 +188,28 @@ Sending and Receiving Ether
|
|||||||
Call Stack Depth
|
Call Stack Depth
|
||||||
================
|
================
|
||||||
|
|
||||||
External function calls can fail any time because they exceed the maximum
|
External function calls can fail at any time
|
||||||
call stack size limit of 1024. In such situations, Solidity throws an exception.
|
because they exceed the maximum call stack size limit of 1024.
|
||||||
|
In such situations, Solidity throws an exception.
|
||||||
Malicious actors might be able to force the call stack to a high value
|
Malicious actors might be able to force the call stack to a high value
|
||||||
before they interact with your contract. Note that, since `Tangerine Whistle <https://eips.ethereum.org/EIPS/eip-608>`_ hardfork, the `63/64 rule <https://eips.ethereum.org/EIPS/eip-150>`_ makes call stack depth attack impractical. Also note that the call stack and the expression stack are unrelated, even though both have a size limit of 1024 stack slots.
|
before they interact with your contract.
|
||||||
|
Note that, since `Tangerine Whistle <https://eips.ethereum.org/EIPS/eip-608>`_ hardfork,
|
||||||
|
the `63/64 rule <https://eips.ethereum.org/EIPS/eip-150>`_ makes call stack depth attack impractical.
|
||||||
|
Also note that the call stack and the expression stack are unrelated,
|
||||||
|
even though both have a size limit of 1024 stack slots.
|
||||||
|
|
||||||
Note that ``.send()`` does **not** throw an exception if the call stack is
|
Note that ``.send()`` does **not** throw an exception if the call stack is depleted
|
||||||
depleted but rather returns ``false`` in that case. The low-level functions
|
but rather returns ``false`` in that case.
|
||||||
``.call()``, ``.delegatecall()`` and ``.staticcall()`` behave in the same way.
|
The low-level functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` behave in the same way.
|
||||||
|
|
||||||
Authorized Proxies
|
Authorized Proxies
|
||||||
==================
|
==================
|
||||||
|
|
||||||
If your contract can act as a proxy, i.e. if it can call arbitrary contracts
|
If your contract can act as a proxy, i.e. if it can call arbitrary contracts with user-supplied data,
|
||||||
with user-supplied data, then the user can essentially assume the identity
|
then the user can essentially assume the identity of the proxy contract.
|
||||||
of the proxy contract. Even if you have other protective measures in place,
|
Even if you have other protective measures in place, it is best to build your contract system such
|
||||||
it is best to build your contract system such that the proxy does not have
|
that the proxy does not have any permissions (not even for itself).
|
||||||
any permissions (not even for itself). If needed, you can accomplish that
|
If needed, you can accomplish that using a second proxy:
|
||||||
using a second proxy:
|
|
||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
@ -236,7 +237,8 @@ using a second proxy:
|
|||||||
tx.origin
|
tx.origin
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Never use tx.origin for authorization. Let's say you have a wallet contract like this:
|
Never use ``tx.origin`` for authorization.
|
||||||
|
Let's say you have a wallet contract like this:
|
||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
@ -279,7 +281,11 @@ Now someone tricks you into sending Ether to the address of this attack wallet:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
If your wallet had checked ``msg.sender`` for authorization, it would get the address of the attack wallet, instead of the owner address. But by checking ``tx.origin``, it gets the original address that kicked off the transaction, which is still the owner address. The attack wallet instantly drains all your funds.
|
If your wallet had checked ``msg.sender`` for authorization, it would get the address of the attack wallet,
|
||||||
|
instead of the owner's address.
|
||||||
|
But by checking ``tx.origin``, it gets the original address that kicked off the transaction,
|
||||||
|
which is still the owner's address.
|
||||||
|
The attack wallet instantly drains all your funds.
|
||||||
|
|
||||||
.. _underflow-overflow:
|
.. _underflow-overflow:
|
||||||
|
|
||||||
@ -319,16 +325,14 @@ Try to use ``require`` to limit the size of inputs to a reasonable range and use
|
|||||||
Clearing Mappings
|
Clearing Mappings
|
||||||
=================
|
=================
|
||||||
|
|
||||||
The Solidity type ``mapping`` (see :ref:`mapping-types`) is a storage-only
|
The Solidity type ``mapping`` (see :ref:`mapping-types`) is a storage-only key-value data structure
|
||||||
key-value data structure that does not keep track of the keys that were
|
that does not keep track of the keys that were assigned a non-zero value.
|
||||||
assigned a non-zero value. Because of that, cleaning a mapping without extra
|
Because of that, cleaning a mapping without extra information about the written keys is not possible.
|
||||||
information about the written keys is not possible.
|
If a ``mapping`` is used as the base type of a dynamic storage array,
|
||||||
If a ``mapping`` is used as the base type of a dynamic storage array, deleting
|
deleting or popping the array will have no effect over the ``mapping`` elements.
|
||||||
or popping the array will have no effect over the ``mapping`` elements. The
|
The same happens, for example, if a ``mapping`` is used as the type of a member field of a ``struct``
|
||||||
same happens, for example, if a ``mapping`` is used as the type of a member
|
that is the base type of a dynamic storage array.
|
||||||
field of a ``struct`` that is the base type of a dynamic storage array. The
|
The ``mapping`` is also ignored in assignments of structs or arrays containing a ``mapping``.
|
||||||
``mapping`` is also ignored in assignments of structs or arrays containing a
|
|
||||||
``mapping``.
|
|
||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
@ -336,7 +340,7 @@ field of a ``struct`` that is the base type of a dynamic storage array. The
|
|||||||
pragma solidity >=0.6.0 <0.9.0;
|
pragma solidity >=0.6.0 <0.9.0;
|
||||||
|
|
||||||
contract Map {
|
contract Map {
|
||||||
mapping (uint => uint)[] array;
|
mapping(uint => uint)[] array;
|
||||||
|
|
||||||
function allocate(uint newMaps) public {
|
function allocate(uint newMaps) public {
|
||||||
for (uint i = 0; i < newMaps; i++)
|
for (uint i = 0; i < newMaps; i++)
|
||||||
@ -356,15 +360,12 @@ field of a ``struct`` that is the base type of a dynamic storage array. The
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Consider the example above and the following sequence of calls: ``allocate(10)``,
|
Consider the example above and the following sequence of calls: ``allocate(10)``, ``writeMap(4, 128, 256)``.
|
||||||
``writeMap(4, 128, 256)``.
|
|
||||||
At this point, calling ``readMap(4, 128)`` returns 256.
|
At this point, calling ``readMap(4, 128)`` returns 256.
|
||||||
If we call ``eraseMaps``, the length of state variable ``array`` is zeroed, but
|
If we call ``eraseMaps``, the length of the state variable ``array`` is zeroed,
|
||||||
since its ``mapping`` elements cannot be zeroed, their information stays alive
|
but since its ``mapping`` elements cannot be zeroed, their information stays alive in the contract's storage.
|
||||||
in the contract's storage.
|
After deleting ``array``, calling ``allocate(5)`` allows us to access ``array[4]`` again,
|
||||||
After deleting ``array``, calling ``allocate(5)`` allows us to access
|
and calling ``readMap(4, 128)`` returns 256 even without another call to ``writeMap``.
|
||||||
``array[4]`` again, and calling ``readMap(4, 128)`` returns 256 even without
|
|
||||||
another call to ``writeMap``.
|
|
||||||
|
|
||||||
If your ``mapping`` information must be deleted, consider using a library similar to
|
If your ``mapping`` information must be deleted, consider using a library similar to
|
||||||
`iterable mapping <https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol>`_,
|
`iterable mapping <https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol>`_,
|
||||||
@ -375,10 +376,11 @@ Minor Details
|
|||||||
|
|
||||||
- Types that do not occupy the full 32 bytes might contain "dirty higher order bits".
|
- Types that do not occupy the full 32 bytes might contain "dirty higher order bits".
|
||||||
This is especially important if you access ``msg.data`` - it poses a malleability risk:
|
This is especially important if you access ``msg.data`` - it poses a malleability risk:
|
||||||
You can craft transactions that call a function ``f(uint8 x)`` with a raw byte argument
|
You can craft transactions that call a function ``f(uint8 x)``
|
||||||
of ``0xff000001`` and with ``0x00000001``. Both are fed to the contract and both will
|
with a raw byte argument of ``0xff000001`` and with ``0x00000001``.
|
||||||
look like the number ``1`` as far as ``x`` is concerned, but ``msg.data`` will
|
Both are fed to the contract and both will look like the number ``1`` as far as ``x`` is concerned,
|
||||||
be different, so if you use ``keccak256(msg.data)`` for anything, you will get different results.
|
but ``msg.data`` will be different, so if you use ``keccak256(msg.data)`` for anything,
|
||||||
|
you will get different results.
|
||||||
|
|
||||||
***************
|
***************
|
||||||
Recommendations
|
Recommendations
|
||||||
@ -388,48 +390,45 @@ Take Warnings Seriously
|
|||||||
=======================
|
=======================
|
||||||
|
|
||||||
If the compiler warns you about something, you should change it.
|
If the compiler warns you about something, you should change it.
|
||||||
Even if you do not think that this particular warning has security
|
Even if you do not think that this particular warning has security implications,
|
||||||
implications, there might be another issue buried beneath it.
|
there might be another issue buried beneath it.
|
||||||
Any compiler warning we issue can be silenced by slight changes to the
|
Any compiler warning we issue can be silenced by slight changes to the code.
|
||||||
code.
|
|
||||||
|
|
||||||
Always use the latest version of the compiler to be notified about all recently
|
Always use the latest version of the compiler to be notified about all recently introduced warnings.
|
||||||
introduced warnings.
|
|
||||||
|
|
||||||
Messages of type ``info`` issued by the compiler are not dangerous, and simply
|
Messages of type ``info``, issued by the compiler, are not dangerous
|
||||||
represent extra suggestions and optional information that the compiler thinks
|
and simply represent extra suggestions and optional information
|
||||||
might be useful to the user.
|
that the compiler thinks might be useful to the user.
|
||||||
|
|
||||||
Restrict the Amount of Ether
|
Restrict the Amount of Ether
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Restrict the amount of Ether (or other tokens) that can be stored in a smart
|
Restrict the amount of Ether (or other tokens) that can be stored in a smart contract.
|
||||||
contract. If your source code, the compiler or the platform has a bug, these
|
If your source code, the compiler or the platform has a bug, these funds may be lost.
|
||||||
funds may be lost. If you want to limit your loss, limit the amount of Ether.
|
If you want to limit your loss, limit the amount of Ether.
|
||||||
|
|
||||||
Keep it Small and Modular
|
Keep it Small and Modular
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
Keep your contracts small and easily understandable. Single out unrelated
|
Keep your contracts small and easily understandable.
|
||||||
functionality in other contracts or into libraries. General recommendations
|
Single out unrelated functionality in other contracts or into libraries.
|
||||||
about source code quality of course apply: Limit the amount of local variables,
|
General recommendations about the source code quality of course apply:
|
||||||
the length of functions and so on. Document your functions so that others
|
Limit the amount of local variables, the length of functions and so on.
|
||||||
can see what your intention was and whether it is different than what the code does.
|
Document your functions so that others can see what your intention was
|
||||||
|
and whether it is different than what the code does.
|
||||||
|
|
||||||
Use the Checks-Effects-Interactions Pattern
|
Use the Checks-Effects-Interactions Pattern
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
Most functions will first perform some checks (who called the function,
|
Most functions will first perform some checks and they should be done first
|
||||||
are the arguments in range, did they send enough Ether, does the person
|
(who called the function, are the arguments in range, did they send enough Ether,
|
||||||
have tokens, etc.). These checks should be done first.
|
does the person have tokens, etc.).
|
||||||
|
|
||||||
As the second step, if all checks passed, effects to the state variables
|
As the second step, if all checks passed, effects to the state variables of the current contract should be made.
|
||||||
of the current contract should be made. Interaction with other contracts
|
Interaction with other contracts should be the very last step in any function.
|
||||||
should be the very last step in any function.
|
|
||||||
|
|
||||||
Early contracts delayed some effects and waited for external function
|
Early contracts delayed some effects and waited for external function calls to return in a non-error state.
|
||||||
calls to return in a non-error state. This is often a serious mistake
|
This is often a serious mistake because of the reentrancy problem explained above.
|
||||||
because of the re-entrancy problem explained above.
|
|
||||||
|
|
||||||
Note that, also, calls to known contracts might in turn cause calls to
|
Note that, also, calls to known contracts might in turn cause calls to
|
||||||
unknown contracts, so it is probably better to just always apply this pattern.
|
unknown contracts, so it is probably better to just always apply this pattern.
|
||||||
@ -437,24 +436,23 @@ unknown contracts, so it is probably better to just always apply this pattern.
|
|||||||
Include a Fail-Safe Mode
|
Include a Fail-Safe Mode
|
||||||
========================
|
========================
|
||||||
|
|
||||||
While making your system fully decentralised will remove any intermediary,
|
While making your system fully decentralized will remove any intermediary,
|
||||||
it might be a good idea, especially for new code, to include some kind
|
it might be a good idea, especially for new code, to include some kind of fail-safe mechanism:
|
||||||
of fail-safe mechanism:
|
|
||||||
|
|
||||||
You can add a function in your smart contract that performs some
|
You can add a function in your smart contract that performs some self-checks like "Has any Ether leaked?",
|
||||||
self-checks like "Has any Ether leaked?",
|
|
||||||
"Is the sum of the tokens equal to the balance of the contract?" or similar things.
|
"Is the sum of the tokens equal to the balance of the contract?" or similar things.
|
||||||
Keep in mind that you cannot use too much gas for that, so help through off-chain
|
Keep in mind that you cannot use too much gas for that,
|
||||||
computations might be needed there.
|
so help through off-chain computations might be needed there.
|
||||||
|
|
||||||
If the self-check fails, the contract automatically switches into some kind
|
If the self-check fails, the contract automatically switches into some kind of "failsafe" mode,
|
||||||
of "failsafe" mode, which, for example, disables most of the features, hands over
|
which, for example, disables most of the features,
|
||||||
control to a fixed and trusted third party or just converts the contract into
|
hands over control to a fixed and trusted third party
|
||||||
a simple "give me back my money" contract.
|
or just converts the contract into a simple "give me back my Ether" contract.
|
||||||
|
|
||||||
Ask for Peer Review
|
Ask for Peer Review
|
||||||
===================
|
===================
|
||||||
|
|
||||||
The more people examine a piece of code, the more issues are found.
|
The more people examine a piece of code, the more issues are found.
|
||||||
Asking people to review your code also helps as a cross-check to find out whether your code
|
Asking people to review your code also helps as a cross-check to find out
|
||||||
is easy to understand - a very important criterion for good smart contracts.
|
whether your code is easy to understand -
|
||||||
|
a very important criterion for good smart contracts.
|
||||||
|
@ -73,7 +73,7 @@ Tutorial
|
|||||||
Overflow
|
Overflow
|
||||||
========
|
========
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.8.0;
|
pragma solidity >=0.8.0;
|
||||||
@ -97,7 +97,7 @@ Overflow
|
|||||||
|
|
||||||
The contract above shows an overflow check example.
|
The contract above shows an overflow check example.
|
||||||
The SMTChecker does not check underflow and overflow by default for Solidity >=0.8.7,
|
The SMTChecker does not check underflow and overflow by default for Solidity >=0.8.7,
|
||||||
so we need to use the command line option ``--model-checker-targets "underflow,overflow"``
|
so we need to use the command-line option ``--model-checker-targets "underflow,overflow"``
|
||||||
or the JSON option ``settings.modelChecker.targets = ["underflow", "overflow"]``.
|
or the JSON option ``settings.modelChecker.targets = ["underflow", "overflow"]``.
|
||||||
See :ref:`this section for targets configuration<smtchecker_targets>`.
|
See :ref:`this section for targets configuration<smtchecker_targets>`.
|
||||||
Here, it reports the following:
|
Here, it reports the following:
|
||||||
@ -122,7 +122,7 @@ Here, it reports the following:
|
|||||||
If we add ``require`` statements that filter out overflow cases,
|
If we add ``require`` statements that filter out overflow cases,
|
||||||
the SMTChecker proves that no overflow is reachable (by not reporting warnings):
|
the SMTChecker proves that no overflow is reachable (by not reporting warnings):
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.8.0;
|
pragma solidity >=0.8.0;
|
||||||
@ -160,7 +160,7 @@ Since ``f`` is indeed monotonically increasing, the SMTChecker proves that our
|
|||||||
property is correct. You are encouraged to play with the property and the function
|
property is correct. You are encouraged to play with the property and the function
|
||||||
definition to see what results come out!
|
definition to see what results come out!
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.8.0;
|
pragma solidity >=0.8.0;
|
||||||
@ -182,7 +182,7 @@ The following code searches for the maximum element of an unrestricted array of
|
|||||||
numbers, and asserts the property that the found element must be greater or
|
numbers, and asserts the property that the found element must be greater or
|
||||||
equal every element in the array.
|
equal every element in the array.
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.8.0;
|
pragma solidity >=0.8.0;
|
||||||
@ -216,7 +216,7 @@ All the properties are correctly proven safe. Feel free to change the
|
|||||||
properties and/or add restrictions on the array to see different results.
|
properties and/or add restrictions on the array to see different results.
|
||||||
For example, changing the code to
|
For example, changing the code to
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.8.0;
|
pragma solidity >=0.8.0;
|
||||||
@ -268,7 +268,7 @@ Let us place a robot at position (0, 0). The robot can only move diagonally, one
|
|||||||
and cannot move outside the grid. The robot's state machine can be represented by the smart contract
|
and cannot move outside the grid. The robot's state machine can be represented by the smart contract
|
||||||
below.
|
below.
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.8.0;
|
pragma solidity >=0.8.0;
|
||||||
@ -319,7 +319,7 @@ We can also trick the SMTChecker into giving us a path to a certain position we
|
|||||||
think might be reachable. We can add the property that (2, 4) is *not*
|
think might be reachable. We can add the property that (2, 4) is *not*
|
||||||
reachable, by adding the following function.
|
reachable, by adding the following function.
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
function reach_2_4() public view {
|
function reach_2_4() public view {
|
||||||
assert(!(x == 2 && y == 4));
|
assert(!(x == 2 && y == 4));
|
||||||
@ -368,7 +368,7 @@ In some cases, it is possible to automatically infer properties over state
|
|||||||
variables that are still true even if the externally called code can do
|
variables that are still true even if the externally called code can do
|
||||||
anything, including reenter the caller contract.
|
anything, including reenter the caller contract.
|
||||||
|
|
||||||
.. code-block:: Solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.8.0;
|
pragma solidity >=0.8.0;
|
||||||
@ -412,7 +412,7 @@ is already "locked", so it would not be possible to change the value of ``x``,
|
|||||||
regardless of what the unknown called code does.
|
regardless of what the unknown called code does.
|
||||||
|
|
||||||
If we "forget" to use the ``mutex`` modifier on function ``set``, the
|
If we "forget" to use the ``mutex`` modifier on function ``set``, the
|
||||||
SMTChecker is able to synthesize the behaviour of the externally called code so
|
SMTChecker is able to synthesize the behavior of the externally called code so
|
||||||
that the assertion fails:
|
that the assertion fails:
|
||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
@ -483,6 +483,14 @@ All targets are checked by default, except underflow and overflow for Solidity >
|
|||||||
There is no precise heuristic on how and when to split verification targets,
|
There is no precise heuristic on how and when to split verification targets,
|
||||||
but it can be useful especially when dealing with large contracts.
|
but it can be useful especially when dealing with large contracts.
|
||||||
|
|
||||||
|
Proved Targets
|
||||||
|
==============
|
||||||
|
|
||||||
|
If there are any proved targets, the SMTChecker issues one warning per engine stating
|
||||||
|
how many targets were proved. If the user wishes to see all the specific
|
||||||
|
proved targets, the CLI option ``--model-checker-show-proved`` and
|
||||||
|
the JSON option ``settings.modelChecker.showProved = true`` can be used.
|
||||||
|
|
||||||
Unproved Targets
|
Unproved Targets
|
||||||
================
|
================
|
||||||
|
|
||||||
@ -491,6 +499,23 @@ how many unproved targets there are. If the user wishes to see all the specific
|
|||||||
unproved targets, the CLI option ``--model-checker-show-unproved`` and
|
unproved targets, the CLI option ``--model-checker-show-unproved`` and
|
||||||
the JSON option ``settings.modelChecker.showUnproved = true`` can be used.
|
the JSON option ``settings.modelChecker.showUnproved = true`` can be used.
|
||||||
|
|
||||||
|
Unsupported Language Features
|
||||||
|
=============================
|
||||||
|
|
||||||
|
Certain Solidity language features are not completely supported by the SMT
|
||||||
|
encoding that the SMTChecker applies, for example assembly blocks.
|
||||||
|
The unsupported construct is abstracted via overapproximation to preserve
|
||||||
|
soundness, meaning any properties reported safe are safe even though this
|
||||||
|
feature is unsupported.
|
||||||
|
However such abstraction may cause false positives when the target properties
|
||||||
|
depend on the precise behavior of the unsupported feature.
|
||||||
|
If the encoder encounters such cases it will by default report a generic warning
|
||||||
|
stating how many unsupported features it has seen.
|
||||||
|
If the user wishes to see all the specific unsupported features, the CLI option
|
||||||
|
``--model-checker-show-unsupported`` and the JSON option
|
||||||
|
``settings.modelChecker.showUnsupported = true`` can be used, where their default
|
||||||
|
value is ``false``.
|
||||||
|
|
||||||
Verified Contracts
|
Verified Contracts
|
||||||
==================
|
==================
|
||||||
|
|
||||||
@ -518,13 +543,196 @@ which has the following form:
|
|||||||
"source2.sol": ["contract2", "contract3"]
|
"source2.sol": ["contract2", "contract3"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Trusted External Calls
|
||||||
|
======================
|
||||||
|
|
||||||
|
By default, the SMTChecker does not assume that compile-time available code
|
||||||
|
is the same as the runtime code for external calls. Take the following contracts
|
||||||
|
as an example:
|
||||||
|
|
||||||
|
.. code-block:: solidity
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
pragma solidity >=0.8.0;
|
||||||
|
|
||||||
|
contract Ext {
|
||||||
|
uint public x;
|
||||||
|
function setX(uint _x) public { x = _x; }
|
||||||
|
}
|
||||||
|
contract MyContract {
|
||||||
|
function callExt(Ext _e) public {
|
||||||
|
_e.setX(42);
|
||||||
|
assert(_e.x() == 42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
When ``MyContract.callExt`` is called, an address is given as the argument.
|
||||||
|
At deployment time, we cannot know for sure that address ``_e`` actually
|
||||||
|
contains a deployment of contract ``Ext``.
|
||||||
|
Therefore, the SMTChecker will warn that the assertion above can be violated,
|
||||||
|
which is true, if ``_e`` contains another contract than ``Ext``.
|
||||||
|
|
||||||
|
However, it can be useful to treat these external calls as trusted, for example,
|
||||||
|
to test that different implementations of an interface conform to the same property.
|
||||||
|
This means assuming that address ``_e`` indeed was deployed as contract ``Ext``.
|
||||||
|
This mode can be enabled via the CLI option ``--model-checker-ext-calls=trusted``
|
||||||
|
or the JSON field ``settings.modelChecker.extCalls: "trusted"``.
|
||||||
|
|
||||||
|
Please be aware that enabling this mode can make the SMTChecker analysis much more
|
||||||
|
computationally costly.
|
||||||
|
|
||||||
|
An important part of this mode is that it is applied to contract types and high
|
||||||
|
level external calls to contracts, and not low level calls such as ``call`` and
|
||||||
|
``delegatecall``. The storage of an address is stored per contract type, and
|
||||||
|
the SMTChecker assumes that an externally called contract has the type of the
|
||||||
|
caller expression. Therefore, casting an ``address`` or a contract to
|
||||||
|
different contract types will yield different storage values and can give
|
||||||
|
unsound results if the assumptions are inconsistent, such as the example below:
|
||||||
|
|
||||||
|
.. code-block:: solidity
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
pragma solidity >=0.8.0;
|
||||||
|
|
||||||
|
contract D {
|
||||||
|
constructor(uint _x) { x = _x; }
|
||||||
|
uint public x;
|
||||||
|
function setX(uint _x) public { x = _x; }
|
||||||
|
}
|
||||||
|
|
||||||
|
contract E {
|
||||||
|
constructor() { x = 2; }
|
||||||
|
uint public x;
|
||||||
|
function setX(uint _x) public { x = _x; }
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function f() public {
|
||||||
|
address d = address(new D(42));
|
||||||
|
|
||||||
|
// `d` was deployed as `D`, so its `x` should be 42 now.
|
||||||
|
assert(D(d).x() == 42); // should hold
|
||||||
|
assert(D(d).x() == 43); // should fail
|
||||||
|
|
||||||
|
// E and D have the same interface, so the following
|
||||||
|
// call would also work at runtime.
|
||||||
|
// However, the change to `E(d)` is not reflected in `D(d)`.
|
||||||
|
E(d).setX(1024);
|
||||||
|
|
||||||
|
// Reading from `D(d)` now will show old values.
|
||||||
|
// The assertion below should fail at runtime,
|
||||||
|
// but succeeds in this mode's analysis (unsound).
|
||||||
|
assert(D(d).x() == 42);
|
||||||
|
// The assertion below should succeed at runtime,
|
||||||
|
// but fails in this mode's analysis (false positive).
|
||||||
|
assert(D(d).x() == 1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Due to the above, make sure that the trusted external calls to a certain
|
||||||
|
variable of ``address`` or ``contract`` type always have the same caller
|
||||||
|
expression type.
|
||||||
|
|
||||||
|
It is also helpful to cast the called contract's variable as the type of the
|
||||||
|
most derived type in case of inheritance.
|
||||||
|
|
||||||
|
.. code-block:: solidity
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
pragma solidity >=0.8.0;
|
||||||
|
|
||||||
|
interface Token {
|
||||||
|
function balanceOf(address _a) external view returns (uint);
|
||||||
|
function transfer(address _to, uint _amt) external;
|
||||||
|
}
|
||||||
|
|
||||||
|
contract TokenCorrect is Token {
|
||||||
|
mapping (address => uint) balance;
|
||||||
|
constructor(address _a, uint _b) {
|
||||||
|
balance[_a] = _b;
|
||||||
|
}
|
||||||
|
function balanceOf(address _a) public view override returns (uint) {
|
||||||
|
return balance[_a];
|
||||||
|
}
|
||||||
|
function transfer(address _to, uint _amt) public override {
|
||||||
|
require(balance[msg.sender] >= _amt);
|
||||||
|
balance[msg.sender] -= _amt;
|
||||||
|
balance[_to] += _amt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract Test {
|
||||||
|
function property_transfer(address _token, address _to, uint _amt) public {
|
||||||
|
require(_to != address(this));
|
||||||
|
|
||||||
|
TokenCorrect t = TokenCorrect(_token);
|
||||||
|
|
||||||
|
uint xPre = t.balanceOf(address(this));
|
||||||
|
require(xPre >= _amt);
|
||||||
|
uint yPre = t.balanceOf(_to);
|
||||||
|
|
||||||
|
t.transfer(_to, _amt);
|
||||||
|
uint xPost = t.balanceOf(address(this));
|
||||||
|
uint yPost = t.balanceOf(_to);
|
||||||
|
|
||||||
|
assert(xPost == xPre - _amt);
|
||||||
|
assert(yPost == yPre + _amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that in function ``property_transfer``, the external calls are
|
||||||
|
performed on variable ``t``.
|
||||||
|
|
||||||
|
Another caveat of this mode are calls to state variables of contract type
|
||||||
|
outside the analyzed contract. In the code below, even though ``B`` deploys
|
||||||
|
``A``, it is also possible for the address stored in ``B.a`` to be called by
|
||||||
|
anyone outside of ``B`` in between transactions to ``B`` itself. To reflect the
|
||||||
|
possible changes to ``B.a``, the encoding allows an unbounded number of calls
|
||||||
|
to be made to ``B.a`` externally. The encoding will keep track of ``B.a``'s
|
||||||
|
storage, therefore assertion (2) should hold. However, currently the encoding
|
||||||
|
allows such calls to be made from ``B`` conceptually, therefore assertion (3)
|
||||||
|
fails. Making the encoding stronger logically is an extension of the trusted
|
||||||
|
mode and is under development. Note that the encoding does not keep track of
|
||||||
|
storage for ``address`` variables, therefore if ``B.a`` had type ``address``
|
||||||
|
the encoding would assume that its storage does not change in between
|
||||||
|
transactions to ``B``.
|
||||||
|
|
||||||
|
.. code-block:: solidity
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
pragma solidity >=0.8.0;
|
||||||
|
|
||||||
|
contract A {
|
||||||
|
uint public x;
|
||||||
|
address immutable public owner;
|
||||||
|
constructor() {
|
||||||
|
owner = msg.sender;
|
||||||
|
}
|
||||||
|
function setX(uint _x) public {
|
||||||
|
require(msg.sender == owner);
|
||||||
|
x = _x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract B {
|
||||||
|
A a;
|
||||||
|
constructor() {
|
||||||
|
a = new A();
|
||||||
|
assert(a.x() == 0); // (1) should hold
|
||||||
|
}
|
||||||
|
function g() public view {
|
||||||
|
assert(a.owner() == address(this)); // (2) should hold
|
||||||
|
assert(a.x() == 0); // (3) should hold, but fails due to a false positive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reported Inferred Inductive Invariants
|
Reported Inferred Inductive Invariants
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
For properties that were proved safe with the CHC engine,
|
For properties that were proved safe with the CHC engine,
|
||||||
the SMTChecker can retrieve inductive invariants that were inferred by the Horn
|
the SMTChecker can retrieve inductive invariants that were inferred by the Horn
|
||||||
solver as part of the proof.
|
solver as part of the proof.
|
||||||
Currently two types of invariants can be reported to the user:
|
Currently only two types of invariants can be reported to the user:
|
||||||
|
|
||||||
- Contract Invariants: these are properties over the contract's state variables
|
- Contract Invariants: these are properties over the contract's state variables
|
||||||
that are true before and after every possible transaction that the contract may ever run. For example, ``x >= y``, where ``x`` and ``y`` are a contract's state variables.
|
that are true before and after every possible transaction that the contract may ever run. For example, ``x >= y``, where ``x`` and ``y`` are a contract's state variables.
|
||||||
@ -543,7 +751,7 @@ and modulo operations inside Horn rules. Because of that, by default the
|
|||||||
Solidity division and modulo operations are encoded using the constraint
|
Solidity division and modulo operations are encoded using the constraint
|
||||||
``a = b * d + m`` where ``d = a / b`` and ``m = a % b``.
|
``a = b * d + m`` where ``d = a / b`` and ``m = a % b``.
|
||||||
However, other solvers, such as Eldarica, prefer the syntactically precise operations.
|
However, other solvers, such as Eldarica, prefer the syntactically precise operations.
|
||||||
The command line flag ``--model-checker-div-mod-no-slacks`` and the JSON option
|
The command-line flag ``--model-checker-div-mod-no-slacks`` and the JSON option
|
||||||
``settings.modelChecker.divModNoSlacks`` can be used to toggle the encoding
|
``settings.modelChecker.divModNoSlacks`` can be used to toggle the encoding
|
||||||
depending on the used solver preferences.
|
depending on the used solver preferences.
|
||||||
|
|
||||||
@ -627,7 +835,7 @@ option ``--model-checker-solvers {all,cvc4,eld,smtlib2,z3}`` or the JSON option
|
|||||||
|
|
||||||
- if ``solc`` is compiled with it;
|
- if ``solc`` is compiled with it;
|
||||||
- if a dynamic ``z3`` library of version >=4.8.x is installed in a Linux system (from Solidity 0.7.6);
|
- if a dynamic ``z3`` library of version >=4.8.x is installed in a Linux system (from Solidity 0.7.6);
|
||||||
- statically in ``soljson.js`` (from Solidity 0.6.9), that is, the Javascript binary of the compiler.
|
- statically in ``soljson.js`` (from Solidity 0.6.9), that is, the JavaScript binary of the compiler.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
z3 version 4.8.16 broke ABI compatibility with previous versions and cannot
|
z3 version 4.8.16 broke ABI compatibility with previous versions and cannot
|
||||||
|
27
docs/solidity_logo.svg
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
||||||
|
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1300px" height="1300px"
|
||||||
|
viewBox="0 0 1300 1300" enable-background="new 0 0 1300 1300" xml:space="preserve">
|
||||||
|
<title>Vector 1</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<g id="Page-1" sketch:type="MSPage">
|
||||||
|
<g id="solidity" transform="translate(402.000000, 118.000000)" sketch:type="MSLayerGroup">
|
||||||
|
<g id="Group" sketch:type="MSShapeGroup">
|
||||||
|
<path id="Shape" opacity="0.45" enable-background="new " d="M371.772,135.308L241.068,367.61H-20.158l130.614-232.302
|
||||||
|
H371.772"/>
|
||||||
|
<path id="Shape_1_" opacity="0.6" enable-background="new " d="M241.068,367.61h261.318L371.772,135.308H110.456
|
||||||
|
L241.068,367.61z"/>
|
||||||
|
<path id="Shape_2_" opacity="0.8" enable-background="new " d="M110.456,599.822L241.068,367.61L110.456,135.308
|
||||||
|
L-20.158,367.61L110.456,599.822z"/>
|
||||||
|
<path id="Shape_3_" opacity="0.45" enable-background="new " d="M111.721,948.275l130.704-232.303h261.318L373.038,948.275
|
||||||
|
H111.721"/>
|
||||||
|
<path id="Shape_4_" opacity="0.6" enable-background="new " d="M242.424,715.973H-18.893l130.613,232.303h261.317
|
||||||
|
L242.424,715.973z"/>
|
||||||
|
<path id="Shape_5_" opacity="0.8" enable-background="new " d="M373.038,483.761L242.424,715.973l130.614,232.303
|
||||||
|
l130.704-232.303L373.038,483.761z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -112,11 +112,11 @@ Events are convenience interfaces with the EVM logging facilities.
|
|||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.21 <0.9.0;
|
pragma solidity ^0.8.22;
|
||||||
|
|
||||||
|
event HighestBidIncreased(address bidder, uint amount); // Event
|
||||||
|
|
||||||
contract SimpleAuction {
|
contract SimpleAuction {
|
||||||
event HighestBidIncreased(address bidder, uint amount); // Event
|
|
||||||
|
|
||||||
function bid() public payable {
|
function bid() public payable {
|
||||||
// ...
|
// ...
|
||||||
emit HighestBidIncreased(msg.sender, msg.value); // Triggering event
|
emit HighestBidIncreased(msg.sender, msg.value); // Triggering event
|
||||||
|
@ -16,11 +16,11 @@ Many projects will implement their own style guides. In the event of
|
|||||||
conflicts, project specific style guides take precedence.
|
conflicts, project specific style guides take precedence.
|
||||||
|
|
||||||
The structure and many of the recommendations within this style guide were
|
The structure and many of the recommendations within this style guide were
|
||||||
taken from python's
|
taken from Python's
|
||||||
`pep8 style guide <https://peps.python.org/pep-0008/>`_.
|
`pep8 style guide <https://peps.python.org/pep-0008/>`_.
|
||||||
|
|
||||||
The goal of this guide is *not* to be the right way or the best way to write
|
The goal of this guide is *not* to be the right way or the best way to write
|
||||||
Solidity code. The goal of this guide is *consistency*. A quote from python's
|
Solidity code. The goal of this guide is *consistency*. A quote from Python's
|
||||||
`pep8 <https://peps.python.org/pep-0008/#a-foolish-consistency-is-the-hobgoblin-of-little-minds>`_
|
`pep8 <https://peps.python.org/pep-0008/#a-foolish-consistency-is-the-hobgoblin-of-little-minds>`_
|
||||||
captures this concept well.
|
captures this concept well.
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ captures this concept well.
|
|||||||
|
|
||||||
A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is most important.
|
A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is most important.
|
||||||
|
|
||||||
But most importantly: **know when to be inconsistent** -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don't hesitate to ask!
|
But most importantly: **know when to be inconsistent** -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And do not hesitate to ask!
|
||||||
|
|
||||||
|
|
||||||
***********
|
***********
|
||||||
@ -448,7 +448,7 @@ No:
|
|||||||
y = 2;
|
y = 2;
|
||||||
longVariable = 3;
|
longVariable = 3;
|
||||||
|
|
||||||
Don't include a whitespace in the receive and fallback functions:
|
Do not include a whitespace in the receive and fallback functions:
|
||||||
|
|
||||||
Yes:
|
Yes:
|
||||||
|
|
||||||
@ -1284,6 +1284,21 @@ Avoiding Naming Collisions
|
|||||||
This convention is suggested when the desired name collides with that of
|
This convention is suggested when the desired name collides with that of
|
||||||
an existing state variable, function, built-in or otherwise reserved name.
|
an existing state variable, function, built-in or otherwise reserved name.
|
||||||
|
|
||||||
|
Underscore Prefix for Non-external Functions and Variables
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
* ``_singleLeadingUnderscore``
|
||||||
|
|
||||||
|
This convention is suggested for non-external functions and state variables (``private`` or ``internal``). State variables without a specified visibility are ``internal`` by default.
|
||||||
|
|
||||||
|
When designing a smart contract, the public-facing API (functions that can be called by any account)
|
||||||
|
is an important consideration.
|
||||||
|
Leading underscores allow you to immediately recognize the intent of such functions,
|
||||||
|
but more importantly, if you change a function from non-external to external (including ``public``)
|
||||||
|
and rename it accordingly, this forces you to review every call site while renaming.
|
||||||
|
This can be an important manual check against unintended external functions
|
||||||
|
and a common source of security vulnerabilities (avoid find-replace-all tooling for this change).
|
||||||
|
|
||||||
.. _style_guide_natspec:
|
.. _style_guide_natspec:
|
||||||
|
|
||||||
*******
|
*******
|
||||||
|
@ -44,7 +44,7 @@ Explicit Conversions
|
|||||||
|
|
||||||
If the compiler does not allow implicit conversion but you are confident a conversion will work,
|
If the compiler does not allow implicit conversion but you are confident a conversion will work,
|
||||||
an explicit type conversion is sometimes possible. This may
|
an explicit type conversion is sometimes possible. This may
|
||||||
result in unexpected behaviour and allows you to bypass some security
|
result in unexpected behavior and allows you to bypass some security
|
||||||
features of the compiler, so be sure to test that the
|
features of the compiler, so be sure to test that the
|
||||||
result is what you want and expect!
|
result is what you want and expect!
|
||||||
|
|
||||||
@ -130,6 +130,7 @@ If the array is shorter than the target type, it will be padded with zeros at th
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. index:: ! literal;conversion, literal;rational, literal;hexadecimal number
|
||||||
.. _types-conversion-literals:
|
.. _types-conversion-literals:
|
||||||
|
|
||||||
Conversions between Literals and Elementary Types
|
Conversions between Literals and Elementary Types
|
||||||
@ -152,6 +153,8 @@ that is large enough to represent it without truncation:
|
|||||||
converted to an integer type. From 0.8.0, such explicit conversions are as strict as implicit
|
converted to an integer type. From 0.8.0, such explicit conversions are as strict as implicit
|
||||||
conversions, i.e., they are only allowed if the literal fits in the resulting range.
|
conversions, i.e., they are only allowed if the literal fits in the resulting range.
|
||||||
|
|
||||||
|
.. index:: literal;string, literal;hexadecimal
|
||||||
|
|
||||||
Fixed-Size Byte Arrays
|
Fixed-Size Byte Arrays
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
@ -182,6 +185,8 @@ if their number of characters matches the size of the bytes type:
|
|||||||
bytes2 e = "x"; // not allowed
|
bytes2 e = "x"; // not allowed
|
||||||
bytes2 f = "xyz"; // not allowed
|
bytes2 f = "xyz"; // not allowed
|
||||||
|
|
||||||
|
.. index:: literal;address
|
||||||
|
|
||||||
Addresses
|
Addresses
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ The example below uses ``_allowances`` to record the amount someone else is allo
|
|||||||
|
|
||||||
contract MappingExample {
|
contract MappingExample {
|
||||||
|
|
||||||
mapping (address => uint256) private _balances;
|
mapping(address => uint256) private _balances;
|
||||||
mapping (address => mapping (address => uint256)) private _allowances;
|
mapping(address => mapping(address => uint256)) private _allowances;
|
||||||
|
|
||||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||||
|
@ -47,8 +47,8 @@ non-persistent area where function arguments are stored, and behaves mostly like
|
|||||||
|
|
||||||
.. _data-location-assignment:
|
.. _data-location-assignment:
|
||||||
|
|
||||||
Data location and assignment behaviour
|
Data location and assignment behavior
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Data locations are not only relevant for persistency of data, but also for the semantics of assignments:
|
Data locations are not only relevant for persistency of data, but also for the semantics of assignments:
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ with the :ref:`default value<default-value>`.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.. index:: ! array;literals, ! inline;arrays
|
.. index:: ! literal;array, ! inline;arrays
|
||||||
|
|
||||||
Array Literals
|
Array Literals
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
@ -372,7 +372,7 @@ Array Members
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
In EVM versions before Byzantium, it was not possible to access
|
In EVM versions before Byzantium, it was not possible to access
|
||||||
dynamic arrays return from function calls. If you call functions
|
dynamic arrays returned from function calls. If you call functions
|
||||||
that return dynamic arrays, make sure to use an EVM that is set to
|
that return dynamic arrays, make sure to use an EVM that is set to
|
||||||
Byzantium mode.
|
Byzantium mode.
|
||||||
|
|
||||||
@ -582,10 +582,10 @@ and the assignment will effectively garble the length of ``x``.
|
|||||||
To be safe, only enlarge bytes arrays by at most one element during a single
|
To be safe, only enlarge bytes arrays by at most one element during a single
|
||||||
assignment and do not simultaneously index-access the array in the same statement.
|
assignment and do not simultaneously index-access the array in the same statement.
|
||||||
|
|
||||||
While the above describes the behaviour of dangling storage references in the
|
While the above describes the behavior of dangling storage references in the
|
||||||
current version of the compiler, any code with dangling references should be
|
current version of the compiler, any code with dangling references should be
|
||||||
considered to have *undefined behaviour*. In particular, this means that
|
considered to have *undefined behavior*. In particular, this means that
|
||||||
any future version of the compiler may change the behaviour of code that
|
any future version of the compiler may change the behavior of code that
|
||||||
involves dangling references.
|
involves dangling references.
|
||||||
|
|
||||||
Be sure to avoid dangling references in your code!
|
Be sure to avoid dangling references in your code!
|
||||||
@ -641,7 +641,7 @@ Array slices are useful to ABI-decode secondary data passed in function paramete
|
|||||||
/// after doing basic validation on the address argument.
|
/// after doing basic validation on the address argument.
|
||||||
function forward(bytes calldata payload) external {
|
function forward(bytes calldata payload) external {
|
||||||
bytes4 sig = bytes4(payload[:4]);
|
bytes4 sig = bytes4(payload[:4]);
|
||||||
// Due to truncating behaviour, bytes4(payload) performs identically.
|
// Due to truncating behavior, bytes4(payload) performs identically.
|
||||||
// bytes4 sig = bytes4(payload);
|
// bytes4 sig = bytes4(payload);
|
||||||
if (sig == bytes4(keccak256("setOwner(address)"))) {
|
if (sig == bytes4(keccak256("setOwner(address)"))) {
|
||||||
address owner = abi.decode(payload[4:], (address));
|
address owner = abi.decode(payload[4:], (address));
|
||||||
@ -686,11 +686,11 @@ shown in the following example:
|
|||||||
uint fundingGoal;
|
uint fundingGoal;
|
||||||
uint numFunders;
|
uint numFunders;
|
||||||
uint amount;
|
uint amount;
|
||||||
mapping (uint => Funder) funders;
|
mapping(uint => Funder) funders;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint numCampaigns;
|
uint numCampaigns;
|
||||||
mapping (uint => Campaign) campaigns;
|
mapping(uint => Campaign) campaigns;
|
||||||
|
|
||||||
function newCampaign(address payable beneficiary, uint goal) public returns (uint campaignID) {
|
function newCampaign(address payable beneficiary, uint goal) public returns (uint campaignID) {
|
||||||
campaignID = numCampaigns++; // campaignID is return variable
|
campaignID = numCampaigns++; // campaignID is return variable
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
Value Types
|
Value Types
|
||||||
===========
|
===========
|
||||||
|
|
||||||
The following types are also called value types because variables of these
|
The following are called value types because their variables will always be passed by value, i.e. they are always copied when they
|
||||||
types will always be passed by value, i.e. they are always copied when they
|
|
||||||
are used as function arguments or in assignments.
|
are used as function arguments or in assignments.
|
||||||
|
|
||||||
.. index:: ! bool, ! true, ! false
|
.. index:: ! bool, ! true, ! false
|
||||||
@ -47,7 +46,7 @@ access the minimum and maximum value representable by the type.
|
|||||||
|
|
||||||
Integers in Solidity are restricted to a certain range. For example, with ``uint32``, this is ``0`` up to ``2**32 - 1``.
|
Integers in Solidity are restricted to a certain range. For example, with ``uint32``, this is ``0`` up to ``2**32 - 1``.
|
||||||
There are two modes in which arithmetic is performed on these types: The "wrapping" or "unchecked" mode and the "checked" mode.
|
There are two modes in which arithmetic is performed on these types: The "wrapping" or "unchecked" mode and the "checked" mode.
|
||||||
By default, arithmetic is always "checked", which mean that if the result of an operation falls outside the value range
|
By default, arithmetic is always "checked", meaning that if an operation's result falls outside the value range
|
||||||
of the type, the call is reverted through a :ref:`failing assertion<assert-and-require>`. You can switch to "unchecked" mode
|
of the type, the call is reverted through a :ref:`failing assertion<assert-and-require>`. You can switch to "unchecked" mode
|
||||||
using ``unchecked { ... }``. More details can be found in the section about :ref:`unchecked <unchecked>`.
|
using ``unchecked { ... }``. More details can be found in the section about :ref:`unchecked <unchecked>`.
|
||||||
|
|
||||||
@ -141,7 +140,7 @@ Exponentiation
|
|||||||
|
|
||||||
Exponentiation is only available for unsigned types in the exponent. The resulting type
|
Exponentiation is only available for unsigned types in the exponent. The resulting type
|
||||||
of an exponentiation is always equal to the type of the base. Please take care that it is
|
of an exponentiation is always equal to the type of the base. Please take care that it is
|
||||||
large enough to hold the result and prepare for potential assertion failures or wrapping behaviour.
|
large enough to hold the result and prepare for potential assertion failures or wrapping behavior.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
In checked mode, exponentiation only uses the comparatively cheap ``exp`` opcode for small bases.
|
In checked mode, exponentiation only uses the comparatively cheap ``exp`` opcode for small bases.
|
||||||
@ -182,7 +181,7 @@ Operators:
|
|||||||
Address
|
Address
|
||||||
-------
|
-------
|
||||||
|
|
||||||
The address type comes in two flavours, which are largely identical:
|
The address type comes in two largely identical flavors:
|
||||||
|
|
||||||
- ``address``: Holds a 20 byte value (size of an Ethereum address).
|
- ``address``: Holds a 20 byte value (size of an Ethereum address).
|
||||||
- ``address payable``: Same as ``address``, but with the additional members ``transfer`` and ``send``.
|
- ``address payable``: Same as ``address``, but with the additional members ``transfer`` and ``send``.
|
||||||
@ -258,13 +257,13 @@ reverts on failure.
|
|||||||
|
|
||||||
* ``send``
|
* ``send``
|
||||||
|
|
||||||
Send is the low-level counterpart of ``transfer``. If the execution fails, the current contract will not stop with an exception, but ``send`` will return ``false``.
|
``send`` is the low-level counterpart of ``transfer``. If the execution fails, the current contract will not stop with an exception, but ``send`` will return ``false``.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024
|
There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024
|
||||||
(this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order
|
(this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order
|
||||||
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
|
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
|
||||||
use a pattern where the recipient withdraws the money.
|
use a pattern where the recipient withdraws the Ether.
|
||||||
|
|
||||||
* ``call``, ``delegatecall`` and ``staticcall``
|
* ``call``, ``delegatecall`` and ``staticcall``
|
||||||
|
|
||||||
@ -424,7 +423,7 @@ Dynamically-sized byte array
|
|||||||
``string``:
|
``string``:
|
||||||
Dynamically-sized UTF-8-encoded string, see :ref:`arrays`. Not a value-type!
|
Dynamically-sized UTF-8-encoded string, see :ref:`arrays`. Not a value-type!
|
||||||
|
|
||||||
.. index:: address, literal;address
|
.. index:: address, ! literal;address
|
||||||
|
|
||||||
.. _address_literals:
|
.. _address_literals:
|
||||||
|
|
||||||
@ -440,7 +439,7 @@ an error. You can prepend (for integer types) or append (for bytesNN types) zero
|
|||||||
.. note::
|
.. note::
|
||||||
The mixed-case address checksum format is defined in `EIP-55 <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md>`_.
|
The mixed-case address checksum format is defined in `EIP-55 <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md>`_.
|
||||||
|
|
||||||
.. index:: literal, literal;rational
|
.. index:: integer, rational number, ! literal;rational
|
||||||
|
|
||||||
.. _rational_literals:
|
.. _rational_literals:
|
||||||
|
|
||||||
@ -518,7 +517,7 @@ regardless of the type of the right (exponent) operand.
|
|||||||
uint128 a = 1;
|
uint128 a = 1;
|
||||||
uint128 b = 2.5 + a + 0.5;
|
uint128 b = 2.5 + a + 0.5;
|
||||||
|
|
||||||
.. index:: literal, literal;string, string
|
.. index:: ! literal;string, string
|
||||||
.. _string_literals:
|
.. _string_literals:
|
||||||
|
|
||||||
String Literals and Types
|
String Literals and Types
|
||||||
@ -565,6 +564,8 @@ character sequence ``abcdef``.
|
|||||||
Any Unicode line terminator which is not a newline (i.e. LF, VF, FF, CR, NEL, LS, PS) is considered to
|
Any Unicode line terminator which is not a newline (i.e. LF, VF, FF, CR, NEL, LS, PS) is considered to
|
||||||
terminate the string literal. Newline only terminates the string literal if it is not preceded by a ``\``.
|
terminate the string literal. Newline only terminates the string literal if it is not preceded by a ``\``.
|
||||||
|
|
||||||
|
.. index:: ! literal;unicode
|
||||||
|
|
||||||
Unicode Literals
|
Unicode Literals
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@ -575,7 +576,7 @@ They also support the very same escape sequences as regular string literals.
|
|||||||
|
|
||||||
string memory a = unicode"Hello 😃";
|
string memory a = unicode"Hello 😃";
|
||||||
|
|
||||||
.. index:: literal, bytes
|
.. index:: ! literal;hexadecimal, bytes
|
||||||
|
|
||||||
Hexadecimal Literals
|
Hexadecimal Literals
|
||||||
--------------------
|
--------------------
|
||||||
@ -589,7 +590,8 @@ of the hexadecimal sequence.
|
|||||||
Multiple hexadecimal literals separated by whitespace are concatenated into a single literal:
|
Multiple hexadecimal literals separated by whitespace are concatenated into a single literal:
|
||||||
``hex"00112233" hex"44556677"`` is equivalent to ``hex"0011223344556677"``
|
``hex"00112233" hex"44556677"`` is equivalent to ``hex"0011223344556677"``
|
||||||
|
|
||||||
Hexadecimal literals behave like :ref:`string literals <string_literals>` and have the same convertibility restrictions.
|
Hexadecimal literals in some ways behave like :ref:`string literals <string_literals>` but are not
|
||||||
|
implicitly convertible to the ``string`` type.
|
||||||
|
|
||||||
.. index:: enum
|
.. index:: enum
|
||||||
|
|
||||||
@ -653,13 +655,13 @@ smallest and respectively largest value of the given enum.
|
|||||||
|
|
||||||
.. _user-defined-value-types:
|
.. _user-defined-value-types:
|
||||||
|
|
||||||
User Defined Value Types
|
User-defined Value Types
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
A user defined value type allows creating a zero cost abstraction over an elementary value type.
|
A user-defined value type allows creating a zero cost abstraction over an elementary value type.
|
||||||
This is similar to an alias, but with stricter type requirements.
|
This is similar to an alias, but with stricter type requirements.
|
||||||
|
|
||||||
A user defined value type is defined using ``type C is V``, where ``C`` is the name of the newly
|
A user-defined value type is defined using ``type C is V``, where ``C`` is the name of the newly
|
||||||
introduced type and ``V`` has to be a built-in value type (the "underlying type"). The function
|
introduced type and ``V`` has to be a built-in value type (the "underlying type"). The function
|
||||||
``C.wrap`` is used to convert from the underlying type to the custom type. Similarly, the
|
``C.wrap`` is used to convert from the underlying type to the custom type. Similarly, the
|
||||||
function ``C.unwrap`` is used to convert from the custom type to the underlying type.
|
function ``C.unwrap`` is used to convert from the custom type to the underlying type.
|
||||||
@ -680,7 +682,7 @@ type with 18 decimals and a minimal library to do arithmetic operations on the t
|
|||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity ^0.8.8;
|
pragma solidity ^0.8.8;
|
||||||
|
|
||||||
// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.
|
// Represent a 18 decimal, 256 bit wide fixed point type using a user-defined value type.
|
||||||
type UFixed256x18 is uint256;
|
type UFixed256x18 is uint256;
|
||||||
|
|
||||||
/// A minimal library to do fixed point operations on UFixed256x18.
|
/// A minimal library to do fixed point operations on UFixed256x18.
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
.. index:: ! denomination
|
||||||
|
|
||||||
**************************************
|
**************************************
|
||||||
Units and Globally Available Variables
|
Units and Globally Available Variables
|
||||||
**************************************
|
**************************************
|
||||||
|
|
||||||
.. index:: wei, finney, szabo, gwei, ether
|
.. index:: ! wei, ! finney, ! szabo, ! gwei, ! ether, ! denomination;ether
|
||||||
|
|
||||||
Ether Units
|
Ether Units
|
||||||
===========
|
===========
|
||||||
@ -21,7 +23,7 @@ The only effect of the subdenomination suffix is a multiplication by a power of
|
|||||||
.. note::
|
.. note::
|
||||||
The denominations ``finney`` and ``szabo`` have been removed in version 0.7.0.
|
The denominations ``finney`` and ``szabo`` have been removed in version 0.7.0.
|
||||||
|
|
||||||
.. index:: time, seconds, minutes, hours, days, weeks, years
|
.. index:: ! seconds, ! minutes, ! hours, ! days, ! weeks, ! years, ! denomination;time
|
||||||
|
|
||||||
Time Units
|
Time Units
|
||||||
==========
|
==========
|
||||||
@ -52,7 +54,7 @@ interpret a function parameter in days, you can in the following way:
|
|||||||
|
|
||||||
function f(uint start, uint daysAfter) public {
|
function f(uint start, uint daysAfter) public {
|
||||||
if (block.timestamp >= start + daysAfter * 1 days) {
|
if (block.timestamp >= start + daysAfter * 1 days) {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +107,7 @@ Block and Transaction Properties
|
|||||||
|
|
||||||
Both the timestamp and the block hash can be influenced by miners to some degree.
|
Both the timestamp and the block hash can be influenced by miners to some degree.
|
||||||
Bad actors in the mining community can for example run a casino payout function on a chosen hash
|
Bad actors in the mining community can for example run a casino payout function on a chosen hash
|
||||||
and just retry a different hash if they did not receive any money.
|
and just retry a different hash if they did not receive any compensation, e.g. Ether.
|
||||||
|
|
||||||
The current block timestamp must be strictly larger than the timestamp of the last block,
|
The current block timestamp must be strictly larger than the timestamp of the last block,
|
||||||
but the only guarantee is that it will be somewhere between the timestamps of two
|
but the only guarantee is that it will be somewhere between the timestamps of two
|
||||||
@ -233,7 +235,7 @@ Mathematical and Cryptographic Functions
|
|||||||
the ecrecover function remained unchanged.
|
the ecrecover function remained unchanged.
|
||||||
|
|
||||||
This is usually not a problem unless you require signatures to be unique or use them to identify items.
|
This is usually not a problem unless you require signatures to be unique or use them to identify items.
|
||||||
OpenZeppelin have a `ECDSA helper library <https://docs.openzeppelin.com/contracts/4.x/api/utils#ECDSA>`_ that you can use as a wrapper for ``ecrecover`` without this issue.
|
OpenZeppelin has an `ECDSA helper library <https://docs.openzeppelin.com/contracts/4.x/api/utils#ECDSA>`_ that you can use as a wrapper for ``ecrecover`` without this issue.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -280,7 +282,7 @@ For more information, see the section on :ref:`address`.
|
|||||||
There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024
|
There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024
|
||||||
(this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order
|
(this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order
|
||||||
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
|
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
|
||||||
Use a pattern where the recipient withdraws the money.
|
Use a pattern where the recipient withdraws the Ether.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
Due to the fact that the EVM considers a call to a non-existing contract to always succeed,
|
Due to the fact that the EVM considers a call to a non-existing contract to always succeed,
|
||||||
@ -311,13 +313,16 @@ For more information, see the section on :ref:`address`.
|
|||||||
semantics than ``delegatecall``.
|
semantics than ``delegatecall``.
|
||||||
|
|
||||||
|
|
||||||
.. index:: this, selfdestruct
|
.. index:: this, selfdestruct, super
|
||||||
|
|
||||||
Contract Related
|
Contract-related
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
``this`` (current contract's type)
|
``this`` (current contract's type)
|
||||||
the current contract, explicitly convertible to :ref:`address`
|
The current contract, explicitly convertible to :ref:`address`
|
||||||
|
|
||||||
|
``super``
|
||||||
|
A contract one level higher in the inheritance hierarchy
|
||||||
|
|
||||||
``selfdestruct(address payable recipient)``
|
``selfdestruct(address payable recipient)``
|
||||||
Destroy the current contract, sending its funds to the given :ref:`address`
|
Destroy the current contract, sending its funds to the given :ref:`address`
|
||||||
@ -331,7 +336,7 @@ Furthermore, all functions of the current contract are callable directly includi
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a
|
From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a
|
||||||
deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behaviour
|
deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior
|
||||||
as stated in `EIP-6049 <https://eips.ethereum.org/EIPS/eip-6049>`_.
|
as stated in `EIP-6049 <https://eips.ethereum.org/EIPS/eip-6049>`_.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@ -375,7 +380,7 @@ The following properties are available for a contract type ``C``:
|
|||||||
In addition to the properties above, the following properties are available
|
In addition to the properties above, the following properties are available
|
||||||
for an interface type ``I``:
|
for an interface type ``I``:
|
||||||
|
|
||||||
``type(I).interfaceId``:
|
``type(I).interfaceId``
|
||||||
A ``bytes4`` value containing the `EIP-165 <https://eips.ethereum.org/EIPS/eip-165>`_
|
A ``bytes4`` value containing the `EIP-165 <https://eips.ethereum.org/EIPS/eip-165>`_
|
||||||
interface identifier of the given interface ``I``. This identifier is defined as the ``XOR`` of all
|
interface identifier of the given interface ``I``. This identifier is defined as the ``XOR`` of all
|
||||||
function selectors defined within the interface itself - excluding all inherited functions.
|
function selectors defined within the interface itself - excluding all inherited functions.
|
||||||
|
@ -15,7 +15,7 @@ Using the Commandline Compiler
|
|||||||
Basic Usage
|
Basic Usage
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
One of the build targets of the Solidity repository is ``solc``, the solidity commandline compiler.
|
One of the build targets of the Solidity repository is ``solc``, the Solidity commandline compiler.
|
||||||
Using ``solc --help`` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage.
|
Using ``solc --help`` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage.
|
||||||
If you only want to compile a single file, you run it as ``solc --bin sourceFile.sol`` and it will print the binary. If you want to get some of the more advanced output variants of ``solc``, it is probably better to tell it to output everything to separate files using ``solc -o outputDirectory --bin --ast-compact-json --asm sourceFile.sol``.
|
If you only want to compile a single file, you run it as ``solc --bin sourceFile.sol`` and it will print the binary. If you want to get some of the more advanced output variants of ``solc``, it is probably better to tell it to output everything to separate files using ``solc -o outputDirectory --bin --ast-compact-json --asm sourceFile.sol``.
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ or ../ <direct-imports>` are treated as relative to the directories specified us
|
|||||||
Furthermore, the part of the path added via these options will not appear in the contract metadata.
|
Furthermore, the part of the path added via these options will not appear in the contract metadata.
|
||||||
|
|
||||||
For security reasons the compiler has :ref:`restrictions on what directories it can access <allowed-paths>`.
|
For security reasons the compiler has :ref:`restrictions on what directories it can access <allowed-paths>`.
|
||||||
Directories of source files specified on the command line and target paths of
|
Directories of source files specified on the command-line and target paths of
|
||||||
remappings are automatically allowed to be accessed by the file reader, but everything
|
remappings are automatically allowed to be accessed by the file reader, but everything
|
||||||
else is rejected by default.
|
else is rejected by default.
|
||||||
Additional paths (and their subdirectories) can be allowed via the
|
Additional paths (and their subdirectories) can be allowed via the
|
||||||
@ -114,15 +114,15 @@ Setting the EVM Version to Target
|
|||||||
*********************************
|
*********************************
|
||||||
|
|
||||||
When you compile your contract code you can specify the Ethereum virtual machine
|
When you compile your contract code you can specify the Ethereum virtual machine
|
||||||
version to compile for to avoid particular features or behaviours.
|
version to compile for to avoid particular features or behaviors.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
Compiling for the wrong EVM version can result in wrong, strange and failing
|
Compiling for the wrong EVM version can result in wrong, strange and failing
|
||||||
behaviour. Please ensure, especially if running a private chain, that you
|
behavior. Please ensure, especially if running a private chain, that you
|
||||||
use matching EVM versions.
|
use matching EVM versions.
|
||||||
|
|
||||||
On the command line, you can select the EVM version as follows:
|
On the command-line, you can select the EVM version as follows:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ at each version. Backward compatibility is not guaranteed between each version.
|
|||||||
- It is possible to access dynamic data returned from function calls.
|
- It is possible to access dynamic data returned from function calls.
|
||||||
- ``revert`` opcode introduced, which means that ``revert()`` will not waste gas.
|
- ``revert`` opcode introduced, which means that ``revert()`` will not waste gas.
|
||||||
- ``constantinople``
|
- ``constantinople``
|
||||||
- Opcodes ``create2`, ``extcodehash``, ``shl``, ``shr`` and ``sar`` are available in assembly.
|
- Opcodes ``create2``, ``extcodehash``, ``shl``, ``shr`` and ``sar`` are available in assembly.
|
||||||
- Shifting operators use shifting opcodes and thus need less gas.
|
- Shifting operators use shifting opcodes and thus need less gas.
|
||||||
- ``petersburg``
|
- ``petersburg``
|
||||||
- The compiler behaves the same way as with constantinople.
|
- The compiler behaves the same way as with constantinople.
|
||||||
@ -172,8 +172,10 @@ at each version. Backward compatibility is not guaranteed between each version.
|
|||||||
the optimizer.
|
the optimizer.
|
||||||
- ``london``
|
- ``london``
|
||||||
- The block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_) can be accessed via the global ``block.basefee`` or ``basefee()`` in inline assembly.
|
- The block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_) can be accessed via the global ``block.basefee`` or ``basefee()`` in inline assembly.
|
||||||
- ``paris`` (**default**)
|
- ``paris``
|
||||||
- Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_).
|
- Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_).
|
||||||
|
- ``shanghai`` (**default**)
|
||||||
|
- Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 <https://eips.ethereum.org/EIPS/eip-3855>`_).
|
||||||
|
|
||||||
.. index:: ! standard JSON, ! --standard-json
|
.. index:: ! standard JSON, ! --standard-json
|
||||||
.. _compiler-api:
|
.. _compiler-api:
|
||||||
@ -201,7 +203,7 @@ Input Description
|
|||||||
.. code-block:: javascript
|
.. code-block:: javascript
|
||||||
|
|
||||||
{
|
{
|
||||||
// Required: Source code language. Currently supported are "Solidity" and "Yul".
|
// Required: Source code language. Currently supported are "Solidity", "Yul" and "SolidityAST" (experimental).
|
||||||
"language": "Solidity",
|
"language": "Solidity",
|
||||||
// Required
|
// Required
|
||||||
"sources":
|
"sources":
|
||||||
@ -225,9 +227,17 @@ Input Description
|
|||||||
"bzzr://56ab...",
|
"bzzr://56ab...",
|
||||||
"ipfs://Qma...",
|
"ipfs://Qma...",
|
||||||
"/tmp/path/to/file.sol"
|
"/tmp/path/to/file.sol"
|
||||||
// If files are used, their directories should be added to the command line via
|
// If files are used, their directories should be added to the command-line via
|
||||||
// `--allow-paths <path>`.
|
// `--allow-paths <path>`.
|
||||||
]
|
]
|
||||||
|
// If language is set to "SolidityAST", an AST needs to be supplied under the "ast" key.
|
||||||
|
// Note that importing ASTs is experimental and in particular that:
|
||||||
|
// - importing invalid ASTs can produce undefined results and
|
||||||
|
// - no proper error reporting is available on invalid ASTs.
|
||||||
|
// Furthermore, note that the AST import only consumes the fields of the AST as
|
||||||
|
// produced by the compiler in "stopAfter": "parsing" mode and then re-performs
|
||||||
|
// analysis, so any analysis-based annotations of the AST are ignored upon import.
|
||||||
|
"ast": { ... } // formatted as the json ast requested with the ``ast`` output selection.
|
||||||
},
|
},
|
||||||
"destructible":
|
"destructible":
|
||||||
{
|
{
|
||||||
@ -262,9 +272,9 @@ Input Description
|
|||||||
// The peephole optimizer is always on if no details are given,
|
// The peephole optimizer is always on if no details are given,
|
||||||
// use details to switch it off.
|
// use details to switch it off.
|
||||||
"peephole": true,
|
"peephole": true,
|
||||||
// The inliner is always on if no details are given,
|
// The inliner is always off if no details are given,
|
||||||
// use details to switch it off.
|
// use details to switch it on.
|
||||||
"inliner": true,
|
"inliner": false,
|
||||||
// The unused jumpdest remover is always on if no details are given,
|
// The unused jumpdest remover is always on if no details are given,
|
||||||
// use details to switch it off.
|
// use details to switch it off.
|
||||||
"jumpdestRemover": true,
|
"jumpdestRemover": true,
|
||||||
@ -294,7 +304,7 @@ Input Description
|
|||||||
// optimization-sequence:clean-up-sequence. For more information see
|
// optimization-sequence:clean-up-sequence. For more information see
|
||||||
// "The Optimizer > Selecting Optimizations".
|
// "The Optimizer > Selecting Optimizations".
|
||||||
// This field is optional, and if not provided, the default sequences for both
|
// This field is optional, and if not provided, the default sequences for both
|
||||||
// optimization and clean-up are used. If only one of the options is provivded
|
// optimization and clean-up are used. If only one of the sequences is provided
|
||||||
// the other will not be run.
|
// the other will not be run.
|
||||||
// If only the delimiter ":" is provided then neither the optimization nor the clean-up
|
// If only the delimiter ":" is provided then neither the optimization nor the clean-up
|
||||||
// sequence will be run.
|
// sequence will be run.
|
||||||
@ -306,7 +316,8 @@ Input Description
|
|||||||
},
|
},
|
||||||
// Version of the EVM to compile for.
|
// Version of the EVM to compile for.
|
||||||
// Affects type checking and code generation. Can be homestead,
|
// Affects type checking and code generation. Can be homestead,
|
||||||
// tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul, berlin, london or paris
|
// tangerineWhistle, spuriousDragon, byzantium, constantinople,
|
||||||
|
// petersburg, istanbul, berlin, london, paris or shanghai (default)
|
||||||
"evmVersion": "byzantium",
|
"evmVersion": "byzantium",
|
||||||
// Optional: Change compilation pipeline to go through the Yul intermediate representation.
|
// Optional: Change compilation pipeline to go through the Yul intermediate representation.
|
||||||
// This is false by default.
|
// This is false by default.
|
||||||
@ -348,7 +359,7 @@ Input Description
|
|||||||
// Addresses of the libraries. If not all libraries are given here,
|
// Addresses of the libraries. If not all libraries are given here,
|
||||||
// it can result in unlinked objects whose output data is different.
|
// it can result in unlinked objects whose output data is different.
|
||||||
"libraries": {
|
"libraries": {
|
||||||
// The top level key is the the name of the source file where the library is used.
|
// The top level key is the name of the source file where the library is used.
|
||||||
// If remappings are used, this source file should match the global path
|
// If remappings are used, this source file should match the global path
|
||||||
// after remappings were applied.
|
// after remappings were applied.
|
||||||
// If this key is an empty string, that refers to a global level.
|
// If this key is an empty string, that refers to a global level.
|
||||||
@ -380,7 +391,9 @@ Input Description
|
|||||||
// userdoc - User documentation (natspec)
|
// userdoc - User documentation (natspec)
|
||||||
// metadata - Metadata
|
// metadata - Metadata
|
||||||
// ir - Yul intermediate representation of the code before optimization
|
// ir - Yul intermediate representation of the code before optimization
|
||||||
|
// irAst - AST of Yul intermediate representation of the code before optimization
|
||||||
// irOptimized - Intermediate representation after optimization
|
// irOptimized - Intermediate representation after optimization
|
||||||
|
// irOptimizedAst - AST of intermediate representation after optimization
|
||||||
// storageLayout - Slots, offsets and types of the contract's state variables.
|
// storageLayout - Slots, offsets and types of the contract's state variables.
|
||||||
// evm.assembly - New assembly format
|
// evm.assembly - New assembly format
|
||||||
// evm.legacyAssembly - Old-style assembly format in JSON
|
// evm.legacyAssembly - Old-style assembly format in JSON
|
||||||
@ -394,10 +407,8 @@ Input Description
|
|||||||
// evm.deployedBytecode.immutableReferences - Map from AST ids to bytecode ranges that reference immutables
|
// evm.deployedBytecode.immutableReferences - Map from AST ids to bytecode ranges that reference immutables
|
||||||
// evm.methodIdentifiers - The list of function hashes
|
// evm.methodIdentifiers - The list of function hashes
|
||||||
// evm.gasEstimates - Function gas estimates
|
// evm.gasEstimates - Function gas estimates
|
||||||
// ewasm.wast - Ewasm in WebAssembly S-expressions format
|
|
||||||
// ewasm.wasm - Ewasm in WebAssembly binary format
|
|
||||||
//
|
//
|
||||||
// Note that using a using `evm`, `evm.bytecode`, `ewasm`, etc. will select every
|
// Note that using `evm`, `evm.bytecode`, etc. will select every
|
||||||
// target part of that output. Additionally, `*` can be used as a wildcard to request everything.
|
// target part of that output. Additionally, `*` can be used as a wildcard to request everything.
|
||||||
//
|
//
|
||||||
"outputSelection": {
|
"outputSelection": {
|
||||||
@ -433,10 +444,18 @@ Input Description
|
|||||||
"divModNoSlacks": false,
|
"divModNoSlacks": false,
|
||||||
// Choose which model checker engine to use: all (default), bmc, chc, none.
|
// Choose which model checker engine to use: all (default), bmc, chc, none.
|
||||||
"engine": "chc",
|
"engine": "chc",
|
||||||
|
// Choose whether external calls should be considered trusted in case the
|
||||||
|
// code of the called function is available at compile-time.
|
||||||
|
// For details see the SMTChecker section.
|
||||||
|
"extCalls": "trusted",
|
||||||
// Choose which types of invariants should be reported to the user: contract, reentrancy.
|
// Choose which types of invariants should be reported to the user: contract, reentrancy.
|
||||||
"invariants": ["contract", "reentrancy"],
|
"invariants": ["contract", "reentrancy"],
|
||||||
|
// Choose whether to output all proved targets. The default is `false`.
|
||||||
|
"showProved": true,
|
||||||
// Choose whether to output all unproved targets. The default is `false`.
|
// Choose whether to output all unproved targets. The default is `false`.
|
||||||
"showUnproved": true,
|
"showUnproved": true,
|
||||||
|
// Choose whether to output all unsupported language features. The default is `false`.
|
||||||
|
"showUnsupported": true,
|
||||||
// Choose which solvers should be used, if available.
|
// Choose which solvers should be used, if available.
|
||||||
// See the Formal Verification section for the solvers description.
|
// See the Formal Verification section for the solvers description.
|
||||||
"solvers": ["cvc4", "smtlib2", "z3"],
|
"solvers": ["cvc4", "smtlib2", "z3"],
|
||||||
@ -483,7 +502,7 @@ Output Description
|
|||||||
// Mandatory: Error type, such as "TypeError", "InternalCompilerError", "Exception", etc.
|
// Mandatory: Error type, such as "TypeError", "InternalCompilerError", "Exception", etc.
|
||||||
// See below for complete list of types.
|
// See below for complete list of types.
|
||||||
"type": "TypeError",
|
"type": "TypeError",
|
||||||
// Mandatory: Component where the error originated, such as "general", "ewasm", etc.
|
// Mandatory: Component where the error originated, such as "general" etc.
|
||||||
"component": "general",
|
"component": "general",
|
||||||
// Mandatory ("error", "warning" or "info", but please note that this may be extended in the future)
|
// Mandatory ("error", "warning" or "info", but please note that this may be extended in the future)
|
||||||
"severity": "error",
|
"severity": "error",
|
||||||
@ -520,8 +539,14 @@ Output Description
|
|||||||
"userdoc": {},
|
"userdoc": {},
|
||||||
// Developer documentation (natspec)
|
// Developer documentation (natspec)
|
||||||
"devdoc": {},
|
"devdoc": {},
|
||||||
// Intermediate representation (string)
|
// Intermediate representation before optimization (string)
|
||||||
"ir": "",
|
"ir": "",
|
||||||
|
// AST of intermediate representation before optimization
|
||||||
|
"irAst": {/* ... */},
|
||||||
|
// Intermediate representation after optimization (string)
|
||||||
|
"irOptimized": "",
|
||||||
|
// AST of intermediate representation after optimization
|
||||||
|
"irOptimizedAst": {/* ... */},
|
||||||
// See the Storage Layout documentation.
|
// See the Storage Layout documentation.
|
||||||
"storageLayout": {"storage": [/* ... */], "types": {/* ... */} },
|
"storageLayout": {"storage": [/* ... */], "types": {/* ... */} },
|
||||||
// EVM-related outputs
|
// EVM-related outputs
|
||||||
@ -599,13 +624,6 @@ Output Description
|
|||||||
"heavyLifting()": "infinite"
|
"heavyLifting()": "infinite"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// Ewasm related outputs
|
|
||||||
"ewasm": {
|
|
||||||
// S-expressions format
|
|
||||||
"wast": "",
|
|
||||||
// Binary format (hex string)
|
|
||||||
"wasm": ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -628,6 +646,6 @@ Error Types
|
|||||||
10. ``Exception``: Unknown failure during compilation - this should be reported as an issue.
|
10. ``Exception``: Unknown failure during compilation - this should be reported as an issue.
|
||||||
11. ``CompilerError``: Invalid use of the compiler stack - this should be reported as an issue.
|
11. ``CompilerError``: Invalid use of the compiler stack - this should be reported as an issue.
|
||||||
12. ``FatalError``: Fatal error not processed correctly - this should be reported as an issue.
|
12. ``FatalError``: Fatal error not processed correctly - this should be reported as an issue.
|
||||||
13. ``YulException``: Error during Yul Code generation - this should be reported as an issue.
|
13. ``YulException``: Error during Yul code generation - this should be reported as an issue.
|
||||||
14. ``Warning``: A warning, which didn't stop the compilation, but should be addressed if possible.
|
14. ``Warning``: A warning, which didn't stop the compilation, but should be addressed if possible.
|
||||||
15. ``Info``: Information that the compiler thinks the user might find useful, but is not dangerous and does not necessarily need to be addressed.
|
15. ``Info``: Information that the compiler thinks the user might find useful, but is not dangerous and does not necessarily need to be addressed.
|
||||||
|