El valor máximo de uint256 se puede obtener con type(uint256).max; el cual es
115792089237316195423570985008687907853269984665640564039457584007913129639935
o 2²⁵⁶-1.
Pero es más limpio y seguro usar type(uint256).max.
Lo mismo se puede usar para los tipos de enteros con signo
//57896044618658097711785492504343953926634992332820282019728792003956564819967
type(int256).max;
//-57896044618658097711785492504343953926634992332820282019728792003956564819968
type(int256).min;
Las matemáticas detrás de los valores máximos en los enteros y enteros sin signo
Para los enteros sin signo, simplemente introduce 2 ** n - 1 en la terminal con tu lenguaje interpretado favorito para obtener la respuesta, donde n es el tamaño del uint en cuestión, por ejemplo uint128 o uint32 (o incluso tamaños raramente usados pero válidos como uint208). Un uintN significa que hay N bits que representan el número, y cuando todos ellos están establecidos en 1, esta es la representación binaria máxima.
La EVM usa el Complemento a dos para representar números con signo, por lo que para obtener el valor máximo de un entero con signo, la fórmula es y el valor más negativo es .
Formas poco convencionales de obtener el valor máximo de uint256
También podrías especificarlo en hexadecimal, lo cual sería un poco más limpio que usar la representación decimal, pero aún así consume espacio y es propenso a errores.
Valor máximo de uint256 en hexadecimal
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
¡Son exactamente 64 'f’s, no te equivoques! El 64 se deriva de dividir 256 bits entre 8 para obtener el número de bytes (32), y cada byte máximo se representa en hexadecimal por 0xff.
~uint256(0) es equivalente al valor máximo de uint256
El valor máximo de uint256 son 256 bits, todos establecidos en uno. Entonces, ¿qué tal usar el operador de inversión de bits? (~)
type(uint256).max == ~uint256(0) // this will return true
Otra solución fea es causar un underflow en el entero
function maximum() public pure returns(uint256) {
unchecked { return uint256(0) - uint256(1); }
}
El siguiente código funciona correctamente, pero es engañoso y no se recomienda su uso
function maxUint() public pure returns (uint256) {
return 2**256 - 1;
}
Devuelve el valor correcto, el cual puedes verificar con
assert(2**256 - 1 == type(uint256).max);
Si escribes 2**256 como una constante en Solidity, el código no compilará porque el compilador reconoce que 2**256 es demasiado grande para caber en uint256. Pero si es seguido inmediatamente por un “- 1”, entonces el compilador reconoce que el resultado de la aritmética es válido con el tipo.
uint256(-1) ya no funciona
En versiones más antiguas de Solidity, uint256(-1) se podía usar para obtener el valor máximo, pero eso ya no compilará.
Es mejor evitar toda esta gimnasia y simplemente hacer type(uint256).max;
¿Qué tan grande es 2^256 - 1?
Para dar algo de contexto al número, el número estimado de átomos en el universo conocido es de aproximadamente 10^80. Para visualizarlo, pongamos los números uno al lado del otro:
115792089237316195423570985008687907853269984665640564039457584007913129639935
100000000000000000000000000000000000000000000000000000000000000000000000000000000
Eso significa aproximadamente que 1,000 variables uint256 podrían enumerar cada átomo en el universo conocido. Dado que la mayoría de las “cosas” de interés están compuestas por mucho más de 1,000 átomos, un solo uint256 puede enumerar cualquier conjunto útil de cosas con espacio de sobra.
Como corolario, dos valores uint256 elegidos al azar (equivalentes a la salida de un hash keccak256), para todos los fines prácticos, nunca tendrán una colisión.
Aprende más
Si eres nuevo en Solidity, consulta nuestro curso gratuito de Solidity para principiantes.
Para desarrolladores intermedios y avanzados, por favor consulta nuestro solidity bootcamp para expertos.
Publicado originalmente el 2 de abril de 2023