E se pudéssemos cunhar tokens de forma segura e gratuita fora da cadeia (off-chain)?
E se os detentores de tokens pudessem migrar sem necessidade de confiança dentro da cadeia (on-chain) esses tokens conforme desejado?
E se os contratos de token incluíssem um mecanismo integrado para mover tokens entre contratos ou mesmo entre blockchains?
Apresentando O Token Abstrato
O padrão token abstrato permite que os participantes movam tokens dentro e fora da cadeia conforme desejado, permitindo cunhagens de alto volume e custo zero, preservando a capacidade de composição na cadeia.
Tokens abstratos fornecem uma interface padrão em blockchains EVM para:
- Cunhar tokens fora da cadeia como mensagens
- Reificar tokens dentro da cadeia via contrato inteligente
- De-reificar tokens de volta em mensagens
Os tokens abstratos podem ficar em conformidade com os padrões existentes, como ERC20, ERC721 e ERC1155, e são especialmente adequados para aplicações de token como airdrops, recibos, credenciais e uma nova forma de ponte (bridging).
Rascunho da Interface
A interface proposta é definida abaixo e a implementação de referência está disponível no Github. Pule para a explicação se o Solidity não for sua preferência.
interface IAbstractToken {
event Reify(AbstractTokenMessage);
event Dereify(AbstractTokenMessage);
// transforma token(s) de mensagem em contrato
function reify(AbstractTokenMessage calldata message) external;
// transforma token(s) de contrato em mensagem
function dereify(AbstractTokenMessage calldata message) external;
// verifica o status da mensagem de token abstrato: uma mensagem de token abstrato válida só pode ser reificada uma vez
function status(AbstractTokenMessage calldata message)
external
view
returns (AbstractTokenMessageStatus status);
// identificador de mensagem único
function id(AbstractTokenMessage calldata message) external view returns (bytes32);
// quantidade de token(s) na mensagem
function amount(AbstractTokenMessage calldata message) external view returns (uint256);
// referência a informações adicionais sobre o(s) token(s)
function uri(AbstractTokenMessage calldata message) external view returns (string memory);
}
Esta ainda é uma especificação genérica — como seria um padrão de token específico como um Abstract ERC20 ou Abstract ERC1155? Simplesmente sobrecarregamos as funções que implementam a movimentação de tokens para permitir transferências que começam com tokens como mensagens.
interface IAbstractERC20 is IAbstractToken, IERC20, IERC165 {
// reificar a mensagem e depois transferir os tokens
function transfer(
address to,
uint256 amount,
AbstractTokenMessage calldata message
) external returns (bool);
// reificar a mensagem e, em seguida, transfira a partir (transferFrom) dos tokens
function transferFrom(
address from,
address to,
uint256 amount,
AbstractTokenMessage calldata message
) external returns (bool);
}
Explicação
Aqui está como os tokens abstratos funcionam.
✍️ Cunhando mensagens de token fora da cadeia
Os tokens abstratos são cunhados como mensagens fora da cadeia. O token existe assim que uma mensagem válida é criada, pois cada mensagem de token válida é vinculada a um contrato de implementação específico, um proprietário e metadados de token exatos. As mensagens incluem os seguintes membros.
struct AbstractTokenMessage {
uint64 chainId; // a cadeia onde o(s) token(s) pode(m) ser reificado(s)
address implementation; // o contrato pelo qual o(s) token(s) pode(m) ser reificado(s)
address owner; // o endereço que possui o(s) token(s)
bytes meta; // informações específicas-da-aplicação que definem o(s) token(s)
bytes proof; // informações específicas-da-aplicação autorizando a criação do(s) token(s)
}
As implementações de referência para IAbstractERC20
, IAbstractERC721
e IAbstractERC1155
codificam id de token, quantidade e uri no campo meta e usam uma assinatura EIP-712 por um endereço de emissão especificado como o campo de prova.
🧱 Reificando Tokens Na Cadeia
// exemplo de script ethers.js para interagir com o contrato de token
const tokenContract = await ethers.getContractAt(
"MyAbstractToken",
address,
owner
);
// chamada para mover o token para a blockchain
await tokenContract.reify(tokenMessage)
A reificação é idempotente: cada mensagem token é definida por um id único e pode ser reificada no máximo uma vez. Como os detalhes do token e do proprietário são especificados na mensagem confirmada, a mensagem não precisa ser mantida em segredo. Eve pode chamar tokenContract.reify(tokenMessageForBob)
quantas vezes quiser, mas Bob receberá os tokens especificados na cadeia.
Assim, os usuários que possuem mensagens de token abstratas válidas podem tratá-los como tokens reais com a confiança de que podem ser movidos na cadeia conforme desejado.
(∘) Compondo Tokens Abstratos Com DeFi
Tokens abstratos são tokens padrão uma vez reificados na cadeia e podem ser manipulados como tokens regulares. Ferramentas criptográficas que entendem tokens abstratos podem fornecer ainda mais funcionalidade. Por exemplo:
Carteiras e aplicativos podem armazenar mensagens de token abstratas e procurar os metadados do token para cada mensagem para mostrar ao usuário os tokens abstratos que eles possuem
As primitivas DeFi na cadeia podem aceitar mensagens de token como entradas, permitindo que os contratos componham a reificação com outras primitivas, como negociação ou empréstimo.
Como exemplo, considere um aplicativo DeFi que bloqueia o acesso do usuário com um token abstrato criado por um parceiro de conformidade. O aplicativo pode mostrar a cada usuário seu status de elegibilidade e detalhes de token armazenando e analisando seus metadados de token abstratos. Ele também pode permitir que usuários elegíveis acessem a funcionalidade do aplicativo na cadeia, independentemente de como eles mantêm seu token de elegibilidade.
// este token de elegibilidade ERC1155 segue o padrão token abstrato
IAbstractToken1155 eligibilityToken;
// os usuários devem ter pelo menos um token com ID 1
uint256 constant ELIGIBLE_ID = 1;
// o usuário detém o token de elegibilidade na cadeia
function borrow(CreditApplication a) external {
_borrow(a);
}
// o usuário mantém o token de elegibilidade como uma mensagem
function borrow(CreditApplication a, AbstractTokenMessage m) external {
// reificar o token antes de prosseguir
eligibilityToken.reify(m);
_borrow(a);
}
function _borrow(CreditApplication a) internal {
// verifique se o usuário está qualificado
require(eligibilityToken.balanceOf(msg.sender, ELIGIBLE_ID) > 0, "ineligible");
// componentes internos da aplicação após a verificação
credit(a);
Esta aplicação também pode permitir que os usuários troquem um token mantido como uma mensagem em uma transação usando um método transferFrom()
compatível com token abstrato - a reificação pode ser composta diretamente com outras ações na cadeia.
// negocie com um ERC20 mantido na cadeia
function swap(
address bidToken,
uint256 bidTokenAmount,
address askToken,
uint256 askAmount
) external;
// negocie com um Abstract ERC20 mantido como uma mensagem
function swap(
AbstractTokenMessage calldata bidTokenMessage,
address askToken,
uint256 askAmount
) external;
Por que isso é importante? Isso significa que os usuários podem obter tokens gratuitamente e manter uma ótima experiência de usuário se mais tarde decidirem usar esses tokens na cadeia.
☁️ De-Reificando Tokens de Volta para Mensagens
Os tokens na cadeia podem ser de-reificados ou transformados novamente em uma mensagem de token abstrata, chamando o contrato de token na cadeia com uma nova mensagem de token válida.
// chamada para mover o token para fora da blockchain
await tokenContract.dereify(newTokenMessage)
Observe que a nova mensagem de token pode ter um emissor, proprietário, metadados, cadeia ou contrato diferente! O contrato de token abstrato impõe regras de de-reificação, por exemplo restringindo quem pode de-reificar tokens ou garantindo que alguém possa apenas abstrair tokens que já possuai. Qualquer um pode verificar o contrato de token para verificar se os tokens que foram de-reificados foram queimados (burnt) na cadeia e podem analisar a mensagem do token para ver para onde os tokens serão direcionados a seguir.
As aplicações de de-reificação exigem cuidado para minimizar a confiança e evitar gastos duplos! Algum mecanismo deve impedir que uma mensagem de token seja reificada no novo contrato, a menos que os tokens envolvidos tenham sido primeiro de-reificados no antigo contrato.
Limitações
Os tokens abstratos funcionam melhor quando as seguintes condições e compensações são aceitáveis.
Existe uma boa maneira de visualizar mensagens de token
As mensagens de token são um novo conceito e os usuários precisam de uma maneira de visualizá-las e salvá-las. Carteiras e aplicativos provavelmente são os melhores lugares para visualizar esses tokens - portanto, tokens abstratos podem funcionar bem para um novo aplicativo disposto a criar suporte.
Uma prova concisa de validade está disponível
O contrato de implementação precisa de alguma forma para verificar se a mensagem abstrata do token é válida. A implementação de referência depende de um signatário para fornecer uma assinatura EIP-712, mas outras provas também podem funcionar bem.
A cunhagem gratuita é útil
Se os tokens forem usados na cadeia imediatamente, o formato de mensagem de token fora da cadeia terá pouco valor. Se muitos tokens não puderem ser usados na cadeia, os tokens abstratos fornecem economia de gás e conveniência iniciais.
Uma entidade confiável pode suportar a de-reificação
Cada contrato de token abstrato deve definir as condições, se houver, sob as quais os tokens podem ser de-reificados. Algum oráculo para autorizar a de-reificação deve estar presente para evitar gastos duplos, seja o emissor original do token ou um protocolo de passagem de mensagem de cadeia cruzada. O padrão de token abstrato não pode fazer nada entre cadeias por conta própria.
Aplicações
Dadas essas limitações, acreditamos que os casos de uso abaixo representam os melhores casos de uso iniciais para tokens abstratos.
Airdrops e outras distribuições
Distribuições de tokens em larga escala geralmente usam provas Merkle para conceder tokens a um grande número de usuários em uma transação concisa: cada usuário posteriormente envia sua prova Merkle específica ao reivindicar tokens. Este é um ótimo padrão porque minimiza as taxas de transação para os distribuidores e permite que os solicitantes adiem as taxas de transação até que o desejem. Mas não há uma maneira padrão de armazenar a prova merkle ou exibir os tokens resgatáveis!
Os tokens abstratos fornecem uma interface padrão para aumentar a legibilidade do airdrop: a mensagem do token abstrato inclui tudo o que é necessário para um aplicativo entender o airdrop e ajudar o usuário a reivindicar tokens na cadeia.
Recibos
Os aplicativos criptos podem emitir um token abstrato como um registro para cada atividade relevante, seja completando um passeio de bicicleta no Strava, participando de uma conferência Ethereum ou alcançando vários picos locais.
Por que os tokens abstratos se adequam:
- Aplicativos cripto são um local sensível para armazenar mensagens de token abstratas relacionadas ao aplicativo.
- O funil do evento no aplicativo (por exemplo, entrar em uma corrida) para um token valioso (por exemplo, vencer a corrida), que pode usar o consenso na cadeia, tem uma desistência extremamente alta, portanto, faz sentido emitir tokens para representar esses eventos se a cunhagem for gratuita.
- Tokens interessantes que finalizam na cadeia são uma boa maneira de recompensar e incentivar os usuários
Credenciais
Os provedores de identidade podem conceder a cada candidato aprovado um token abstrato que codifica sua elegibilidade para vários aplicativos on-chain. Em seguida, esses usuários podem interagir perfeitamente com aplicativos DeFi compatíveis - incorrendo apenas em um custo de gás para cunhar suas credenciais tokenizadas conforme desejado.
Por que os tokens abstratos se adequam:
- Às vezes, os aplicativos DeFi exigem credenciais na cadeia
- O provedor de conformidade (compliance) já é uma parte confiável, portanto, eles podem criar uma prova para mensagens de token abstratas usando uma assinatura EIP-712
- Cunhar credenciais diretamente na cadeia é muito caro: tokens abstratos permitem que os provedores de conformidade criem as credenciais assim que o usuário for aprovado, mas o usuário só paga pela emissão quando a credencial é necessária para uma atividade específica na cadeia
- A capacidade de composição (Composability) permite que usuários qualificados acessem o aplicativo sem pular nenhum obstáculo adicional na cadeia
🌁 Bridging específico para tokens
Um caso de uso em que a de-reificação pode ser útil é uma entidade que fornece ativos agrupados para atividades de cadeia cruzada (cross-chain). Quando um usuário faz uma solicitação de de-reificação para mover tokens de uma cadeia para outra (por exemplo, com um método requestDereify()
que bloqueia temporariamente seus tokens), a entidade pode gerar uma nova mensagem abstrata de token newMessage
. Então qualquer um pode chamar dereify(newMessage)
na cadeia antiga e reify(newMessage)
na nova cadeia.
Neste exemplo, os tokens abstratos fornecem alguma auditabilidade do fluxo de fundos entre as cadeias. Ao contrário das pontes tradicionais, quando os tokens abstratos são movidos da cadeia A para B, os tokens originais na cadeia A desaparecem - a ponte na cadeia A não está “segurando” nenhum token em uma ponte que possa ser roubado posteriormente.
Próximos passos
O Padrão Token Abstrato visa a utilidade prática. Por favor, entre em contato se você vir possíveis melhorias no padrão ou quiser hackear algumas aplicações piloto!
Recursos
Esse artigo é uma tradução feita por @bananlabs. Você pode encontrar o artigo original aqui
Latest comments (0)