🇧🇷
Ethereum Developer Pack - PT
  • Ethereum Developer Pack - PT
  • Módulo 1
    • Introdução a Smart Contracts
      • Fundamentos de Blockchain
        • Histórico
        • Bitcoin
        • O que é Blockchain
        • Conceitos-chave em Blockchain
        • Como funciona a Blockchain
        • Tipos de Blockchain
        • Modelos de Consenso
      • A nova Internet
        • Web 3
        • Elementos Fundamentais
        • Impacto do Ethereum em Diversos Setores
      • Wallets
        • Componentes de uma wallet
        • Tipos de Wallet
        • Códigos Mnemônicos
      • Ethereum 101
        • Smart Contracts
        • Contas
          • Tipos de contas
          • Conteúdo das contas
        • Transações
          • Componentes
          • Ciclo de vida
        • Gás
        • Solidity
        • EVM
          • A máquina de estados
          • Opcodes
          • Como funciona a EVM
          • Clientes de execução
          • DApps
      • Blockchain Explorer
        • Funções de um blockchain explorer
        • Beneficios de utilizar um blockchain explorer
      • Remix
        • Características do Remix
        • Workspaces ou espaços de trabalho
        • Carregar e compilar um contrato
        • Implantar na máquina virtual do Remix (Remix VM)
        • Interagindo com funções
        • Deployar em uma rede pública
      • Crie seu primeiro Smart Contract
  • Módulo 2
    • Fundamentos de Solidity
      • Hello World
      • Tipos de Dados
      • Funções
      • Variáveis
        • Exercício 1
      • Operadores
        • Ejercicio 2
      • Constructor
        • Exercício 3
      • Convenções de nomenclatura
      • Tipos de armazenamento para variáveis
      • Estruturas de Controle
        • Exercício 4
      • Modificadores
      • Eventos
        • Exercício 5
      • Tipos de Referencia
        • Arrays
          • Exercício 6
        • Mappings
          • Exercício 7
        • Structs
          • Exercício 8
      • Address Payable
      • Como os contratos e funções recebem Ether.
      • Transferências de Ether
      • Conceitos Avançados
        • Codificação de ABI
        • Hashing
        • This
        • Herança
        • Abstract
        • Interface
        • Chamada entre contratos
        • EVM
        • ABI
        • Bytecode
        • Opcodes
  • Módulo 3
    • ERCs, Bibliotecas e Padrões de Desenvolvimento
      • Boas Práticas de Desenvolvimento
      • Padrões de Desenvolvimento
      • EIP & ERC
      • ERC-20
      • ERC-721
      • Open Zeppelin
      • Crie um Token ERC-20
      • Almacenamiento Descentralizado: IPFS
      • Crea un Token ERC-721
      • DeFi
  • Módulo 4
    • Kit de ferramentas para desenvolvimento na Ethereum
      • Requisitos para o módulo 4
        • Terminal
        • Git e Github
        • Node.js e npm
        • Visual Studio Code para Solidity
      • Toolkit
        • JSON-RPC
        • Ethers.js
          • Exercício
        • Hardhat
          • Implantação de um contrato no Hardhat
          • Implantação de um contrato em uma rede pública
        • Scaffold-ETH
          • Características do Scaffold-ETHCaracterísticas
          • Como instalar o Scaffold-ETH
  • Módulo 5
    • Segurança, Testes e Auditorias
      • Testes
        • Importância de realizar testes
        • Métodos para testar contratos inteligentes
          • Testes automatizados
          • Testes manuais
        • Conceitos importantes em testes
        • Ferramentas para testes
        • Testes com Hardhat
        • Recursos adicionais
      • Segurança
        • Uma mentalidade diferente de design
        • Principais vulnerabilidades em contratos inteligentes
          • Reentrancy attack (ataque de reentrada)
          • Replay attack (ataque de repetición)
          • Price Oracle Manipulation (Manipulación de Oráculos de Precios)
          • Missing Access Control (Pérdida de Control de Acceso)
          • Reward Manipulation (Manipulación de Recompensas)
          • Failure to Initialize (Falla al Inicializar)
          • Front-running
          • Invariant Breaks (Quebra de Invariantes)
          • Mishandling of ETH (Má gestão de ETH)
          • Denial of Service (DoS - Negação de Serviço)
          • Integer overflow and underflow (Overflow e Underflow de inteiros)
          • Phishing y Typosquatting
        • Recursos adicionais
      • Auditoria de smart contracts
        • Processo de Auditoria
        • Ferramentas
        • Como se preparar para uma auditoria
        • O teste Rekt
        • Desafios
        • Recursos adicionais
  • Contribuye
    • Kipu Explorer
