8 minutos de leitura
Este guia inclui referências à rede de teste Kovan, que já não é mantida ativamente. Embora os passos específicos relacionados com esta cadeia possam não ser aplicáveis, o processo geral pode ser válido para outras cadeias. Recomendamos que explore alternativas atuais para a sua implementação. Se desejar ver uma versão atualizada deste guia, informe-nos!
Visão geral
Por vezes, envia-se uma transação na Ethereum sem gas suficiente devido ao congestionamento da rede ou ao excesso de transações pendentes que oferecem um preço de gas superior ao que ofereceu na sua transação. Se tiver uma transação de alta prioridade mas com pouco gas, poderá acabar por ter de esperar horas ou até dias até que a transação seja processada. Nestes casos, terá de reenviar uma transação com mais gas e o mesmo nonce, para que seja minerada o mais rapidamente possível.
Neste guia, iremos abordar toda a terminologia e as informações relacionadas com o envio de uma transação na Ethereum e com o reenvio da mesma transação utilizando o Ethers.js numa das redes de teste da Ethereum.
O que é uma transação na Ethereum?
Realizamos uma transação sempre que queremos adicionar, atualizar ou modificar algo na rede Ethereum. Basicamente, uma transação é a forma como o mundo real interage com a rede blockchain da Ethereum. Por cada transação que realizamos na rede Ethereum, temos de pagar uma taxa chamada «gas». O «gas» é expresso em wei (a menor unidade de ETH) ou em gwei.
Tipos de transações na Ethereum
Existem três tipos comuns de transações na rede Ethereum:
- Uma transação normal, em que ocorre uma transferência de ETH/ether de uma conta para outra.
- Uma transação que cria um contrato é o tipo de transação em que um contrato inteligente é implementado na rede blockchain da Ethereum.
- Uma transação que invoca um contrato; esta transação é enviada com alguns dados e é utilizada para consultar ou interagir com um contrato inteligente previamente implementado.
Parâmetros de uma transação típica na Ethereum
- de: O endereço do remetente, um endereço de 20 bytes que representa a conta que inicia a transação.
- para: O endereço do destinatário, um endereço de 20 bytes que representa uma conta do destinatário ou uma conta de contrato.
- valor: Trata-se da quantidade de ETH enviada na transação de uma conta para outra.
- data: Este campo contém o bytecode para transações de implementação de contratos. Para a execução de uma função de contrato, inclui uma assinatura de função e argumentos codificados. Este campo não é necessário nem é deixado em branco nas transações de transferência de fundos.
- gasLimit: Este é o valor máximo, em wei, que uma transação pode utilizar como gas.
- gasPrice: Este é o montante em wei que o remetente está disposto a pagar pela transação.
- chainId: Esta é a identificação da rede do seu nó Ethereum (mainnet: 1, rinkeby: 4, kovan: 42, etc.)
- nonce: É o número de transações que um determinado endereço envia. Sempre que um endereço envia uma transação, o nonce aumenta em 1.
Fluxo de transações na Ethereum
- Criar um objeto de transação e atribuir-lhe todos os parâmetros necessários.
- Assinar a transação com a chave privada do remetente.
- Envio da transação para a rede blockchain da Ethereum através de um nó da Ethereum.
Assinatura de uma transação
Assinar uma transação significa gerar uma assinatura num objeto de transação utilizando a chave privada do remetente. Se quiseres saber mais sobre a assinatura e a validação na Ethereum, eis algumas leituras excelentes: «Signing and Verifying Ethereum Signatures», de Yos, e «Ethereum: Signing and Validating», de Angello Pozo.
Agora que já compreendemos melhor as transações na Ethereum, vamos enviar uma nós próprios.
Pré-requisitos
- NodeJS instalado no seu sistema
- Um editor de texto
- Terminal, também conhecido como linha de comandos
Instalação das ferramentas necessárias.
Vamos utilizar o NodeJS para gerir o nosso pacote de bibliotecas e para trabalhar com o ficheiro JavaScript. Para verificar se tem o NodeJS instalado no seu sistema, abra um terminal e execute:
$ node -v
Se ainda não estiver instalado, pode descarregar a versão LTS do NodeJS a partir do site oficial.
Para enviar uma transação, vamos utilizar um pequeno código JavaScript e a biblioteca ethers.js (certifique-se de que é a versão 5.7). Pode instalá-la com o npm a partir da linha de comandos/terminal:
$ npm install --save ethers@5.7
O problema mais comum nesta etapa é uma falha interna do `node-gyp`. Pode seguir as instruções de instalação do node-gyp aqui.
Outro problema comum é um cache desatualizado. Limpa o teu cache do npm digitando simplesmente o seguinte no teu terminal:
$ npm cache clean
Pode consultar o nosso guia sobre o ethers.js para saber mais sobre a biblioteca ethers.js.
Criar uma carteira e obter algum ETH para teste
Agora, vamos criar uma carteira para nós próprios. Para tal, comece por criar um ficheiro index.js ou um ficheiro JavaScript com o nome que preferir. Pode copiar e colar isto no seu editor de código:
var ethers = require('ethers');
var chave-privada = "0x0111111111111111111122222222222222222223333333333333333333344445";
var carteira = new ethers.Carteira(chave privada);
console.log("Endereço: " + carteira.endereço);
Vamos ver o que acontece aqui: Importar a biblioteca ethers.js que instalámos anteriormente (linha 1), Criar uma chave privada específica para a nossa carteira; terá de criar uma para si, que pode ser qualquer número, mas certifique-se de que contém o mesmo número de dígitos que o indicado acima (linha 2), Criar uma instância da carteira com o ethers utilizando a chave privada (linha 3), Exibir o endereço da nossa carteira com o texto «Address» na consola (linha 4).
Agora, execute o ficheiro utilizando:
$ node index.js
Se tudo correr bem, a saída apresentada na janela do terminal deverá ter o seguinte aspeto:
Endereço: 0x3f5D3070Fc7924479B5e367a83EC2b284E9c4e04
Como todas as transações requerem «gas» como taxa e vamos precisar de algum para enviar a transação, vamos colocar algum ETH de teste na nossa carteira. Para tal, vamos utilizar um nó Kovan; por isso, aceda a esta fonte Kovan para obter algum ETH de teste, cole o endereço da carteira que obteve ao executar o código acima e clique em «send me KETH!».
Nota: Trata-se de ETH de teste, que não tem valor de mercado.
Configurar o seu ponto de acesso Quicknode para a Ethereum
Para os nossos objetivos de hoje, podemos utilizar praticamente qualquer cliente Ethereum, como o Geth ou o OpenEthereum (anteriormente conhecido como Parity). Para iniciar um nó Ethereum por nossa conta, teremos primeiro de selecionar um cliente e configurá-lo; sincronizar um nó Ethereum e mantê-lo é uma tarefa desafiante; a sincronização de um nó completo Ethereum pode demorar dias.
Como isso é um pouco complicado demais para enviar apenas uma transação, vamos utilizar um endpoint gratuito do Quicknode para facilitar o processo. Depois de criares o teu endpoint gratuito do Ethereum, copia o endpoint do teu Provedor HTTP:
Para este guia, estamos a utilizar um nó da rede de teste Kovan.

