1,Solana智能合约不存储任何状态信息(因为每一个智能合约都会在用户地址上产生一个合约账户),所有的数据都是存储在用户地址上的合约账户里面。这是Etherscan智能合约和Solana智能合约的最大区别
10,PDA地址是使用预定义种子(比如一串字符串),凹凸种子(从255到0),ProgramId(所属合约地址)生成的一个没有私钥的地址,在合约里面使用PDA地址调用另一个合约需要传PDA地址的种子签名(代码示例)
11,如果想使用PDA地址创建数据账户,只能在合约里面创建(示例代码),不能在前端直接创建因为它没有私钥不能签名。
二、安装Solana客户端,官方文档
$ export http_proxy=http://127.0.0.1:58591/
$ export https_proxy=http://127.0.0.1:58591/
# 注意:执行这个脚本可能需要代理(默认安装路径:~/.local/share/solana/install/)
$ sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
# 验证Solana客户端是否安装成功(注意:建议使用1.18.18及以上版本,如果非这个版本,建议使用命令 solana-install init 1.18.18 安装)
$ solana --version
# 更新Solana客户端(注意:这个命令可能需要代理)
$ solana-install update
# 安装或使用指定版本Solana客户端(注意:这个命令可能需要代理,建议使用1.18.18及以上的版本)
$ solana-install init 1.18.18
# 查看已安装的Solana客户端
$ solana-install list
# 创建代币(注意:spl-token命令是安装好Solana客户端后就会有)
# --decimals 指定精度为12,
# --program-id 指定Solana代币标准程序ID创建代币(注意:这里使用的是Token-2022 Program ID也是当前最新的)
# --enable-metadata 开启元数据(后面可以指定代币的一些信息数据,比如名称等等)
$ spl-token create-token --decimals 12 --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb --enable-metadata
# 代币地址 # 代币程序地址(就是代币Program Id)
Creating token 8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT under program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
# 代币地址(注意:代币地址存储所有代币数据,该数据所有权就是代币创建者)
Address: 8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT
Decimals: 12
# 交易签名也是交易Hash
Signature: 3yc6xVVWZBoVZuqucbmSWKj87QwXtk1YhwkKRpqv2xhu53Vyodwy25t7EjFJxZJmcVRbEBHDBH3kejCsSSBryBSm
# 为上面刚刚创建的代币初始化元数据(就是设置代币名称,简称,代币网址URL)
# 注意:8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT 是代币地址
$ spl-token initialize-metadata 8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT "TokenName" "TokenSymbol" "https://spl.solana.com/token-2022"
# 查询代币分配总量
$ spl-token supply 8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT
# 创建代币持有账户(因为Solana地址本身不能持有ERC20代币,只能创建代币持有账户持有代币,然后我拥有代币持有账户的所有权)
# --fee-payer 指定交易签名地址密钥对文件
# --owner 指定代币持有账户的所有者地址
# 第一个参数是代币地址
$ spl-token create-account 8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT --fee-payer ~/.config/solana/id.json --owner CokWw92izG3TrnkZJK3RujGwnUKq1i29pzL4shpUpVaE
# 代币持有账户地址
Creating account 4GLLKhsTCkm7roqFiTEm5fg4LDrjBZmgyT94cJ6kAaTr
# 交易签名也是交易Hash
Signature: SUqvh7h3qgZV3sywXEmYzegiemffr51fQeoAuWbETTzEqfs8vuxr8KAVF6Nx7httt13wripV2mHtMhqhoEFuwHv
# 为代币持有账户Mint(分配)代币。第一个参数是代币地址,第二个参数是分配数量,第三个参数是代币持有账户地址
$ spl-token mint 8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT 10000 -- 4GLLKhsTCkm7roqFiTEm5fg4LDrjBZmgyT94cJ6kAaTr
# 查看某个代币余额(参数是代币地址)
$ spl-token balance 8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT
# 转帐代币(除前两个选项以外,第一个参数是代币地址,第二个参数是代币数量,第三个参数是接收地址)
# --fund-recipient 表示如果接收地址没有该代币持有账户会帮其创建,如果有则不创建
# --allow-unfunded-recipient 表示如果接收地址没有Solana余额也执行转帐
$ spl-token transfer --fund-recipient --allow-unfunded-recipient 8kDYBqzYrKayd2fQ63BPd8ed1sk8hsUWQ2y6JcBUhHdT 11 3f2PCtqDp1vNm5yJk53t5peTL15ZjXcTm8bsUXpUWE2q
# 打包下载依赖可能需要代理
$ export http_proxy=http://127.0.0.1:58591/
$ export https_proxy=http://127.0.0.1:58591/
# 测试智能合约代码
# cargo test-sbf --manifest-path=./Cargo.toml (效果等同下面)
$ cargo-test-sbf --manifest-path=./Cargo.toml
# 查看编译打包工具版本以及相关依赖版本
# 注意:下面显示的rustc版本是Solana客户端自带的Rust工具,可使用rustup show命令查看已安装的rust工具,里面的solana就是下面这个
# rust工具默认安装在 ~/.rustup/toolchains 目录
$ cargo-build-sbf --version
solana-cargo-build-sbf 1.18.18
platform-tools v1.41
rustc 1.75.0
# 打包Solana智能合约程序
# --bpf-out-dir 指定打包后文件输出目录
# cargo build-sbf --manifest-path=./Cargo.toml --sbf-out-dir=build(效果等同下面)
$ cargo-build-sbf --manifest-path=./Cargo.toml --sbf-out-dir=build
# 清空Solana打包程序
$ cargo clean --manifest-path=./Cargo.toml && rm -rf ./build
# 分模块指定Solana本地验证节点日志级别,如果想全局指定可使用命令 export RUST_LOG=ERROR(注意:不指定日志级别它默认打印info日志,打得太多太快)
# 说明:solana_runtime::system_instruction_processor=info 可打印我们代码里面的日志,方便调试代码
$ export RUST_LOG=solana_bpf_loader=error,solana_rbpf=error,solana_runtime::system_instruction_processor=info,solana_runtime::message_processor=error
# 启动本地Solana验证节点
$ solana-test-validator
# 创建密钱包(就是部署智能合约的账户),钱包密钥对默认创建在 ~/.config/solana/id.json
# 指定密钥对存储路径示例: solana-keygen new -o ~/data-data/dev-tools/Solana/test-key/id.json
# 可指定参数 --no-outfile 表示不存储密钥对数据
$ solana-keygen new
# 将Solana服务端设置成本地(或者使用:solana config set --url http://127.0.0.1:8899)
$ solana config set --url localhost
# 将Solana服务端设置成开发网络
$ solana config set --url devnet
# 将Solana服务端设置成测试网络
$ solana config set --url testnet
# 将Solana服务端设置成主网
$ solana config set --url mainnet-beta
# 获取Solana服务端配置
$ solana config get
# 指定Solana部署所使用的钱包账户(如果不指定会默认使用 ~/.config/solana/id.json)
$ solana config set -k ~/.config/solana/id.json
# 领取空投(注意:不领取的话账户里面没有钱)
$ solana airdrop 100
# 查看钱包余额
$ solana balance
# 部署智能合约(注意:/home/helloworld.so 是已经打包好的合约程序)
# --with-compute-unit-price 指定自定义Gas价格加快部署交易,可防止Blockhash expired(Blockhash过期部署错误))
# solana program deploy --with-compute-unit-price 1000 /home/helloworld.so
$ solana program deploy /home/helloworld.so
# 部署成功后的合约地址
Program Id: EjS5rkqgXAUWqhvUip9nWN9mmdRzKLxmsfoXnUggn7pM
# 当前命令行窗口使用代理
$ export http_proxy=http://127.0.0.1:58591/
$ export https_proxy=http://127.0.0.1:58591/
# 安装 AVM
$ cargo install --git https://github.com/coral-xyz/anchor avm --locked --force
# 安装最新Anchor套件
$ avm install latest
# 使用最新Anchor套件
$ avm use latest
# 验证Anchor套件是否安装成功
$ anchor --version
# 如果前端要使用 Anchor的话需要安装一下插件
$ npm install -g mocha
$ npm install -g @project-serum/anchor
# 使用Anchor创建项目
$ anchor init "项目名称"
# 使用Anchor编译项目,编译完成以后在target/idl目录下会生成IDL json文件(类似于ABI)(注意:该命令需要在项目目录下执行)
$ anchor build
# 使用客户端JS代码测试链上程序(注意:这个测试代码是写在tests目录下的(具体可参考hw_06_anchor_simple项目))
# --skip-local-validator 表示不自动启动本地Solana验证节点
$ anchor test --skip-local-validator