---
title: "Cómo leer y escribir variables de storage empaquetadas en Yul"
description: "Entiende cómo leer y escribir variables de storage empaquetadas en Yul"
---

# Cómo leer y escribir variables de storage empaquetadas en Yul

[Yul](http://www.alchemy.com/overviews/what-is-yul) es un lenguaje de programación intermedio que puede usarse para escribir una forma de lenguaje ensamblador dentro de [smart contracts](https://www.alchemy.com/overviews/solidity-smart-contract). 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](http://www.alchemy.com/overviews/yul-memory), [Storage](http://www.alchemy.com/overviews/yul-storage), y [Smart Contract Calls](http://www.alchemy.com/overviews/yul-contract-calls) en Yul.
