Ir para o conteúdo

Biblioteca JavaScript Ethers.js

Introdução

A biblioteca Ethers.js fornece ferramentas para interagir com nós Ethereum usando JavaScript, semelhante à Web3.js. As redes EVM alimentadas pela Tanssi oferecem uma API compatível com Ethereum/JSON-RPC, então você pode usar Ethers.js para interagir com uma rede EVM da Tanssi como faria no Ethereum. Para mais detalhes, consulte a documentação oficial.

Neste guia você aprenderá a usar Ethers.js na sua rede EVM da Tanssi. Para demonstrar, enviaremos uma transação e implantaremos um contrato em uma appchain EVM de demonstração rodando no Dancelight. Para sua própria appchain Tanssi, basta trocar o endpoint.

Se preferir vídeo, veja os tutoriais no topo desta página sobre Enviar transações com Ethers.js e Implantar contratos com Ethers.js.

Note

Os exemplos deste guia partem de um ambiente MacOS ou Ubuntu 20.04. Se estiver usando Windows, adapte os comandos conforme necessário.

Verifique também se você tem o Node.js e um gerenciador de pacotes (como npm ou yarn) instalados. Para saber como instalar o Node.js, consulte a documentação oficial.

Além disso, certifique-se de ter inicializado um arquivo package.json para módulos ES6. Você pode criar um package.json padrão com npm executando npm init --yes.

Verificando pré-requisitos

Para os exemplos deste guia você precisará:

  • De uma conta com fundos na rede EVM da Tanssi que estiver usando para testes

Instalando Ethers.js

Instale a biblioteca Ethers.js e o compilador Solidity:

npm install ethers solc@0.8.0
yarn add ethers solc@0.8.0

Configurando o provedor Ethers

Os scripts a seguir usam um provedor Ethers para falar com a rede.

  1. Importe ethers
  2. Defina providerRPC com name, rpc e chainId da rede
  3. Crie o provider com ethers.JsonRpcProvider
// 1. Importe ethers
import { ethers } from "ethers";

// 2. Defina as configurações da rede
const providerRPC = {
  evmNetwork: {
    name: 'dancelight-evm-network',
    // Insira aqui sua URL RPC
    rpc: 'https://services.tanssi-testnet.network/dancelight-2001/',
    chainId: 5678, // 0x162E em hexadecimal,
  },
};
// 3. Crie o provider do ethers
const provider = new ethers.JsonRpcProvider(
  providerRPC.evmNetwork.rpc, 
  {
    chainId: providerRPC.evmNetwork.chainId,
    name: providerRPC.evmNetwork.name,
  }
);

Guarde este trecho; ele é reutilizado nos scripts abaixo.

Enviar uma transação

Criaremos dois scripts: um para consultar saldos e outro para enviar a transação.

Script de saldos

Crie o arquivo:

touch balances.js

Depois monte o script:

  1. Inclua o provedor
  2. Defina addressFrom e addressTo
  3. Crie a função balances
  4. Use provider.getBalance e ethers.formatEther para exibir os saldos
  5. Chame balances()
// 1. Adicione aqui a lógica do provider do Ethers:
// {...}

// 2. Crie as variáveis de endereço
const addressFrom = 'INSERT_ADDRESS_FROM';
const addressTo = 'INSERT_ADDRESS_TO';

// 3. Crie a função de saldos
const balances = async () => {
  // 4. Busque os saldos
  const balanceFrom = ethers.formatEther(await provider.getBalance(addressFrom));
  const balanceTo = ethers.formatEther(await provider.getBalance(addressTo));

  console.log(`The balance of ${addressFrom} is: ${balanceFrom} TANGO`);
  console.log(`The balance of ${addressTo} is: ${balanceTo} TANGO`);
};

// 5. Chamar a função de saldos
balances();
Ver o script completo
// Import ethers
import { ethers } from 'ethers';

