Como enviar transações da blockchain a partir de um backend
ÍNDICE
- Requisitos para criar uma transação de transferência
- Método de transação de envio
O envio de uma transação a partir de um aplicativo web3 é um processo um tanto simples quando estamos usando Metamask ou qualquer outra carteira. Nós nos conectamos ao aplicativo e assinamos a transação com apenas um clique. Mas, nos bastidores, muita coisa está acontecendo e, sempre que você precisa assinar e enviar uma transação manualmente a partir do backend, você passa a compreender todas as etapas envolvidas no processo.
Neste artigo, vou explicar como assinar e enviar uma transação a partir de um backend usando o web3.js. Este é um cenário muito comum dos aplicativos web3 que querem cunhar NFTs para seus usuários, bridges, ou qualquer outro aplicativo que tenha uma carteira de aplicativos.
Como exemplo, farei uma transferência de tokens ERC20, mas você pode substituir o método de contrato por qualquer coisa que você queira.
Nota: use npm init -y && npm i web3 dotenv
para instalar as dependências necessárias.
Requisitos para Criar uma Transação de Transferência
Como sempre, quando se interage com contratos inteligentes, precisamos de alguns parâmetros:
- Endpoint do nó RPC: usado para enviar nossa transação para um nó da blockchain para que seja propagado e coletado pelo trxpool. Você pode obter gratuitamente da Chainstack
- Endereço da carteira e chave privada: é necessário assinar as transações do nosso backend e enviá-las. Lembre-se de manter a chave segura como uma variável de ambiente e não incluí-la em seu código!
- Contrato inteligente ABI: assim como quando precisamos interagir com um contrato inteligente de um front-end, precisamos do arquivo ABI json.
- Endereço do contrato inteligente: o endereço do contrato inteligente na blockchain. Você pode ler como implantar um contrato inteligente aqui.
Com todos esses parâmetros precisamos de:
- Carregar todos os parâmetros a partir de variáveis de ambiente.
- Criar um provedor web3 utilizando o endpoint RPC.
- Importar a carteira para o fornecedor usando sua chave privada. Importante!
- Criar uma referência de contrato inteligente usando seu endereço, ABI, e o provedor web3.
const Web3 = require('web3');
//carrega o arquivo env nas variáveis de ambiente
require('dotenv').config();
// carrega o contrato ABI do arquivo
const TOKEN_ABI_JSON = require('./MyToken.json');
const RPC_ENDPOINT = process.env.RPC_ENDPOINT;
const ORIGIN_CONTRACT_ADDRESS = process.env.TOKEN_CONTRACT_ADDRESS;
const WALLET_ADDRESS = process.env.WALLET_ADDRESS;
const WALLET_KEY = process.env.PRIV_KEY;
const web3Provider = new Web3(process.env.RPC_ENDPOINT);
// importa a carteira no provedor
web3Provider.eth.accounts.wallet.add(WALLET_KEY);
const tokenContract = new web3Provider.eth.Contract(
TOKEN_ABI_JSON.abi,
TOKEN_CONTRACT_ADDRESS
);
// transfere as variáveis da transação
const amount = '1000000';
const recipientAddress = '0x21321321331321311232123';
// método para fazer a transferência
await transferTokens(web3Provider, tokenContract, amount, recipientAddress);
Método de transação de envio
Para realmente enviar a transação, criei uma função separada que recebe o provedor web3, a referência do contrato inteligente, o valor e o endereço do destinatário.
const transferTokens = async (provider, contract, amount, address) => {
try {
console.log(`Transfering ${amount} tokens to ${address} 💸💸💸💸💸`);
// 1 cria a transação do contrato inteligente
const trx = contract.methods.transfer(address, amount);
// 2 calcula a taxa do gas
const gas = await trx.estimateGas({ from: BRIDGE_WALLET });
console.log('gas :>> ', gas);
// 3 calcula o preço do gas
const gasPrice = await provider.eth.getGasPrice();
console.log('gasPrice :>> ', gasPrice);
// 4 codifica os dados de transação
const data = trx.encodeABI();
console.log('data :>> ', data);
// 5 obtém o número da transação para a carteira
const nonce = await provider.eth.getTransactionCount(WALLET_ADDRESS);
console.log('nonce :>> ', nonce);
// 6 constrói o objeto de transação com todos os dados
const trxData = {
// o trx é enviado da carteira
from: WALLET_ADDRESS,
// o destino do trx é o contrato do token ERC20
to: ORIGIN_TOKEN_CONTRACT_ADDRESS,
/** Os dados contêm a quantidade de parâmetros do endereço do destinatário do método do contrato de transferência */
data,
gas,
gasPrice,
nonce,
};
console.log('Transaction ready to be sent');
/** 7 envia a transação, ela será automaticamente assinada
já que o fornecedor tem a carteira **/
const receipt = await provider.eth.sendTransaction(trxData);
console.log(`Transaction sent, hash is ${receipt.transactionHash}`);
return true;
} catch (error) {
console.error('Error in transferTokens >', error);
return false;
}
};
Vamos rever, passo a passo, como estamos construindo a transação e enviando-a do back-end:
- criar transações de contrato inteligente usando o
contract.methods.methodName()
. Isto pode ser usado para qualquer método de contrato inteligente 😉 - calcular a taxa de gas usando
trx.estimateGas()
. - calcular o preço do gas usando
provider.eth.getGasPrice()
. - codificar os dados da transação usando
trx.encodeABI()
. - obter o número da transação para a carteira com
provider.eth.getTransactionCount(WALLET_ADDRESS)
. - construir o objeto de transação com todos os dados.
- enviar os dados da transação com
provider.eth.sendTransaction(trxData)
. A transação será automaticamente assinada porque a propriedadefrom
no objeto de dados da transação, corresponde ao endereço da carteira que importamos no provedor. - Imprimir o hash da transação
Como você pode ver, estes são passos múltiplos e, se você pensar nisso, estes são exatamente os que a Metamask faz, para nós, nos bastidores. A Metamask já tem nosso endereço de carteira para que possa calcular o gas, o número da transação (ou nonce), codificar todos os dados da transação e enviá-los por meio dos endpoints RPC que foram configurados (fornecidos pela Infura por padrão).
Espero que isso o ajude a entender como as transações blockchain são submetidas e, se você tiver alguma dúvida, sinta-se à vontade para entrar em contato comigo e ficarei feliz em ajudar 🤙
Publicado em 31-03-2022
Esse artigo foi escrito por soliditytips e traduzido por Fátima Lima. O original pode ser lido aqui.
Latest comments (0)