Solana开发必备基本概念
Solana 开发者文档中有很多术语和解释,但我们不需要了解所有这些来开始开发。本文将介绍Solana的常见术语和开发涉及的关键数据结构。
一键发币: SOL | BNB | ETH | BASE | Blast | ARB | OP | POLYGON | AVAX | FTM | OK
Solana 开发者文档中有很多术语和解释,但我们不需要了解所有这些来开始开发。 Solana 智能合约也称为链上程序(on-chain program)。 与 EOS 等其他链运行的 WebAssembly 字节码不同,Solana 的可执行文件是 BPF 字节码,它将由 Solana 节点运行时加载并执行。
那么我们如何生成BPF字节码呢? 我们需要可以生成 BPF 字节码的编译器。 通常,LLVM 可以将 C 和 Rust 编译为 BPF 字节码。 由于 Solana 是建立在 Rust 之上的,所以这里我们也使用 Rust 作为示例。
1、基本术语
以下列出Solana模型中常见的基本术语:
- 交易
交易(transaction)用于向 Solana 节点发送请求。 一个交易可能包含多个指令(instruction)。 节点收到交易后,会解析指令,并根据每条指令传递的program_id参数调用相关的链上程序。
- 指令
指令(instruction)是Solana节点执行的最小单元:
Dapp 将序列化的程序参数和账户信息发送到 Solana 节点,Solana 节点找到相关的链上程序并将数据发送给程序,然后程序将其反序列化并使用参数执行命令。
- 帐户
Solana 链上资源包括 RAM、文件、CPU(计算预算)等,与 EOS 的 RAM 和 CPU 不同。 Solana 定义了每个程序可以使用的最大数量,例如堆栈大小(4MB)、CPU 时间(200,000BPF)、栈深度(64)等。因此我们不会看到程序竞争资源。
链上保存的每条信息都是一个文件。在 Solana 中,人们总是对帐户(account)和文件(file)感到困惑,它们实际上是同一件事,就像在 Unix 中一样,一切都是文件。 所以人们需要为文件空间支付SOL。 如果你想关闭一个文件,只需将该文件的所有 SOL 转出即可,因为无需支付该文件的空间费用。
- 运行时
正如我们之前提到的,Solana 运行时(runtime)运行 BPF 字节码,你可能想知道为什么它选择 BPF,而不是 WebAssembly,或者 Lua、python ?
我认为最主要的原因是性能,TPS始终是Solana的第一优先级,而BPF运行时消耗的资源较低。 程序内资源的限制可以在Solana SDK中找到。
pub struct BpfComputeBudget {
/// Number of compute units that an instruction is allowed. Compute units
/// are consumed by program execution, resources they use, etc...
pub max_units: u64,
/// Number of compute units consumed by a log call
pub log_units: u64,
/// Number of compute units consumed by a log_u64 call
pub log_64_units: u64,
/// Number of compute units consumed by a create_program_address call
pub create_program_address_units: u64,
/// Number of compute units consumed by an invoke call (not including the cost incurred by
/// the called program)
pub invoke_units: u64,
/// Maximum cross-program invocation depth allowed including the original caller
pub max_invoke_depth: usize,
/// Base number of compute units consumed to call SHA256
pub sha256_base_cost: u64,
/// Incremental number of units consumed by SHA256 (based on bytes)
pub sha256_byte_cost: u64,
/// Maximum BPF to BPF call depth
pub max_call_depth: usize,
/// Size of a stack frame in bytes, must match the size specified in the LLVM BPF backend
pub stack_frame_size: usize,
/// Number of compute units consumed by logging a `Pubkey`
pub log_pubkey_units: u64,
}
2、关键数据结构
下面列出Solana开发中常见的关键数据结构:
- Pubkey
Pubkey(公钥)代表一个Base58格式的账户地址,同样在指令中ProgramId也是同样的格式,就像我们之前说的链上程序是一个和账户一样的文件,唯一的区别是它是可执行的。
#[repr(transparent)]
#[derive(
Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash, AbiExample,
)]
pub struct Pubkey([u8; 32]);]
- AccountInfo
AccountInfo(账户信息) 是我们在链上存储帐户的方式。 你还可以将这些属性视为文件属性:
/// Account information
#[derive(Clone)]
pub struct AccountInfo<'a> {
/// Public key of the account
pub key: &'a Pubkey,
/// Was the transaction signed by this account's public key?
pub is_signer: bool,
/// Is the account writable?
pub is_writable: bool,
/// The lamports in the account. Modifiable by programs.
pub lamports: Rc<RefCell<&'a mut u64>>,
/// The data held in this account. Modifiable by programs.
pub data: Rc<RefCell<&'a mut [u8]>>,
/// Program that owns this account
pub owner: &'a Pubkey,
/// This account's data contains a loaded program (and is now read-only)
pub executable: bool,
/// The epoch at which this account will next owe rent
pub rent_epoch: Epoch,
}
key是这个文件的id,是一个base58地址;lamports代表文件空间的租金费用,所以lamports不能为0,0表示文件被关闭;is_writable代表这是一个可执行文件(程序)或一个普通帐户;data存储文件的内容,是二进制数据的缓冲区。 每个文件/帐户都是由称为所有者(owner)的程序创建的。
- ProgramResult
ProgramResult(程序结果) 是 ProgramError
类型的结果,它被定义为运行时抛出的错误的枚举。 如果程序运行良好,我们调用 Ok()
来得到正确的结果,如果出现问题,我们返回 ProgramError
:
/// Reasons the program may fail
#[derive(Clone, Debug, Deserialize, Eq, Error, PartialEq, Serialize)]
pub enum ProgramError {
/// Allows on-chain programs to implement program-specific error types and see them returned
/// by the Solana runtime. A program-specific error may be any type that is represented as
/// or serialized to a u32 integer.
#[error("Custom program error: {0:#x}")]
Custom(u32)
...
}use std::{
result::Result as ResultGeneric,
};
pub type ProgramResult = ResultGeneric<(), ProgramError>;
- AccountMeta(账户元数据)
账户元数据(AccountMeta)主要用在指令中,传入账户地址、该账户是否是签名者、内容是否可写等信息。
/// Account metadata used to define Instructions
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct AccountMeta {
/// An account's public key
pub pubkey: Pubkey,
/// True if an Instruction requires a Transaction signature matching `pubkey`.
pub is_signer: bool,
/// True if the `pubkey` can be loaded as a read-write account.
pub is_writable: bool,
}
3、结束语
操作 Solana 程序更像是对文件进行 CRUD 操作。 在下一个教程中,我们将展示一些实现这些操作的常见方法。
原文链接:Solana Development Tutorial: Key Concepts
DefiPlot翻译整理,转载请标明出处