Modelo de Conta Solana

Na Solana, todos os dados são armazenados no que chamamos de "contas". Você pode pensar nos dados na Solana como um banco de dados público com uma única tabela "Contas", onde cada entrada nesta tabela é uma "conta". Cada conta da Solana compartilha o mesmo tipo de Conta base.

ContasContas

Pontos-chave

  • As contas podem armazenar até 10MiB de dados, que contêm código de programa executável ou estado do programa.
  • As contas exigem um depósito de rent em lamports (SOL) que é proporcional à quantidade de dados armazenados, e você pode recuperá-lo totalmente ao fechar a conta.
  • Cada conta tem um proprietário de programa. Apenas o programa que possui uma conta pode alterar seus dados ou deduzir seu saldo de lamports. Mas qualquer pessoa pode aumentar o saldo.
  • Contas sysvar são contas especiais que armazenam o estado do cluster da rede.
  • Contas de programa armazenam o código executável de contratos inteligentes.
  • Contas de dados são criadas por programas para armazenar e gerenciar o estado do programa.

Conta

Cada conta na Solana tem um endereço único de 32 bytes, frequentemente mostrado como uma string codificada em base58 (ex: vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo6NmXEyxm).

A relação entre a conta e seu endereço funciona como um par chave-valor, onde o endereço é a chave para localizar os dados on-chain correspondentes da conta. O endereço da conta atua como o "ID único" para cada entrada na tabela "Contas".

Endereço da ContaEndereço da Conta

A maioria das contas Solana usa uma chave pública Ed25519 como seu endereço.

import { generateKeyPairSigner } from "@solana/kit";
// Kit does not enable extractable private keys
const keypairSigner = await generateKeyPairSigner();
console.log(keypairSigner);
Console
Click to execute the code.

Embora as chaves públicas sejam comumente usadas como endereços de conta, a Solana também suporta um recurso chamado Endereços Derivados de Programa (PDAs). PDAs são endereços especiais que você pode derivar deterministicamente de um ID de programa e entradas opcionais (seeds).

import { Address, getProgramDerivedAddress } from "@solana/kit";
const programAddress = "11111111111111111111111111111111" as Address;
const seeds = ["helloWorld"];
const [pda, bump] = await getProgramDerivedAddress({
programAddress,
seeds
});
console.log(`PDA: ${pda}`);
console.log(`Bump: ${bump}`);
Console
Click to execute the code.

Tipo de Conta

As contas têm um tamanho máximo de 10MiB e cada conta na Solana compartilha o mesmo tipo base Account.

Tipo de ContaTipo de Conta

Cada Conta na Solana tem os seguintes campos.

Base Account Type
pub struct Account {
/// lamports in the account
pub lamports: u64,
/// data held in this account
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
pub data: Vec<u8>,
/// the program that owns this account. If executable, the program that loads this account.
pub owner: Pubkey,
/// this account's data contains a loaded program (and is now read-only)
pub executable: bool,
/// the epoch at which this account will next owe rent
pub rent_epoch: Epoch,
}

Campo Lamports

O saldo da conta em lamports, a menor unidade de SOL (1 SOL = 1 bilhão de lamports). O saldo em SOL de uma conta é a quantidade no campo lamports convertida para SOL.

As contas Solana devem ter um saldo mínimo de lamports que é proporcional à quantidade de dados armazenados na conta (em bytes). Este saldo mínimo é chamado de "rent".

O saldo de lamports armazenado na conta pode ser totalmente recuperado quando a conta é fechada.

Campo de Dados

Um array de bytes que armazena dados arbitrários para uma conta. O campo de dados é comumente chamado de "dados da conta."

  • Para contas de programa (contratos inteligentes), este campo contém o código do programa executável ou o endereço de outra conta que armazena o código do programa executável.
  • Para contas não executáveis, geralmente armazena estados que devem ser lidos.

