Solana 学习#
2. 从 Solana 网络读取数据#
(1) Summary 概括#
SOL 是 Solana 原生代币的名称。每个 SOL 由 10 亿个 Lamports 组成。
账户存储代币、NFT、程序和数据。
地址指向 Solana 网络上的帐户。任何人都可以读取给定地址的数据。大多数地址也是公钥。
(2) Accounts 账户#
Solana 上存储的所有数据都存储在帐户中。帐户可以存储:
- SOL
- 其他代币,例如 USDC
- NFT
- 程序
- 程序数据
(3) SOL 介绍#
SOL 是 Solana 的原生代币 - SOL 用于支付交易费用、支付账户租金等。 SOL 有时用 ◎ 符号显示。每个 SOL 由 10 亿个 Lamports 组成。
与金融应用程序通常以美分(美元)和便士(英镑)进行数学计算的方式相同,Solana 应用程序通常将 SOL 作为 Lamport 进行传输、支出、存储和处理,仅转换为完整的 SOL 来显示给用户。
(4) Addresses 地址#
地址唯一标识帐户。地址通常显示为 base-58 编码字符串,例如 dDCQNnDmNbFVi8cQhKAgXhyhXeJ625tvwsunRyRc7c8。 Solana 上的大多数地址也是公钥。谁控制了地址的匹配密钥,谁就控制了该帐户 —— 例如,拥有密钥的人可以从该帐户发送代币。
(5) 代码#
import { PublicKey,LAMPORTS_PER_SOL,Keypair,Connection, clusterApiUrl } from "@solana/web3.js";
console.log("生成公私钥对");
const keypair = Keypair.generate();
console.log(`The public key is: `, keypair.publicKey.toBase58());
console.log(`The secret key is: `, keypair.secretKey);
console.log('----------------------');
console.log("创建连接");
const connection = new Connection(clusterApiUrl("devnet"));
// console.log(connection)
console.log(`✅ Connected!`)
console.log("----------------------");
console.log("获取账户余额");
const address = new PublicKey('4pa3H5FwfPPSYH8JGKiKb91mgjx6iVbt4X3XJAdV7s5g');
const balance = await connection.getBalance(address);
const balanceInSol = balance / LAMPORTS_PER_SOL;
console.log(`The balance of the account at ${address} is ${balanceInSol} SOL`);
console.log(`✅ Finished!`)
3. 在 Solana 网络上创建交易 \#
(1) Summary 概括#
对链上数据的所有修改都是通过交易发生的。事务主要是一组调用 Solana 程序的指令。事务是原子的,这意味着它们要么成功(如果所有指令都已正确执行),要么失败,就像事务根本没有运行一样。
(2) Transactions are atomic 交易是原子的#
对链上数据的任何修改都是通过发送到程序的交易发生的。
Solana 上的交易与其他地方的交易类似:它是原子的。原子性意味着整个事务运行或失败。
想想网上支付的东西:
- 您的账户余额已被扣除
- 银行将资金转给商户
这两件事都需要发生才能使交易成功。如果其中任何一个失败,则任何一个都不会发生,而不是向商家付款但不从您的帐户中扣除,或者从帐户中扣除但不向商家付款。
原子意味着事务要么发生(意味着所有单独步骤都成功),要么整个事务失败。
(3) Transactions contain instructions 交易包含指令#
Solana 上的事务中的步骤称为指令。
每条指令包含:
- 将读取和 / 或写入的帐户数组。这就是 Solana 快速的原因 - 影响不同账户的交易同时处理
- 要调用的程序的公钥
- 传递给正在调用的程序的数据,结构为字节数组
运行事务时,将使用事务中包含的指令调用一个或多个 Solana 程序。
(4) 代码#
import { Transaction,SystemProgram,sendAndConfirmTransaction,Connection,LAMPORTS_PER_SOL,clusterApiUrl,Keypair, PublicKey } from "@solana/web3.js"
const connection = new Connection(clusterApiUrl("devnet"), "confirmed")
//生成一个新的密钥对
const senderKeypair = Keypair.generate()
//空投
await connection.requestAirdrop(senderKeypair.publicKey, LAMPORTS_PER_SOL)//1SOL=1000000000LAMPORTS
//接受者
const receiverPubkey = new PublicKey("4pa3H5FwfPPSYH8JGKiKb91mgjx6iVbt4X3XJAdV7s5g")
//获取接收者的余额
const receiverBalance = await connection.getBalance(receiverPubkey)
//获取发送者的余额
const senderBalance = await connection.getBalance(senderKeypair.publicKey)
console.log("sender balance:", senderBalance)
console.log("receiver balance:", receiverBalance)
const transaction = new Transaction()
const sendSolInstruction = SystemProgram.transfer({
fromPubkey: senderKeypair.publicKey,//与发送者帐户对应的公钥
toPubkey: receiverPubkey,//与接收者帐户对应的公钥
lamports: LAMPORTS_PER_SOL/2//发送到 Lamps 的 SOL 数量。
})
transaction.add(sendSolInstruction)
const signature =await sendAndConfirmTransaction(
connection,//集群连接
transaction,//一笔交易
[senderKeypair]//一组密钥对,将充当交易的签名者 - 在本例中,我们只有一个签名者:发送者。
)
//获取接收者的余额
const receiverBalance01 =await connection.getBalance(receiverPubkey)
//获取发送者的余额
const senderBalance01 =await connection.getBalance(senderKeypair.publicKey)
console.log("sendered balance:", senderBalance01)
console.log("receivered balance:", receiverBalance01)
console.log("signature:", signature)
4. 使用令牌计划创建令牌#
(1) Summary 概括#
SOL 是 Solana 的 “原生代币”。所有其他代币,可替代代币和不可替代代币(NFT),都称为 SPL 代币
令牌程序包含创建 SPL 令牌并与之交互的说明
代币铸币厂是定义特定代币的账户。这包括有关代币本身的信息(例如它有多少位小数)、允许铸造更多代币的帐户(称为造币机构)以及在哪里可以找到有关代币的更多信息(例如描述、图像等)。造币机构可以使用代币铸造来制造更多代币!
代币账户持有特定代币铸币厂的代币。对于大多数用户来说,他们的每个代币铸币厂的余额都存储在关联的代币账户中 - 其地址由其钱包地址和代币铸币厂组成的账户。
创建代币铸币厂和代币账户需要在 SOL 中分配租金。 Token 账户的租金可以在账户关闭时退还,但 Token Mints 目前无法关闭。
(2) 代币铸造步骤#
- Creating a new Token Mint
创建一个新的代币铸币厂- Creating Token Accounts 创建令牌帐户
- Minting 铸币
- Transferring tokens from one holder to another
将代币从一个持有者转移到另一个持有者- Burning tokens 燃烧代币
(3) Token Account 代币账户#
在铸造代币(发行新供应)之前,需要一个代币账户来保存新发行的代币。
代币账户持有特定 “铸币厂” 的代币,并拥有指定的账户 “所有者”。只有所有者有权减少代币账户余额(转账、销毁等),而任何人都可以向代币账户发送代币以增加其余额。
在你给我的 Solana 代码里,这个新创建的账户用于持有代币(mint)的状态和元数据,而你作为付款人支付了创建这个账户所需的费用,同时你也拥有这个代币的铸造权(mint authority)。
5. 使用 Metaplex 创建 Solana NFT#
(1) Summary 概括#
不可替代代币 (NFT) 在 Solana 上表示为 SPL 代币,具有关联的元数据帐户、0 位小数和最大供应量 1
Metaplex 提供了一系列工具,可简化 Solana 区块链上 NFT 的创建和分发
令牌元数据计划标准化了将元数据附加到 SPL 令牌的过程
Metaplex SDK 是一个提供用户友好的 API 的工具,可以帮助开发者使用 Metaplex 提供的链上工具
Candy Machine 程序是一种 NFT 分发工具,用于从集合中创建和铸造 NFT
Sugar CLI 是一个工具,可以简化上传媒体 / 元数据文件和为集合创建糖果机的过程
(2) Solana 上的 NFT#
6. 自定义链上程序#
7. 链上程序开发#
(1) Anchor 程序结构#
Anchor 使用宏和特征为您生成样板 Rust 代码。它们为您的程序提供了清晰的结构,以便您可以更轻松地推理您的代码。主要的高级宏和属性是:
- declare_id - 用于声明程序的链上地址的宏
- #[program] - 用于表示包含程序指令逻辑的模块的属性宏
- 帐户 - 应用于表示指令所需帐户列表的结构的特征
- #[account] - 用于定义程序的自定义帐户类型的属性宏