// Define network configurations
const providerRPC = {
  evmNetwork: {
    name: 'dancelight-evm-network',
    rpc: 'https://services.tanssi-testnet.network/dancelight-2001', // Insert your RPC URL here
    chainId: 5678, // 0x162E in hex,
  },
};
// Create ethers provider
const provider = new ethers.JsonRpcProvider(providerRPC.evmNetwork.rpc, {
  chainId: providerRPC.evmNetwork.chainId,
  name: providerRPC.evmNetwork.name,
});

// Define addresses
const addressFrom = 'INSERT_ADDRESS_FROM';
const addressTo = 'INSERT_ADDRESS_TO';

// Create balances function
const balances = async () => {
  // Fetch balances
  const balanceFrom = ethers.formatEther(
    await provider.getBalance(addressFrom)
  );
  const balanceTo = ethers.formatEther(await provider.getBalance(addressTo));

  console.log(`The balance of ${addressFrom} is: ${balanceFrom} TANGO`);
  console.log(`The balance of ${addressTo} is: ${balanceTo} TANGO`);
};

// Call the balances function
balances();

Execute:

node balances.js

Saldos serão exibidos em TANGO.

node balances.js The balance of 0x44236223aB4291b93EEd10E4B511B37a398DEE55 is: 20.0 TANGO
The balance of 0x8841701Dba3639B254D9CEe712E49D188A1e941e is: 1.0 TANGO

Script de envio de transação

Crie o arquivo:

touch transaction.js

Passos:

  1. Inclua o provedor
  2. Defina privateKey e addressTo (não armazene chaves reais em arquivos JS)
  3. Crie a wallet com privateKey e provider
  4. Crie a função send
  5. Monte o objeto de transação (to, value com ethers.parseEther)
  6. Envie com wallet.sendTransaction e aguarde o recibo
  7. Chame send()
// 1. Adicione aqui a lógica do provider do Ethers:
// {...}

// 2. Crie as variáveis da conta
const accountFrom = {
  privateKey: 'INSERT_YOUR_PRIVATE_KEY',
};
const addressTo = 'INSERT_ADDRESS_TO';

// 3. Crie a wallet
let wallet = new ethers.Wallet(accountFrom.privateKey, provider);

// 4. Crie a função de envio
const send = async () => {
  console.log(`Attempting to send transaction from ${wallet.address} to ${addressTo}`);

  // 5. Crie o objeto da tx
  const tx = {
    to: addressTo,
    value: ethers.parseEther('1'),
  };

  // 6. Assine e envie a tx — aguarde o recibo
  const createReceipt = await wallet.sendTransaction(tx);
  await createReceipt.wait();
  console.log(`Transaction successful with hash: ${createReceipt.hash}`);
};

// 7. Chame a função de envio
send();
Ver o script completo
// Import ethers
import { ethers } from 'ethers';

// Define network configurations
const providerRPC = {
  evmNetwork: {
    name: 'dancelight-evm-network',
    rpc: 'https://services.tanssi-testnet.network/dancelight-2001', // Insert your RPC URL here
    chainId: 5678, // 0x162E in hex,
  },
};

// Create ethers provider
const provider = new ethers.JsonRpcProvider(providerRPC.evmNetwork.rpc, {
  chainId: providerRPC.evmNetwork.chainId,
  name: providerRPC.evmNetwork.name,
});

// Define accounts and wallet
const accountFrom = {
  privateKey: 'INSERT_YOUR_PRIVATE_KEY',
};
const addressTo = 'INSERT_ADDRESS_TO';
const wallet = new ethers.Wallet(accountFrom.privateKey, provider);

// Create send function
const send = async () => {
  console.log(
    `Attempting to send transaction from ${wallet.address} to ${addressTo}`
  );

  // Create transaction
  const tx = {
    to: addressTo,
    value: ethers.parseEther('1'),
  };

  // Send transaction and get hash
  const createReceipt = await wallet.sendTransaction(tx);
  await createReceipt.wait();
  console.log(`Transaction successful with hash: ${createReceipt.hash}`);
};

// Call the send function
send();

Rode com:

node transaction.js

O hash será exibido. Use balances.js antes/depois para confirmar a mudança de saldo.