A leitura de dados de uma conta Solana envolve duas etapas:

  1. Buscar a conta usando seu endereço (chave pública)
  2. Desserializar o campo de dados da conta de bytes brutos para a estrutura de dados apropriada, que é definida pelo programa que possui a conta

Campo Owner

O ID do programa (chave pública) do programa que possui esta conta.

Cada conta Solana tem um programa designado como seu proprietário. Apenas o programa que possui uma conta pode alterar os dados da conta ou deduzir seu saldo de lamports.

As instruções definidas em um programa determinam como os dados da conta e o saldo de lamports podem ser alterados.

Campo Executable

Este campo indica se uma conta é um programa executável.

  • Se true, a conta é um programa Solana executável.
  • Se false, a conta é uma conta de dados que armazena estado.

Para contas executáveis, o campo owner contém o ID do programa de um programa carregador. Programas carregadores são programas integrados responsáveis por carregar e gerenciar contas de programas executáveis.

Campo Rent Epoch

O campo rent_epoch é um campo legado que não é mais utilizado.

Originalmente, este campo rastreava quando uma conta precisaria pagar rent (em lamports) para manter seus dados na rede. No entanto, esse mecanismo de cobrança de rent foi descontinuado.

Campo Lamports

O saldo da conta em lamports, a menor unidade de SOL (1 SOL = 1 bilhão de lamports). O saldo em SOL de uma conta é a quantidade no campo lamports convertida para SOL.

As contas Solana devem ter um saldo mínimo de lamports que é proporcional à quantidade de dados armazenados na conta (em bytes). Este saldo mínimo é chamado de "rent".

O saldo de lamports armazenado na conta pode ser totalmente recuperado quando a conta é fechada.

Campo de Dados

Um array de bytes que armazena dados arbitrários para uma conta. O campo de dados é comumente chamado de "dados da conta."

  • Para contas de programa (contratos inteligentes), este campo contém o código do programa executável ou o endereço de outra conta que armazena o código do programa executável.
  • Para contas não executáveis, geralmente armazena estados que devem ser lidos.

A leitura de dados de uma conta Solana envolve duas etapas:

  1. Buscar a conta usando seu endereço (chave pública)
  2. Desserializar o campo de dados da conta de bytes brutos para a estrutura de dados apropriada, que é definida pelo programa que possui a conta

Campo Owner

O ID do programa (chave pública) do programa que possui esta conta.

Cada conta Solana tem um programa designado como seu proprietário. Apenas o programa que possui uma conta pode alterar os dados da conta ou deduzir seu saldo de lamports.

As instruções definidas em um programa determinam como os dados da conta e o saldo de lamports podem ser alterados.

Campo Executable

Este campo indica se uma conta é um programa executável.

  • Se true, a conta é um programa Solana executável.
  • Se false, a conta é uma conta de dados que armazena estado.

Para contas executáveis, o campo owner contém o ID do programa de um programa carregador. Programas carregadores são programas integrados responsáveis por carregar e gerenciar contas de programas executáveis.

Campo Rent Epoch

O campo rent_epoch é um campo legado que não é mais utilizado.

Originalmente, este campo rastreava quando uma conta precisaria pagar rent (em lamports) para manter seus dados na rede. No entanto, esse mecanismo de cobrança de rent foi descontinuado.

Base Account Type
pub struct Account {
/// lamports in the account
pub lamports: u64,
}
// Example Token Mint Account
Account {
lamports: 1461600,
}
// Example Token Program Account
Account {
lamports: 4513200894,
}

Rent

Para armazenar dados na blockchain, as contas também devem manter um saldo em lamports (SOL) que é proporcional à quantidade de dados armazenados na conta (em bytes). Este saldo é chamado de "rent", mas funciona mais como um depósito porque você pode recuperar o valor total ao fechar uma conta. Você pode encontrar o cálculo aqui usando estas constantes.

O termo "rent" vem de um mecanismo obsoleto que deduzia regularmente lamports das contas que ficavam abaixo do limite de rent. Este mecanismo não está mais ativo.

Proprietário do programa