Vais precisar disto mais tarde, por isso copia e guarda.
Envio e reenvio de uma transação
Agora, temos uma carteira com algum ETH de teste. Vamos, então, enviar uma transação para transferir algum ETH para outra conta/carteira. Para tal, vamos adicionar mais algumas coisas úteis ao nosso ficheiro index.js. Podes copiar e colar isto no teu editor de código:
var ethers = require('ethers');
var url = 'ADD_YOUR_ETHEREUM_NODE_URL';
var customHttpProvider = new ethers.providers.JsonRpcProvider(url);
var privateKey = "0x0111111111111111111122222222222222222223333333333333333333344445";
var wallet = new ethers.Wallet(privateKey);
console.log("Address: " + wallet.address);
tx = {
to: "0x6E0d01A76C3Cf4288372a29124A26D4353EE51BE",
value: ethers.utils.parseEther("0.05"),
chainId: 42,
nonce: 3
}
customHttpProvider.estimateGas(tx).then(function(estimate) {
tx.gasLimit = estimate;
tx.gasPrice = ethers.utils.parseUnits("0.14085197", "gwei");
wallet.signTransaction(tx).then((signedTX)=>{
customHttpProvider.sendTransaction(signedTX).then(console.log);
});
});
Por isso, substitua `ADD_YOUR_ETHEREUM_NODE_URL` pelo fornecedor HTTP indicado na secção anterior.
Uma breve explicação do código acima: estamos a importar a biblioteca «ethers» que instalámos anteriormente (linha 1), a definir o URL do nosso nó Ethereum (linha 2), a instanciar uma instância «JsonRpcProvider» da biblioteca «ethers» (linha 3), a criar uma chave privada específica para a nossa carteira — terá de criar uma para si, pode ser qualquer número, mas certifique-se de que contém o mesmo número de dígitos (linha 4), criando uma instância de carteira com o ethers utilizando a chave privada (linha 5), exibindo o endereço da nossa carteira com o texto «Address» na consola (linha 6), criando um objeto de transação e adicionando o campo «to» com o endereço do destinatário — pode gerar um endereço aleatório utilizando `var wallet = Wallet.createRandom();`, um campo «value» indicando o valor do ETH a enviar, um campo «chainId» definido aqui como 42, uma vez que estamos a utilizar a Kovan, um campo «nonce» definido como 3 (linhas 7-12), estimando o «gasLimit» através do nosso nó e definindo o preço do gás (linhas 13-15), Assinando o objeto de transação com a chave privada da nossa carteira e enviando-o, além de apresentar a transação na consola (linhas 16-18).
Vamos experimentar isto:
$ node index.js
O resultado será algo semelhante a isto:

