本文撰写于2025年02月11日15时21分55秒,恰逢去年年底部署了几个合约,遂将其中若干错误之处一并删除,如有问题请在评论区留言
学习完以太坊基础知识和比特币白皮书后接着来学习 Solana,官方文档 https://solana.com/zh/docs?locale=docs
关于 Solana 所采用的加密算法,在 Solana 中采用了 Ed25519 curve 非对称加密算法,用于生成数字签名和验证数字签名。与对称加密算法不同,非对称加密使用一对密钥:pubkey 公钥与 secretkey 私钥,如果使用公钥加密,则只有对应的私钥能够进行解密;如果使用私钥加密,则可以使用对应的公钥验证签名,即判断该签名是否由私钥的持有者发起。
Solana 使用 Rust 语言进行开发。若您此前未接触过 Rust,建议先花些时间阅读相关资料。以下是我整理的一些 Rust 教程:
Introduction
Solana 的高性能网络是其突出的亮点之一。为实现高吞吐量,Solana 采用了许多独特的技术,其中最为关键的是时间戳技术——Proof of History(PoH)。PoH 是 Solana 的一项创新,它把时间序列作为区块链的一部分,允许节点在无需全网同步的情况下验证交易的顺序,从而大幅提升了系统的处理效率。Solana 的区块链与其他区块链不同,它采用了”单链架构”,这一点有别于以太坊和比特币的多链架构。Solana 的设计允许其在单个区块内处理大量交易,且无需链间通信或合并,因此可以达到每秒数万笔交易的吞吐量。Solana 同样支持智能合约与去中心化应用(DApps),但与以太坊相比,其智能合约运行更加高效、成本更低。Solana 的智能合约使用 Rust 或者 C 语言编写,而不是以太坊上的 Solidity 语言,这给开发者带来了一些新的挑战,但也提供了更大的灵活性和更强的性能。
Solana 白皮书:https://solana.com/solana-whitepaper.pdf
关于 Solana 的网络
Solana 的网络环境分为开发网、测试网、主网三类:开发网供 Solana 节点开发使用,更新频繁;测试网主要面向 DApp 开发者,相对稳定
- DevNet: https://api.devnet.solana.com
- TestNet: https://api.testnet.solana.com
- MainNet: https://api.mainnet-beta.solana.com
Develop Environment
首先安装 Rust 环境
1 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y |
接着下载 Solana 的 CLI
1 | sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)" |
下载完成后,程序会提示配置环境变量,按提示配置即可
1 | ❯ sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)" |
接着输入 solana --version 查看版本
以下列举几条常用命令
- 配置网络
1 | solana config set --url https://api.mainnet-beta.solana.com # 主网 |
- 创建钱包
1 | ❯ solana-keygen new --outfile ~/wallet_test.json # 保管好 |
此处生成的助记词即对应 BIP39 标准
https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
- 查看账户信息,首次创建可通过水龙头领取测试代币 https://faucet.solana.com/
1 | ❯ solana-keygen pubkey # 看看你的 |
此处关联 GitHub 账号即可领取一定数量的测试网 SOL

只可惜这些并非真金白银。

也可以通过以下命令获取
1 | solana airdrop |
- 转账
1 | solana transfer <destination-public-key> <amount> --from ~/my-wallet.json |
- 创建代币账户(用于接收和持有 SPL Token 的新账户)
1 | solana spl-token create-account <mint-address> |
- 获取区块链的最新区块信息
1 | solana block |
- 部署智能合约
1 | solana program deploy <path-to-your-program> |
- 更新 Solana
1 | solana update |
需求一:假设手中有两个钱包需要互相转账,可以使用以下命令
1 | ❯ solana config set --keypair ~/wallet_a.json |
需求二:由 B 钱包向 A 钱包转账
1 | ❯ solana address |
该笔交易的详细信息可在开发网上查看

