Programas
Na Solana, os "smart contracts" são chamados de programas. Programas são implantados na blockchain em contas que contêm o binário executável compilado do programa. Os usuários interagem com os programas enviando transações contendo instruções que indicam ao programa o que fazer.
Pontos-chave
- Programas são contas contendo código executável, organizados em funções chamadas instruções.
- Embora os programas sejam stateless (sem estado), eles podem incluir instruções que criam e atualizam outras contas para armazenar dados.
- Uma autoridade de atualização pode atualizar programas. Uma vez que essa autoridade é removida, o programa se torna imutável.
- Os usuários podem verificar se os dados de uma conta de programa na blockchain correspondem ao seu código-fonte público através de builds verificáveis.
Escrevendo Programas Solana
Os programas Solana são predominantemente escritos na linguagem de programação Rust, com duas abordagens comuns para desenvolvimento:
-
Anchor: Um framework projetado para o desenvolvimento de programas Solana. Ele oferece uma maneira mais rápida e simples de escrever programas, usando macros Rust para reduzir código repetitivo. Para iniciantes, é recomendado começar com o framework Anchor.
-
Rust Nativo: Esta abordagem envolve escrever programas Solana em Rust sem utilizar frameworks. Oferece mais flexibilidade mas vem com maior complexidade.
Atualizando Programas Solana
Para saber mais sobre a implantação e atualização de programas, consulte a página implantando programas.
Os programas podem ser diretamente modificados por uma conta designada como "autoridade de atualização", que é tipicamente a conta que originalmente implantou o programa. Se a autoridade de atualização for revogada e definida como null, o programa se torna imutável e não pode mais ser atualizado.
Programas Verificáveis
As compilações verificáveis permitem que qualquer pessoa verifique se o código on-chain de um programa corresponde ao seu código-fonte público, tornando possível detectar discrepâncias entre as versões de origem e as implantadas.
A comunidade de desenvolvedores da Solana introduziu ferramentas para suportar compilações verificáveis, permitindo que tanto desenvolvedores quanto usuários verifiquem se os programas on-chain refletem com precisão o código-fonte compartilhado publicamente.
-
Pesquisando por Programas Verificados: Para verificar rapidamente programas verificados, os usuários podem pesquisar por um endereço de programa no Solana Explorer. Veja um exemplo de um programa verificado aqui.
-
Ferramentas de Verificação: O Solana Verifiable Build CLI da Ellipsis Labs permite que os usuários verifiquem independentemente programas on-chain em relação ao código-fonte publicado.
-
Suporte para Compilações Verificáveis no Anchor: O Anchor fornece suporte integrado para compilações verificáveis. Detalhes podem ser encontrados na documentação do Anchor.
Berkeley Packet Filter (BPF)
A Solana usa LLVM (Low Level Virtual Machine) para compilar programas em arquivos ELF (Executable and Linkable Format). Esses arquivos contêm a versão personalizada da Solana do bytecode eBPF, chamado "Solana Bytecode Format" (sBPF). O arquivo ELF contém o binário do programa e é armazenado on-chain em uma conta executável quando o programa é implantado.
Programas Integrados
Programas Carregadores
Cada programa é propriedade de outro programa, que é seu carregador. Atualmente, existem cinco programas carregadores:
Carregador | ID do Programa | Notas | Link de Instruções |
---|---|---|---|
native | NativeLoader1111111111111111111111111111111 | Possui os outros quatro carregadores | — |
v1 | BPFLoader1111111111111111111111111111111111 | Instruções de gerenciamento estão desativadas, mas os programas ainda executam | — |
v2 | BPFLoader2111111111111111111111111111111111 | Instruções de gerenciamento estão desativadas, mas os programas ainda executam | Instruções |
v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Está sendo descontinuado | Instruções |
v4 | LoaderV411111111111111111111111111111111111 | Espera-se que o v4 se torne o carregador padrão | Instruções |
Estes loaders são necessários para criar e gerenciar programas personalizados:
- Implantar um novo programa ou buffer
- Fechar um programa ou buffer
- Reimplantar / atualizar um programa existente
- Transferir a autoridade sobre um programa
- Finalizar um programa
Loader-v3 e loader-v4 suportam modificações em programas após sua implantação inicial. A permissão para isso é regulada pela autoridade de um programa porque a propriedade da conta de cada programa reside com o loader.
Programas pré-compilados
Programa Ed25519
Programa | ID do Programa | Descrição | Instruções |
---|---|---|---|
Programa Ed25519 | Ed25519SigVerify111111111111111111111111111 | Verifica assinaturas ed25519. Se alguma assinatura falhar, um erro é retornado. | Instruções |
O programa ed25519 processa uma instrução. O primeiro u8
é uma contagem do
número de assinaturas a verificar, seguido por um único byte de preenchimento.
Depois disso, a seguinte estrutura é serializada, uma para cada assinatura a
verificar.
struct Ed25519SignatureOffsets {signature_offset: u16, // offset to ed25519 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to public key of 32 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
O pseudocódigo da verificação de assinatura:
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionsinstruction_index = ed25519_signature_instruction_index != u16::MAX ? ed25519_signature_instruction_index : current_instruction;signature = instructions[instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]instruction_index = ed25519_pubkey_instruction_index != u16::MAX ? ed25519_pubkey_instruction_index : current_instruction;pubkey = instructions[instruction_index].data[ed25519_pubkey_offset..ed25519_pubkey_offset + 32]instruction_index = ed25519_message_instruction_index != u16::MAX ? ed25519_message_instruction_index : current_instruction;message = instructions[instruction_index].data[ed25519_message_data_offset..ed25519_message_data_offset + ed25519_message_data_size]if pubkey.verify(signature, message) != Success {return Error}}return Success}
Programa Secp256k1
Programa | ID do Programa | Descrição | Instruções |
---|---|---|---|
Programa Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Verifica operações de recuperação de chave pública secp256k1 (ecrecover). | Instruções |
O programa secp256k1 processa uma instrução que recebe como primeiro byte uma contagem da seguinte estrutura serializada nos dados da instrução:
struct Secp256k1SignatureOffsets {secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytessecp_signature_instruction_index: u8, // instruction index to find signaturesecp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytessecp_pubkey_instruction_index: u8, // instruction index to find pubkeysecp_message_data_offset: u16, // offset to start of message datasecp_message_data_size: u16, // size of message datasecp_message_instruction_index: u8, // instruction index to find message data}
O pseudocódigo da verificação de recuperação:
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionssignature = instructions[secp_signature_instruction_index].data[secp_signature_offset..secp_signature_offset + 64]recovery_id = instructions[secp_signature_instruction_index].data[secp_signature_offset + 64]ref_eth_pubkey = instructions[secp_pubkey_instruction_index].data[secp_pubkey_offset..secp_pubkey_offset + 20]message_hash = keccak256(instructions[secp_message_instruction_index].data[secp_message_data_offset..secp_message_data_offset + secp_message_data_size])pubkey = ecrecover(signature, recovery_id, message_hash)eth_pubkey = keccak256(pubkey[1..])[12..]if eth_pubkey != ref_eth_pubkey {return Error}}return Success}
Isso permite ao usuário especificar quaisquer dados de instrução na transação para dados de assinatura e mensagem. Ao especificar uma sysvar de instruções especial, também é possível receber dados da própria transação.
O custo da transação contará o número de assinaturas a serem verificadas multiplicado pelo multiplicador de custo de verificação de assinatura.
Programa Secp256r1
Programa | ID do Programa | Descrição | Instruções |
---|---|---|---|
Programa Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Verifica até 8 assinaturas secp256r1. Recebe uma assinatura, chave pública e mensagem. Retorna erro se alguma falhar. | Instruções |
O programa secp256r1 processa uma instrução. O primeiro u8
é uma contagem do
número de assinaturas a verificar, seguido por um único byte de preenchimento.
Depois disso, a seguinte estrutura é serializada, uma para cada assinatura a
verificar:
struct Secp256r1SignatureOffsets {signature_offset: u16, // offset to compact secp256r1 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to compressed public key of 33 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
O pseudocódigo da verificação de assinatura:
process_instruction() {if data.len() < SIGNATURE_OFFSETS_START {return Error}num_signatures = data[0] as usizeif num_signatures == 0 || num_signatures > 8 {return Error}expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_STARTif data.len() < expected_data_size {return Error}for i in 0..num_signatures {offsets = parse_signature_offsets(data, i)signature = get_data_slice(data, instruction_datas, offsets.signature_instruction_index, offsets.signature_offset, SIGNATURE_SERIALIZED_SIZE)if s > half_curve_order {return Error}pubkey = get_data_slice(data, instruction_datas, offsets.public_key_instruction_index, offsets.public_key_offset, COMPRESSED_PUBKEY_SERIALIZED_SIZE)message = get_data_slice(data, instruction_datas, offsets.message_instruction_index, offsets.message_data_offset, offsets.message_data_size)if !verify_signature(signature, pubkey, message) {return Error}}return Success}
Nota: Valores S baixos são aplicados para todas as assinaturas para evitar maleabilidade acidental de assinatura.
Programas Principais
O genesis do cluster Solana inclui uma lista de programas especiais que fornecem funcionalidades principais para a rede. Historicamente, estes eram referidos como programas "nativos" e costumavam ser distribuídos junto com o código do validator.
Programa | ID do Programa | Descrição | Instruções |
---|---|---|---|
System Program | 11111111111111111111111111111111 | Cria novas contas, aloca dados de conta, atribui contas a programas proprietários, transfere lamports de contas pertencentes ao System Program e paga taxas de transação. | SystemInstruction |
Vote Program | Vote111111111111111111111111111111111111111 | Cria e gerencia contas que rastreiam o estado de votação do validator e recompensas. | VoteInstruction |
Stake Program | Stake11111111111111111111111111111111111111 | Cria e gerencia contas que representam stake e recompensas para delegações a validators. | StakeInstruction |
Config Program | Config1111111111111111111111111111111111111 | Adiciona dados de configuração à cadeia, seguidos pela lista de chaves públicas que têm permissão para modificá-los. Diferentemente de outros programas, o Config Program não define instruções individuais. Tem apenas uma instrução implícita: "store". Seus dados de instrução são um conjunto de chaves que controlam o acesso à conta e os dados a serem armazenados nela. | ConfigInstruction |
Compute Budget Program | ComputeBudget111111111111111111111111111111 | Define limites e preços de unidades de computação para transações, permitindo que os usuários controlem recursos computacionais e taxas de priorização. | ComputeBudgetInstruction |
Address Lookup Table Program | AddressLookupTab1e1111111111111111111111111 | Gerencia tabelas de consulta de endereços, que permitem que as transações referenciem mais contas do que normalmente caberia na lista de contas da transação. | ProgramInstruction |
ZK ElGamal Proof Program | ZkE1Gama1Proof11111111111111111111111111111 | Fornece verificação de prova de conhecimento zero para dados criptografados com ElGamal. | — |
Is this page helpful?