简介
# 区块链概念
# Coin (原生货币) 与 Token (代币)
- 所有区块链协议都有代表价值且可交易的 Coin。在 Solana 上,这种 Coin 被称为 SOL。
- Token 是由各个项目在基础区块链 (base blockchain) 上构建的协议。所有区块链项目都是 “代币化的”。
# smart contract - 智能合约
智能合约是写入区块链代码并在满足条件时自动执行的合约。Solana 和某些其他协议可以做到这一点,但其他一些区块链(尤其是比特币)却无法做到。
# dApp
dApp 是一种去中心化的应用程序 (decentralized application) ,或者说是使用智能合约的应用。任何加密程序 —— 例如市场、区块链游戏或用于 DAO 治理的工具 —— 都属于 dApp。
# Web3
- Web 1.0 是静态网站和超链接 (如 AOL 或 GeoCities)
- Web 2 是社交媒体(如 Twitter、Facebook 和 等等)
- Web 3 是围绕去中心化的思想构建的
# NFT
NFT 的全称是 “非同质化代币”。
# Solana 概念
# 特点
- 非常快的确认时间:一个交易只需 400 毫秒就可以被整个网络验证,远快于其他区块链。
- 低交易费用
# Solana Accounts - Solana 账户
# Sending Transactions - 发送交易
# Program Derived Addresses (PDAs) - 程序派生地址
# Cross-Program Invocations (CPIs) - 跨程序调用
# Solana Playground (Solpg) - 开发环境
无需安装任何东西,只需在浏览器访问 https://beta.solpg.io/ (opens new window),即可快速开发、部署和测试 Solana 程序。
# 连接 Playground
点击屏幕左下方的 Not connected
按钮。
# 创建或导入钱包密钥
- 首次使用,点击
Save keypair
保存新创建的钱包 - 下次时候时,可点击
import keypair
导入此前创建的钱包
操作后,窗口底部可看到钱包地址、SOL 余额和连接的集群(默认为 devnet)。
- 钱包地址 (wallet address) :通常为 Ed25519 密钥对的 32 字节公钥 显示为 base-58 编码的字符串(例如,
7MNj7pL1y7XpPnN7ZeuaE4ctwg3WeufbX5o85sA91J1
)。相应的私钥会从此地址签署交易。在 Solana 上,地址是用户钱包、程序(智能合约)或网络上任何其他账户的唯一标识符。 - 公共集群 (Common clusters):
devnet
:用于开发人员实验的开发网络testnet
:为验证器测试保留的网络(请勿用作应用程序开发人员)mainnet-beta
:用于实时交易的主要 Solana 网络
# 获取 Devnet SOL
在开始开发之前,需要获取一些 devnet SOL
。
# 主要用途
- 创建新帐户以在网络上存储数据或部署程序
- 与 Solana 网络交互时支付交易费
# 获取方法
方法一:使用 Playground 终端
# 给自己空投5个sol
solana airdrop 5
方法二:使用 Devnet Faucet
- 访问 https://faucet.solana.com/ (opens new window)
- 输入 Playground 屏幕下方显示的钱包地址,填写金额
- 点击 “Confirm Airdrop” 即可收到 devnet SOL
# 网络接口
在 Solana 上,所有数据都存在于 “account” 中。可理解为所有数据都存储在一个名为 account
的 Map, key
为钱包地址, value
为账号类型。
pub struct Account {
/// lamports in the account
pub lamports: u64,
/// data held in this account
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
pub data: Vec<u8>,
/// the program that owns this account. If executable, the program that loads this account.
pub owner: 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,
}
Solana 帐户包含以下任一内容:
- 状态:用于读写数据。这包括有关令牌、用户数据或程序中定义的其他数据的信息。
- 可执行程序:包含 Solana 程序实际代码的账户。这些账户存储网络执行的指令。
# 获取账户 - 钱包信息
钱包为 系统程序 (opens new window) ,Solana 的原生程序之一
点击此链接 (opens new window)在 Solana Playground 中打开示例
// 获取你的 Playground 钱包地址
const address = pg.wallet.publicKey;
// 获取该地址的账户的 `AccountInfo`
const accountInfo = await pg.connection.getAccountInfo(address);
console.log(JSON.stringify(accountInfo, null, 2));
- 在 Playground 终端中,输入
run
命令并按回车键,运行代码,得到以下输出
Running client...
client.ts:
{
"data": {
"type": "Buffer",
"data": []
},
"executable": false,
"lamports": 16000000000,
"owner": "11111111111111111111111111111111",
"rentEpoch": 18446744073709552000,
"space": 0
}
data
- 包含账户 “数据” 的字段。对于钱包来说,此字段为空(0 字节),但其他账户使用此字段以序列化字节缓冲区的形式存储任意数据。executable
- 指示帐户是否可作为可执行程序运行的标志。对于钱包和存储状态的帐户,此标志显示false
。owner
- 显示哪个程序控制该帐户的字段。对于钱包, 系统程序所有者地址为11111111111111111111111111111111
.lamports
- 账户中的 lampors 余额(1 SOL = 1,000,000,000 lampors)。rentEpoch
与 Solana 已弃用的租金收取机制相关的遗留字段(目前未使用)。space
-data
字段(不是Account
类型中的字段)的字节容量(长度)
# 获取账户 - Token Extensions Program (代币扩展程序)
点击此链接 (opens new window)在 Solana Playground 中打开示例。您将看到以下代码:
import { PublicKey } from "@solana/web3.js";
const address = new PublicKey("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
const accountInfo = await pg.connection.getAccountInfo(address);
console.log(JSON.stringify(accountInfo, null, 2));
run
输出:
Running client...
client.ts:
{
"data": {
"type": "Buffer",
"data": [
2,
0,
//... additional bytes
86,
51
]
},
"executable": true,
"lamports": 1141440,
"owner": "BPFLoaderUpgradeab1e11111111111111111111111",
"rentEpoch": 18446744073709552000,
"space": 36
}
代币扩展程序
作为可执行程序账户运行,保持相同的 Account
结构。
executable
- 设置为true
,表示可执行程序帐户。data
- 包含序列化数据(不同于钱包账户中的空数据)。程序账户的数据保存的是另一个账户(程序可执行数据账户)的地址,该账户包含程序的字节码。owner
- 可升级伯克利数据包过滤器 (BPF) 加载程序 (BPFLoaderUpgradeab1e11111111111111111111111
) 拥有此帐户,其功能相当于管理可执行帐户的本机程序。
可以检查 Solana Explorer 中的 代币扩展程序帐户 (opens new window) 及其相应的 程序可执行数据帐户 (opens new window) 。
# 获取账户 - Mint 账户
点击此链接 (opens new window)在 Solana Playground 中打开示例。您将看到以下代码:
import { PublicKey } from "@solana/web3.js";
const address = new PublicKey("C33qt1dZGZSsqTrHdtLKXPZNoxs6U1ZBfyDkzmj6mXeR");
const accountInfo = await pg.connection.getAccountInfo(address);
console.log(JSON.stringify(accountInfo, null, 2));
在此示例中,代码获取 devnet 上现有 Mint 帐户的地址。
run
输出:
Running client...
client.ts:
{
"data": {
"type": "Buffer",
"data": [
1,
0,
//... additional bytes
0,
0
]
},
"executable": false,
"lamports": 4176000,
"owner": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",
"rentEpoch": 18446744073709552000,
"space": 430
}
owner
- 代币扩展程序 (TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
) 拥有 mint 账户。executable
- 设置为false
,因为此帐户存储状态而不是可执行代码。data
:包含有关代币的序列化数据(铸造权限、供应、小数等)。