---
title: "Como ler e escrever variáveis de storage compactadas em Yul"
description: "Entenda Como Ler e Escrever Variáveis de Storage Compactadas em Yul"
---

# Como ler e escrever variáveis de storage compactadas em Yul

[Yul](http://www.alchemy.com/overviews/what-is-yul) é uma linguagem de programação intermediária que pode ser usada para escrever uma forma de linguagem assembly dentro de [smart contracts](https://www.alchemy.com/overviews/solidity-smart-contract). Depois de aprender sobre a sintaxe do Yul e como o storage funciona, é importante entender como ler e escrever variáveis de storage empacotadas (packed) em Yul.

## **Como ler e escrever variáveis de storage empacotadas em yul**

Suponha que você queira mudar var5 para 4. Sabemos que var5 está localizada no slot 3, então você pode tentar algo assim:

Usando getValInHex\(3\) vemos que o slot 3 foi reescrito para:

`0x0000000000000000000000000000000000000000000000000000000000000004`

Isso é um problema porque agora var4 foi reescrita para 0. Nesta seção vamos ver como ler e escrever variáveis empacotadas, mas primeiro precisamos aprender um pouco mais sobre a sintaxe do Yul.

Se você não estiver familiarizado com essas operações não se preocupe, vamos ver cada uma com exemplos.

Vamos começar com and\(\). Vamos pegar dois bytes32 e testar o operador and\(\) para ver o que ele retorna.

Se você olhar a saída, vemos:

`0x0000000000000000000000009acc1d6aa9b846083e8a497a661853aae07f0f00` 

O motivo disso é que o and\(\) olha cada bit de ambas as entradas e compara seus valores. 

Se ambos os bits forem 1 \(pense em termos de binário: ativo ou inativo\), mantemos o bit como está. 

Caso contrário, ele é definido como 0.

Agora veja o código do or\(\).

Desta vez a saída é:

`0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`

Isso acontece porque ele verifica se algum dos dois bits está ativo.

Vamos ver o que acontece se mudarmos a variável mask para:

`0x00ffffffffffffffffffffff0000000000000000000000000000000000000000`

Como você pode ver, a saída muda para:

`0x00ffffffffffffffffffffff9acc1d6aa9b846083e8a497a661853aae07f0f00`

Note que o primeiro byte é 0x00, porque nenhuma das entradas tem bits ativos no primeiro byte.

xor\(\) é um pouco diferente. Ele exige que um bit esteja ativo \(1\) e o outro bit esteja inativo \(0\). 

**Aqui está uma demonstração em código:**

A saída é:

`0xffffffffffffffffffffffff0000000000000000000000000000000000000000`

A diferença principal fica evidente quando vemos que os únicos bits ativos na saída são onde 0x00 e 0xff estão alinhados.

shl\(\) e shr\(\) funcionam de forma bem parecida entre si. Ambos deslocam o valor de entrada por uma quantidade de bits informada. shl\(\) desloca para a esquerda e shr\(\) desloca para a direita. 

Vamos ver um pouco de código!

Saída:

ans1: `0x0000ffff00000000000000000000000000000000000000000000000000000000`

ans2: `0x00000000000000000000000000000000000000000000000000000000ffff0000`

Vamos começar olhando ans1. Fazemos shr\(\) por 16 bits \(2 bytes\). Como você pode ver, os últimos dois bytes mudam de 0xffff para 0x0000, e os primeiros dois bytes são deslocados dois bytes para a direita. Sabendo disso, ans2 parece autoexplicativo; tudo que acontece é que os bits são deslocados para a esquerda em vez de para a direita.

**Antes de escrever em var5, vamos escrever uma função que lê var4 e var5 primeiro.**

A saída é 1 e 2, como esperado. 

Para obter var4 precisamos apenas usar uma mask para definir o valor como:

`0x0000000000000000000000000000000000000000000000000000000000000001`

Então retornamos um uint128 igual a 1. 

Ao ler var5, precisamos deslocar var4 para fora, fazendo um shift para a direita. 

Isso nos deixa com o seguinte, que podemos retornar:

`0x0000000000000000000000000000000000000000000000000000000000000002`

É importante notar que às vezes você terá que fazer shift e mask em conjunto para ler um valor que tenha mais de 2 variáveis empacotadas em um slot de storage.

**Ok, finalmente estamos prontos para mudar o valor de var5 para 4!**

O primeiro passo é carregar o slot de storage 3. 

Em seguida, precisamos criar uma mask. 

De forma semelhante a quando lemos var4, queremos isolar o valor em:

`0x0000000000000000000000000000000000000000000000000000000000000001`

O próximo passo é formatar nosso novo valor para que fique na posição do slot de var5, assim:

`0x0000000000000000000000000000000400000000000000000000000000000000`

Diferente de quando lemos var5, desta vez vamos deslocar nosso valor para a esquerda. 

Por fim, vamos usar or\(\) para combinar nossos valores em 32 bytes de hexadecimal, e armazenar esse valor no slot 3. 

Podemos conferir nosso trabalho chamando getValInHex\(3\). 

Isso vai retornar isto, , que é o que esperamos ver:

`0x0000000000000000000000000000000400000000000000000000000000000001`

Ótimo, agora você sabe como ler e escrever em slots de storage empacotados! Em seguida, aprenda como [Memory](http://www.alchemy.com/overviews/yul-memory), [Storage](http://www.alchemy.com/overviews/yul-storage) e [Smart Contract Calls](http://www.alchemy.com/overviews/yul-contract-calls) funcionam em Yul.