Na Solana, os "contratos inteligentes" são chamados de programas. A propriedade do programa é uma parte fundamental do Modelo de Conta da Solana. Cada conta tem um programa designado como seu proprietário. Apenas o programa proprietário pode:

  • Alterar o campo data da conta
  • Deduzir lamports do saldo da conta

Cada programa define a estrutura dos dados armazenados no campo data de uma conta. As instruções do programa determinam como esses dados e o saldo lamports da conta podem ser alterados.

System Program

Por padrão, todas as novas contas pertencem ao System Program. O System Program executa as seguintes funções principais:

FunçãoDescrição
Criação de novas contasApenas o System Program pode criar novas contas.
Alocação de espaçoDefine a capacidade em bytes para o campo de dados de cada conta.
Atribuição de propriedadeUma vez que o System Program cria uma conta, ele pode reatribuir o programa proprietário designado para uma conta de programa diferente. É assim que programas personalizados assumem a propriedade de novas contas criadas pelo System Program.
Transferência de SOLTransfere lamports (SOL) de contas do System Program para outras contas.

Observe que todas as contas "wallet" na Solana são "System Accounts" pertencentes ao System Program. O saldo em lamports nessas contas mostra a quantidade de SOL possuída pela carteira. Apenas System Accounts podem pagar taxas de transação.

System AccountSystem Account

Quando SOL é enviado para um novo endereço pela primeira vez, uma conta é automaticamente criada nesse endereço, pertencente ao System Program.

No exemplo abaixo, um novo keypair é gerado e financiado com SOL. Execute o código para ver o resultado. Observe que o campo owner da conta é o System Program com o endereço 11111111111111111111111111111111.

import {
airdropFactory,
createSolanaRpc,
createSolanaRpcSubscriptions,
generateKeyPairSigner,
lamports
} from "@solana/kit";
// Create a connection to Solana cluster
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate a new keypair
const keypair = await generateKeyPairSigner();
console.log(`Public Key: ${keypair.address}`);
// Funding an address with SOL automatically creates an account
const signature = await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: keypair.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
const accountInfo = await rpc.getAccountInfo(keypair.address).send();
console.log(accountInfo);
Console
Click to execute the code.

Contas Sysvar

Contas Sysvar são contas especiais em endereços predefinidos que fornecem acesso aos dados de estado do cluster. Essas contas são atualizadas dinamicamente com dados sobre o cluster da rede. Você pode encontrar a lista completa de contas Sysvar aqui.

O exemplo a seguir mostra como buscar e desserializar os dados da conta Sysvar Clock.

import { createSolanaRpc } from "@solana/kit";
import { fetchSysvarClock, SYSVAR_CLOCK_ADDRESS } from "@solana/sysvars";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const accountInfo = await rpc
.getAccountInfo(SYSVAR_CLOCK_ADDRESS, { encoding: "base64" })
.send();
console.log(accountInfo);
// Automatically fetch and deserialize the account data
const clock = await fetchSysvarClock(rpc);
console.log(clock);
Console
Click to execute the code.

Program Account

Implantar um programa Solana cria um program account executável. O program account armazena o código executável do programa. Program accounts são de propriedade de um Loader Program.

Program AccountProgram Account

Para simplificar, você pode tratar o program account como o próprio programa. Quando você invoca as instruções de um programa, você especifica o endereço do program account (comumente chamado de "Program ID").

O exemplo a seguir busca o Token Program account para mostrar que program accounts têm o mesmo tipo base Account, exceto que o campo executable é definido como true. Como program accounts contêm código executável em seu campo de dados, não desserializamos os dados.

