Os contratos inteligentes são os blocos de construção da tecnologia blockchain. Embora muitos desenvolvedores usem linguagens populares como Solidity, há outra maneira de escrever contratos inteligentes: usando opcodes. Neste guia para iniciantes, exploraremos como escrever, testar e implantar um contrato inteligente usando apenas opcodes.
O que são Opcodes e por que usá-los?
Opcodes, abreviação de códigos de operação, são as instruções básicas que a Máquina Virtual Ethereum (EVM) entende. Eles podem parecer complexos, mas oferecem benefícios exclusivos:
1. Compreensão profunda da EVM:
Trabalhar diretamente com Opcodes proporciona uma compreensão profunda de como a EVM funciona e oferece insights que podem ser valiosos para desenvolvedores, pesquisadores e educadores.
2. Otimização de Gás:
Os Opcodes permitem que os desenvolvedores otimizem o código para eficiência de gás – reduzindo os custos de transação.
3. Funcionalidade personalizada:
Os Opcodes permitem um nível de personalização e controle que pode não ser alcançado por meio de linguagens de alto nível. Os desenvolvedores podem criar funcionalidades específicas de acordo com seus requisitos exclusivos.
4. Análise de segurança:
Ao examinar o bytecode de um contrato, auditores e especialistas em segurança podem identificar vulnerabilidades e garantir que o contrato se comporte conforme pretendido.
Guia passo a passo para escrever um contrato inteligente usando Opcodes
Escrever contratos inteligentes usando opcodes pode ser complicado, mas vamos analisar a tarefa e aprender como podemos implantar nosso primeiro contrato inteligente usando opcodes.
1. Entenda os Opcodes EVM
Compreender os opcodes é o primeiro passo. Existem cerca de 120 opcodes, cada um com funcionalidades diferentes. aqui estão alguns exemplos:
Para saber mais sobre opcodes, você pode consultar este guia completo. Pratique usando o Playground EVM para se sentir confortável com os opcodes.
2. Escreva o Opcode para o Contrato Inteligente
Agora, quando você estiver confortável com os opcodes, descreva a lógica do seu contrato. Determine quais funções você deseja executar e como os dados serão armazenados e manipulados.
Para este guia, escreveremos um opcode muito simples para somar dois números.
É assim que parece:
PUSH1 0X02
PUSH2 0X03
ADD
Vamos simplificar estas linhas:
-
PUSH1 0x02
empurra o valor0x02
na pilha -
PUSH1 0x03
empurra o valor0x03
na pilha -
ADD
retira os dois primeiros valores da pilha, soma-os e coloca o resultado de volta na pilha
3. Calcule o Bytecode para o Opcode
Assim que tivermos o opcode do nosso contrato, vamos entender como podemos calcular o bytecode para o opcode fornecido:
PUSH1 0x02
-
PUSH1
O código de operação paraPUSH1
é0x60
-
0x02
O valor a ser colocado na pilha - Combinado, isso dá o bytecode
0x6002
-
PUSH1
0x03
-
PUSH1
: O código de operação paraPUSH1
é0x60
. -
0x03
: O valor a ser colocado na pilha. - Combinado, isso dá o bytecode
0x6003
. ADD
-
ADD
: O código de operação paraADD
é0x01
. - Não há valor associado, então o bytecode é simplesmente
0x01
.
Juntando tudo, o bytecode completo para os opcodes fornecidos é:
0x6002600301
Este bytecode pode ser usado para implantar ou interagir com um contrato na rede Ethereum.
4. Implante o contrato
O Remix não fornece uma maneira direta de compilar opcodes brutos. Portanto, precisaremos usar um contrato wrapper que incluirá o bytecode como construtor. Isso nos permitirá implantar os opcodes.
Esta é a aparência do nosso contrato wrapper:
pragma solidity ^0.8.0;
contract DeployOpcodes {
uint256 public sum;
constructor() {
deployOpcodes();
}
function deployOpcodes() private {
assembly {
let x := mload(0x40) // Encontra um local de armazenamento vazio
mstore(x, 0x02) // Primeiro número a adicionar
mstore(add(x, 0x20), 0x03) // Segundo número a ser adicionado
let result := add(mload(x), mload(add(x, 0x20))) // Soma os números
sstore(sum.slot, result) // Armazena o resultado na variável de estado "sum"
}
}
function getSum() public view returns (uint256) {
return sum;
}
}
Neste contrato, temos vários componentes principais:
-
Declaração do Contrato
DeployOpcodes
: Este é o nome do nosso contrato e é onde hospedaremos todas as funções e variáveis relacionadas à implantação do nosso opcode. -
Função Privada
DeployOpcodes
: Dentro desta função, trabalharemos diretamente com a Máquina Virtual Ethereum (EVM) usando linguagem assembly. Aqui está um detalhamento do que cada linha faz:
a.Bloco de montagem: Começamos com a palavra-chave assembly
, permitindo-nos escrever código EVM de baixo nível.
b.Encontrando um local de armazenamento vazio: A linha **let x := mload(0x40)
carrega o valor no local da memória 0x40
, um local especial na EVM que geralmente contém o “ponteiro de memória livre”. Ao atribuir este valor à variável x
, encontramos um local de armazenamento vazio.
c.Armazenando o primeiro número:Em seguida, **mstore(x, 0x02)
armazena o valor 0x02
no local da memória apontado por x
. Isso representa o primeiro número que queremos adicionar.
d.Armazenando o segundo número: A linha mstore(add(x, 0x20), 0x03)
armazena o valor 0x03
no local da memória x + 0x20
. Isso representa o segundo número a ser adicionado.
e. Calculando a Soma: Com **let result := add(mload(x), mload(add(x, 0x20)))
, carregamos os valores nas posições de memória x e x + 0x20
, adicione-os e atribua o resultado a uma variável chamada resultado.
f. Armazenando o Resultado: Finalmente, **sstore(sum.slot, result)
armazena o valor de resultado no slot de armazenamento correspondente à variável de estado sum
. Isso nos permite recuperar a soma posteriormente.
Agora usar o Remix é fácil! Compile o código e clique no botão Deploy!
Você pode ver que temos a função getSum que retornará o valor 5 para nós.
É assim que escrevemos nossos contratos inteligentes usando opcodes.
Escrever contratos inteligentes usando opcodes não é apenas um exercício acadêmico; é uma ferramenta poderosa para desenvolvedores que desejam otimizar, personalizar e compreender profundamente seus contratos inteligentes.
Se você achou este guia útil, aplauda-o e siga-me para obter mais informações!
Pari Tomar (Twitter ||LinkedIn)
Este artigo foi escrito por Pari Tomar e traduzido por Diogo Jorge. O artigo original pode ser encontrado aqui.
Top comments (0)