node transaction.js Attempting to send transaction from 0x44236223aB4291b93EEd10E4B511B37a398DEE55 to 0x8841701 Dba3639B254D9CEe712E49D188A1e941e
Transaction successful with hash: 0x29d87c00704b949cb4cc04fdc6c98d53b3c0ec4fb3ffe0c52864a73 b586f563c
node balances.js The balance of 0x44236223aB4291b93EEd10E4B511B37a398DEE55 is: 18.999958 TANGO
The balance of 0x8841701Dba3639B254D9CEe712E49D188A1e941e is: 2.0 TANGO

Implantar um contrato

O contrato que você irá compilar e implantar nas próximas seções é um simples incrementador, chamado Incrementer.sol. Comece criando o arquivo do contrato:

touch Incrementer.sol

Depois, adicione o código Solidity ao arquivo:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Incrementer {
    uint256 public number;

    constructor(uint256 _initialNumber) {
        number = _initialNumber;
    }

    function increment(uint256 _value) public {
        number = number + _value;
    }

    function reset() public {
        number = 0;
    }
}

A função constructor, executada quando o contrato é implantado, define o valor inicial da variável number armazenada on-chain (padrão é 0). A função increment soma o _value informado ao número atual, mas exige uma transação, pois modifica o dado armazenado. Por fim, a função reset zera o valor armazenado.

Note

Este contrato é apenas um exemplo simples para fins ilustrativos.

Script de compilação

Nesta seção, você criará um script que usa o compilador Solidity para gerar o bytecode e a interface (ABI) do contrato Incrementer.sol. Para começar, crie o arquivo compile.js executando:

touch compile.js

Em seguida, escreva o script e conclua estas etapas:

  1. Importe os pacotes fs e solc
  2. Use fs.readFileSync para ler e salvar o conteúdo de Incrementer.sol em source
  3. Monte o objeto input para o compilador Solidity especificando language, sources e settings
  4. Compile o contrato usando solc.compile com o objeto input
  5. Extraia o contrato compilado e exporte-o para ser usado no script de implantação
// 1. Import packages
import fs from 'fs';
import solc from 'solc';

// 2. Get path and load contract
const source = fs.readFileSync('Incrementer.sol', 'utf8');

// 3. Create input object
const input = {
  language: 'Solidity',
  sources: {
    'Incrementer.sol': {
      content: source,
    },
  },
  settings: {
    outputSelection: {
      '*': {
        '*': ['*'],
      },
    },
  },
};
// 4. Compile the contract
const tempFile = JSON.parse(solc.compile(JSON.stringify(input)));
const contractFile = tempFile.contracts['Incrementer.sol']['Incrementer'];

// 5. Export contract data
export default contractFile;

Script de deploy

Compile Incrementer.sol e depois crie deploy.js:

touch deploy.js

Passos:

  1. Importe o contrato de compile.js
  2. Inclua o provedor
  3. Defina privateKey (não salve chaves reais em JS)
  4. Guarde bytecode e abi
  5. Crie a wallet
  6. Crie a ContractFactory
  7. Crie a função deploy
  8. Use incrementer.deploy(5) e aguarde o recibo
  9. Chame deploy()
// 1. Importe o arquivo do contrato
import contractFile from './compile';

// 2. Adicione aqui a lógica do provider do Ethers:
// {...}

// 3. Crie as variáveis da conta
const accountFrom = {
  privateKey: 'INSERT_YOUR_PRIVATE_KEY',
};

// 4. Salve o bytecode e o ABI
const bytecode = contractFile.evm.bytecode.object;
const abi = contractFile.abi;

// 5. Crie a wallet
let wallet = new ethers.Wallet(accountFrom.privateKey, provider);

// 6. Crie a instância do contrato com o assinante
const incrementer = new ethers.ContractFactory(abi, bytecode, wallet);

// 7. Crie a função de deploy
const deploy = async () => {
  console.log(`Attempting to deploy from account: ${wallet.address}`);

  // 8. Envie a tx (valor inicial definido como 5) e aguarde o recibo
  const contract = await incrementer.deploy(5);
  const txReceipt = await contract.deploymentTransaction().wait();

  console.log(`Contract deployed at address: ${txReceipt.contractAddress}`);
};

