NOVO: Helius adquire a Light Protocol
Extensões de token Plug and Play
Blog/Desenvolvimento

Extensões de token Plug and Play

Engenheiro de integração0xSolanaGirl no X
8 min de leitura

Introdução

As extensões de token facilitam a criação de tokens programáveis na Solana. Os desenvolvedores podem combinar mais de uma dezena de extensões de mint e de conta usando o novo programa Token Extensions. Ao concluir o tutorial, você criará e interagirá com tokens fungíveis e não fungíveis, tokens que rendem juros, tokens congelados, tokens sobre os quais você tem autoridade total — inclusive para retirá-los de contas que não pertencem a você — e fechará contas de mint para recuperar fundos. 

Plug and Play Token Extensions é um tutorial com exemplos interativos no Solana Playground para ajudar você a aprender sobre extensões de token usando TypeScript para criar os seguintes tokens:

O código usado neste tutorial foi adaptado do Guia para desenvolvedores da Solana. Os scripts para criar extensões de token estão na seção Recursos adicionais. 

Conta de extensões de token

Com novas instruções, as extensões de token são desenvolvidas sobre o Token Program. As contas criadas com ambos os programas são idênticas em sua extensão inicial, até o ponto em que terminam as instruções do Token Program e começam as instruções das extensões de token. Quem não conhece os dados de conta pode saber mais sobre o espaço de conta em uma introdução ao Anchor. Em resumo, as contas na Solana precisam ser criadas com espaço explicitamente alocado para armazenar dados on-chain. Com esse espaço, podemos calcular a quantidade de lamports necessária para isentar a conta de aluguel.

Veja como criar uma conta de mint com extensões. Para alocar espaço para as extensões de token, use a função getMintLen a fim de obter o tamanho da conta de mint com extensões. No exemplo NonFungibleToken.ts, obtenha o tamanho do mint para os tipos de extensão MetadataPointer e MintCloseAuthority.

NonFungibleToken.ts linha 54:

Código
  // Size of Mint Account with extension
  const mintLen = getMintLen([
    ExtensionType.MetadataPointer,
    ExtensionType.MintCloseAuthority,
  ]);

As extensões de metadados e de ponteiro de metadados permitem armazenar e apontar para metadados sem depender de protocolos de terceiros. TokenMetadata é uma interface de @solana/spl-token-metadata com campos como updateAuthority, mint, name, symbol, uri e additionalMetadata. O tamanho dos metadados é obtido usando a função pack no objeto de metadados. 

‍NonFungibleToken.ts linha 60:

Código
  // Metadata to store in Mint Account
  const metaData: TokenMetadata = {
    updateAuthority: updateAuthority,
    mint: mint,
    name: "Solana Soldier",
    symbol: "SOLD",
    uri: "https://shdw-drive.genesysgo.net/G1Tzt42SDqCV3x9vPY5X826foA8fEk8BR4bB5wARh75d/OIG2.jpg",
    additionalMetadata: [["armor", null]],
  };
  // Size of metadata
  const metadataLen = pack(metaData).length;
  // Size of MetadataExtension 2 bytes for type, 2 bytes for length
  const metadataExtension = TYPE_SIZE + LENGTH_SIZE;

Some o tamanho do mint, a extensão de metadados e o tamanho dos metadados para encontrar a quantidade mínima de lamports necessária para a conta de mint.

NonFungibleToken.ts linha 75:

Código
  // Minimum lamports required for Mint Account
  const lamports = await connection.getMinimumBalanceForRentExemption(
    mintLen + metadataExtension + metadataLen
  );

Instruções das extensões de token

Bibliotecas da Solana como @solana/spl-token e @solana/spl-token-metadata adicionam suporte a TypeScript para o programa Token Extensions. Comece criando uma conta com a quantidade correta de espaço e de lamports para isenção de aluguel usando SystemProgram de @solana/web3.js.

NonFungibleToken.ts linha 80:

Código
  // Instruction to invoke System Program to create new account
  const createAccountInstruction = SystemProgram.createAccount({
    fromPubkey: payer.publicKey, // Account that will transfer lamports to created account
    newAccountPubkey: mint, // Address of the account to create
    space: mintLen, // Amount of bytes to allocate to the created account
    lamports, // Amount of lamports transferred to created account
    programId: TOKEN_2022_PROGRAM_ID, // Program assigned as owner of created account
  });

Em seguida, podemos criar instruções para especificar o mint. As instruções a seguir precisam ser executadas antes de chamar initializeMint. As instruções anteriores ao mint usadas em Plug and Play são:

As contas de metadados podem ser inicializadas e atualizadas de forma independente de initializeMint. No entanto, o ponteiro de metadados precisa ser inicializado antes do mint. A ordem das instruções na transação determina a ordem em que elas são executadas. Crie uma conta de mint, inicialize o ponteiro de metadados e depois a autoridade de fechamento do mint com a chave pública do mint. Em seguida, inicialize as contas de mint e de metadados e atualize os metadados adicionais.

‍NonFungibleToken.ts linha 135:

Código
  transaction = new Transaction().add(
    createAccountInstruction,
    initializeMetadataPointerInstruction,
    initializeMintCloseAuthorityInstruction,
    initializeMintInstruction,
    initializeMetadataInstruction,
    updateFieldInstruction
  );

Os arquivos nonFungibleToken.ts, soulboundToken.ts, interestBearingToken.ts e delegateToken.ts seguem a mesma estrutura para criar tokens. A diferença está nas extensões e instruções utilizadas. 

