¿Cómo funcionan los desbordamientos en solidez?

Acabo de terminar el Token Level en Zeppelin's Ethernaut y al final me explicaron que los overflows son muy comunes en solidity. Ni siquiera pensé en desbordamientos, solo traté de robar las fichas.

Este es el código que muestran:


Los desbordamientos son muy comunes en la solidez y deben verificarse con declaraciones de control como:

if(a + c > a) {
a = a + c;
}

Una alternativa más fácil es usar la biblioteca SafeMath de OpenZeppelin que verifica automáticamente los desbordamientos en todos los operadores matemáticos. El código resultante se ve así:

 a = a.add(c);

Si hay un desbordamiento, el código se revertirá.


Simplemente no puedo entender qué son los desbordamientos en solidez, ¿alguien puede darme una explicación de novato sobre qué son o señalarme un artículo donde mirar? ¡Gracias!

Respuestas (2)

De https://programtheblockchain.com/posts/2018/04/27/avoiding-integer-overflows-safemath-isnt-enough/ :

Los enteros de tamaño fijo tienen un rango de valores que pueden representar. Por ejemplo, un entero sin signo de 8 bits puede almacenar valores entre 0 y 255 (2^8-1). Cuando el resultado de alguna aritmética cae fuera del rango admitido, se produce un desbordamiento de enteros . En la máquina virtual Ethereum (EVM), la consecuencia de un desbordamiento de enteros es que se pierden los bits más significativos del resultado. Por ejemplo, cuando se trabaja con enteros sin signo de 8 bits, 255 + 1 = 0. Esto es más fácil de ver en binario, donde 1111 1111 + 0000 0001debería estar 1 0000 0000, pero debido a que solo hay 8 bits disponibles, el bit más a la izquierda se pierde, lo que da como resultado un valor de 0000 0000.

Intuitivamente, el efecto de un desbordamiento de enteros se puede considerar como el valor "envolvente".

Muchas gracias @smarx, excelente artículo, justo lo que necesitaba.

Un desbordamiento es cuando el resultado de una operación binaria (es decir, una operación con dos operandos), no se ajusta al tipo de los operandos (el tipo más grande, si no son idénticos).

Por ejemplo:

uint8 a = 43;
uint16 b = 65500;
uint32 c = a + b;

En el código anterior, el resultado debería ser que cestá establecido en 65543.

El tipo de cpuede representar este valor correctamente, pero el resultado de a + bse calcula en uint16(el tipo más grande de ay b), que no puede representar este valor correctamente.