SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
04.12.2024

Aula 221: Lendo e Entendendo Bytecode da EVM

O bytecode da Ethereum Virtual Machine (EVM) é a linguagem de programação de baixo nível que a rede Ethereum interpreta. Compreender como ler e interpretar o bytecode da EVM pode oferecer aos desenvolvedores uma visão mais aprofundada de como os contratos inteligentes funcionam internamente e permitir que eles otimizem seus contratos para desempenho e eficiência de gás.

Nesta aula, exploraremos a estrutura do bytecode da EVM, como lê-lo e como interagir com ele. Também forneceremos exemplos e explicações para ajudar a esclarecer esses conceitos.

O que é o Bytecode da EVM?

O bytecode da EVM é essencialmente uma coleção de opcodes (códigos de operação) que a EVM processa para executar várias funções, como operações aritméticas, armazenamento de dados e fluxo de controle. Cada opcode corresponde a uma operação específica que pode ser executada pela EVM.

O bytecode da EVM é gerado quando o código-fonte Solidity é compilado. O bytecode geralmente é representado em formato hexadecimal.

Visualizando o Bytecode

Para examinar o bytecode de um determinado contrato inteligente, podemos usar o Remix IDE ou uma ferramenta de linha de comando para compilar um contrato em Solidity. Abaixo está um exemplo simples de contrato em Solidity:

// SimpleStorage.sol
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 public storedData;

    function set(uint256 x) public {
        storedData = x;
    }

    function get() public view returns (uint256) {
        return storedData;
    }
}

Após compilar este contrato, podemos recuperar o bytecode correspondente da EVM. No Remix, isso pode ser encontrado frequentemente na seção "Bytecode" dos resultados da compilação.

Entendendo o Bytecode da EVM

Vamos dar uma olhada em uma versão simplificada do que o bytecode do contrato SimpleStorage pode parecer:

0x6060604052341561000f57600080fd5b5b6100176100436000396000f3

O bytecode da EVM geralmente começa com 0x, significando que é um número hexadecimal. Aqui está uma explicação de alguns opcodes comuns que podem estar presentes no bytecode:

  • 0x60 - Este é o opcode PUSH1, que empurra o próximo byte para a pilha.
  • 0x40 - Este é o opcode MSIZE, que empurra o tamanho da memória para a pilha.
  • 0x52 - Este é o opcode MSTORE, que armazena uma palavra na memória.
  • 0x15 - Este é o opcode CALLVALUE, utilizado para recuperar a quantidade de Ether enviada na chamada.

Opcodes Comuns

  1. PUSHx: Esses opcodes empurram x bytes para a pilha (por exemplo, PUSH1, PUSH2, etc.).
  2. MLOAD: Carrega uma palavra da memória.
  3. MSTORE: Armazena uma palavra na memória.
  4. SLOAD: Lê uma palavra do armazenamento.
  5. SSTORE: Escreve uma palavra no armazenamento.
  6. ADD, SUB, MUL, DIV: Operações aritméticas básicas.
  7. JUMP, JUMPI: Fluxo de controle para saltos e saltos condicionais.

Interagindo com o Bytecode

Você pode usar Web3.js ou Ethers.js juntamente com a rede Ethereum para interagir com o bytecode. Aqui está um exemplo mínimo usando Ethers.js para implantar um contrato de forma programática, que implica lidar com bytecode.

const { ethers } = require("ethers");

async function main() {
    const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545');
    const signer = provider.getSigner();

    const SimpleStorageABI = [
        "function set(uint256 x)",
        "function get() view returns (uint256)"
    ];

    const SimpleStorageBytecode = "0x606060405234..."; // Use o bytecode real aqui

    const factory = new ethers.ContractFactory(SimpleStorageABI, SimpleStorageBytecode, signer);
    const contract = await factory.deploy();

    await contract.deployed();

    console.log("Contrato implantado em:", contract.address);

    await contract.set(42);
    const storedData = await contract.get();
    console.log("Dados armazenados:", storedData.toString());
}

main().catch(console.error);

Conclusão

Compreender o bytecode da EVM ajuda a aprimorar suas habilidades de desenvolvimento, permitindo que você veja as operações subjacentes que seus contratos inteligentes executam. Usando ferramentas como o Remix e bibliotecas como Ethers.js, você pode implantar contratos e utilizar seu bytecode de forma eficaz. Nas próximas aulas, exploraremos técnicas de otimização e padrões avançados em desenvolvimento de contratos inteligentes.

Sinta-se à vontade para experimentar os exemplos fornecidos e explorar mais sobre bytecode e os internals da EVM!

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!