É hora de atualizar nossas habilidades aprendendo tudo sobre Chamadas entre Contratos. Aqui está a Parte 2 da série de tutoriais trazida a você pelo Laika, o Request Builder para Web3.
Conforme exploramos na primeira parte desta série, é possível a interação entre os contratos inteligentes, de modo que uma interação em um contrato inteligente possa afetar outro contrato inteligente. Se você perdeu a primeira parte, aqui está o link útil: https://www.web3dev.com.br/fatimalima/como-chamar-um-contrato-inteligente-a-partir-de-outro-contrato-inteligente-parte-13-3bfn
Certifique-se de ter configurado seu espaço de trabalho Laika antes de continuar. Consulte nossos documentos aqui.
https://docs.getlaika.app/fundamentals/create-a-new-request
Nesta parte desta série de artigos, exploraremos a chamada de funções no Solidity. Portanto, prepare seu IDE Remix (ou qualquer outro IDE de sua preferência) e vamos lá!
Passo 1 — Usando o Contrato de Exemplo em Tempo Real
A beleza de todo esse sistema é que podemos considerar e usar qualquer contrato inteligente e habilitar chamadas em um contrato separado, tudo usando seu endereço de contrato implantado (o único fator aqui é que você precisa saber especificamente qual método chamar, ou seja, a ABI - Application Binary Interface deve ser conhecida). Podemos simplesmente criar um contrato de chamada para chamada(s) específica(s) usando os métodos diretamente na instância do contrato que é criado.
Nesta parte da série de tutoriais, consideraremos o uso do seguinte contrato. Você já deve ter ouvido falar do Protocolo UMA, talvez até o tenha usado!
Consideraremos especificamente o Oracle Optimistic (OO) do UMA e exploraremos a "integração OO mínima viável" oficial. O mesmo contrato pode ser encontrado em seu link de documentação oficial aqui: https://docs.umaproject.org/developers/getting-started
Passo 2 — Analisando o Contrato
O contrato abaixo é fornecido oficialmente pelo Protocolo UMA, no momento da redação deste artigo.
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.14;
import "https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle/interfaces/OptimisticOracleV2Interface.sol";
// *************************************
// * Integração Mínima Viável do OO *
// *************************************
// Este contrato mostra como começar a trabalhar o mais rápido possível com o Oracle Optimistic do UMA.
// Fazemos uma solicitação de preço simples para o OO e a retornamos para o usuário.
contract OO_GettingStarted {
// Crie uma instância do Oracle Optimistic no endereço implementado na rede Görli.
OptimisticOracleV2Interface oo = OptimisticOracleV2Interface(0xA5B9d8a0B0Fa04Ba71BDD68069661ED5C0848884);
// Use o identificador yes no (sim não) para fazer perguntas arbitrárias, como o clima em um determinado dia.
bytes32 identifier = bytes32("YES_OR_NO_QUERY");
// Publique a pergunta em dados auxiliares. Observe que essa é uma forma simplificada de dados auxiliares para servir de exemplo. Um mercado
// de produção do mundo real usaria algo um pouco mais complexo e precisaria estar em conformidade com uma estrutura mais robusta.
bytes ancillaryData =
bytes("Q:Did the temperature on the 25th of July 2022 in Manhattan NY exceed 35c? A:1 for yes. 0 for no.");
uint256 requestTime = 0; // Armazene a hora da solicitação para usarmos novamente mais tarde.
// Envie uma solicitação de dados para o Oracle Optimistic.
function requestData() public {
requestTime = block.timestamp; // Defina a hora da solicitação como a hora do bloco atual.
IERC20 bondCurrency = IERC20(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6); // Use o WETH Görli como moeda de bônus.
uint256 reward = 0; // Defina a recompensa como 0 (para não precisarmos financiá-la com esse contrato)).
// Agora, faça a solicitação de preço para o Oracle Optimistic e defina a liveness como 30 para que ela seja liquidada rapidamente.
oo.requestPrice(identifier, requestTime, ancillaryData, bondCurrency, reward);
oo.setCustomLiveness(identifier, requestTime, ancillaryData, 30);
}
// Liquide a solicitação depois que ela tiver passado pelo período de atividade de 30 segundos. Isso faz com que o preço votado seja finalizado.
// No mundo real, o uso do Oracle Optimistic deve ser mais longo para dar tempo aos competidores de pegarem as propostas de preço de BAT (Basic Attention Token).
function settleRequest() public {
oo.settle(address(this), identifier, requestTime, ancillaryData);
}
// Obtenha o preço resolvido do Oracle Optimistic que foi liquidado.
function getSettledData() public view returns (int256) {
return oo.getRequest(address(this), identifier, requestTime, ancillaryData).resolvedPrice;
}
}
Em vez de seguir o caminho tradicional de escrever nosso contrato inteligente e interagir com outro contrato auto-escrito, entenderemos um contrato pré-escrito e exploraremos novas metodologias.
Neste contrato, podemos ver alguns aspectos importantes:
- A criação da instância OO dentro do contrato é mostrada assim:
// Crie uma instância do Oracle Optimistic no endereço implantado na rede Görli.
OptimisticOracleV2Interface oo = OptimisticOracleV2Interface(0xA5B9d8a0B0Fa04Ba71BDD68069661ED5C0848884);
Esse é o método mais comum de instanciar um contrato implantado existente dentro do contrato de chamada de que você precisa.
A ABI está sendo fornecida diretamente pela importação do arquivo de código do contrato (https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/oracle/interfaces/OptimisticOracleV2Interface.sol. Isso é importante para fazer com que o contrato herde as variáveis e funções do contrato de Interface, que será usado posteriormente.
Podemos ver o uso de variáveis especialmente declaradas, como o
identifier
que deve ser o "YES_OR_NO_QUERY" neste exemplo específico (elas foram predefinidas para uso específico no ecossistema UMA).
//Use o identificador yes no para fazer perguntas arbitrárias, como o clima em um determinado dia.
bytes32 identifier = bytes32("YES_OR_NO_QUERY");
- Lidaremos com a solicitação de dados do Oracle, que já está predefinida no mesmo contrato para nossa conveniência.
// Envie uma solicitação de dados para o Oracle Optimistic.
function requestData() public {
requestTime = block.timestamp; // Defina a hora da solicitação como a hora do bloco atual.
IERC20 bondCurrency = IERC20(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6); // Use WETH Görli como moeda de bônus.
uint256 reward = 0; // Defina a recompensa como 0 (para não precisarmos financiá-la com esse contrato).
// Agora, faça a solicitação de preço para o Oracle Optimistic e defina a liveness (tempo em que o sistema se mantém funcionando e atualizado em tempo real) como 30 para que ela seja liquidada rapidamente.
oo.requestPrice(identifier, requestTime, ancillaryData, bondCurrency, reward);
oo.setCustomLiveness(identifier, requestTime, ancillaryData, 30);
}
Alguns aspectos importantes a serem observados aqui são: \
a) Estamos definindo IERC20 bondCurrency = IERC20(…)
usando o endereço (0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6) que é o endereço implantado na Goerli ETH. Esse é o bondCurrency solicitado pelo sistema Oracle para solicitar dados.
b) Estamos chamando as funções corretas (conforme herdadas pela interface importada), fazendo a solicitação de preço com os parâmetros necessários aqui.
//Faça a solicitação de preço para o Oracle Optimistic e defina a liveness como 30, para que a liquidação seja rápida.
oo.requestPrice(identifier, requestTime, ancillaryData, bondCurrency, reward);
oo.setCustomLiveness(identifier, requestTime, ancillaryData, 30);
Portanto, você pode ver como podemos configurar chamadas para outro contrato pré-implantado, certificando-nos de que os aspectos mencionados acima devam ser cumpridos.
Observação: Se não tivermos o código-fonte do contrato em mãos, precisaremos definir nossa própria interface no mesmo contrato. Além disso, é importante ter em mente os parâmetros exigidos no contrato original, sem os quais nossos esforços falhariam.
Passo 3 — Implantando o contrato de chamada
Agora que entendemos como será o nosso contrato e como ele funciona, tudo o que precisamos fazer é compilá-lo e implantá-lo na rede certa. Lembre-se de que aqui estamos lidando com a testnet (rede de teste) Goerli ETH!
Conforme explicado na Parte 1 desta série, tudo o que você precisa fazer é ir até a guia Compile (Compilar) e, uma vez feito isso, ir até a guia Deploy and Run (Implantar e Executar) e conectar seu provedor injetado (ou seja, a carteira Metamask) em seu IDE Remix. Certifique-se de que sua carteira Metamask esteja configurada na rede Goerli ETH neste momento.
>>>>> gd2md-html alert: inline image link here (to images/image2.png). Store image on your image server and adjust path/filename/extension if necessary.
(Back to top)(Next alert)
>>>>>
Detalhes da Testnet Goerli ETH
Caso não tenha a rede habilitada em sua carteira, você pode usar os detalhes fornecidos acima para adicioná-la.
Agora, basta clicar em Deploy e aguardar a conclusão do processo. (É claro que você precisará de um pouco de ETH da Goerli nesse momento)
Passo 4 — Finalmente, Laika!
Agora que implantamos nosso contrato e temos seu endereço, podemos simplesmente importá-lo para nosso espaço de trabalho do Laika!
\
_Nosso endereço de contrato: 0xe06cF07b37c80555B8191e70DD73E4B05d5E6E8F \
_(você pode usar nosso contrato implantado e concluir o experimento).
Lembre-se de que primeiro precisamos ir para https://web.getlaika.app e clique em [New Request].
>>>>> gd2md-html alert: inline image link here (to images/image3.png). Store image on your image server and adjust path/filename/extension if necessary.
(Back to top)(Next alert)
>>>>>
Clique em “ABI” para copiar a ABI
Você precisará da ABI do contrato antes de poder criar a coleção. Clique em copiar a ABI e cole-a no modal New Request.
>>>>> gd2md-html alert: inline image link here (to images/image4.png). Store image on your image server and adjust path/filename/extension if necessary.
(Back to top)(Next alert)
>>>>>
Cole o endereço do contrato implantado e a ABI e clique em [Import]
[
{
"inputs": [],
"name": "requestData",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "settleRequest",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getSettledData",
"outputs": [
{
"internalType": "int256",
"name": "",
"type": "int256"
}
],
"stateMutability": "view",
"type": "function"
}
]
Acima está o ABI json com o qual estamos trabalhando aqui.
>>>>> gd2md-html alert: inline image link here (to images/image5.png). Store image on your image server and adjust path/filename/extension if necessary.
(Back to top)(Next alert)
>>>>>
Espaço de Trabalho Laika com a coleção de solicitações importada
Se todas as etapas tiverem sido seguidas corretamente até este ponto, você poderá ver as três solicitações criadas na coleção de solicitações New Contract. Agora, tudo o que você precisa fazer é clicar em [Send] para chamar a função.
Vamos tentar clicar em write requestData
. Observe que essa é uma função Write (de gravação), portanto, precisaremos assinar uma transação em nossa carteira conectada e passar a transação on-chain.
>>>>> gd2md-html alert: inline image link here (to images/image6.png). Store image on your image server and adjust path/filename/extension if necessary.
(Back to top)(Next alert)
>>>>>
Resposta bruta recebida da chamada requestData
{
"to": "0xe06cF07b37c80555B8191e70DD73E4B05d5E6E8F",
"from": "0x5568416Fc7E9D575277c78a4f8272e873839f001",
"contractAddress": null,
"transactionIndex": 19,
"gasUsed": "177419",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200100080000000000000000000000000000000002000040000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x4dbce8ac0273efa1cae57469703ddae367172efa8c5f03a0895e42360e1f870e",
"transactionHash": "0xfe89d049503ef921c2581a6887b66aa6cd451e02d60f6932423393244473af6d",
"logs": [
{
"transactionIndex": 19,
"blockNumber": 8339720,
"transactionHash": "0xfe89d049503ef921c2581a6887b66aa6cd451e02d60f6932423393244473af6d",
"address": "0xA5B9d8a0B0Fa04Ba71BDD68069661ED5C0848884",
"topics": [
"0xf1679315ff325c257a944e0ca1bfe7b26616039e9511f9610d4ba3eca851027b",
"0x000000000000000000000000e06cf07b37c80555b8191e70dd73e4b05d5e6e8f"
],
"data": "0x5945535f4f525f4e4f5f515545525900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063c9843000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061513a446964207468652074656d7065726174757265206f6e207468652032357468206f66204a756c79203230323220696e204d616e68617474616e204e5920657863656564203335633f20413a3120666f72207965732e203020666f72206e6f2e00000000000000000000000000000000000000000000000000000000000000",
"logIndex": 65,
"blockHash": "0x4dbce8ac0273efa1cae57469703ddae367172efa8c5f03a0895e42360e1f870e"
}
],
"blockNumber": 8339720,
"confirmations": 2,
"cumulativeGasUsed": "5442917",
"effectiveGasPrice": "2678517203",
"status": 1,
"type": 2,
"byzantium": true
}
Portanto, estamos basicamente solicitando dados do Oracle Optimistic do UMA implantados ao vivo e servindo a seu propósito na blockchain. Você está convidado a se aprofundar no ecossistema UMA para entender melhor o que está acontecendo aqui.
Você sempre poderá usar o Laika para ajudá-lo em sua jornada de desenvolvedor.
E é isso! Laika é a sua interface de usuário completa baseada em ABI para interação de contratos em muitas, se não em todas, as redes EVM! Mais redes serão adicionadas em breve, portanto, fique de olho! Compartilhe suas experiências de uso do Laika conosco em nossas redes sociais.
Adios por enquanto e até breve!
🐶❤💛
Conecte-se conosco
Facebook: https://www.facebook.com/getlaikaapp/ \
Discord: https://discord.gg/4DzwHuxhcf \
Website: https://getlaika.app
Mais referências (em inglês):
- Introdução Geral aos Contratos Inteligentes da Fundação Ethereum
- Documentação Laika
- Github UMA
- UMA DocumentUMA Githubation
Esse artigo foi escrito por Ishan Pandey e traduzido por Fátima Lima. O original pode ser lido aqui.
Latest comments (0)