// 9. Chame a função de deploy
deploy();
Ver o script completo
// Import ethers and compile
import { ethers } from 'ethers';
import contractFile from './compile.js';

// Define network configurations
const providerRPC = {
  evmNetwork: {
    name: 'dancelight-evm-network',
    rpc: 'https://services.tanssi-testnet.network/dancelight-2001', // Insert your RPC URL here
    chainId: 5678, // 0x162E in hex,
  },
};

// Create ethers provider
const provider = new ethers.JsonRpcProvider(providerRPC.evmNetwork.rpc, {
  chainId: providerRPC.evmNetwork.chainId,
  name: providerRPC.evmNetwork.name,
});

// Define accounts and wallet
const accountFrom = {
  privateKey: 'INSERT_YOUR_PRIVATE_KEY',
};
let wallet = new ethers.Wallet(accountFrom.privateKey, provider);

// Load contract info
const bytecode = contractFile.evm.bytecode.object;
const abi = contractFile.abi;

// Create contract instance with signer
const incrementer = new ethers.ContractFactory(abi, bytecode, wallet);

// Create deploy function
const deploy = async () => {
  console.log(`Attempting to deploy from account: ${wallet.address}`);

  // Send tx (initial value set to 5) and wait for receipt
  const contract = await incrementer.deploy(5);
  const txReceipt = await contract.deploymentTransaction().wait();

  console.log(`Contract deployed at address: ${txReceipt.contractAddress}`);
};

// Call the deploy function
deploy();

Execute:

node deploy.js

O endereço do contrato será exibido.

node deploy.js Attempting to deploy from account: 0x44236223aB4291b93EEd10E4B511B37a398DEE55
Contract deployed at address: 0x2EF0C649C08D55637dec9fCcebCFeD27F2F2a5F2

Ler dados do contrato (calls)

Calls não alteram estado; nenhuma transação é enviada. Crie get.js:

touch get.js

Passos:

  1. Importe o contractFile de compile.js
  2. Inclua o provedor
  3. Defina contractAddress
  4. Crie a instância com ethers.Contract
  5. Crie a função get
  6. Chame incrementer.number() e exiba o valor
  7. Chame get()
// 1. Importe o ABI do contrato
import contractFile from './compile';

// 2. Adicione aqui a lógica do provider do Ethers:
// {...}

// 3. Variável do endereço do contrato
const contractAddress = 'INSERT_CONTRACT_ADDRESS';

// 4. Crie a instância do contrato
const incrementer = new ethers.Contract(
  contractAddress,
  contractFile.abi,
  provider
);

// 5. Crie a função get
const get = async () => {
  console.log(`Fazendo uma chamada para o contrato no endereço: ${contractAddress}`);

  // 6. Chame o contrato 
  const data = await incrementer.number();

  console.log(`The current number stored is: ${data}`);
};

// 7. Chame a função get
get();
Ver o script completo
// Import ethers and compile
import { ethers } from 'ethers';
import contractFile from './compile.js';

// Define network configurations
const providerRPC = {
  evmNetwork: {
    name: 'dancelight-evm-network',
    rpc: 'https://services.tanssi-testnet.network/dancelight-2001', // Insert your RPC URL here
    chainId: 5678, // 0x162E in hex,
  },
};

// Create ethers provider
const provider = new ethers.JsonRpcProvider(providerRPC.evmNetwork.rpc, {
  chainId: providerRPC.evmNetwork.chainId,
  name: providerRPC.evmNetwork.name,
});

// Contract address variable
const contractAddress = 'INSERT_CONTRACT_ADDRESS';

// Create contract instance
const incrementer = new ethers.Contract(
  contractAddress,
  contractFile.abi,
  provider
);

// Create get function
const get = async () => {
  console.log(`Making a call to contract at address: ${contractAddress}`);

  // Call contract
  const data = await incrementer.number();

  console.log(`The current number stored is: ${data}`);
};

