Na Solana, um contrato inteligente é chamado de programa. Um programa é uma conta sem estado que contém código executável. Este código é organizado em funções chamadas instruções. Os utilizadores interagem com um programa enviando uma transação contendo uma ou mais instruções. Uma transação pode incluir instruções de múltiplos programas.
Quando um programa é implantado, a Solana usa LLVM para compilá-lo em formato executável e vinculável (ELF). O ficheiro ELF contém o binário do programa em formato de bytecode Solana (sBPF) e é guardado on-chain numa conta executável.
sBPF é a versão personalizada da Solana do bytecode eBPF.
Escrever programas
A maioria dos programas é escrita em Rust, com duas abordagens de desenvolvimento comuns:
- Anchor: Anchor é um framework concebido para desenvolvimento Solana rápido e fácil. Usa macros Rust para reduzir código repetitivo—sendo ótimo para iniciantes.
- Rust nativo: Escreva programas em Rust sem utilizar quaisquer frameworks. Esta abordagem oferece mais flexibilidade mas vem com maior complexidade.
Atualizar programas
Para
modificar
um programa existente, uma conta deve ser designada como a
autoridade de atualização.
(Normalmente a mesma conta que originalmente
implantou o programa.) Se a autoridade de
atualização for revogada e definida como None, o programa não pode mais ser
atualizado.
Verificar programas
A Solana suporta builds verificáveis, que permitem aos utilizadores verificar se o código on-chain de um programa corresponde ao seu código-fonte público. O framework Anchor fornece suporte integrado para criar um build verificável.
Para verificar se um programa existente está verificado, procure o seu ID de programa no Solana Explorer. Alternativamente, pode usar a Solana Verifiable Build CLI da Ellipsis Labs para verificar independentemente programas on-chain.
Programas integrados
O System Program
O System Program é a única conta que pode criar novas contas. Por padrão, todas as novas contas pertencem ao System Program, embora muitas sejam atribuídas a um novo proprietário após a criação. O System Program executa as seguintes funções principais:
| Função | Descrição |
|---|---|
| Criação de nova conta | Apenas o System Program pode criar novas contas. |
| Alocação de espaço | Define a capacidade em bytes para o campo de dados de cada conta. |
| Atribuir propriedade do programa | Depois que o System Program cria uma conta, pode reatribuir o proprietário do programa designado para uma conta de programa diferente. É assim que programas personalizados assumem a propriedade de novas contas criadas pelo System Program. |
| Transferir SOL | Transfere lamports (SOL) de contas do sistema para outras contas. |
O endereço do System Program é 11111111111111111111111111111111.
Programas de carregamento
Cada programa pertence a outro—o seu carregador. Os carregadores são usados para implementar, reimplementar, atualizar ou fechar programas. Também são usados para finalizar um programa e transferir a autoridade do programa.
Os programas de carregamento são por vezes referidos como 'BPF Loaders'.
Atualmente existem cinco programas de carregamento, conforme mostrado na tabela abaixo.
| Carregador | ID do programa | Notas | Ligação de instruções |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | Possui os outros quatro carregadores | — |
| v1 | BPFLoader1111111111111111111111111111111111 | As instruções de gestão estão desativadas, mas os programas ainda são executados | — |
| v2 | BPFLoader2111111111111111111111111111111111 | As instruções de gestão estão desativadas, mas os programas ainda são executados | Instruções |
| v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Os programas podem ser atualizados após a implementação. O executável do programa é armazenado numa conta de dados de programa separada | Instruções |
| v4 | LoaderV411111111111111111111111111111111111 | Em desenvolvimento (não lançado) | Instruções |
Programas implantados com loader-v3 ou loader-v4 podem ser modificáveis após a implantação, conforme determinado pela sua autoridade de atualização.
Quando um novo programa é implantado, a versão mais recente do loader será usada por padrão.
Programas pré-compilados
Além dos programas loader, a Solana fornece os seguintes programas pré-compilados.
Verificar assinatura ed25519
O programa ed25519 é usado para verificar uma ou mais assinaturas 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 instruction data da instrução contém uma contagem do número de assinaturas a serem verificadas, seguido por um único byte de preenchimento. Depois disso, a seguinte estrutura é serializada, uma para cada assinatura a ser verificada.
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}
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}
Verificar recuperação secp256k1
O programa secp256k1 é usado para verificar operações de recuperação de chave pública 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. O primeiro byte da instrução contém uma contagem do número de chaves públicas a serem verificadas. Depois disso, a seguinte estrutura é criada uma vez para cada chave pública, então serializada e adicionada aos 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}
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 que o usuário especifique 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 verificar multiplicado pelo multiplicador de custo de verificação de assinatura.
O programa secp256r1 é usado para verificar até 8 assinaturas 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 instruction data da instrução é uma contagem do número de assinaturas a serem verificadas, seguido por um único byte de preenchimento. Depois disso, a seguinte estrutura é criada para cada assinatura, então serializada e adicionada aos dados da instrução.
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}
Valores S baixos são aplicados para todas as assinaturas para evitar maleabilidade acidental 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}
Programas principais
Os programas na lista abaixo fornecem a funcionalidade principal da rede.
| Programa | ID do Programa | Descrição | Instruções |
|---|---|---|---|
| System | 11111111111111111111111111111111 | Criar novas contas, alocar dados de conta, atribuir contas a programas proprietários, transferir lamports de contas pertencentes ao Programa do Sistema e pagar taxas de transação | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | Criar e gerenciar contas que rastreiam o estado de votação do validator e recompensas | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | Criar e gerenciar contas que representam stake e recompensas para delegações a validators | StakeInstruction |
| Config | Config1111111111111111111111111111111111111 | Adicionar dados de configuração à cadeia, seguidos pela lista de chaves públicas que têm permissão para modificá-la. Diferentemente de outros programas, o programa Config não define instruções individuais. Ele 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 aos dados armazenados nela | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | Definir limites e preços de unidades de computação para transações, permitindo que os usuários controlem recursos de computação e taxas de priorização | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | Gerenciar 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 | ZkE1Gama1Proof11111111111111111111111111111 | Fornece verificação de prova de conhecimento zero para dados criptografados com ElGamal | — |
Is this page helpful?