Copie a sequência de caracteres do campo «hash» (algo como «0xe49c8122656c612bf5f1e10b251f56671acf01d831b6876c37c5a52053035642») e cole-a na caixa de pesquisa do Etherscan do Kovan para verificar o estado da transação. Verá que a transação ainda não foi adicionada ao novo bloco na blockchain e apresenta o estado «pendente». Isso deve-se ao facto de termos introduzido um valor de gas significativamente baixo.
Agora, vamos tentar enviar a mesma transação com o mesmo nonce, mas, desta vez, aumentando o valor do gas; altere o valor de gasPrice na linha 15 do código de «0,14085197» para «2,14085197» e volte a executar o código:
$ node index.js
Copie a sequência de hash da nova saída e cole-a na caixa de pesquisa do Kovan Etherscan para verificar o estado da transação. Desta vez, a nossa transação será adicionada ao bloco e apresentará o estado «sucesso», uma vez que a enviámos com um valor de gasPrice adequado e mais elevado.
Nota: É importante ter em conta que o valor do «nonce» é o mesmo em ambas as transações. Conforme mencionado anteriormente, o nonce é um indicador do número de transações que um endereço Ethereum possui. Para reenviar uma transação com um valor de gas mais elevado, deve utilizar o mesmo nonce da transação original. Se utilizar um nonce mais elevado, isso será considerada uma nova transação, o que implicará gastar mais ETH do que pretendia.
Conclusão
Assim, tal como vimos no exemplo anterior, o preço do gás numa transação deve ser competitivo para que a transação seja aprovada. Os mineradores da blockchain definem o gás com base no espaço disponível no bloco e no valor que todas as transações estão dispostas a pagar para ocupar esse espaço; quando existe uma transação com um valor de gás inferior ao valor-limite, esta não será aprovada. As transações com um valor de gás mais elevado em comparação com outras transações são aprovadas rapidamente.
Subscreve a nossa newsletter para receberes mais artigos e guias sobre o Ethereum. Se tiveres algum comentário, não hesites em contactar-nos através do Twitter; e, se tiveres alguma dúvida, podes sempre conversar connosco no nosso servidor da comunidade no Discord. Lá estão alguns dos programadores mais fixes que há, obrigado :)
