Programas
En Solana, un contrato inteligente se llama programa. Un programa es una cuenta sin estado que contiene código ejecutable. Este código está organizado en funciones llamadas instrucciones. Los usuarios interactúan con un programa enviando una transacción que contiene una o más instrucciones. Una transacción puede incluir instrucciones de múltiples programas.
Cuando se despliega un programa, Solana utiliza LLVM para compilarlo en formato ejecutable y enlazable (ELF). El archivo ELF contiene el binario del programa en Formato de Bytecode de Solana (sBPF) y se guarda en la cadena en una cuenta ejecutable.
sBPF es la versión personalizada de Solana del bytecode eBPF.
Escribir programas
La mayoría de los programas están escritos en Rust, con dos enfoques comunes de desarrollo:
- Anchor: Anchor es un framework diseñado para el desarrollo rápido y fácil en Solana. Utiliza macros de Rust para reducir el código repetitivo, lo que lo hace ideal para principiantes.
- Rust nativo: Escribir programas en Rust sin utilizar ningún framework. Este enfoque ofrece más flexibilidad pero conlleva mayor complejidad.
Actualizar programas
Para modificar un programa existente, una cuenta debe ser designada como la autoridad de actualización. (Típicamente la misma cuenta que originalmente desplegó el programa.) Si la autoridad de actualización es revocada y establecida como null, el programa ya no podrá ser actualizado.
Verificar programas
Solana admite compilaciones verificables, que permiten a los usuarios comprobar si el código en cadena de un programa coincide con su código fuente público. El framework Anchor proporciona soporte integrado para crear una compilación verificable.
Para comprobar si un programa existente está verificado, busca su ID de programa en el Explorador de Solana. Alternativamente, puedes usar la CLI de Compilación Verificable de Solana de Ellipsis Labs, para verificar de forma independiente los programas en cadena.
Programas integrados
El System Program
El System Program es la única cuenta que puede crear nuevas cuentas. Por defecto, todas las nuevas cuentas son propiedad del System Program, aunque muchas son asignadas a un nuevo propietario al momento de su creación. El System Program realiza las siguientes funciones clave:
| Función | Descripción |
|---|---|
| Creación de nuevas cuentas | Solo el System Program puede crear nuevas cuentas. |
| Asignación de espacio | Establece la capacidad en bytes para el campo de datos de cada cuenta. |
| Asignación de propiedad de programa | Una vez que el System Program crea una cuenta, puede reasignar el propietario del programa designado a una cuenta de programa diferente. Así es como los programas personalizados toman posesión de las nuevas cuentas creadas por el System Program. |
| Transferencia de SOL | Transfiere lamports (SOL) desde cuentas del Sistema a otras cuentas. |
La dirección del System Program es 11111111111111111111111111111111.
Programas cargadores
Cada programa es propiedad de otro—su cargador. Los cargadores se utilizan para desplegar, redesplegar, actualizar o cerrar programas. También se utilizan para finalizar un programa y transferir la autoridad del programa.
Actualmente existen cinco programas cargadores, como se muestra en la tabla a continuación.
| Cargador | ID del programa | Notas | Enlace a instrucciones |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | Es propietario de los otros cuatro cargadores | — |
| v1 | BPFLoader1111111111111111111111111111111111 | Las instrucciones de gestión están deshabilitadas, pero los programas siguen ejecutándose | — |
| v2 | BPFLoader2111111111111111111111111111111111 | Las instrucciones de gestión están deshabilitadas, pero los programas siguen ejecutándose | Instrucciones |
| v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Los programas pueden actualizarse después del despliegue. El ejecutable del programa se almacena en una cuenta de datos de programa separada | Instrucciones |
| v4 | LoaderV411111111111111111111111111111111111 | En desarrollo (no publicado) | Instrucciones |
Los programas desplegados con loader-v3 o loader-v4 pueden ser modificables después de su despliegue, según lo determine su autoridad de actualización.
Cuando se despliega un nuevo programa, se utilizará la última versión del cargador por defecto.
Programas precompilados
Además de los programas cargadores, Solana proporciona los siguientes programas precompilados.
Verificar firma ed25519
El programa ed25519 se utiliza para verificar una o más firmas ed25519.
| Programa | ID del programa | Descripción | Instrucciones |
|---|---|---|---|
| Programa Ed25519 | Ed25519SigVerify111111111111111111111111111 | Verifica firmas ed25519. Si alguna firma falla, se devuelve un error. | Instrucciones |
El programa ed25519 procesa una instrucción. El primer u8 de la instrucción
contiene un contador del número de firmas a verificar, seguido de un solo byte
de relleno. Después de eso, se serializa la siguiente estructura, una para cada
firma 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}
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 recuperación secp256k1
El programa secp256k1 se utiliza para verificar operaciones de recuperación de clave pública secp256k1.
| Programa | ID del programa | Descripción | Instrucciones |
|---|---|---|---|
| Programa Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Verifica operaciones de recuperación de clave pública secp256k1 (ecrecover). | Instrucciones |
El programa secp256k1 procesa una instrucción. El primer byte de la instrucción contiene un contador del número de claves públicas a verificar. Después de eso, se crea la siguiente estructura una vez para cada clave pública, luego se serializa y se añade a los datos de instrucción.
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}
Esto permite al usuario especificar cualquier dato de instrucción en la transacción para datos de firma y mensaje. Al especificar una sysvar de instrucciones especial, también se puede recibir datos de la transacción misma.
El costo de la transacción contará el número de firmas a verificar multiplicado por el multiplicador de costo de verificación de firma.
El programa secp256r1 se utiliza para verificar hasta 8 firmas secp256r1.
| Programa | ID del programa | Descripción | Instrucciones |
|---|---|---|---|
| Programa Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Verifica hasta 8 firmas secp256r1. Toma una firma, clave pública y mensaje. Devuelve error si alguna falla. | Instrucciones |
El programa secp256r1 procesa una instrucción. El primer instruction data de la instrucción es un recuento del número de firmas a verificar, seguido de un byte de relleno. Después de eso, se crea la siguiente estructura para cada firma, luego se serializa y se agrega a los datos de instrucción.
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}
Se imponen valores S bajos para todas las firmas para evitar la maleabilidad accidental de la firma.
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 principales
Los programas en la lista a continuación proporcionan la funcionalidad central de la red.
| Programa | ID del programa | Descripción | Instrucciones |
|---|---|---|---|
| System | 11111111111111111111111111111111 | Crear nuevas cuentas, asignar datos de cuenta, asignar cuentas a programas propietarios, transferir lamports desde cuentas propiedad del Programa System y pagar tarifas de transacción | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | Crear y gestionar cuentas que rastrean el estado de votación del validator y las recompensas | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | Crear y gestionar cuentas que representan stake y recompensas para delegaciones a validators | StakeInstruction |
| Config | Config1111111111111111111111111111111111111 | Agregar datos de configuración a la cadena, seguidos de la lista de claves públicas que pueden modificarla. A diferencia de otros programas, el programa Config no define instrucciones individuales. Tiene solo una instrucción implícita: "store". Sus datos de instrucción son un conjunto de claves que controlan el acceso a la cuenta y los datos almacenados en ella | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | Establecer límites y precios de unidades de cómputo para transacciones, permitiendo a los usuarios controlar recursos de cómputo y tarifas de priorización | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | Gestionar tablas de búsqueda de direcciones, que permiten a las transacciones hacer referencia a más cuentas de las que cabrían en la lista de cuentas de la transacción | ProgramInstruction |
| ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | Proporciona verificación de prueba de conocimiento cero para datos cifrados con ElGamal | — |
Is this page helpful?