学习 Solana

最近在学习 Solana,Solana 是一个 TPS ~3000 的高性能区块链,对比 Ethereum 这种 TPS ~200 的链,加上其低廉的矿工费,属于公链中比较强势的。

相对于 Ethereum 的 ECDSA 算法,Solana 采用的是 Ed25519 算法,账户地址是 Ed25519 的公钥的 base58 编码。Solana 每个 Account 都有他的 Owner,Owner 和 Holder 是不同的,比如一个 Data Account 他的 Owner 是一个 Program Account,但是他的 Holder 是地址对应的私钥,只有 Owner 有权限操作 Account。

我在 devnet 测试时就遇到过这样一个问题,随便填充的一个私钥对应的地址是一个 PDA,我尝试使用 system_instruction::transfer 转出地址上的 SOL 时失败了,因为我只是 Holder 而 Owner 是一个 Program Account,这里有个相关问题。

Raw Transaction 解析

Solana Transaction: 提交到 pushTansaction RPC 接口的 base64 解码后的 16 进制分割
  |- Signature 部分
       |- Length: 有多少个签名,长度为 1 个 byte
       |- SignatueN: N 个长度为 64 位的 Ed25519 签名
  |- Message 部分(签名部分是对整个 Message 部分的签名)
       |- Message Header: 长度为 3 个 byte
            |- 有签名的 Account 数量: 1 个 byte
            |- 有签名的只读 Account 数量: 1 个 byte
            |- 无签名的只读 Account 数量: 1 个 byte
       |- Account Addresses
            |- Length: 本交易内涉及多少个账户,长度为 1 个 byte
            |- AddressN: N 个长度为 32 位的钱包地址(Ed25519 公钥)或 ProgramID
       |- Recent Blockhash: 近期的 Blockhash,如果 Block 过老节点会拒绝此交易
       |- Instructions
            |- Length: 本交易内有多少个 Instruction,长度为 1 个 byte
            |- InstructionN: N 个长度不确定的指令,通过对应字段长度逐字节读入
                  |- Program ID Index: Program ID 在 Account Addresses 中的位置,长度为 1 个 byte
                  |- Account Address Indexes: 本指令涉及的地址索引
                        |- Length: 有多少个地址索引,长度为 1 个 byte
                        |- IndexN: Address 在 Account Addresses 中的位置,长度为 1 个 byte
                  |- Instruction Data 不定长的调用数据
                        |- Length: 调用数据长度,长度为 1 个 byte
                        |- Data: bincode 编码的调用 Program 用的数据

我制作了一个 Solana 交易解析工具,把 base64/hex 的 raw transaction data 粘贴进去即可解析出上述结构。

Transaction Fee 由 Account Addresses 列表中的第一个地址支付。

智能合约

一般使用 Anchor 进行开发,Solana Playground 就很够用了,solana airdrop 5 -> build -> deploy -> run 非常丝滑,如果左下角一个默认生成的钱包地址不够用,可以在 client 的 typescript 脚本里面自己再生成一些钱包。

const another_wallet = web3.Keypair.fromSeed(Uint8Array.from(Array<number>(32).fill(112)));

奶爸只是做了些 Tutorials,测试了下账户读写权限看了看交易结构,后面有过深度使用后再继续分享。

常见问题

与 EVM 系链相比,Solana 有哪些独特的地方?

  • Solana 账户没有 Nonce,同区块内不同的交易根据地址列表读写情况并行执行,交易内的 Instructions 原子化执行。
  • 同一个区块内的交易通常是先到先服务设置优先费用可以使交易优先排序
  • Solana 没有类似 Solidity 合约中的 Event,只有一个 msg! 可以打印一些字符串,这里是相关 Issue
  • Solana 一般不在合约中校验类似 eth_personalSigneth_signTypedData 消息签名,而是通过交易的 Signer 来校验权限
  • 节点没有提供类似 EVM 节点 debug_ NS,无法追踪交易到每一步调用的输入输出

Comments