作者:Tiny熊
账户模型

账户模型 → 编程模型
• 程序和数据是各自独立的账户( executable 区分), 代码和数据的分离 • 程序是数据账号的 Owner, 负责管理数据账户 • 程序是无状态的,给大规模并发执行提供了条件

PDA (Program Derived Addresses ) 账号 • 专门用来保存程序数据的账户,没有私钥, • 曲线外的生成的账户:根据 程序(owner) + 种子 + bump 生成

Token(代币)是数字资产,代表区块链网络上的所有权、访问权限或价值。可以将它们视为完全以数字形式存在的可编程证书:它们可以代表从货币和所有权股份到投票权和访问通行证的任何事物。
从最基本的层面来看,代币是区块链账本中的一条记录,表示“此地址拥有 X 数量的此资产”。与需要实物证书或集中式数据库来跟踪所有权的传统资产不同,代币利用区块链技术创建了防篡改、透明的所有权记录。
代币实现了可编程所有权:任何人都可以创建具有自定义规则的数字资产,这些规则规定了代币如何转移、授予哪些权利或如何与其他系统交互。
这为自动分红、条件转移或基于预定义条件自动执行的复杂金融工具等可能性打开了大门。
关键的创新在于,代币可以在全球范围内即时转移,无需中介,具有透明性(任何人都可以验证所有权),并且可以通过复杂的逻辑进行编程,同时保持底层区块链的安全性保障。
代币可以根据不同的类别进行分类,例如根据它们的用途或内在特性进行分类。
根据这些代币的功能,我们可以将其分为以下几类:
根据“技术”特性,代币分为两类:同质化代币和非同质化代币。
同质化代币和非同质化,从 Token Program 实现角度看是一样的,他们是从数量上来确定其具备的特性:
Token Program 无法强制执行这些特性。因此,像 MPL-token-metadata 这样的程序不仅提供了元数据的实现,还提供了强制执行这些约束的实现,从而可以轻松创建 NFT。
在以太坊中,每种代币都需要部署一个完整的智能合约,其中包含所有的代币逻辑、状态管理和转移规则。
尽管大多数代币遵循 ERC-20 标准, 但每种代币都是一个带有自定义代码的独立程序。
以太坊中,合约地址成为代币的标识符,所有余额都存储在该合约的状态中,该状态内部有一个余额映射。
在 Solana 上,由于程序(逻辑)与数据分离,所有与代币相关的逻辑都由 SPL Token Program 和 Token2022 Program 处理:Solana 的原生代币框架,定义了所有代币的创建、管理和转移方式。
这是一个单一的统一程序,处理网络中的所有代币操作,确保一致性和互操作性。
使用 Mint 账号来确定 Token 的唯一性, "mint" 账户包含代币的配置:总量 supply、decimal、mintAuthority 和 freezeAuthority。它相当于代币在 Solana 上的“出生证明”。
Token 主要涉及 3 个账户:Token Program 、Mint Account 、ATA Account(Token Account)
SPL Token 程序 或 Token 2022 程序,包含所有的代币逻辑、状态管理和转移规则。
主要功能:
在 Solana 上,代币通过由 Token Program 拥有的 Mint 账户地址唯一标识。此账户充当特定代币的全局计数器,并存储以下数据:
元数据
在区块浏览器和钱包中,代币通常通过特定的名称和图像变得可识别且易于阅读。
代币的名称、符号和图像称为 Metadata。因为在其原生形式中,Mint 账户只是一个 32 字节长的公钥,没有附加任何人类可读的信息。
在原生的 SPL Token 程序中,无法直接在代币上设置元数据。因此,像 Metaplex 这样的协议开发了 MPL-token-metadata 程序,为每个代币提供了关联元数据的方法。
在 Token2022 程序中可以使用 Token Extensions ,Metadata 扩展允许你将元数据直接嵌入到 mint account 中,从而无需依赖外部程序。
示例: https://solscan.io/token/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

ATA 是一个特定的 Token Account , 用于跟踪每个代币单位的个人所有权。Token Account 存储以下数据:
关联 Token Account 的地址是 根据所有者地址和 mint account 地址派生出来的(Associated Token Program 的 PDA)。
ATA = findProgramAddress(
[wallet, token_program_id, mint],
associated_token_program_id
)

