Pular para o conteúdo principal
Change page

Padrão Multi-Token ERC-1155

Última edição: @borja_reverter(opens in a new tab), 15 de agosto de 2023

Introdução

Uma interface padrão para contratos que gerenciam vários tipos de tokens. Um único contrato implementado pode incluir qualquer combinação de tokens fungíveis, tokens não fungíveis ou outras configurações, por exemplo, tokens semifungíveis.

O que se entende por padrão Multi-Token?

A ideia é simples e trata-se de criar uma interface de contratos inteligentes que possa representar e controlar qualquer número de tipos de token, fungíveis ou não fungíveis. Dessa forma, o token ERC-1155 pode fazer as mesmas funções que um token ERC-20 ou um token ERC-721, ou ainda as duas funções simultaneamente. Ele melhora a funcionalidade de ambos os padrões ERC-20 e ERC-721, tornando-os mais eficientes e corrigindo erros óbvios de implementação.

O token ERC-1155 é descrito com profundidade em EIP-1155(opens in a new tab).

Pré-requisitos

Para entender melhor esta página, recomendamos ler primeiro sobre padrões de token, ERC-20 e ERC-721.

Funções e características do ERC-1155:

  • Transferências em lote: transfira vários ativos em uma única chamada.
  • Saldo em lote: obtenha os saldos de vários ativos em uma única chamada.
  • Aprovação em lote: aprove todos os tokens de um endereço.
  • Hooks: receba hook de tokens.
  • Suporte para NFT: se a cunhagem for de apenas 1, tratar como NFT.
  • Regras de transferência segura: conjunto de regras para transferências seguras.

Transferências em lote

As transferências em lote funcionam de forma muito semelhante às transferências regulares do ERC-20. Vejamos a função transferFrom da ERC-20 habitual:

1// ERC-20
2function transferFrom(address from, address to, uint256 value) external returns (bool);
3
4// ERC-1155
5function safeBatchTransferFrom(
6 address _from,
7 address _to,
8 uint256[] calldata _ids,
9 uint256[] calldata _values,
10 bytes calldata _data
11) external;
Exibir tudo
Copiar

A única diferença no ERC-1155 é que passamos os valores como um array e também passamos um array de ‘ids’. Por exemplo, dadas as matrizes ids=[3, 6, 13] e values=[100, 200, 5], as transferências resultantes serão

  1. Transferir 100 tokens da ID 3 de _from para _to.
  2. Transferir 200 tokens da ID 6 de _from para _to.
  3. Transferir 5 tokens da ID 13 de _from to _to.

No ERC-1155, só temos transferFrom, ou seja, não há transfer. Para usá-lo como uma transferência regular, ou transfer, defina o endereço de origem como o endereço que está chamando a função.

Saldo em lote

A respectiva chamada balanceOf do ERC-20 também tem sua função parceira com suporte para lotes. Como lembrete, esta é a versão do ERC-20:

1// ERC-20
2function balanceOf(address owner) external view returns (uint256);
3
4// ERC-1155
5function balanceOfBatch(
6 address[] calldata _owners,
7 uint256[] calldata _ids
8) external view returns (uint256[] memory);
Copiar

Ainda mais simples para a chamada de saldo, podemos recuperar saldos múltiplos em uma única chamada. Passamos a matriz de proprietários, seguida pela matriz dos IDs dos tokens.

Por exemplo, dado _ids=[3, 6, 13] e _owners=[0xbeef..., 0x1337..., 0x11...], o valor de retorno será

1[
2 balanceOf(0xbeef...),
3 balanceOf(0x1337...),
4 balanceOf(0x1111...)
5]
Copiar

Aprovação em lote

1// ERC-1155
2function setApprovalForAll(
3 address _operator,
4 bool _approved
5) external;
6
7function isApprovedForAll(
8 address _owner,
9 address _operator
10) external view returns (bool);
Exibir tudo
Copiar

As aprovações são um pouco diferentes do ERC-20. Em vez de aprovar valores específicos, você define um operador para aprovados ou não aprovados via setApprovalForAll.

Ler o status atual pode ser feito via isApprovedForAll. Como você pode ver, é uma operação de tudo ou nada. Você não pode definir quantos tokens aprovar ou mesmo quais classes de token.

Isto é intencionalmente concebido pensando na simplicidade. Você só pode aprovar tudo para um endereço.

Receber hooks

1function onERC1155BatchReceived(
2 address _operator,
3 address _from,
4 uint256[] calldata _ids,
5 uint256[] calldata _values,
6 bytes calldata _data
7) external returns(bytes4);
Copiar

Dado o suporte da EIP-165(opens in a new tab), o ERC-1155 pode receber hooks apenas por contratos inteligentes. A função de hook deve retornar um valor mágico predefinido de 4 bytes que é dado como:

1bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
Copiar

Quando o contrato de recebimento devolve este valor, assume-se que o contrato aceita a transferência e sabe como lidar com os tokens ERC-1155. Ótimo, nenhum token bloqueados em um contrato!

Suporte para NFTs

Quando a oferta é apenas uma, o token é essencialmente um token não-fungível (NFT, pela sigla em inglês) E como é padrão para o ERC-721, você pode definir um URL de metadados. Esse URL pode ser lido e modificado pelos clientes; veja aqui(opens in a new tab).

Regra de transferência segura

Já abordamos algumas regras de transferência segura nas explicações anteriores. Mas vamos analisar as regras mais importantes:

  1. O chamador deve ser aprovado para gastar os tokens para o endereço _from ou o chamador deve ser igual ao endereço _from.
  2. A chamada de transferência deve ser revertida caso
    1. o enderaço _to seja 0.
    2. o comprimento dos _ids não seja o mesmo que o comprimento dos _values.
    3. qualquer um do saldos dos titulares dos tokens em _ids seja menor que as respectivas quantidades em _values enviados para o destinatário.
    4. ocorra qualquer outro erro.

Nota: Todas as funções por lotes, incluindo o hook, também existem como versões sem lotes. Isto é feito para fins de eficiência do gás, já que é provável que a transferência de apenas um ativo continue sendo a maneira habitualmente mais utilizada. Por simplificar as explicações, as deixamos de lado, incluindo as regras de transferência segura. Os nomes são idênticos, basta eliminar a palavra "lote".

Leitura adicional

Este artigo foi útil?