1) Nos últimos 4-5 anos, experimentei uma infinidade de arquiteturas de aplicações Solana, e percebi que já era hora de escrever sobre as descobertas. Começando com a menos complicada e adicionando progressivamente mais complexidade. Então aqui vai: Arquitetura de Aplicação Solana, um tópico.
2) Vamos começar com o modo fácil. Provavelmente, este é o aspeto da sua primeira aplicação Solana. Um frontend simples em react, que estabelece uma conexão com um RPC. Não há necessidade de um servidor API. O RPC é o seu servidor. Nos primeiros dias, estes estavam cheios de getAccountInfos, lógica de construção de tx personalizada, etc. Mais tarde, quando o desempenho começa a sofrer, você adiciona camadas de cache e agrupamento. Entra o getMultipleAccounts. Talvez você também adicione assinaturas websocket + polling para atualizar a interface ao vivo. Esta arquitetura permite protótipos extremamente rápidos. Praticamente não há devops. Custos de servidor negligenciáveis (basta implantar no vercel, etc). No entanto, tem algumas falhas principais.
3) O primeiro problema que você enfrenta são as consultas complexas. Nesta arquitetura, tudo o que você tem é o RPC vanilla do Solana. Isso significa que você precisa tratar o Solana da maneira como um RPC o expõe -- como um banco de dados NoSQL com um problema de atitude. Consultas pontuais não são um problema. Você pode até ser super criativo com PDAs para percorrer os dados do seu programa como se fosse um banco de dados gráfico. Mas assim que você precisa fazer seu primeiro gPA, você está em apuros. A interface não é ergonômica de forma alguma. Se você tiver qualquer tipo de dados de comprimento dinâmico, não poderá usá-los de forma alguma. Dependendo do seu provedor de RPC, pode ser incrivelmente lento. Mesmo sem gPAs, essa abordagem tende a ser muito mais lenta do que seu típico aplicativo web2 com renderização do lado do servidor e um banco de dados normal.
4) O segundo problema que você enfrenta é a portabilidade da lógica de construção de transações. Com esta configuração, toda a lógica para construir transações está (a) no seu código frontend ou (b) em bibliotecas que seu código importa. No caso de (a), qualquer um que queira construir transações fora do seu frontend vai passar por um grande sofrimento (isso inclui você, quando inevitavelmente precisar de mais aplicativo). No caso de (b), quaisquer alterações na lógica de construção de transações exigem publicações de bibliotecas, todos atualizando seus pacotes e, em seguida, atualizações de UI. Confiar fortemente em ferramentas Anchor, como a resolução de contas, pode minimizar a quantidade de lógica que precisa ser portável -- mas o problema persiste. Isso rouba sua agilidade e torna difícil mudar os endpoints de contratos inteligentes enquanto garante que todas as versões da sua lógica de construção de TX continuem funcionando.
5) O terceiro problema que você enfrenta é o fato de que as UIs geralmente são ruins em submeter transações, especialmente com a lógica de reenvio. Um usuário pode navegar para fora da página, a TX para de tentar reenviar. Grandes quantidades de transações tendem a ter dificuldades para serem concluídas. É difícil depurar à distância por que as coisas não estão sendo concluídas.
6) A questão final aqui é que você não é o único com essa arquitetura. Um RPC é valioso, e você basicamente tem que expor sua URL de RPC no seu frontend. Agora, você acaba entrando em um jogo de gato e rato para garantir que ninguém esteja roubando seu RPC e aumentando seus custos.
7) E agora, o que vem a seguir? Normalmente, mesmo que não esteja a abordar a portabilidade de tx, acaba por precisar de lidar com consultas de lista. gPA é péssimo, e todos nós sabemos disso. Portanto, pode construir uma arquitetura híbrida. Nesta arquitetura, mantém a capacidade de prototipar rapidamente, mas empurra as consultas difíceis e feias para uma API. Um bom exemplo concreto disto é a governança -- você tem propostas que estão a ser criadas e que têm um conjunto de etiquetas associadas a elas ("Económico", "Técnico", etc). gPA não consegue filtrar por etiqueta.
8) Esta arquitetura não resolveu a portabilidade das transações, nem as pessoas a puxar o seu RPC. Mas em grande escala, você pode pelo menos resolver o problema de gPAs lentos/impossíveis. Isso introduz um novo problema -- indexadores. Mais sobre isso mais tarde.
9) Finalmente, você tem o que eu chamaria de pilha "enterprise" do Solana. Você não está mais tratando o Solana como um banco de dados NoSQL. Em vez disso, você está tratando-o como um barramento de eventos. O frontend não sabe nada sobre o modelo de dados do Solana. O servidor constrói transações e as passa para a interface do usuário para assinatura, depois as envia para o próprio Solana. Ele trata isso como um evento e espera que ele se propague de volta para os indexadores que mudarão os dados subjacentes. Essa configuração tem uma ótima portabilidade de transações - qualquer um pode acessar sua API com parâmetros limpos e receber de volta transações/instruções. Isso resulta em uma interface do usuário extremamente ágil -- no que diz respeito à interface do usuário, isso é basicamente web2. Você pode aproveitar ao máximo o SSR. O RPC está abstraído -- ninguém pode roubar seus créditos. Mas essa configuração tem seus problemas.
10) O primeiro problema que você encontrará é a dor do indexador. Embora isso tenha sido aliviado nos últimos anos (graças às equipes da Triton, Helius e StreamingFast), eu ainda acabo batendo no nosso indexador com uma chave inglesa regularmente. Você vai perder mensagens. Quando você perde uma mensagem, sua interface de usuário entra em um estado estranho (exemplo: eu te enviei um NFT, na blockchain você o recebeu, meu banco de dados diz que eu ainda o possuo). Esses tipos de problemas são irritantes de depurar. É culpa sua? É do seu provedor de dados? Quem sabe! Aí se vai sua tarde.
11) A próxima questão com que você se deparará é o tempo. Quando você está usando diretamente o RPC para tudo, eles permitem que você passe compromissos e lide com os dados mais recentes. Com um indexador, tudo isso é manual. Isso significa que, ao construir transações, você pode estar construindo-as com base em dados desatualizados. Você retorna uma transação que está condenada ao fracasso. Você pode resolver o problema dos dados desatualizados usando provedores de dados que lhe dão dados extremamente rápidos (ex Helius laser stream). Mas então você precisa lidar manualmente com reorgs. Ou seja, os dados que você indexa precisam ser desindexados se aquela tx não acabar realmente sendo processada. Isso é um pesadelo.
12) Você pode "hackear" problemas de temporização construindo transações apenas com dados do RPC e usando seus dados indexados apenas para alimentar a interface do usuário. Mas então, os usuários ainda terão problemas com potenciais inconsistências entre a interface do usuário e a cadeia. Ou seja, a interface diz que eu possuo este NFT e posso transferi-lo, então o backend grita comigo e diz que não posso.
13) O problema final que você enfrenta com esta configuração é o custo, e se formos melodramáticos, "a morte da descentralização." O sonho do web3 era não ter que implantar toneladas de servidores centralizados. Agora você implantou infraestrutura suficiente para conseguir um emprego de arquiteto principal em uma empresa web2. Custa dinheiro. Custa tempo. E é tudo muito centralizado. Quão descentralizado é o seu protocolo se a melhor maneira de interagir com ele é através de uma API web2? E há cerca de 72 desenvolvedores no solana que saberiam como interagir com ele sem essa API.
14) No final, não vou morrer em nenhuma colina em torno da descentralização. O que é melhor para os usuários tende a ser a melhor escolha. A configuração "enterprise" leva a webapps rápidas e modernas e a uma separação clara de preocupações. Por outro lado, isso adiciona custo de devops e torna você menos ágil. Recomendo que a maioria das startups comece com o método direto para rpc, a menos que você esteja construindo algo que precise explicitamente ser rápido ou ter semânticas de consulta complexas. O tempo para o mercado é fundamental. Você sempre pode contratar um engenheiro de nível médio mais tarde e colocá-lo na masmorra de indexação.
15) Fin. Se algum de vocês encontrou uma configuração melhor, avise-me. Estas são todas as coisas que eu tentei. Estou a gostar bastante de brincar com a configuração empresarial ultimamente.
35,89K