Ir para o conteúdo

Pré-compilado ERC-20 do Token Nativo

Introdução

O contrato precompilado ERC-20 do token nativo em redes EVM com Tanssi permite que os desenvolvedores interajam com o token nativo do protocolo por meio de uma interface ERC-20. Embora o token nativo da sua rede não seja um ERC-20, agora você pode interagir com ele como se fosse um ERC-20 puro.

Um dos principais benefícios dessa precompilada é eliminar a necessidade de ter uma representação embrulhada do token do protocolo como um smart contract ERC-20, como o WETH no Ethereum. Além disso, ela minimiza a necessidade de múltiplas representações embrulhadas do mesmo token do protocolo. Consequentemente, dApps que precisam interagir com o token do protocolo via interface ERC-20 podem fazê-lo sem precisar de um contrato separado.

Por baixo dos panos, a precompilada ERC-20 executa ações específicas do Substrate relacionadas ao módulo de saldos do Substrate, escrito em Rust. O módulo de saldos fornece funcionalidades para lidar com diversos tipos de saldos.

Este guia mostrará como interagir com os tokens UNIT, os tokens nativos do protocolo para redes de teste rápido no Dancelight, por meio da precompilada ERC-20. Você pode seguir e adaptar este guia para interagir com a sua própria rede.

A precompilada está localizada no endereço:

0x0000000000000000000000000000000000000800

Note

O uso de precompiladas pode trazer consequências inesperadas. As precompiladas do Tanssi são derivadas das do Moonbeam; portanto, familiarize-se com as considerações de segurança das precompiladas do Moonbeam.

Interface Solidity do ERC-20

A interface ERC20.sol nas redes EVM do Tanssi segue o Padrão de Token EIP-20, que define as funções e eventos exigidos para um token interoperar com diferentes aplicações.

ERC20.sol
/ SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.3;

/// @dev The IERC20 contract's address.
address constant IERC20_ADDRESS = 0x0000000000000000000000000000000000000800;

/// @dev The IERC20 contract's instance.
IERC20 constant IERC20_CONTRACT = IERC20(IERC20_ADDRESS);

/// @title ERC20 interface
/// @dev see https://github.com/ethereum/EIPs/issues/20
/// @dev copied from https://github.com/OpenZeppelin/openzeppelin-contracts
/// @custom:address 0x0000000000000000000000000000000000000800
interface IERC20 {
    /// @dev Returns the name of the token.
    /// @custom:selector 06fdde03
    function name() external view returns (string memory);

    /// @dev Returns the symbol of the token.
    /// @custom:selector 95d89b41
    function symbol() external view returns (string memory);

    /// @dev Returns the decimals places of the token.
    /// @custom:selector 313ce567
    function decimals() external view returns (uint8);

    /// @dev Total number of tokens in existence
    /// @custom:selector 18160ddd
    function totalSupply() external view returns (uint256);

    /// @dev Gets the balance of the specified address.
    /// @custom:selector 70a08231
    /// @param owner The address to query the balance of.
    /// @return An uint256 representing the amount owned by the passed address.
    function balanceOf(address owner) external view returns (uint256);

    /// @dev Function to check the amount of tokens that an owner allowed to a spender.
    /// @custom:selector dd62ed3e
    /// @param owner address The address which owns the funds.
    /// @param spender address The address which will spend the funds.
    /// @return A uint256 specifying the amount of tokens still available for the spender.
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    /// @dev Transfer token for a specified address
    /// @custom:selector a9059cbb
    /// @param to The address to transfer to.
    /// @param value The amount to be transferred.
    /// @return true if the transfer was succesful, revert otherwise.
    function transfer(address to, uint256 value) external returns (bool);

    /// @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
    /// Beware that changing an allowance with this method brings the risk that someone may use both the old
    /// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
    /// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
    /// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    /// @custom:selector 095ea7b3
    /// @param spender The address which will spend the funds.
    /// @param value The amount of tokens to be spent.
    /// @return true, this cannot fail
    function approve(address spender, uint256 value) external returns (bool);

