Como ler e escrever variáveis de storage compactadas em Yul
Escrito por Mark Jonathas
Yul é uma linguagem de programação intermediária que pode ser usada para escrever uma forma de linguagem assembly dentro de smart contracts. 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, Storage e Smart Contract Calls funcionam em Yul.
Visões gerais relacionadas
Solidity3 de dezembro de 2025
As 6 melhores IDEs de Solidity para desenvolvedores (2026)
Conheça as melhores IDEs para desenvolvimento em Solidity.
Solidity19 de novembro de 2025
Otimização de gas em Solidity: 12 técnicas para deixar seus smart contracts mais baratos e eficientes
Quer escrever código melhor e reduzir suas taxas de gas?
Solidity13 de novembro de 2025
12 boas práticas de segurança para smart contracts em Solidity
Proteja seus smart contracts com essas dicas e ferramentas de segurança de especialistas.

Construa magia blockchain
A Alchemy combina os produtos e ferramentas de desenvolvimento Web3 mais poderosos com recursos, comunidade e suporte lendário.