Powered by GitBook
On this page
  1. Módulo 1
  2. Introdução a Smart Contracts
  3. Ethereum 101
  4. EVM

Como funciona a EVM

PreviousOpcodesNextClientes de execução

Last updated 23 days ago

De forma simplificada, quando um usuário quer executar uma função de um smart contract, ele envia uma transação para o endereço ou conta do smart contract. A EVM pega o bytecode, o decompõe em opcodes, os executa e atualiza o novo estado na blockchain. Tal como mostrado no gráfico a seguir.

De forma simplificada, quando um usuário deseja executar uma função de um contrato inteligente, ele envia uma transação para o endereço ou conta do contrato inteligente. A EVM pega o bytecode, o decompõe em opcodes, executa-os e atualiza o novo estado na blockchain. Como mostrado no gráfico a seguir.

Para ver a execução com mais detalhes, vejamos quais são os componentes que compõem a EVM.

O Código

O código é o local onde o contrato inteligente é armazenado. Os dados do programa, armazenados no código, são persistentes e fazem parte de um campo de estado de uma contract account. O código é o bytecode interpretado e executado pela EVM durante a execução do contrato inteligente. Ele é imutável, ou seja, não pode ser modificado, mas pode ser lido com as instruções CODESIZE e CODECOPY. O código de um contrato também pode ser lido por outros contratos, usando as instruções EXTCODESIZE e EXTCODECOPY.

O Contador de Programa (PC)

O Contador de Programa (PC) codifica qual instrução, armazenada no bytecode, deve ser lida a seguir pela EVM. O PC normalmente é incrementado em um byte para apontar para a próxima instrução, com algumas exceções. Por exemplo, a instrução PUSHx possui mais de um byte e faz com que o PC ignore seu parâmetro. A instrução JUMP não aumenta o valor do PC; em vez disso, modifica o contador de programa para uma posição especificada no topo da pilha. JUMPI também realiza essa ação, caso sua condição seja verdadeira (um valor de código diferente de zero); caso contrário, incrementa o PC como outras instruções.

A Pilha ou Stack

A pilha é uma lista de elementos de 32 bytes utilizada para armazenar entradas e saídas de instruções de contratos inteligentes. Uma pilha é criada por contexto de chamada e destruída quando o contexto de chamada termina. Quando um novo valor é colocado na pilha, ele é adicionado ao topo, e as instruções interagem apenas com os valores superiores. Atualmente, a pilha possui um limite máximo de 1024 valores. Todas as instruções interagem com a pilha, mas ela pode ser manipulada diretamente com instruções como PUSH1, POP, DUP1 ou SWAP1.

A Memória

A memória da EVM não é persistente e é destruída ao final do contexto de chamada. No início de um contexto de chamada, a memória é inicializada com o valor 0. A leitura e a escrita na memória geralmente são realizadas com as instruções MLOAD e MSTORE, respectivamente, mas também é possível acessá-la por meio de outras instruções, como CREATE ou EXTCODECOPY.

O Armazenamento ou Storage

O armazenamento é uma correspondência ou mapa de slots de 32 bytes para valores de 32 bytes. O armazenamento é a memória persistente dos contratos inteligentes: cada valor escrito pelo contrato é mantido após a conclusão de uma chamada, a menos que seu valor seja alterado para 0 ou que a instrução SELFDESTRUCT seja executada. A leitura de bytes armazenados em uma chave não escrita também retorna 0. Cada contrato possui seu próprio armazenamento e não pode ler nem modificar o armazenamento de outro contrato. O armazenamento é lido e escrito com as instruções SLOAD e SSTORE.

