Na seção anterior, você aprendeu como ler dados da rede Solana buscando contas. Para gravar dados na rede Solana, é necessária uma transação. Uma transação contém uma ou mais instruções, e cada instrução invoca um programa.
Os programas definem a lógica de negócio para cada instrução. Quando você envia uma transação, o runtime da Solana executa as instruções da transação em ordem. As transações são atômicas. Ou todas as instruções da transação são executadas com sucesso, ou a transação inteira falha.
Os exemplos nesta seção mostram como:
- Transferir SOL entre contas
- Criar um novo token mint
Transferir SOL
O exemplo abaixo transfere SOL de uma conta para outra. Apenas o programa designado como proprietário de uma conta pode modificar os dados da conta ou deduzir lamports do seu saldo. As contas de carteira são de propriedade do System Program, portanto, transferir SOL entre contas de carteira requer uma instrução que invoca a instrução transfer do System Program. A conta de origem também deve assinar a transação.
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getTransferSolInstruction } from "@solana-program/system";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const receiver = await generateKeyPairSigner();const transferInstruction = getTransferSolInstruction({source: client.payer,destination: receiver.address,amount: lamports(10_000_000n)});const result = await client.sendTransaction([transferInstruction]);console.log("Transaction Signature:", result.context.signature);const { value: senderBalance } = await client.rpc.getBalance(client.payer.address).send();const { value: receiverBalance } = await client.rpc.getBalance(receiver.address).send();console.log("Sender Balance:", senderBalance);console.log("Receiver Balance:", receiverBalance);
Crie um cliente Kit para o validator de teste local. Este trecho adiciona um signatário pagador, conecta-se ao endpoint RPC local, habilita airdrops e financia o pagador com SOL de teste para a transferência.
const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));
Gere um signatário para o destinatário. O remetente é client.payer, que foi
criado por generatedPayer() e financiado por airdropPayer().
const receiver = await generateKeyPairSigner();
O auxiliar getTransferSolInstruction() cria uma instrução do System Program. A
instrução transfere SOL do signatário source para o endereço
destination pelo valor especificado de
amount lamports.
const transferInstruction = getTransferSolInstruction({source: client.payer,destination: receiver.address,amount: lamports(10_000_000n)});
Chame client.sendTransaction() com um array de instruções. O cliente Kit
converte as instruções em uma transação, assina com os signatários vinculados às
instruções, envia a transação e aguarda a confirmação.
const result = await client.sendTransaction([transferInstruction]);console.log("Transaction Signature:", result.context.signature);
Após a transação ser confirmada, busque ambos os saldos usando client.rpc.
const { value: senderBalance } = await client.rpc.getBalance(client.payer.address).send();const { value: receiverBalance } = await client.rpc.getBalance(receiver.address).send();
Criar um token
O exemplo abaixo cria um novo mint de token usando o Token Extensions Program. Um mint account é a conta que define as configurações globais de um token, como decimais, fornecimento, autoridade de mint e autoridade de congelamento.
Criar um mint account requer duas instruções:
- Invocar o System Program para criar uma nova conta de propriedade do Token Extensions Program.
- Invocar o Token Extensions Program para inicializar essa conta como um mint.
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getCreateAccountInstruction } from "@solana-program/system";import {fetchMint,getInitializeMintInstruction,getMintSize,TOKEN_2022_PROGRAM_ADDRESS} from "@solana-program/token-2022";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const mint = await generateKeyPairSigner();const space = BigInt(getMintSize());const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();const createAccountInstruction = getCreateAccountInstruction({payer: client.payer,newAccount: mint,space,lamports: rent,programAddress: TOKEN_2022_PROGRAM_ADDRESS});const initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 2,mintAuthority: client.payer.address,freezeAuthority: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const result = await client.sendTransaction([createAccountInstruction,initializeMintInstruction]);console.log("Mint Address:", mint.address);console.log("Transaction Signature:", result.context.signature);const mintAccount = await fetchMint(client.rpc, mint.address);console.log("Mint Account:", mintAccount);
Crie e financie um cliente Kit, depois gere um signatário para usar como endereço da nova mint account. O pagador do cliente financia a criação da conta e paga a taxa de transação.
const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const mint = await generateKeyPairSigner();
Calcule o tamanho da mint account em bytes, depois faça uma requisição RPC para calcular os lamports necessários para armazenar esses dados na conta. Esse saldo necessário é chamado de rent.
const space = BigInt(getMintSize());const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();
A primeira instrução invoca o System Program. A instrução usa o
payer para financiar uma newAccount,
aloca o space da mint account, transfere os
lamports isentos de rent e atribui a propriedade ao
programAddress.
const createAccountInstruction = getCreateAccountInstruction({payer: client.payer,newAccount: mint,space,lamports: rent,programAddress: TOKEN_2022_PROGRAM_ADDRESS});
A segunda instrução invoca o Token Extensions Program. A instrução inicializa o
endereço da mint com um valor de
decimals, uma mintAuthority,
uma freezeAuthority, e especifica o
tokenProgram que é proprietário da mint account.
const initializeMintInstruction = getInitializeMintInstruction({mint: mint.address,decimals: 2,mintAuthority: client.payer.address,freezeAuthority: client.payer.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});
Envie ambas as instruções em uma única transação. A instrução de criação de conta deve vir antes da instrução de inicialização do mint porque o mint account deve existir antes que o Token Extensions Program possa gravar os dados do mint na conta.
const result = await client.sendTransaction([createAccountInstruction,initializeMintInstruction]);
Após a confirmação da transação, busque o mint account.
const mintAccount = await fetchMint(client.rpc, mint.address);console.log("Mint Account:", mintAccount);
Estes exemplos usam generatedPayer() para criar um keypair descartável para
testes locais. Aplicações em produção nunca devem armazenar chaves privadas
brutas no código — delegue a assinatura a um backend de gerenciamento de
chaves. Consulte Assinatura em
Produção.
Is this page helpful?