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:

CarregadorID do ProgramaNotasLink de Instruções
nativeNativeLoader1111111111111111111111111111111Possui os outros quatro carregadores
v1BPFLoader1111111111111111111111111111111111Instruções de gerenciamento estão desativadas, mas os programas ainda executam
v2BPFLoader2111111111111111111111111111111111Instruções de gerenciamento estão desativadas, mas os programas ainda executamInstruções
v3BPFLoaderUpgradeab1e11111111111111111111111Está sendo descontinuadoInstruções
v4LoaderV411111111111111111111111111111111111Espera-se que o v4 se torne o carregador padrãoInstruçõ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

ProgramaID do ProgramaDescriçãoInstruções
Programa Ed25519Ed25519SigVerify111111111111111111111111111Verifica 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.

Ed25519SignatureOffsets
struct Ed25519SignatureOffsets {
signature_offset: u16, // offset to ed25519 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to public key of 32 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_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().instructions
instruction_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

ProgramaID do ProgramaDescriçãoInstruções
Programa Secp256k1KeccakSecp256k11111111111111111111111111111Verifica 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:

Secp256k1SignatureOffsets
struct Secp256k1SignatureOffsets {
secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytes
secp_signature_instruction_index: u8, // instruction index to find signature
secp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytes
secp_pubkey_instruction_index: u8, // instruction index to find pubkey
secp_message_data_offset: u16, // offset to start of message data
secp_message_data_size: u16, // size of message data
secp_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().instructions
signature = 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

ProgramaID do ProgramaDescriçãoInstruções
Programa Secp256r1Secp256r1SigVerify1111111111111111111111111Verifica 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:

Secp256r1SignatureOffsets
struct Secp256r1SignatureOffsets {
signature_offset: u16, // offset to compact secp256r1 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to compressed public key of 33 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_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 usize
if num_signatures == 0 || num_signatures > 8 {
return Error
}
expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START
if 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.

ProgramaID do ProgramaDescriçãoInstruções
System Program11111111111111111111111111111111Cria 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 ProgramVote111111111111111111111111111111111111111Cria e gerencia contas que rastreiam o estado de votação do validator e recompensas.VoteInstruction
Stake ProgramStake11111111111111111111111111111111111111Cria e gerencia contas que representam stake e recompensas para delegações a validators.StakeInstruction
Config ProgramConfig1111111111111111111111111111111111111Adiciona 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 ProgramComputeBudget111111111111111111111111111111Define 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 ProgramAddressLookupTab1e1111111111111111111111111Gerencia 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 ProgramZkE1Gama1Proof11111111111111111111111111111Fornece verificação de prova de conhecimento zero para dados criptografados com ElGamal.

Is this page helpful?

Índice

Editar Página