No gráfico a seguir, visualiza-se como esses componentes interagem. Diante de uma chamada a um smart contract, os seguintes passos são executados:

  1. Identificação do código a ser executado.

  2. Enquanto houver gás disponível, o contador de programa (PC) incorpora, uma a uma, as instruções que são traduzidas em opcodes e executadas na pilha (stack). A pilha utiliza a memória (temporária) ou o armazenamento (persistente) para armazenar e recuperar dados associados à execução.

  3. Caso o gás não se esgote antes do término da execução, um novo estado para a blockchain é gerado. Caso contrário, o estado é revertido para a situação anterior à execução da transação. O gás consumido não é recuperado.

Para ver a execução com mais detalhes, vejamos quais são os componentes da EVM.

O código

O código é o local onde o contrato inteligente é armazenado. Os dados do programa armazenados no código são persistentes como parte de um campo de estado de uma contract account. O código é o bytecode interpretado e executado pela EVM durante a execução do contrato inteligente. O código é imutável, o que significa que não pode ser modificado, mas pode ser lido com as instruções CODESIZE e CODECOPY. O código de um contrato pode ser lido por outros contratos, com as instruções EXTCODESIZE e EXTCODECOPY.

O Contador de Programa (PC)

O Contador de Programa codifica qual instrução, armazenada no bytecode, deve ser lida a seguir pela EVM. O PC normalmente é incrementado em um byte para apontar para a próxima instrução, com algumas exceções. Por exemplo, a instrução PUSHx possui mais de um byte e faz com que o PC ignore seu parâmetro. A instrução JUMP não aumenta o valor do PC, mas modifica o contador do programa para uma posição especificada na parte superior da pilha. JUMPI também faz isso, se sua condição for verdadeira (um valor de código diferente de zero); caso contrário, incrementa o PC como as outras instruções.

A pilha ou stack

A pilha é uma lista de elementos de 32 bytes que são usados para armazenar entradas e saídas das instruções de contratos inteligentes. Uma pilha é criada para cada contexto de chamada e destruída quando o contexto de chamada é finalizado. Quando um novo valor é colocado na pilha, ele é colocado no topo, e as instruções só utilizam os valores superiores. A pilha atualmente tem um limite máximo de 1024 valores. Todas as instruções interagem com a pilha, mas ela pode ser manipulada diretamente com instruções como PUSH1, POP, DUP1 ou SWAP1.

A memória

A memória da EVM não é persistente e é destruída ao final do contexto de chamada. No início de um contexto de chamada, a memória é inicializada com valor 0. A leitura e escrita da memória geralmente são realizadas com as instruções MLOAD e MSTORE, respectivamente, mas também é possível acessá-la por meio de outras instruções como CREATE ou EXTCODECOPY.

O armazenamento (storage)

O armazenamento é um mapeamento de slots de 32 bytes para valores de 32 bytes. O armazenamento é a memória persistente dos contratos inteligentes: cada valor gravado pelo contrato é mantido após a conclusão de uma chamada, a menos que seu valor seja alterado para 0 ou que a instrução SELFDESTRUCT seja executada. A leitura de bytes armazenados de uma chave não escrita também retorna 0. Cada contrato possui seu próprio armazenamento e não pode ler nem modificar o armazenamento de outro contrato. O armazenamento é lido e escrito com as instruções SLOAD e SSTORE.

Fluxo de execução

No gráfico a seguir, é possível visualizar como esses componentes interagem. Diante de uma chamada a um contrato inteligente, os seguintes passos são executados:

  1. O código a ser executado é identificado.

  2. Enquanto houver gas disponível, o contador de programa (PC) vai processando uma a uma as instruções que são traduzidas em opcodes e executadas na pilha (stack), que se apoia na memória (temporal) ou no storage (persistente), para armazenar e recuperar dados associados à execução.

  3. Se o gas não for consumido antes de finalizar a execução, um novo estado é gerado para a blockchain. Caso contrário, o estado é revertido para a situação anterior à execução da transação. O gas consumido não é recuperado.