Я только что закончил Token Level в Zeppelin's Ethernaut , и в конце они объяснили, что переполнения очень распространены в солидности. Я даже не думал о переливах, я просто пытался украсть токены.
Это код, который они показывают:
Переполнения очень распространены в солидности и должны быть проверены с помощью управляющих операторов, таких как:
if(a + c > a) {
a = a + c;
}
Более простой альтернативой является использование библиотеки OpenZeppelin SafeMath, которая автоматически проверяет наличие переполнения во всех математических операторах. Результирующий код выглядит следующим образом:
a = a.add(c);
Если есть переполнение, код вернется.
Я просто не могу понять, что такое переполнение в солидности, может кто-нибудь объяснить мне новичку, что это такое, или указать мне статью, где посмотреть. Спасибо!
Из https://programtheblockchain.com/posts/2018/04/27/avoiding-integer-overflows-safemath-isnt-enough/ :
Целые числа фиксированного размера имеют диапазон значений, которые они могут представлять. Например, 8-битное целое число без знака может хранить значения от 0 до 255 (2^8-1). Когда результат некоторых арифметических операций выходит за пределы поддерживаемого диапазона, возникает целочисленное переполнение . В виртуальной машине Ethereum (EVM) следствием целочисленного переполнения является потеря старших битов результата. Например, при работе с 8-битными целыми числами без знака 255 + 1 = 0
. Это легче увидеть в двоичном формате, где 1111 1111 + 0000 0001
должно быть 1 0000 0000
, но поскольку доступно только 8 бит, самый левый бит теряется, что приводит к значению 0000 0000
.
Интуитивно эффект целочисленного переполнения можно рассматривать как «обтекание» значения.
Переполнение — это когда результат бинарной операции (т. е. операции с двумя операндами) не соответствует типу операндов (большему типу, если они не идентичны).
Например:
uint8 a = 43;
uint16 b = 65500;
uint32 c = a + b;
В приведенном выше коде результатом должно быть c
значение 65543
.
Тип c
может правильно представлять это значение, но результат a + b
вычисляется в uint16
(более крупный тип a
и b
), который не может правильно представить это значение.
пользователь47673