Solana Concept
账户模型
结构体
1 | pub struct Account { |
该结构体涉及的字段较多,详见官方文档
Solana RPC
关于 RPC 的详细介绍此处不再展开。简言之,在 Solana 中,RPC(Remote Procedure Call) 是与 Solana 区块链进行交互的核心方式,RPC 接口允许开发者通过调用预定义的 API 来获取区块链上的数据、提交交易或执行其他操作,Solana 的 RPC API 提供了高效的接口,能够支持快速读取链上数据及执行交易
本节开头已作介绍,以下给出几条通过 CURL 调用的命令
- getAccountInfo,查询账户信息,包括账户余额、持有的代币等
1 | ❯ curl -X POST https://api.devnet.solana.com \ |
- getBalance,获取指定账户的 SOL 余额
1 | curl -X POST https://api.devnet.solana.com \ |
详见
Solana Hello World
此处直接以官方 Hello World 项目为例
较为基础的环境搭建此处不再说明。先将 URL 设置为 localhost 集群,然后启动
1 | solana config set --url localhost |

此处可通过发送交易进行测试
1 | curl -X POST http://127.0.0.1:8899 \ |
此处引入 Web3.js,其具体用途不再赘述:npm install --save @solana/web3.js@1
构建项目
1 | npm run build:program-rust |
启动客户端
1 | npm run start |
代码解析,lib.rs 用于验证账户被调用的次数
1 | // lib.rs |
若您认为上述步骤较为繁琐,可以使用 Solana Playground 在线编译:https://beta.solpg.io/。结合上面的程序,可以归纳出 Solana 程序的大致逻辑:首先用到了 solana_program 标准库,并将下列代码纳入作用域
1 | use solana_program::{ |
AccountInfo:account_info 模块中的一个结构体,允许我们访问帐户信息。
entrypoint:声明程序入口点的宏,类似于 Rust 中的 main 函数。
ProgramResult:entrypoint 模块中的返回值类型。
Pubkey:pubkey 模块中的一个结构体,允许我们将地址作为公钥访问。
msg:一个允许我们将消息打印到程序日志的宏,类似于 Rust 中的 println宏。
Solana 的入口点由 entrypoint! 宏声明,相应地可以这样声明一个入口点
1 | entrypoint!(process_instruction_one); |
通常编写一个累加程序都需要定义一个变量来存储 cnt,而 Solana 定义了 Account 数据账户用于存储数据,具体可以参看开发文档(链接见上)
1 | /// 定义数据账户的结构 |
随后通过 \#[derive(BorshSerialize, BorshDeserialize, Debug)] 这两个派生宏实现序列化与反序列化

此处的 CounterAccount 结构体对应数据账户,只能由 Owner 所有者修改。总体流程如下:
先创建一个 AccountInfo 迭代器,用于遍历 accounts 数组。
1 | let accounts_iter = &mut accounts.iter(); |
然后从迭代器中获取下一个账户信息,即存储计数器的数据账户
1 | let account = next_account_info(accounts_iter)?; |
接着加载数据账户数据
1 | let mut counter_account = CounterAccount::try_from_slice(&account.data.borrow())?; |
从数据账户的 data 字段中反序列化出 CounterAccount 结构体。try_from_slice 方法会将字节数组转换为 CounterAccount 结构体,随后执行 +=1 并写回账户
1 | counter_account.serialize(&mut &mut account.data.borrow_mut()[..])?; |
其余示例可参见官方文档,此处不再重复
Anchor
Anchor 是 Solana Sealevel 运行时的框架,为编写智能合约提供了若干便利的开发工具。
Rust eDSL 用于编写 Solana 程序
IDL 规范
用于从 IDL 生成客户端的 TypeScript 包
用于开发完整应用程序的 CLI 和工作区管理
机翻自 Github https://github.com/coral-xyz/anchor,官方文档:https://www.anchor-lang.com/docs/installation
安装
1 | cargo install --git https://github.com/coral-xyz/anchor avm --force |
创建项目 https://www.anchor-lang.com/docs/references/cli#init
1 | anchor init anchor_solana_test |
构建智能合约后,会在 target/deploy 目录下生成一个二进制文件
1 | anchor build [anchor_solana_test] |
测试程序
1 | anchor test |
部署程序
1 | anchor deploy --env devnet # 部署到测试网加个 --env 就行了 |
Anchor 同样提供了大量宏,可查阅文档。此处补一份项目结构(基于 Playground)

还是 DevOps 更为便捷。
Solana NFT
- 数量单独设定,一旦超过便无法继续铸造
使用 Anchor 脚手架进行配置
1 | use anchor_spl::{ |
铸造调用为 mint_to(cpi_context, 1)?;,此处补充一张图

Release
切换网络
1 | solana config set --url devnet |
构建项目
1 | anchor init icecliffs_nft |
导入依赖
1 | [package] |
源代码
1 | /// lib.rs |
部署程序
1 | anchor build && anchor deploy |
交互环节
1 | import * as anchor from "@coral-xyz/anchor"; |
铸造 NFT
1 | anchor test |
查看 NFT
1 | minted nft |