O processo começa com a importação de todas as funções necessárias das bibliotecas exigidas da Solana, a definição de um pagador e a geração de um endereço de mint. Em seguida, encontre o espaço e os lamports necessários para o endereço de mint com as extensões de token desejadas. Crie instruções usando as bibliotecas @solana/spl-token e @solana/spl-token-metadata, adicione-as a uma transação, envie a transação para a rede e valide os resultados. 

Operações de token, como transferência e queima, podem ser usadas em diferentes extensões de token. Tokens com a extensão de metadados podem usar as instruções createUpdateFieldInstruction e createRemoveKeyInstruction para atualizar ou remover metadados, respectivamente. 

Plug and Play 

No Solana Playground, o cliente contém as funções necessárias para interagir com as extensões de token. Por exemplo, o token vinculado à alma usa as extensões de não transferibilidade e de metadados para criar um NFT vinculado à alma. As funções para criar e interagir com os tokens estão disponíveis no mesmo arquivo e podem ser importadas — no caso do Solana Playground, você precisa copiar e colar o código em vez de importá-lo. 

O arquivo quest.ts permite que você jogue com o Solana Soldier. Como alternativa, execute cada arquivo que contém extensões de token para conferir suas funcionalidades específicas. A carteira do Playground precisa de SOL da Devnet para executar a missão. Nossa faucet da Devnet da Solana também está disponível para distribuir SOL da Devnet via airdrop.

A missão começa com a criação de um Solana Soldier, um NFT no qual o pagador (pg.wallet.keypair) terá autoridade para fechar o mint, permitindo que ele feche a conta de mint e recupere o SOL. Esse mecanismo é útil para que aplicações recuperem SOL de contas que não estão mais ativas.

Depois de criar um Solana Soldier, use o endereço de mint dele para atualizar os metadados do NFT. Vamos atualizar a armadura do soldado para iron. As funções getMetadata, updateMetadata e removeMetadata estão no arquivo NonFungibleToken.ts a partir da linha 167. As funções podem ser chamadas para contas de mint que usam a extensão de metadados. Para simplificar, as funções de metadados serão incluídas somente no arquivo NonFungibleToken.ts.

Agora é hora de começar a subir de nível. Um token que rende juros representará o nível do Solana Soldier. Importe createInterestBearingToken de InterestBearingToken.ts e use a instrução para criar o token. Os juros na conta crescerão conforme a taxa definida na linha 43 de InterestBearingToken.ts. A função amountToUiAmount pode ser usada para determinar a quantidade de tokens com juros acumulados. Os juros aumentam ao longo do tempo, e podemos chamar amountToUiAmount para verificar o nível do Solana Soldier.

Quando o soldado começar a subir de nível, ele precisará receber uma missão. A missão é representada por um token vinculado à alma: o soldado não pode transferi-lo — tente capturar o erro chamando a função de transferência — e a única maneira de se livrar da missão é queimá-lo. Em vez de abandonar a missão, vamos conferi-la. Dica: verifique os metadados!

Depois que você ler a missão, o tutorial Plug and Play enviará um exército para um endereço de token. O Solana Soldier precisa conseguir convocar o exército de volta ao pagador depois que os tokens forem enviados. As extensões de token tornam isso possível ao introduzir a autoridade de delegado. Essa autoridade pode transferir e queimar tokens, independentemente de quem os possui. Defina como delegado permanente um par de chaves ao qual você tenha acesso. Esse par de chaves precisa assinar a queima e a transferência de tokens.

Os tokens de delegado representarão o Exército da Solana. Crie tokens de delegado na conta de token do inimigo usando createDelegateTokens da linha 33 de DelegateToken.ts. Quando os tokens forem cunhados, o Exército da Solana e o inimigo entrarão em uma batalha hipotética. Depois da batalha, convoque os soldados de volta da conta do inimigo usando a função transferDelegateTokens, encontrada na linha 176 de DelegateTokens.ts.

Observe que nem todos os soldados foram convocados de volta do endereço do inimigo. Vamos supor que eles morreram. Use a função burn de @solana/spl-token para queimar os tokens restantes na conta de token do inimigo (sourceTokenAccount). 

Com o sucesso da batalha, a missão do Solana Soldier chega ao fim. A função closeAccount de @solana/spl-token foi usada para fechar a conta e devolver o aluguel. As extensões de token não abordadas neste artigo incluem transferências confidenciais, taxas de transferência e hooks de transferência. Quase todas as extensões de token podem ser combinadas, com algumas exceções, como hooks de transferência e tokens não transferíveis. Os Solana Playgrounds de referência para as extensões de token abordadas neste tutorial estão disponíveis em Recursos adicionais. 

Conclusão

Inspirado no CryptoZombies, este tutorial Plug and Play abordou os fundamentos da criação de extensões de token populares por meio de uma combinação de extensões. O tutorial demonstra a capacidade de composição das extensões de token em uma experiência de jogo prática. Os exemplos podem ser usados de forma Plug and Play ou como guia para desenvolvedores que criam seus próprios tokens. Do dimensionamento das contas à ordenação das instruções, os exemplos oferecem um processo simplificado para criar contas com extensões de token.  Se você achou a experiência de aprendizado gamificada útil, compartilhe seu feedback em nosso Discord ou marque @helius no X.

Recursos adicionais

Assine a Helius

Acompanhe as novidades mais recentes do desenvolvimento Solana e receba atualizações quando publicarmos

Imagem ampliada