    /// @dev Transfer tokens from one address to another
    /// @custom:selector 23b872dd
    /// @param from address The address which you want to send tokens from
    /// @param to address The address which you want to transfer to
    /// @param value uint256 the amount of tokens to be transferred
    /// @return true if the transfer was succesful, revert otherwise.
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    /// @dev Event emited when a transfer has been performed.
    /// @custom:selector ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
    /// @param from address The address sending the tokens
    /// @param to address The address receiving the tokens.
    /// @param value uint256 The amount of tokens transfered.
    event Transfer(address indexed from, address indexed to, uint256 value);

    /// @dev Event emited when an approval has been registered.
    /// @custom:selector 8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925
    /// @param owner address Owner of the tokens.
    /// @param spender address Allowed spender.
    /// @param value uint256 Amount of tokens approved.
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

/// @title Native currency wrapper interface.
/// @dev Allow compatibility with dApps expecting this precompile to be
/// a WETH-like contract.
interface WrappedNativeCurrency {
    /// @dev Provide compatibility for contracts that expect wETH design.
    /// Returns funds to sender as this precompile tokens and the native tokens are the same.
    /// @custom:selector d0e30db0
    function deposit() external payable;

    /// @dev Provide compatibility for contracts that expect wETH design.
    /// Does nothing.
    /// @custom:selector 2e1a7d4d
    /// @param value uint256 The amount to withdraw/unwrap.
    function withdraw(uint256 value) external;

    /// @dev Event emited when deposit() has been called.
    /// @custom:selector e1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c
    /// @param owner address Owner of the tokens
    /// @param value uint256 The amount of tokens "wrapped".
    event Deposit(address indexed owner, uint256 value);

    /// @dev Event emited when withdraw(uint256) has been called.
    /// @custom:selector 7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65
    /// @param owner address Owner of the tokens
    /// @param value uint256 The amount of tokens "unwrapped".
    event Withdrawal(address indexed owner, uint256 value);
}

Nota

A precompilada ERC-20 não inclui as funções deposit e withdraw nem os eventos associados esperados de um token embrulhado, como o WETH.

Interagir com a interface Solidity

Verificando Pré-requisitos

Para acompanhar este tutorial, você precisará ter sua carteira configurada para funcionar com sua rede EVM com Tanssi e uma conta financiada com tokens nativos. Você pode adicionar sua rede EVM ao MetaMask com um clique no Tanssi dApp ou configurar o MetaMask para Tanssi com a rede EVM de demonstração.

Adicionar token a uma carteira EVM

Se quiser interagir com o token nativo da rede como um ERC-20, adicione um token personalizado à sua carteira compatível com EVM usando o endereço da precompilada. Esta seção mostra como adicionar um ativo externo ao MetaMask.

Para começar, abra o MetaMask, certifique-se de estar conectado à sua rede e:

  1. Acesse a aba Assets
  2. Clique em Import tokens

Import Tokens from Assets Tab in MetaMask

Agora, crie o token personalizado:

  1. Informe o endereço da precompilada — 0x0000000000000000000000000000000000000800. Ao inserir o endereço, os campos Token Symbol e Token Decimal devem ser preenchidos automaticamente. Caso não aconteça, use UNIT como símbolo e 18 para casas decimais (o padrão das redes EVM do Tanssi, igual ao Ethereum)
  2. Clique em Next

Add Custom Token

O MetaMask solicitará a confirmação da importação. Revise os detalhes e clique em Import Tokens para importar os tokens UNIT para sua carteira.

Confirm and Import Tokens

Pronto! Você adicionou o token UNIT como um ERC-20 personalizado na sua rede EVM do Tanssi.

Configuração do Remix

Você pode interagir com a precompilada ERC-20 usando o Remix. Para adicioná-la ao Remix, você precisará:

  1. Obter uma cópia do ERC20.sol
  2. Colar o conteúdo em um arquivo chamado IERC20.sol no Remix

Compilar o contrato

Em seguida, compile a interface no Remix:

  1. Clique na aba Compile (segunda de cima para baixo)
  2. Compile a interface clicando em Compile IERC20.sol

Compiling IERC20.sol

Quando a compilação terminar, aparecerá um check verde ao lado da aba Compile.

Acessar o contrato

Em vez de implantar a precompilada, você acessará a interface informando o endereço do contrato já disponibilizado:

  1. Clique na aba Deploy and Run logo abaixo de Compile no Remix. Lembre-se de que contratos precompilados já estão acessíveis em seus endereços, portanto não há etapa de implantação
  2. Certifique-se de que Injected Web3 está selecionado em ENVIRONMENT. Ao escolher Injected Web3, o MetaMask pode solicitar conexão com o Remix caso ainda não esteja
  3. Verifique se a conta correta aparece em ACCOUNT
  4. Garanta que IERC20 - IERC20.sol esteja selecionado em CONTRACT. Como é um contrato precompilado, não há implantação; você informará o endereço da precompilada em At Address
  5. Informe o endereço da precompilada ERC-20: 0x0000000000000000000000000000000000000800 e clique em At Address

Access the address

A precompilada IERC20 aparecerá na lista de Deployed Contracts.

Obter informações básicas do token

A interface ERC-20 permite obter rapidamente informações como oferta total, nome, símbolo e casas decimais. Para isso:

  1. Expanda o contrato IERC20 em Deployed Contracts
  2. Clique em decimals para obter as casas decimais do token nativo
  3. Clique em name para obter o nome do token
  4. Clique em symbol para obter o símbolo do token
  5. Clique em totalSupply para obter a oferta total de tokens nativos na rede

Total Supply

Os resultados de cada chamada aparecem sob as respectivas funções.

Consultar saldo de uma conta

Para checar o saldo de qualquer endereço na rede usando balanceOf:

  1. Expanda a função balanceOf
  2. Informe o endereço a consultar em owner
  3. Clique em call

Get Balance of an Account

O saldo será exibido abaixo da função balanceOf.

Aprovar um gasto

Para aprovar uma autorização de gasto, forneça um endereço para o spender e o número de tokens permitidos. O spender pode ser uma EOA ou um contrato inteligente. Exemplo: autorizar 1 UNIT.

  1. Expanda approve
  2. Insira o endereço do spender (use a segunda conta criada)
  3. Informe o valor que o spender pode gastar em value. Exemplo: 1 UNIT em Wei (1000000000000000000)
  4. Clique em transact
  5. O MetaMask abrirá para você revisar e confirmar a transação

Confirm Approve Transaction

Após a confirmação, o saldo da sua conta permanece o mesmo porque apenas a permissão foi concedida; nenhum gasto foi feito. Na próxima seção, usaremos allowance para verificar a permissão.

Verificar a permissão do spender

Para checar se o spender recebeu a autorização:

  1. Expanda allowance
  2. Informe seu endereço em owner
  3. Informe o endereço do spender usado anteriormente
  4. Clique em call

Get Allowance of Spender

O valor exibido deve equivaler a 1 UNIT (1000000000000000000).

Enviar transferência padrão

Para enviar tokens diretamente da sua conta a outra:

  1. Expanda transfer
  2. Insira o endereço de destino
  3. Informe a quantidade de UNIT a enviar (ex.: 1 UNIT = 1000000000000000000)
  4. Clique em transact
  5. Confirme a transação no MetaMask

Send Standard Transfer

Após a conclusão, verifique seu saldo via balanceOf ou no MetaMask. O saldo deve ter diminuído em 1 UNIT, e o destinatário deve ter recebido 1 UNIT.

Enviar transferência a partir de uma conta específica

Até agora, você aprovou 1 UNIT para o spender e enviou 1 UNIT com transfer. A função transferFrom permite definir de qual endereço sairão os tokens. Para este exemplo, use a conta do spender para transferir o valor autorizado do owner para o spender.

Primeiro, mude para a conta do spender no MetaMask; o endereço selecionado em Remix será o do spender.

Switch accounts Remix

Em seguida, envie a transferência:

  1. Expanda transferFrom
  2. Informe seu endereço como owner no campo from
  3. Informe o destinatário (o spender) no campo to
  4. Informe a quantidade de UNIT (a autorização é de 1 UNIT, então use 1000000000000000000)
  5. Clique em transact

Send Standard Transfer

Depois da transação, confira o saldo do owner e do spender com balanceOf. O saldo do spender terá aumentado em 1 UNIT e a permissão terá sido consumida. Para confirmar que não há mais permissão, chame allowance passando os endereços do owner e do spender; o resultado deve ser 0.

Zero Allowance

E é isso! Você interagiu com a precompilada ERC-20 usando MetaMask e Remix.

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