Visão geral
A blockchain Solana é uma ferramenta poderosa, que entrega milhares de transações por segundo com taxas de transação quase sem custo. Se você é novo na Web3 ou desenvolveu anteriormente em blockchain baseadas em EVM, este guia o ajudará a entender os primórdios de Solana e a iniciar sua jornada para o desenvolvimento em Solana. Se você já está construindo sobre Solana, use este guia como uma referência para continuar a aumentar sua compreensão dos fundamentos de Solana.
Neste guia, cobriremos especificamente os blocos básicos de construção da Solana: Contas, Programas, Instruções, Transações, RPCs, e Assinaturas. Vamos pular dentro!
TLDR (Resumo)
- Contas são como arquivos em um sistema operacional tradicional - a maioria das coisas na Solana é uma conta: carteiras de usuários, programas, registros de dados e até mesmo programas de sistema.
- Os programas (conhecidos como contratos inteligentes em outras cadeias) são um tipo particular de conta "executável" - são stateless(sem Estado) e só executam código baseado em parâmetros de entrada de usuário. Ao invés de se atualizarem, os programas têm autoridade específica para atualizar os dados (ou estado) de outras contas que eles "possuem".
- Os usuários assinam e enviam transações (pacotes de instruções específicas do programa) através de um RPC a um cluster Solana para dizer aos programas o que fazer.
- Solana usa um mecanismo de consenso único chamado Proof of History (PoH) que depende do tempo e da criptografia para marcar e encomendar transações enviadas para a rede.
- Programas e assinantes de transações autorizam mudanças em certas contas de dados na cadeia para atualizar o estado da rede.
Fome por mais? Continue lendo! 👇
O que é Solana?
Solana é uma cadeia de bloqueio de código aberto otimizada para velocidade e custo, permitindo que as informações e o estado sejam sincronizados globalmente. Solana utiliza uma versão única de Proof of Stake consensus chamada Proof of History, que utiliza uma função de atraso granular verificável para efetivamente marcar e encomendar transações enviadas para a rede. Como definido por Solana, "ele utiliza uma função criptográfica segura escrita de forma que a saída não possa ser prevista a partir da entrada, e deve ser completamente executada para gerar a saída". (...) O Líder sequencia as mensagens do usuário e as ordena de modo que possam ser processadas eficientemente por outros nós do sistema, maximizando a produção". (Fonte: Solana Whitepaper)
Neste artigo, mudaremos o foco para como você pode interagir e construir com Solana. Se você quiser se aprofundar na arquitetura de Solana e na teoria por trás de algumas de suas características de design, aqui estão alguns grandes recursos:
Contas
Como os arquivos em um sistema operacional, as contas são usadas para executar o sistema, armazenar dados ou estado, e executar código.
Existem 3 tipos principais de contas na Solana:
-
Contas de dados que armazenam informações e gerenciam o estado da rede. Existem dois tipos de contas de dados:
- Contas de propriedade do sistema (mais comumente reconhecidas como carteiras) [exemplo: Uma carteira do usuário]
- Contas derivadas de programas (frequentemente referidas como PDAs) - um exemplo comum é uma conta token de usuário para um token específico. Ela é derivada do Programa de Tokens Solana SPL. [exemplo: Uma conta de token de usuário].
- Contas do programa que possuem código executável. Falaremos mais sobre elas na seção seguinte, mas estas contas são stateless (ou seja, os dados passam por elas, mas não as atualiza) [exemplo: Candy Machine v2 Program Account].
- Contas do Sistema Nativo (por exemplo, Programa do Sistema, Votação, Estaqueamento, BPF Loader) [exemplo: Programa do Sistema Solana].
Este artigo se concentrará nos #1 e #2. Se você quiser saber mais sobre o #3, Contas do Sistema Nativo, confira o site docs.solana.com.
Em resumo, quase tudo na Solana é uma conta. O tipo mais comum de conta é a carteira do usuário, uma conta de dados que gerencia o estado do saldo SOL de um usuário.
Cada conta tem um endereço único, ou chave pública (muito parecido com um caminho de arquivo) e um conjunto de metadados associados:
- Iamports: O número de lamports de propriedade desta conta (inteiro de 64 bits sem assinatura)*
- proprietário: Ao proprietário do programa é atribuída esta conta (string do endereço do programa proprietário). O proprietário do programa controla quem tem acesso de escrita às contas - outros programas podem ler os dados de outra conta, mas se eles tentassem modificar esses dados, a transação fracassaria.
- executável: Se esta conta pode processar instruções (booleano). Uma conta com um valor executável de real é na verdade um Programa (ou Contrato Inteligente) - discutiremos isso na próxima seção.
- dados: Qualquer dado adicional associado à conta, armazenado como uma matriz de bytes de dados brutos
- rent_epoch: A próxima época em que esta conta deverá alugar (inteiro de 64 bits sem assinatura)
*os lamports são a menor denominação de SOL, o símbolo nativo de Solana (representam um bilionésimo de um SOL)
Os metadados de qualquer conta podem ser lidos executando a getAccountInfo JSON RPC query ou pesquisando-a no Solana Explorer. O Solana Explorer permite pesquisar qualquer conta e ver detalhes básicos sobre que tipo de conta é e a que Programa está associado. Aqui está um exemplo de uma conta de dados de propriedade do sistema (carteira de um usuário):
Visualizemos um exemplo de todos os tipos de contas:
Muita coisa está acontecendo aqui, mas tudo o que você vê nesta figura é uma Conta. No lado esquerdo, temos uma Conta de Sistema chamada Programa de Sistema, que rege todas as carteiras de usuários. Também temos uma Conta de Programa executável, chamada Solana SPL Token Program, que os usuários podem usar para cunhar, queimar e transferir os tokens SPL. Finalmente, temos o Programa de Contas Derivadas. Neste caso, estas são contas token pertencentes ao Token Program e associadas a uma Conta de Usuário. Observe como 1 carteira de usuário pode ter múltiplas contas token.
Lembre-se, você pode pesquisar qualquer endereço de conta no Solana Explorer para obter seus metadados e entender que tipo de conta é e a que programa está associado.
As contas e dados de contas de Lamports e Rent Epoch são armazenados na memória do validador e são obrigados a pagar "aluguel" em lamports (indicado no campo de metadados de lamports de contas) para permanecer lá. Quanto mais dados forem armazenados em sua conta, mais aluguel será necessário (nota: o tamanho máximo atual da conta é 10-MB). Você pode calcular suas necessidades de aluguel usando o método JSON RPC, getMinimumBalanceForRentExemption. Os validadores são responsáveis pela verificação periódica de todas as contas e pela coleta das contas de aluguel - as contas são verificadas na época identificada no campo de metadados rent_epoch. Se uma conta cair para um saldo de zero-lamport, a rede limpará a conta e os dados serão perdidos. No momento desta publicação, todas as novas contas são obrigadas a manter o status de isenção de aluguel, o que é concedido por 2 anos de aluguel na conta. Fonte: https://docs.solana.com/developing/programming-model/accounts Epochs são uma medida de tempo em Solana, representando atualmente cerca de 2,5 dias.
Programas
Os programas são o que Solana chama de Contratos Inteligentes- eles são o motor que lida com informações e solicitações: tudo, desde transferências de tokens e cunhagem da Candy Machine até logs do "olá mundo" e governança do DeFi Escrow.
- Lembre-se, os programas Solana são contas sem Estado sinalizados como "executáveis": "Os programas são considerados sem estado uma vez que os dados primários armazenados em uma conta de programa é o código BPF compilado".
- Os programas podem usar "Invocação de Programas Cruzados" para usar ou construir sobre outros Programas Solana. Isto é frequentemente referido como componibilidade.
- Ao contrário de muitas outras cadeias populares, os programas são atualizáveis.
- A maioria dos Programas é gerada pelo usuário, mas a Solana Labs construiu e mantém uma série de programas na cadeia conhecidos como Biblioteca de Programas Solana.
- Com efeito, um usuário deve fornecer instruções específicas a um programa, o programa processa essas instruções, e então o programa pode invocar outros programas e/ou atualizar contas derivadas do programa que possui (mais sobre PDAs abaixo).
Contas de Endereço Derivadas do Programa
Um endereço derivado do programa (PDA) é uma conta criada e controlada por um programa específico. PDAs:
- Permitir programas para controlar endereços específicos, chamados endereços de programas, para que nenhum usuário externo possa gerar transações válidas com assinaturas para esses endereços.
- Permitir que os programas assinem programaticamente os endereços dos programas que estão presentes nas instruções invocadas através de Invocações de Interprogramas. Solana deriva deterministicamente PDAs baseados em sementes definidas pelo programa e pelo ID do programa. Mais informações sobre os endereços dos programas gerados podem ser encontradas em docs.solana.
Isto permite que os programas ofereçam serviços trustless, como contas de garantia para o gerenciamento seguro de negócios, apostas ou protocolos de desafio. Se nos referirmos ao nosso esquema acima, o Programa SPL Token gera um PDA para um usuário com base na carteira do usuário e no endereço de cunhagem desse token específico. Esse PDA específico armazenaria o estado ou dados para a quantidade desse token pertencente a um usuário.
Vamos investigar como fazemos os programas funcionarem com instruções e transações.
Instruções
Instruções, em sua essência, dizem a um Programa para fazer algo. Solana define as instruções como "A menor unidade contígua de lógica de execução em um programa". (Fonte: docs.solana.com/terminologia).
Uma instrução consiste em 3 partes:
- A Chave Pública do Programa que você invocará,
- Uma série de Contas que será lida ou modificada, e
- Uma matriz de bytes de quaisquer dados adicionais que sejam necessários para a execução do programa (específico do programa)
Este último ponto é crucial - as instruções são específicas do programa. A transação falhará se você inserir a identificação errada do programa ou não souber a estrutura de dados esperada para passar para o programa.
Em Javascript, uma instrução de transação é algo parecido com isto:
new TransactionInstruction({
programId: new PublicKey(PROGRAM_ID),
keys: [
{ pubkey: signerKeypair.publicKey, isSigner: true, isWritable: true },
{ pubkey: pda, isSigner: false, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false }
],
data: Buffer.from(SOME_ENCODED_DATA),
})
Vale a pena mencionar aqui as informações de Conta necessárias para uma Instrução de Transação. Devemos fornecer a chave pública da conta, se essa conta é ou não um signatário da transação e se a conta será escrita como parte da transação (isto ajuda a contribuir para a capacidade de Solana de executar rapidamente). No exemplo acima, um usuário assina a carteira, e os dados são escritos em um PDA. É comumente necessário incluir também contas do programa do sistema (por exemplo, para criar uma conta). Finalmente, nós passamos ALGUNS_DADOS_CODIFICADOS. O tipo de dados necessários é definido dentro do programa. O programa deve desserializar os dados de entrada para processá-los corretamente.
Transações
As transações são o meio de entregar instruções a um programa na rede. As transações podem agrupar várias instruções para processar várias operações simultaneamente. Por exemplo, imagine um exemplo quando você tem três instruções diferentes: uma instrução para a Carteira A para enviar a Carteira B 1 $SOL, uma instrução para a Carteira B para enviar a Carteira A 33 $USDC, e uma instrução para registrar um memorando para a transação que diz "Carteira A Troca 1 $SOL por 33 $USDC com Carteira B em AAAA-MM-DD". Embora cada uma delas pudesse ser enviada à rede separadamente, o que aconteceria se uma instrução falhasse, mas as outras fossem bem sucedidas? Você teria um cenário em que uma pessoa recebesse seus tokens, e outra não. Ao agrupar as instruções em um pacote, podemos garantir que todas as nossas transações tenham sucesso ou falhem em conjunto.
As transações são atualmente limitadas a 1.232 bytes. Cada transação deve incluir o seguinte:
- um array (lista) de uma ou mais instruções de transação
- um array de todos os endereços de conta com os quais o programa estará interagindo.
- um array de assinaturas: Um subconjunto das contas que passamos para nossa transação também deve incluir uma assinatura. "Essas assinaturas sinalizam programas na cadeia que o titular da conta autorizou a transação. Tipicamente, o programa usa a autorização para permitir o débito da conta ou a modificação de seus dados". (Fonte: docs.solana.com). Por exemplo, isto também pode ser necessário para um criador verificar se um NFT é genuíno.
- um bloqueio recente: um bloqueio é basicamente um carimbo de tempo PoH. Solana, por padrão, deixa cair transações "antigas" para evitar dupla contagem, para permitir que os validadores só verifiquem transações contra um lote muito recente, e para dar aos usuários uma certeza rápida se sua transação foi processada (ou falhou, para que eles possam tentar novamente). Obter um bloqueio recente antes de submeter uma transação permite à rede saber a idade de nossa transação e quando ela deve expirar (se necessário).
Uma vez que a rede recebe uma transação, ela retorna um ID de transação (string codificada de base 58) que pode ser usado para consultar os detalhes da transação.
Vamos discutir como levar sua transação para a rede!
RPC
JSON-RPC é um protocolo de Chamada de Procedimento Remoto codificado em JSON que permite aos usuários enviar informações para um cluster Solana e obter uma resposta da rede. A Solana mantém atualmente três clusters de rede:
- Devnet: um playground para testar a funcionalidade de aplicações e métodos
- Testnet: um ambiente de desenvolvimento usado para testar todas as últimas atualizações planejadas para o sistema
- Mainnet Beta: ambiente de produção
Os clientes podem fazer pedidos de leitura ou escrita para qualquer um dos três grupos usando pedidos JSON-RPC através de um nó Solana. Os nós atuam como "controle de tráfego aéreo" para tratar as solicitações para a rede. Os clientes se conectam aos nós Solana através da classe de conexão Solana Web3:
const HTTP_ENDPOINT = 'https://example.solana-devnet.quiknode.pro/000/';
const SOLANA_CONNECTION = new Connection(HTTP_ENDPOINT);
Na amostra acima, HTTP_ENDPOINT é uma URL HTTP que aponta para um nó Solana que finalmente encaminhará seu pedido para um dos três clusters.
Toda solicitação requer um endpoint API para se conectar com a rede. É aqui que entra o QuickNode! Você é bem-vindo a usar nós públicos ou implantar e gerenciar sua própria infra-estrutura; entretanto, se você quiser tempos de resposta 8x mais rápidos, você pode deixar o trabalho pesado por nossa conta. Veja porque mais de 50% dos projetos na Solana escolhem o QuickNode e se inscrevem para uma conta gratuita aqui. Basta entrar e atualizar o HTTP_ENDPOINT em seu aplicativo com o fornecido no painel de controle de sua conta, e você está pronto para ir!
Uma vez estabelecida uma conexão com um cluster Solana, você pode realizar muitos métodos de leitura ou escrita para a rede. Uma lista completa de métodos e documentação RPC está disponível no QuickNode Docs. Embora cada método tenha seu propósito, alguns poucos que são relevantes para a discussão até agora neste guia são:
- sendTransaction - envia uma Transação para a rede Solana
- getAccountInfo - busca metadados associados a qualquer Conta
- getLatestBlockhash - devolve o último bloqueio da rede
As chamadas HTTP nos permitem dizer à rede para fazer algo (por exemplo, processar uma transação e suas instruções, retornar informações atuais sobre o estado de uma conta, etc.), mas e se quisermos que a rede nos alerte sobre mudanças no estado de uma conta?
Assinaturas
As assinaturas são um tipo especial de solicitação RPC onde fazemos uma solicitação WebSocket (WSS) em vez de usar um endpoint HTTP. Solana Web3 JSON RPC inclui vários métodos de assinatura (por exemplo, accountSubscribe, que ouvirá as mudanças nos lamports ou dados de uma conta). Podemos então assinar estes eventos com uma função de callback, permitindo que alguma ação desejada aconteça sempre que a rede mudar.
O construtor da classe Connection permite-nos passar um opcional commitmentOrConfig. Dentro dele, podemos passar um wsEndpoint. Esta é uma opção para você fornecer uma URL de endpoint para o nó completo JSON RPC Websocket Endpoint. Se você criou um Endpoint QuickNode, você deve ver esta opção no lado direito da página do seu endpoint.
const HTTP_ENDPOINT = 'https://example.solana-devnet.quiknode.pro/000/';
const WSS_ENDPOINT = 'wss://example.solana-devnet.quiknode.pro/000/';
const solanaConnection = new Connection(
HTTP_ENDPOINT,
{wsEndpoint:WSS_ENDPOINT}
);
O que acontece se você não passar um wsEndpoint? Bem, Solana conta com uma função, makeWebsocketUrl, que substitui o https de seu endpoint URL por wss ou http por ws (fonte). Como todos os endpoints HTTP QuickNode têm um endpoint WSS correspondente com o mesmo token de autenticação, é aceitável que você omita este parâmetro a menos que você queira usar um endpoint separado para suas consultas do Websocket.
Para mergulhar mais fundo na criação de assinaturas WebSocket, consulte nosso Guia: Como criar assinaturas de Websocket para Solana Blockchain usando Typescript.
Vamos juntar tudo
Certo! Isso é muita informação - você provavelmente começou a ver algum tecido conjuntivo entre estes primitivos, mas vamos fazer uma rápida recapitulação antes de conectar todas as peças juntas:
- Quase tudo na Solana é uma conta: carteiras de usuário, programas, programas de sistema, dados de programas, etc.
- Os programas são sem estado - as suas instruções de processo e podem chamar outros programas e mudar o estado das contas de dados que possuem.
- As instruções são específicas do programa e dizem a um programa o que fazer.
- Transações pacote uma ou mais instruções com uma assinatura para autorizar um programa a executar uma ou mais tarefas.
- Os protocolos RPC permitem aos clientes enviar pedidos de leitura/escrita para um dos três clusters da Solana através de um nó, como o QuickNode.
- Clients can subscribe to network changes using WebSocket requests through the RPC provider.
Vamos caminhar através de um exemplo ilustrativo. Imaginemos um Programa chamado "GM" que contém um contador que registra sempre que um usuário envia uma mensagem "GM" para o Programa.
No exemplo acima, um cliente cria uma Transação que inclui várias Instruções de Transação. As instruções são específicas do programa, portanto, elas precisam corresponder à estrutura esperada do Programa GM. O Cliente assina e envia a Transação para um cluster Solana através de um provedor de RPCs, como o QuickNode, usando a classe Conexão. O fornecedor do RPC encaminha a solicitação para o cluster. A conta do Programa executa e processa as instruções de entrada recebidas. A conta do Programa é sem estado e não muda, mas autoriza uma mudança nos dados do PDA para incrementar o valor do contador GM. Uma assinatura criada pelo cliente escuta as mudanças no PDA; então, a rede alerta o cliente de que a conta foi alterada.
Encerramento
Ufa! Isso é MUITA informação que acabamos de cobrir. Não tenha medo de ler isto várias vezes para garantir que você compreenda estes conceitos.
Agora que você tem uma compreensão mais robusta de Solana, é hora de construir! Experimente alguns de nossos guias de desenvolvimento Solana para começar. Aqui estão alguns exemplos:
- Como Criar e Enviar (Versionado) Transações na Solana
- Como cunhar um NFT na Solana usando o Typescript
- Como obter logs de transações na Solana
Tem perguntas sobre qualquer um desses conceitos ou apenas quer falar de trabalho? Entre no nosso Discord ou no Twitter e nos informe o que você está construindo!
Nós <3 Feedback!
Se você tiver qualquer feedback ou perguntas sobre este guia, informe-nos. Adoraríamos ouvir de você!
Referência e fontes
- https://solanacookbook.com/core-concepts/accounts.html#deep-dive
- https://www.quicknode.com/guides/solana-development/an-introduction-to-the-solana-account-model
- https://medium.com/@anatolyyakovenko
- https://docs.solana.com/developing/programming-model/accounts
- https://docs.solana.com/developing/clients/jsonrpc-api#getaccountinfo
Artigo escrito no site do QuickNode. A versão original pode ser encontrada aqui. Traduzido e adaptado por Dimitris Calixto.
Oldest comments (0)