Cómo leer y escribir variables de storage empaquetadas en Yul
Escrito por Mark Jonathas
Yul es un lenguaje de programación intermedio que puede usarse para escribir una forma de lenguaje ensamblador dentro de smart contracts. Después de aprender sobre la sintaxis de Yul y cómo funciona el storage, es importante entender cómo leer y escribir variables de storage empaquetadas (packed) en Yul.
Cómo leer y escribir variables de storage empaquetadas en yul
Supongamos que quieres cambiar var5 a 4. Sabemos que var5 está ubicada en el slot 3, así que podrías intentar algo como esto:
Usando getValInHex(3) vemos que el slot 3 ha sido reescrito a:
0x0000000000000000000000000000000000000000000000000000000000000004
Eso es un problema porque ahora var4 ha sido reescrita a 0. En esta sección vamos a repasar cómo leer y escribir variables empaquetadas, pero primero necesitamos aprender un poco más sobre la sintaxis de Yul.
Si no estás familiarizado con estas operaciones no te preocupes, ahora vamos a repasarlas con ejemplos.
Empecemos con and(). Vamos a tomar dos bytes32 y probar el operador and() para ver qué devuelve.
Si miras el output vemos:
0x0000000000000000000000009acc1d6aa9b846083e8a497a661853aae07f0f00
La razón de esto es que lo que hace and() es mirar cada bit de ambos inputs y comparar sus valores.
Si ambos bits son 1 (piénsalo en términos binarios: activo o inactivo), entonces mantenemos el bit tal como está.
De lo contrario, se establece en 0.
Ahora mira el código de or().
Esta vez el output es:
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Esto es porque revisa si alguno de los dos bits está activo.
Veamos qué pasa si cambiamos la variable mask a:
0x00ffffffffffffffffffffff0000000000000000000000000000000000000000
Como puedes ver, el output cambia a:
0x00ffffffffffffffffffffff9acc1d6aa9b846083e8a497a661853aae07f0f00
Nota que el primer byte es 0x00, porque ninguno de los inputs tiene bits activos en el primer byte.
xor() es un poco diferente. Requiere que un bit esté activo (1) y el otro bit esté inactivo (0).
Aquí hay una demostración de código:
El output es:
0xffffffffffffffffffffffff0000000000000000000000000000000000000000
La diferencia clave se hace evidente cuando vemos que los únicos bits activos en el output son cuando 0x00 y 0xff están alineados.
shl() y shr() operan de manera muy similar entre sí. Ambos desplazan el valor de entrada una cantidad de bits dada. shl() desplaza hacia la izquierda y shr() desplaza hacia la derecha.
¡Veamos algo de código!
Output:
ans1: 0x0000ffff00000000000000000000000000000000000000000000000000000000
ans2: 0x00000000000000000000000000000000000000000000000000000000ffff0000
Empecemos mirando ans1. Realizamos shr() por 16 bits (2 bytes). Como puedes ver, los últimos dos bytes cambian de 0xffff a 0x0000, y los primeros dos bytes se desplazan dos bytes hacia la derecha. Sabiendo esto, ans2 resulta evidente; todo lo que ocurre es que los bits se desplazan hacia la izquierda en lugar de hacia la derecha.
Antes de escribir en var5, escribamos primero una función que lea var4 y var5.
El output es 1 y 2 como se esperaba.
Para obtener var4 solo necesitamos usar una mask para fijar el valor a:
0x0000000000000000000000000000000000000000000000000000000000000001
Luego devolvemos un uint128 igual a 1.
Al leer var5, necesitamos desplazar var4 hacia afuera desplazando a la derecha.
Esto nos deja con lo siguiente, que podemos devolver:
0x0000000000000000000000000000000000000000000000000000000000000002
Es importante notar que a veces tendrás que desplazar y enmascarar (mask) en conjunto para leer un valor que tiene más de 2 variables empaquetadas en un slot de storage.
Bien, ¡finalmente estamos listos para cambiar el valor de var5 a 4!
El primer paso es cargar el slot de storage 3.
Luego, necesitamos crear una mask.
De forma similar a cuando leímos var4, queremos aislar el valor a:
0x0000000000000000000000000000000000000000000000000000000000000001
El siguiente paso es formatear nuestro nuevo valor para que esté en la posición del slot de var5, de modo que quede así:
0x0000000000000000000000000000000400000000000000000000000000000000
A diferencia de cuando leímos var5, esta vez vamos a desplazar nuestro valor hacia la izquierda.
Finalmente, vamos a usar or() para combinar nuestros valores en 32 bytes de hexadecimal, y almacenar ese valor en el slot 3.
Podemos verificar nuestro trabajo llamando a getValInHex(3).
Esto va a devolver esto, que es lo que esperamos ver:
0x0000000000000000000000000000000400000000000000000000000000000001
¡Genial, ahora sabes cómo leer y escribir en slots de storage empaquetados! A continuación, aprende cómo funcionan Memory, Storage, y Smart Contract Calls en Yul.
Resúmenes relacionados
Solidity3 de diciembre de 2025
Los 6 mejores IDEs de Solidity para desarrolladores (2026)
Explora los mejores IDEs para el desarrollo en Solidity.
Solidity19 de noviembre de 2025
Optimización de gas en Solidity: 12 técnicas para hacer tus smart contracts más económicos y eficientes
¿Quieres escribir mejor código y reducir tus fees de gas?
Solidity13 de noviembre de 2025
12 mejores prácticas de seguridad para smart contracts en Solidity
Protege tus smart contracts con estos consejos y herramientas de seguridad de expertos.

Construye magia blockchain
Alchemy combina los productos y herramientas de desarrollo Web3 más potentes con recursos, comunidad y un soporte legendario.