Renaissance Labs

Posted on Feb 14, 2022Read on Mirror.xyz

Solana 众知

Transactions

Fact Sheet

  • Instructions are the most basic operational unit on Solana
  • Each instruction contains:
    • The program_id of the intended program
    • An array of all accounts it intends to read from or write to
    • An instruction_data byte array that is specific to the intended program
  • Multiple instructions can be bundled into a single transaction
  • Each transaction contains:
    • An array of all accounts it intends to read from or write to
    • One or more instructions
    • A recent blockhash
    • One or more signatures
  • Instructions are processed in order and atomically
  • If any part of an instruction fails, the entire transaction fails.
  • Transactions are limited to 1232 bytes

Fees

The Solana network collects two types of fees:

In Solana, transaction fees are deterministic: there is no concept of a fee market in which users can pay higher fees to increase their chances of being included in the next block. At the time of this writing, transaction fees are determined only by the number of signatures required (i.e. lamports_per_signature), not by the amount of resources used. This is because there is currently a hard cap of 1232 bytes on all transactions.

All transactions require at least one writable account to sign the transaction. Once submitted, the writable signer account that is serialized first will be the fee payer. This account will pay for the cost of the transaction regardless of whether the transaction succeeds or fails. If the fee payer does not have a sufficient balance to pay the transaction fee, the transaction will be dropped.

At the time of this writing, 50% of all transaction fees are collected by the validator that produces the block, while the remaining 50% are burned. This structure works to incentivize validators to process as many transactions as possible during their slots in the leader schedule.

Programs

Fact Sheet

  • Programs process instructions from both end users and other programs
  • All programs are stateless: any data they interact with is stored in separate accounts that are passed in via instructions
  • Programs themselves are stored in accounts marked as executable
  • All programs are owned by the BPF Loaderopen in new window and executed by the Solana Runtimeopen in new window
  • Developers most commonly write programs in Rust or C++, but can choose any language that targets the LLVMopen in new window's BPFopen in new window backend
  • All programs have a single entry point where instruction processing takes place (i.e. process_instruction); parameters always include:
    • program_id: pubkey
    • accounts: array,
    • instruction_data: byte array

Acccount

Account Model

There are 3 kinds of accounts on Solana:

  • Data accounts store data
  • Program accounts store executable programs
  • Native accounts that indicate native programs on Solana such as System, Stake, and Vote

Within data accounts, there are 2 types:

  • System owned accounts
  • PDA (Program Derived Address) accounts

Each account has an address (usually a public key) and an owner (address of a program account). The full field list an account stores is found below.

solana

There are a few important ownership rules:

  • Only a data account's owner can modify its data and debit lamports
  • Anyone is allowed to credit lamports to a data account
  • The owner of an account may assign a new owner if the account's data is zeroed out

Program accounts do not store state.

Fact Sheet

  • Accounts are used to store data
  • Each account has a unique address
  • Accounts have a max size of 10mb
  • PDA accounts have a max size of 10kb
  • PDA accounts can be used to sign on behalf of a program
  • Account size is static
  • Account data storage is paid with rent
  • Default account owner is the System Program

关键数据结构

Pubkey实际上就是32个字符表示的base58的Account地址,在Instruction中,我们看到的ProgramId 就是这样的类型,因为Program本身其实是一个文件,也就是Account,只是是可执行的文件。

AccountInfo就是一个Account在链上的表达形式,可以认为是一个文件的属性,想象一下state函数列出的文件属性。其中,key表示文件名,也就是base58的地址。而文件大小可以认为是lamports,这里区别于我们操作系统里面的文件,操作系统里面的文件的大小是可以为0的,且文件存在,而Solana链上的Account如果其大小也就是lamports为0的话,就认为这个文件被删除了。这里的“executable”表示文件是否可执行,如果是可执行的,那么就是一个智能合约账号。而data里面则是文件的内容,类似电脑上的ls列出的文件属性,和cat列出来的文件内容。每个文件都要由一个程序来创建,这个程序称之为这个文件的拥有者,也就是这里的owner。

ProgramResult实际上类型为ProgramError的Result对象,而ProgramError是Solana自定义的一个Error的枚举,也就是Solana抛出来的错误枚举。在合约中,当正常逻辑执行结束后,我们通过Ok()来返回这里Reuslt正确的结果,如果出错了,则通过这里的Result中的ProgramError错误返回。

AccountMeta主要用于Instruction结构的定义,用于协助传递这个指令需要的其他账号信息,其中包括了账号的地址,这个账号是否为签名账号,以及这个账号对应的内容(AccountInfo)是否可以修改。

Instruction在上面已经有介绍了,代表一个处理指令,包含了要处理他的程序的地址program_id,以及这个程序处理时需要用到的AccountMeta表示的账号信息,还有这个指令对应的具体数据payload部分的data。

这里真实的用户协议数据是序列化后,存放在data里面的,所以整体流程是DApp客户端将自定义的指令数据序列化到data里面,然后将账号信息和data发到链上,Solana节点为其找到要执行的程序,并将账号信息和数据data传递给合约程序,合约程序里面将这个data数据反序列化,得到客户端传过来的具体参数。

Reference

https://www.webxlab.net/article/detail/X3wdBaqGAE

Solana