En palabras simples, el desbordamiento es una situación en la que uint (entero sin signo) alcanza su tamaño de bytes. Luego, el siguiente elemento agregado devolverá el primer elemento variable.
Digamos que tenemos un uint8, que solo puede tener 8 bits. Eso significa que el número más grande que podemos almacenar es el binario 11111111 (en decimal 2^8 - 1 = 255)
Mira el código de abajo.
uint8 balance = 255; balance++;
Si ejecuta el código anterior, el "saldo" será 0. Este es un ejemplo simple de desbordamiento. Si agrega 1 al binario 11111111, se restablece a 00000000.
En el caso de subdesbordamiento, si resta 1 de un uint8 que es 0, cambiará el valor a 255.
Ahora les muestro una implementación simple de underflow en Solidity.
Creemos un contrato inteligente simple llamado "ChangeBalance.sol". Vamos a usar Solidity 0.7 para este ejemplo porque Solidity 0.8 estaba asegurado.
pragma solidity 0.7.0; contract ChangeBalance { uint8 public balance; function decrease() public { balance--; } function increase() public { balance++; } }
Compilemos e implementemos el contrato inteligente. Como puede ver, el saldo inicial es 0.
Si presiona el botón "disminuir", entonces el "saldo" se reduce en uno. Veamos qué pasa después.
Como puede ver, el saldo actualizado ahora es 255.
La forma más fácil es usar al menos una versión 0.8 del compilador Solidity. En Solidity 0.8, el compilador se encargará automáticamente de verificar los desbordamientos y subdesbordamientos.
Déjame mostrarte cómo funciona en la práctica. Para hacer eso, cambiaré la versión del compilador e implementaré un nuevo contrato.
pragma solidity 0.8.0; contract ChangeBalance { uint8 public balance; function decrease() public { balance--; } function increase() public { balance++; } }
El saldo inicial es el mismo, es decir, 0.
Veamos qué sucedió cuando presionamos "disminuir". Ahora obtendrá un error en la consola Remix.
También publicado aquí