spl-token create-token: 其实是创建 mint 账户, 保存:
solana-keygen grind --starts-with Lbc:1spl-token create-token mint_keypair.jsonspl-token create-account <mint account> :创建 ATAspl-token mint <mint account> <TOKEN_AMOUNT> [<ATA>]:发行spl-token balance <mint account> 查看余额spl-token supply <mint account> : 查看发行量spl-token account-info/display <mint account> : 查看 Token mint 的账户信息spl-token transfer <mint account> <TOKEN_AMOUNT> <RECIPIENT_WALLET_ADDRESS or RECIPIENT_TOKEN_ACCOUNT_ADDRESS>
spl-token create-account --owner <ata_owner> <MINT_ACCOUTT> --fee-payer key.jsonspl-token accounts : 查看我所有的 Token 账户及余额spl-token close <mint_account> : 关闭 ATA (需要余额为 0 )spl-token burn <ATA account> <amount>spl-token create-token --decimals 0(创建 mint ): 每一个 NFT需要有一个独立的 mint 账户Token2022 在 SPL Token 原有指令的基础上添加了扩展模块

spl-token create-token --enable-metadata --decimals 0 --program-2022
spl-token initialize-metadata 3w...m NAME Symbol https://raw.githubusercontent.com/lbc-team/hello_gill/refs/heads/main/metadata/nft-metadata.json
Solana web3.js是一个流行而简洁的 JavaScript 客户端库,可以让开发者便捷地与Solana区块链交互,与以太坊的ethers.js库类似。
你需要使用npm安装web3.js库:
npm install @solana/web3.js@1.98.0
下面将快速覆盖几个关键示例,分别是:
转移 SPL 代币
完整代码可在这里 查看。
在开始之前,我们需要导入一些库:
const solanaWeb3 =require('@solana/web3.js');
const splToken =require('@solana/spl-token');
要与链交互,首先要创建一个连接对象:
const connection = new solanaWeb3.Connection(
"https://api.devnet.solana.com",
{ wsEndpoint: "wss://api.devnet.solana.com" }
);
这里我们使用 Solana 官方提供的 Devnet RPC / WebSocket 节点。Devnet 是一个面向开发者的测试网络,适合用于学习、调试和开发应用。
定义一个异步主函数:
async function main() {}
然后定义加载方法:
function loadKeypair(path: string): Keypair {
const secretKeyString = fs.readFileSync(path, "utf8");
const secretKey = Uint8Array.from(JSON.parse(secretKeyString));
return Keypair.fromSecretKey(secretKey);
}
const walletKeyPair = loadKeypair(PAYER_KEYPAIR_PATH);
你现在已经有了一个主钱包,可以用它检查余额:
let balance = await connection.getBalance(walletKeyPair.publicKey);
console.log(balance / solanaWeb3.LAMPORTS_PER_SOL);
这会打印用户钱包中 SOL 的数量。
const mint = await splToken.createMint(
connection,
walletKeyPair,
walletKeyPair.publicKey,
null, // freeze authority
9, // decimals
undefined,
{},
splToken.TOKEN_PROGRAM_ID
);
然后为钱包创建一个关联的 Token 账户:
const tokenAccount =await splToken.getOrCreateAssociatedTokenAccount(
connection,
walletKeyPair,
mint,
walletKeyPair.publicKey
);
接着铸造代币:
await splToken.mintTo(
connection,
walletKeyPair,
mint,
tokenAccount.address,
walletKeyPair.publicKey,
1000 * 1e9
);
执行这段代码后,你应该看到代币成功进入你的 Token 账户。
接着以同样的方式为接收者创建ATA 账户 (getOrCreateAssociatedTokenAccount) , 并进行转账:
await splToken.transfer(
connection,
walletKeyPair,
payerTokenAccount.address,
receiverTokenAccount.address,
walletKeyPair.publicKey,
100 * 1e9
);
做完这些步骤后你就具备了 Solana 核心开发流程的基础技能