import { Address, createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const programId = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address;
const accountInfo = await rpc
.getAccountInfo(programId, { encoding: "base64" })
.send();
console.log(accountInfo);
Console
Click to execute the code.

Quando você implanta um programa Solana, ele é armazenado em um program account. Os program accounts são de propriedade de um Programa Carregador. Existem várias versões do carregador, mas todas, exceto o loader-v3, armazenam o código executável diretamente no program account. O loader-v3 armazenena o código executável em uma "program data account" separada, e o program account apenas aponta para ela. Quando você implanta um novo programa, a CLI da Solana usa a versão mais recente do carregador por padrão.

Buffer Account

O loader-v3 possui um tipo especial de conta para preparar temporariamente o upload de um programa durante a implantação ou atualizações. No loader-v4, ainda existem buffers, mas são apenas program accounts normais.

Program Data Account

O loader-v3 funciona de maneira diferente de todos os outros programas BPF Loader. O program account contém apenas o endereço de uma program data account, que armazena o código executável real:

Program Data AccountProgram Data Account

Não confunda essas program data accounts com as data accounts dos programas (veja abaixo).

Data Account

Na Solana, o código executável de um programa é armazenado em uma conta diferente da que guarda o estado do programa. Isso é semelhante a como os sistemas operacionais normalmente têm arquivos separados para programas e seus dados.

Para manter o estado, os programas definem instruções para criar contas separadas que eles possuem. Cada uma dessas contas tem seu próprio endereço único e pode armazenar qualquer dado arbitrário definido pelo programa.

Data AccountData Account

Observe que apenas o System Program pode criar novas contas. Uma vez que o System Program cria uma conta, ele pode então atribuir a propriedade da nova conta a outro programa.

Em outras palavras, criar uma conta de dados para um programa personalizado envolve duas etapas:

  1. Invocar o System Program para criar uma conta e transferir a propriedade para o programa personalizado
  2. Invocar o programa personalizado, que agora é proprietário da conta, para inicializar os dados da conta conforme definido pela instrução do programa

Este processo de criação de conta é frequentemente abstraído como uma única etapa, mas é útil entender o processo subjacente.

O exemplo a seguir mostra como criar e buscar uma conta Token Mint pertencente ao programa Token 2022.

import {
airdropFactory,
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
generateKeyPairSigner,
getSignatureFromTransaction,
lamports,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners
} from "@solana/kit";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
getInitializeMintInstruction,
getMintSize,
TOKEN_2022_PROGRAM_ADDRESS,
fetchMint
} from "@solana-program/token-2022";
// Create Connection, local validator in this example
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate keypairs for fee payer
const feePayer = await generateKeyPairSigner();
// Fund fee payer
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: feePayer.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
// Generate keypair to use as address of mint
const mint = await generateKeyPairSigner();
// Get default mint account size (in bytes), no extensions enabled
const space = BigInt(getMintSize());
// Get minimum balance for rent exemption
const rent = await rpc.getMinimumBalanceForRentExemption(space).send();
// Instruction to create new account for mint (token 2022 program)
// Invokes the system program
const createAccountInstruction = getCreateAccountInstruction({
payer: feePayer,
newAccount: mint,
lamports: rent,
space,
programAddress: TOKEN_2022_PROGRAM_ADDRESS
});
// Instruction to initialize mint account data
// Invokes the token 2022 program
const initializeMintInstruction = getInitializeMintInstruction({
mint: mint.address,
decimals: 9,
mintAuthority: feePayer.address
});
const instructions = [createAccountInstruction, initializeMintInstruction];
// Get latest blockhash to include in transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
// Create transaction message
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }), // Create transaction message
(tx) => setTransactionMessageFeePayerSigner(feePayer, tx), // Set fee payer
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), // Set transaction blockhash
(tx) => appendTransactionMessageInstructions(instructions, tx) // Append instructions
);
// Sign transaction message with required signers (fee payer and mint keypair)
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
// Send and confirm transaction
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
// Get transaction signature
const transactionSignature = getSignatureFromTransaction(signedTransaction);
console.log("Mint Address:", mint.address);
console.log("Transaction Signature:", transactionSignature);
const accountInfo = await rpc.getAccountInfo(mint.address).send();
console.log(accountInfo);
const mintAccount = await fetchMint(rpc, mint.address);
console.log(mintAccount);
Console
Click to execute the code.

Is this page helpful?

Índice

Editar Página