O Blueprint da Conta
Contas são a única abstração de armazenamento do Solana: cada carteira, binário de programa, conta de token e registro de aplicativo é o mesmo objeto on-chain. Uma vez que você veja essa uniformidade - cinco campos, um proprietário, travas explícitas - aluguel, CPIs, PDAs e Sealevel são lidos como consequências de uma única escolha de design, não casos especiais.
Noções Básicas do Modelo de Conta é a entrada prática; Anatomia da Conta, Aluguel e Isenção de Aluguel, Propriedade e Permissões da Conta, Estado de Propriedade do Programa e Contas do Sistema vs. Contas de Programa cada um foca em um mecanismo. Esta página fica abaixo: por que um tipo de conta existe e como isso permite a execução paralela.
Resumo
- O Solana armazena todo o valor e estado on-chain como contas - registros de formato fixo com
lamports,data,owner,executableerent_epoch- e apenas o programa proprietário pode mutardata. - Por que Importa: Uma abstração significa um modelo de permissão, uma regra de financiamento (aluguel) e uma lista de travas; essa lista é o que permite ao Sealevel executar transações não sobrepostas em paralelo.
- Conceitos Chave: abstração de conta única, escritas do proprietário, propriedade do sistema vs. propriedade do programa, contas executáveis, isenção de aluguel, criação de conta (alocar + atribuir + financiar), PDAs, listas explícitas de contas.
- Quando Usar: Projetando onde o estado vive, depurando erros de proprietário incorreto ou conta ausente, dimensionando o aluguel, explicando o Solana para colegas nativos de EVM, ou raciocinando sobre quais transações podem ser executadas lado a lado.
- Limitações / Compromissos: Você deve dimensionar e financiar contas antecipadamente, declarar todas as contas que uma transação toca e dividir o estado "quente" entre endereços para paralelismo - sem um saco de armazenamento global oculto dentro de um programa.
- Tópicos Relacionados: anatomia da conta, aluguel, permissões de propriedade, estado de propriedade do programa, contas do sistema vs. contas de programa.
Fundamentos
O Solana não dá às carteiras um tipo, aos contratos outro e ao armazenamento um terceiro. Ele lhe dá um tipo de conta em um endereço de chave pública, interpretado por quantos lamports ele detém, qual programa o possui, se ele é executável e quais bytes estão em seu buffer de dados.
Essa escolha é deliberada. Um registro uniforme mantém o AccountsDB simples, torna as verificações de permissão locais a uma única owner pubkey e transforma "o que esta transação pode tocar?" em uma lista finita de endereços que o cliente deve declarar. O agendamento paralelo se torna um problema de gráfico sobre esses endereços, não uma suposição sobre o que um programa pode ler mais tarde.
Cada conta expõe os mesmos cinco campos principais:
| Campo | Papel |
|---|---|
lamports | Saldo de SOL em lamports (financiamento + taxas + depósito de aluguel) |
data | Buffer de bytes opaco (vazio para muitas carteiras; estruturado para estado de aplicativo) |
owner | Programa ID permitido para escrever data e aplicar regras do lado do proprietário |
executable | true se esta conta for código de programa carregável |
rent_epoch | Campo legado de rastreamento de aluguel; contas isentas de aluguel efetivamente ficam na época máxima |
Pense no estado global como um mapa de endereço para este registro - não como espécies separadas para "contratos com armazenamento" e "EOAs com saldos":
Endereço (Pubkey)
|
v
+------------------+
| lamports | <- saldo / depósito de aluguel
| data: [u8] | <- vazio, layout Borsh, ou bytes do programa
| owner: Pubkey | <- quem pode escrever dados
| executable: bool | <- programa vs dados
| rent_epoch | <- marcador legado / isento
+------------------+Escritas do proprietário é a regra de segurança central: apenas o programa nomeado em owner pode mutar os data dessa conta. Outros programas podem ler uma conta se ela for passada, e podem mover lamports sob regras específicas, mas não podem reescrever os bytes de outro programa. Signatários provam "quem solicitou isso"; o campo proprietário prova "qual programa pode alterar este armazenamento".
Carteiras comuns são tipicamente de propriedade do sistema: Programa do Sistema como proprietário, executable falso e geralmente data vazio. O estado útil da carteira é o saldo de lamports (saldos de token vivem em outras contas). O estado do aplicativo vive em contas de propriedade do programa cujo proprietário é o seu ID de programa e cujo buffer contém um layout que o programa entende. Programas em si são contas com executable: true, de propriedade de um loader, contendo bytecode em vez de campos de aplicativo.
Essa divisão - código em contas executáveis, estado durável em contas de dados - é por que os programas Solana são chamados de sem estado: o executável não tem um mapa de armazenamento privado; cada campo durável vive em outro endereço que sua instrução deve nomear.
Mecânicas e Interações
Criar uma conta são três trabalhos em um fluxo
Nada útil existe em um endereço não utilizado até que algo aloque espaço, atribua um proprietário e financie o mínimo isento de aluguel para esse tamanho. O Programa do Sistema geralmente faz o trabalho do ciclo de vida; seu programa (ou outro proprietário) então interpreta o buffer.
Conceitualmente:
pagador (de propriedade do sistema) nova conta
+----------------+ +------------------+
| lamports: $$$ | --financiar aluguel-> | lamports: min |
| data: [] | | data: [0; N] |
| owner: Sistema | --alocar N------> | owner: SeuProg |
+----------------+ --atribuir prop.---> | executable: false|
+------------------+Isenção de aluguel é um depósito de lamports escalado por tamanho: data maior trava mais SOL na conta. A prática de produção financia esse depósito uma vez para que a conta permaneça ativa; fechar sob as instruções corretas retorna esses lamports a um destinatário. Subfinanciamento não é um aviso suave - contas não isentas não persistem como o estado de produção exige.
Propriedade do sistema vs. propriedade do programa vs. executável
Três papéis cotidianos compartilham a mesma estrutura:
- Carteira de propriedade do sistema / pagador de taxas - detém SOL; o Programa do Sistema transfere e cria; sem layout de aplicativo em
data. - Conta de dados de propriedade do programa - detém estado estruturado; apenas seu programa escreve
data; frequentemente um PDA para endereçamento determinístico. - Conta de programa executável - de propriedade de um loader,
executable: true; detém ou aponta para bytecode do programa (loaders atualizáveis frequentemente dividem a identidade do programa de uma conta ProgramData que armazena os bytes).
O modelo mental é: identidade é o endereço, permissão é o proprietário, significado é o layout de data, e "isso é código?" é o sinalizador executável. O proprietário é sempre um ID de programa; uma chave pública de administrador é geralmente um campo dentro do buffer que seu programa verifica por si mesmo.
PDAs: endereços derivados do programa sem chaves privadas
Um endereço derivado do programa (PDA) ainda é apenas um endereço de conta. Ele é derivado de sementes (seeds) e um ID de programa para que nenhuma chave privada comum possa assinar por ele; o programa proprietário pode autorizá-lo via sementes em CPI. PDAs respondem como um programa detém cofres, configurações e estado por usuário sem uma chave secreta on-chain. Detalhes de semente e bump pertencem a outro lugar; aqui, um PDA não é um segundo tipo de conta - apenas um endereço e convenção de assinatura sobre o mesmo registro.
Listas explícitas de contas e Sealevel
Clientes devem declarar todas as contas que uma instrução lerá ou escreverá. O runtime usa essa lista para carregar contas do AccountsDB, marcar cada uma como somente leitura ou gravável, travar contas graváveis sobrepostas para que conflitos não se intercalem e agendar trabalhos não sobrepostos concorrentemente (Sealevel).
Contas da Tx A: [User1, VaultA, TokenProg] (gravável: User1, VaultA)
Contas da Tx B: [User2, VaultB, TokenProg] (gravável: User2, VaultB)
|
v
Nenhuma conta gravável compartilhada -> pode executar em paralelo
Contas da Tx C: [User1, VaultA, ...]
Conflita com a Tx A em VaultA gravável -> deve serializarSe o programa precisar de uma conta não declarada, a execução falha; não há caminho ambiente "carregar qualquer chave que eu hash mais tarde" para mutação. Essa fricção é intencional: paralelismo precisa de um mundo fechado de endereços antes do início da execução. Muitas contas de estado pequenas e não sobrepostas (por exemplo, um PDA por usuário) não são apenas um estilo de API - são como você deixa espaço para vazão concorrente.
Como as peças interagem em uma instrução
Um caminho típico de "atualizar meu perfil":
- O cliente lista o assinante do usuário, o PDA do perfil (gravável), o Programa do Sistema se estiver criando e seu programa.
- O runtime trava essas contas por sinalizadores somente leitura/gravável.
- Seu programa é executado; apenas as contas que ele possui podem ter
datareescrito por sua lógica. - Ele desserializa
data, verifica a autoridade contra o assinante, escreve novos bytes e retorna. - O sucesso confirma o registro; a falha aborta toda a transação.
O aluguel foi definido na criação. A propriedade foi definida na atribuição. O paralelismo foi definido por quais endereços pousaram na mensagem. O corpo da instrução apenas fornece a lógica de negócios.
Considerações Avançadas e Aplicações
A abstração de conta única força compromissos que parecem estranhos se você espera "um contrato, armazenamento interno infinito". Você paga em dimensionamento antecipado, conexão explícita e proliferação de contas; você ganha propriedade clara, aluguel recuperável e conjuntos de conflitos visíveis para o agendador.
| Papel da conta | Força | Fraqueza | Melhor ajuste |
|---|---|---|---|
| Carteira de propriedade do sistema | Detentor de SOL simples; pagador de taxas natural | Dados vazios/não tipados; não para esquemas de aplicativos | Usuários, tesourarias de SOL, pagadores de instruções |
| Conta de dados de propriedade do programa | Estado tipado sob escritas do proprietário; aluguel fechável | Alocar, financiar e passar todas as vezes | Configuração, escrow, registros por usuário, cofres |
| Conta de programa executável | Lógica compartilhada; padrões de loader atualizáveis | Não é estado de aplicativo; atualizações exigem cuidado com a autoridade | Apenas código de programa on-chain |
Granularidade é a principal alavancagem de desempenho. Uma conta gigante de estado global serializa todos os escritores. Muitas contas por entidade permitem que usuários não sobrepostos executem em paralelo, ao custo de mais endereços, mais aluguel e listas de contas mais longas. Compressão e índices ajudam em escala, mas a cadeia ainda pensa em contas e travas declaradas.
CPI e propriedade compõem porque a propriedade é absoluta. Para alterar uma conta de token, você faz CPI para o Programa de Token - você não pode mexer em seus bytes sozinho. "Quem pode mutar isso?" é um fato do runtime, e o limite de confiança do Sealevel corresponde ao mesmo campo owner que você usa para contas de aplicativo.
Atualizabilidade também tem formato de conta. Com o loader atualizável, a identidade e os bytes do programa podem viver em contas relacionadas (programa + ProgramData). Fechar, realocar ou migrar estado é sempre "mover ou reescrever sob regras do proprietário", não "editar uma árvore de armazenamento oculta".
Para revisões de design, responda primeiro: onde cada campo vive, qual programa o possui, qual autoridade está dentro de data, custo de espaço e aluguel, quais endereços cada cliente deve passar e quais pares de transações contendem na mesma conta gravável. Respostas claras cortam bugs de propriedade e serialização acidental de hot-path.
Conceitos Errôneos Comuns
- "Carteiras, programas e estado são tipos de objetos on-chain diferentes." Eles são a mesma estrutura de conta; os papéis diferem por
owner,executablee como você interpretadata. - "Meu programa armazena campos dentro do binário do programa." Executáveis detêm código (via loaders); campos de aplicativo duráveis vivem em contas separadas de propriedade do programa que você cria e passa.
- "Proprietário significa a chave pública da carteira do usuário." Proprietário é sempre um ID de programa. O controle do usuário é geralmente uma verificação de assinante contra um campo de autoridade armazenado em
data, ou regras do Programa do Sistema para contas de propriedade do sistema. - "Se eu conhecer um endereço, o runtime buscará o que eu precisar." Caminhos de mutação exigem que a conta apareça na lista de contas da transação com o sinalizador gravável correto; contas não declaradas não estão ambientemente disponíveis.
- "Aluguel é uma assinatura mensal para sempre." A prática de produção é o financiamento isento de aluguel na criação; o depósito escala com o tamanho e é recuperável quando a conta é fechada corretamente.
- "Uma conta grande é mais simples e tudo bem em escala." É mais simples codificar no início, mas cada escritor serializa nesse endereço; o Sealevel não pode paralelizar travas graváveis conflitantes.
FAQs
Qual é a ideia mais importante no modelo de conta?
Tudo on-chain é uma conta com os mesmos campos, e apenas o programa proprietário pode escrever os dados dessa conta - então permissões, aluguel e travas paralelas formam um sistema consistente.
Quais são os cinco campos principais da conta?
lamports (saldo), data (buffer de bytes), owner (programa permitido para escrever dados), executable (se a conta é código de programa) e rent_epoch (rastreamento de aluguel legado; contas isentas usam a convenção de época máxima).
O que a regra de escritas do proprietário realmente impõe?
O runtime rejeita mutações de dados de qualquer programa que não seja o owner da conta. Seu programa só pode reescrever contas que ele possui; para alterar o layout de outra pessoa, você deve fazer CPI para o programa proprietário dela.
Por que as carteiras comuns são de propriedade do sistema?
O Programa do Sistema as possui para que possa criar contas, atribuir proprietários e transferir SOL sob regras de assinatura. Carteiras tipicamente têm dados vazios e não são usadas como armazenamento de aplicativos estruturado.
Onde o estado estruturado do meu aplicativo deve viver?
Em contas de propriedade do seu programa: aloque espaço, atribua seu ID de programa como proprietário, financie lamports isentos de aluguel e, em seguida, serialize seu layout em data a cada atualização.
Como as contas de programa executáveis diferem das contas de dados?
Elas têm executable: true e são de propriedade de um loader; sua carga útil é bytecode ou contabilidade do loader, não seu esquema de aplicativo. Você as invoca como programas, não como sacos de estado mutáveis comuns.
O que significa "isento de aluguel" na prática?
A conta detém lamports suficientes para seu tamanho de dados, de modo que não esteja sujeita à coleta contínua de aluguel. O depósito exigido cresce com o espaço alocado; fechar a conta é como você recupera esses lamports.
Quais etapas criam uma conta de dados utilizável?
Aloque um buffer de dados do tamanho certo, atribua o programa proprietário pretendido e financie pelo menos o mínimo isento de aluguel - geralmente pago por um pagador de taxas de propriedade do sistema na mesma transação que inicializa os campos.
PDAs são um tipo diferente de conta?
Não. Um PDA é um endereço derivado para que um programa possa controlá-lo sem uma chave privada. Uma vez criado, ainda é um registro de conta normal com os mesmos cinco campos.
Por que os clientes devem declarar todas as contas na transação?
Para que o runtime possa carregar, travar e agendar contas antes da execução. O Sealevel usa essas listas para executar transações não sobrepostas em paralelo e para evitar acesso a estado não declarado.
Como o modelo de conta permite o paralelismo do Sealevel?
Transações que não compartilham contas graváveis conflitantes podem ser executadas concorrentemente porque seus conjuntos de travas não se intersectam. Listas explícitas de contas tornam esses conjuntos de travas conhecidos antecipadamente.
Qual é a diferença entre o proprietário da conta e a autoridade da conta?
Proprietário é o ID do programa nos metadados da conta. Autoridade é geralmente uma chave pública em nível de aplicativo armazenada dentro de data que seu programa verifica contra um assinante de transação.
Duas programas podem possuir a mesma conta?
Não. Existe um único campo owner. Comportamento compartilhado requer CPI para o programa proprietário ou redesenho de qual programa deve possuir o estado.
O que acontece quando fecho uma conta?
Sob as regras do programa proprietário, os dados são zerados ou a conta é reatribuída, e os lamports restantes (incluindo o depósito de aluguel) são transferidos para um destinatário - recuperando o capital travado para esse estado.
Como devo pensar sobre saldos de tokens neste modelo?
Saldos SPL vivem em contas de token de propriedade do Programa de Token, não nos dados vazios da conta do sistema da carteira. A carteira ainda é uma conta; cada saldo de token é outra conta com seu próprio proprietário e layout.
Relacionados
- Noções Básicas do Modelo de Conta - exemplos práticos do modelo de conta
- Anatomia da Conta - detalhamento campo a campo do registro da conta
- Aluguel e Isenção de Aluguel - depósitos baseados em tamanho e recuperação no fechamento
- Propriedade e Permissões da Conta - escritas do proprietário e verificações de assinante
- Estado de Propriedade do Programa - programas sem estado e contas de dados
- Contas do Sistema vs. Contas de Programa - papéis de carteira vs. dados vs. executável
Versões da Stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1 e @solana/kit 7.0.0.