// Call get function
get();

Rode com:

node get.js
node get.js Making a call to contract at address: 0x2EF0C649C08D55637dec9fCcebCFeD27F2F2a5F2
The current number stored is: 5

Interagir com o contrato (send)

Sends alteram estado e exigem transação. Crie increment.js e reset.js:

touch increment.js reset.js

increment.js:

  1. Importe contractFile
  2. Inclua o provedor
  3. Defina privateKey, contractAddress, _value (não salve chaves reais em JS)
  4. Crie a wallet
  5. Crie a instância do contrato com signer
  6. Crie a função increment
  7. Chame incrementer.increment(_value) e aguarde recibo
  8. Chame increment()
// 1. Importe o ABI do contrato
import contractFile from './compile';

// 2. Adicione aqui a lógica do provider do Ethers:
// {...}

// 3. Crie as variáveis
const accountFrom = {
  privateKey: 'INSERT_YOUR_PRIVATE_KEY',
};
const contractAddress = 'INSERT_CONTRACT_ADDRESS';
const _value = 3;

// 4. Crie a wallet
let wallet = new ethers.Wallet(accountFrom.privateKey, provider);

// 5. Crie a instância do contrato com o assinante
const incrementer = new ethers.Contract(
  contractAddress,
  contractFile.abi,
  wallet
);

// 6. Crie a função de incremento
const increment = async () => {
  console.log(
    `Chamando a função de incremento por ${_value} no contrato no endereço: ${contractAddress}`
  );

  // 7. Assine e envie a tx e aguarde o recibo
  const createReceipt = await incrementer.increment(_value);
  await createReceipt.wait();

  console.log(`Tx successful with hash: ${createReceipt.hash}`);
};

// 8. Chame a função de incremento
increment();
Ver o script completo
// Import ethers and compile
import { ethers } from 'ethers';
import contractFile from './compile.js';

// Define network configurations
const providerRPC = {
  evmNetwork: {
    name: 'dancelight-evm-network',
    rpc: 'https://services.tanssi-testnet.network/dancelight-2001', // Insert your RPC URL here
    chainId: 5678, // 0x162E in hex,
  },
};

// Create ethers provider
const provider = new ethers.JsonRpcProvider(providerRPC.evmNetwork.rpc, {
  chainId: providerRPC.evmNetwork.chainId,
  name: providerRPC.evmNetwork.name,
});

// Create variables
const accountFrom = {
  privateKey: 'INSERT_YOUR_PRIVATE_KEY',
};
const contractAddress = 'INSERT_CONTRACT_ADDRESS';
const _value = 3;

// Create wallet
let wallet = new ethers.Wallet(accountFrom.privateKey, provider);

// Create contract instance with signer
const incrementer = new ethers.Contract(
  contractAddress,
  contractFile.abi,
  wallet
);

// Create increment function
const increment = async () => {
  console.log(
    `Calling the increment by ${_value} function in contract at address: ${contractAddress}`
  );

  // Sign and send tx and wait for receipt
  const createReceipt = await incrementer.increment(_value);
  await createReceipt.wait();

  console.log(`Tx successful with hash: ${createReceipt.hash}`);
};

// Call the increment function
increment();

reset.js:

  1. Importe contractFile
  2. Inclua o provedor
  3. Defina privateKey e contractAddress
  4. Crie a wallet
  5. Crie a instância do contrato com signer
  6. Crie a função reset
  7. Chame incrementer.reset() e aguarde recibo
  8. Chame reset()
// 1. Importe o ABI do contrato
import contractFile from './compile';

// 2. Adicione aqui a lógica do provider do Ethers:
// {...}

// 3. Crie as variáveis
const accountFrom = {
  privateKey: 'INSERT_YOUR_PRIVATE_KEY',
};
const contractAddress = 'INSERT_CONTRACT_ADDRESS';

// 4. Crie a wallet
let wallet = new ethers.Wallet(accountFrom.privateKey, provider);

// 5. Crie a instância do contrato com o assinante
const incrementer = new ethers.Contract(
  contractAddress,
  contractFile.abi,
  wallet
);

// 6. Crie a função de reset
const reset = async () => {
  console.log(`Chamando a função de reset no contrato no endereço: ${contractAddress}`);

  // 7. Assine e envie a tx e aguarde o recibo
  const createReceipt = await incrementer.reset();
  await createReceipt.wait();

  console.log(`Tx successful with hash: ${createReceipt.hash}`);
};

// 8. Chame a função de reset
reset();
Ver o script completo
// Import ethers and compile
import { ethers } from 'ethers';
import contractFile from './compile.js';

// Define network configurations
const providerRPC = {
  evmNetwork: {
    name: 'dancelight-evm-network',
    rpc: 'https://services.tanssi-testnet.network/dancelight-2001', // Insert your RPC URL here
    chainId: 5678, // 0x162E in hex,
  },
};

// Create ethers provider
const provider = new ethers.JsonRpcProvider(providerRPC.evmNetwork.rpc, {
  chainId: providerRPC.evmNetwork.chainId,
  name: providerRPC.evmNetwork.name,
});

// Create variables
const accountFrom = {
  privateKey: 'INSERT_YOUR_PRIVATE_KEY',
};
const contractAddress = 'INSERT_CONTRACT_ADDRESS';

// Create wallet
let wallet = new ethers.Wallet(accountFrom.privateKey, provider);

// Create contract instance with signer
const incrementer = new ethers.Contract(
  contractAddress,
  contractFile.abi,
  wallet
);

// Create reset function
const reset = async () => {
  console.log(
    `Calling the reset function in contract at address: ${contractAddress}`
  );

  // Sign and send tx and wait for receipt
  const createReceipt = await incrementer.reset();
  await createReceipt.wait();

  console.log(`Tx successful with hash: ${createReceipt.hash}`);
};

// Call the reset function
reset();

Rode:

node increment.js
node reset.js

Use get.js junto para confirmar a mudança de valor.

node increment.js Calling the reset function in contract at address: 0x2EF0C649C08D55637dec9fCcebCFe D27F2F2a5F2
Tx successful with hash: 0xb689da50a43e98b5a83ff64757afbf100be12e2db6ff4d0504168f262cc08fb0
node get.js Making a call to contract at address: 0x2EF0C649C08D55637dec9fCcebCFeD27F2F2a5F2
The current number stored is: 0
As informações apresentadas aqui foram fornecidas por terceiros e estão disponíveis apenas para fins informativos gerais. A Tanssi não endossa nenhum projeto listado e descrito no Site de Documentação da Tanssi (https://docs.tanssi.network/). A Tanssi Foundation não garante a precisão, integridade ou utilidade dessas informações. Qualquer confiança depositada nelas é de sua exclusiva responsabilidade. A Tanssi Foundation se exime de toda responsabilidade decorrente de qualquer confiança que você ou qualquer outra pessoa possa ter em qualquer parte deste conteúdo. Todas as declarações e/ou opiniões expressas nesses materiais são de responsabilidade exclusiva da pessoa ou entidade que as fornece e não representam necessariamente a opinião da Tanssi Foundation. As informações aqui não devem ser interpretadas como aconselhamento profissional ou financeiro de qualquer tipo. Sempre busque orientação de um profissional devidamente qualificado em relação a qualquer assunto ou circunstância em particular. As informações aqui podem conter links ou integração com outros sites operados ou conteúdo fornecido por terceiros, e tais sites podem apontar para este site. A Tanssi Foundation não tem controle sobre esses sites ou seu conteúdo e não terá responsabilidade decorrente ou relacionada a eles. A existência de qualquer link não constitui endosso desses sites, de seu conteúdo ou de seus operadores. Esses links são fornecidos apenas para sua conveniência, e você isenta e exonera a Tanssi Foundation de qualquer responsabilidade decorrente do uso dessas informações ou das informações fornecidas por qualquer site ou serviço de terceiros.
Última atualização: 9 de dezembro de 2025
| Criada: 9 de dezembro de 2025