本文介绍了如何使用 Solana Web3.js 2.0 库在 Solana 区块链上创建可替代代币(Fungible Token),包括设置连接、生成密钥对、创建铸币账户、初始化铸币、创建关联代币账户(ATA)以及铸造代币等步骤。
Solana 的 Web3.js 2.0 库引入了一种与 Solana 区块链交互的新方式,强调可组合性和模块化。在本指南中,我们将探讨如何使用这个更新的库创建一个同质化代币。
让我们开始吧!
使用 Solana Web3.js 2.0 库编写一个脚本,在 Solana 区块链上创建一个同质化代币:
| 依赖项 | 版本 | 
|---|---|
| @solana/web3.js | ^2.0.0 | 
| @solana-program/system | ^0.5.0 | 
| @solana-program/token | ^0.4.1 | 
| solana cli | 1.18.8 | 
让我们开始吧!
Solana 上的同质化代币是一种数字资产,其中每个单位可以与同一代币的另一个单位互换。这些代币是使用 Solana 的代币程序创建和管理的,该程序提供了铸造、转移和销毁代币的功能。同质化代币可以用于存储和交换价值(例如,USDC 或其他资产)、作为实用工具(例如,用于即将推出的 NFT 铸造的白名单代币)、代表协议中的权益(例如,治理代币),或者任何你能想到的其他用途。
Solana 上同质化代币的关键组件包括:
现在,让我们探索如何使用 Solana Web3.js 2.0 创建这些组件。
首先,让我们设置我们的项目:
mkdir solana-fungible-token && cd solana-fungible-token
将你的项目初始化为 Node.js 项目:
npm init -y
安装依赖项:
npm install @solana/web3.js@2 @solana-program/system @solana-program/token && npm install --save-dev @types/node typescript ts-node
注意:你可能需要使用
--legacy-peer-deps标志来安装@solana-program/system和@solana-program/token包。
在项目中添加一个 tsconfig.json 文件:
tsc --init --resolveJsonModule true
在项目目录中创建一个名为 create-token.ts 的新文件:
echo > create-token.ts
很好!现在,我们准备好开始编码了。
在你的 create-token.ts 文件中,让我们首先导入必要的依赖项:
import { getCreateAccountInstruction } from "@solana-program/system";
import {
    findAssociatedTokenPda,
    getCreateAssociatedTokenIdempotentInstructionAsync,
    getInitializeMintInstruction,
    getMintSize,
    getMintToInstruction,
    TOKEN_PROGRAM_ADDRESS
} from "@solana-program/token";
import {
    airdropFactory,
    createSolanaRpc,
    createSolanaRpcSubscriptions,
    generateKeyPairSigner,
    lamports,
    sendAndConfirmTransactionFactory,
    pipe,
    createTransactionMessage,
    setTransactionMessageLifetimeUsingBlockhash,
    signTransactionMessageWithSigners,
    getSignatureFromTransaction,
    setTransactionMessageFeePayerSigner,
    appendTransactionMessageInstructions,
    CompilableTransactionMessage,
    TransactionMessageWithBlockhashLifetime,
    Commitment,
} from "@solana/web3.js";
const LAMPORTS_PER_SOL = BigInt(1_000_000_000);
const DECIMALS = 9;
const DROP_AMOUNT = 100;
在这里,我们从 Solana Web3.js 2.0 库和 Solana 程序库中导入了各种函数。
接下来,让我们创建我们的 main 函数,该函数将包含我们脚本的逻辑:
async function main() {
    // 1 - 建立与 Solana 集群的连接
    // 2 - 生成密钥对
    // 3 - 向支付者账户空投 SOL
    // 4 - 创建铸币账户并初始化铸币
    // 5 - 创建关联代币账户并铸造代币
}
main();
在 main 函数内部,让我们建立与本地 Solana 集群的连接:
    // 1 - 建立与 Solana 集群的连接
    const httpEndpoint = 'http://127.0.0.1:8899';
    const wsEndpoint = 'ws://127.0.0.1:8900';
    const rpc = createSolanaRpc(httpEndpoint);
    const rpcSubscriptions = createSolanaRpcSubscriptions(wsEndpoint);
    console.log(`✅ - 已建立与 ${httpEndpoint} 的连接`);
我们使用 createSolanaRpc 和 createSolanaRpcSubscriptions 函数来创建我们的 RPC 连接。在本指南中,我们使用 localhost,但如果你准备连接到远程 Solana 集群,你可以使用你的 QuickNode HTTP Provider 和 WSS Provider 端点,这些端点可以从你的 QuickNode 仪表板 获取。
让我们为代币创建过程生成必要的密钥对。在步骤 2 中的 main 函数中添加以下代码:
    // 2 - 生成密钥对
    const mintAuthority = await generateKeyPairSigner();
    const payer = await generateKeyPairSigner();
    const owner = await generateKeyPairSigner();
    const mint = await generateKeyPairSigner();
    const [ata] = await findAssociatedTokenPda({
        mint: mint.address,
        owner: owner.address,
        tokenProgram: TOKEN_PROGRAM_ADDRESS,
 });
    console.log(`✅ - 已生成密钥对`);
    console.log(`     铸币权限:${mintAuthority.address}`);
    console.log(`     支付者:${payer.address}`);
    console.log(`     所有者:${owner.address}`);
    console.log(`     铸币账户:${mint.address}`);
    console.log(`     关联代币账户:${ata}`);
在这里,我们为铸币权限、支付者、所有者和铸币账户本身生成了密钥对。我们还使用 findAssociatedTokenPda 函数派生了关联代币账户 (ATA) 地址。作为示例,我们将地址记录到控制台以供参考。
在创建代币之前,我们需要用 SOL 为我们的支付者账户提供资金。让我们使用 airdropFactory 函数来完成此操作。在步骤 3 中的 main 函数中添加以下代码:
    // 3 - 向支付者账户空投 SOL
    const airdrop = airdropFactory({ rpc, rpcSubscriptions });
    const airdropTx = await airdrop({
        commitment: 'processed',
        lamports: lamports(LAMPORTS_PER_SOL),
        recipientAddress: payer.address
    });
    console.log(`✅ - 已向支付者空投 1 SOL:${airdropTx}`);
在这里,我们使用 airdropFactory 函数创建一个 airdrop 函数,然后我们使用该函数向我们的支付者账户空投 1 SOL。
现在我们的 payer 账户有了 SOL,让我们创建并初始化我们的铸币账户。在步骤 4 中的 main 函数中添加以下代码:
    // 4 - 创建铸币账户并初始化铸币
    const mintSpace = BigInt(getMintSize());
    const mintRent = await rpc.getMinimumBalanceForRentExemption(mintSpace).send();
    const instructions = [\
        // 创建铸币账户\
        getCreateAccountInstruction({\
            payer,\
            newAccount: mint,\
            lamports: mintRent,\
            space: mintSpace,\
            programAddress: TOKEN_PROGRAM_ADDRESS,\
        }),\
        // 初始化铸币\
        getInitializeMintInstruction({\
            mint: mint.address,\
            decimals: DECIMALS,\
            mintAuthority: mintAuthority.address\
        }),\
    ];
    const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
    const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });
    const signAndSendTransaction = createSignAndSendTransaction(sendAndConfirmTransaction);
    const createMintTxid = await pipe(
        createTransactionMessage({ version: 0 }),
        (tx) => setTransactionMessageFeePayerSigner(payer, tx),
        (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
        (tx) => appendTransactionMessageInstructions(instructions, tx),
        (tx) => signAndSendTransaction(tx)
    );
    console.log(`✅ - 铸币账户已创建并初始化:${createMintTxid}`);
此部分展示了 Web3.js 2.0 的几个关键特性:
getCreateAccountInstruction 和 getInitializeMintInstruction 来创建用于创建和初始化我们的铸币账户的指令。pipe 函数在创建和发送交易时将多个操作链接在一起。createSignAndSendTransaction,这是我们稍后将定义的自定义辅助函数,以允许我们签名和发送我们的交易。最后,让我们创建另一个交易,为我们的所有者创建一个关联代币账户 (ATA) 并向其铸造一些代币。在步骤 5 中的 main 函数中添加以下代码:
    // 5 - 创建关联代币账户并铸造代币
    const mintInstructions = [\
        // 创建目标关联代币账户\
        await getCreateAssociatedTokenIdempotentInstructionAsync({\
            mint: mint.address,\
            payer,\
            owner: owner.address,\
        }),\
        // 向目标关联代币账户铸造代币\
        getMintToInstruction({\
            mint: mint.address,\
            token: ata,\
            amount: BigInt(DROP_AMOUNT * 10 ** DECIMALS),\
            mintAuthority, // 通过包含签名者而不是公钥来签名\
        })\
    ];
    const mintTxid = await pipe(
        createTransactionMessage({ version: 0 }),
        (tx) => setTransactionMessageFeePayerSigner(payer, tx),
        (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
        (tx) => appendTransactionMessageInstructions(mintInstructions, tx),
        (tx) => signAndSendTransaction(tx)
    );
    console.log(`✅ - 代币已铸造到 ATA:${mintTxid}`);
在这里,我们为我们的所有者创建了一个 ATA 并向其铸造代币。我们使用 getCreateAssociatedTokenIdempotentInstructionAsync 函数来创建 ATA,并使用 getMintToInstruction 向其铸造代币。我们使用与步骤 4 中类似的 pipe 函数来创建和发送我们的交易。
让我们在文件末尾添加一个辅助函数来处理签名和发送交易。在你的 create-token.ts 文件末尾添加以下代码:
const createSignAndSendTransaction = (sendAndConfirmTransaction: ReturnType<typeof sendAndConfirmTransactionFactory>) => {
    return async (
        transactionMessage: CompilableTransactionMessage & TransactionMessageWithBlockhashLifetime,
        commitment: Commitment = 'processed',
        skipPreflight: boolean = true
    ) => {
        const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
        try {
            await sendAndConfirmTransaction(signedTransaction, { commitment, skipPreflight });
            return getSignatureFromTransaction(signedTransaction);
        } catch (e) {
            console.error('交易失败:', e);
            throw e;
        }
    };
};
这个辅助函数封装了签名和发送交易的过程,使我们的主代码更加简洁和易读。
在本指南中,我们将使用本地 Solana 验证器。打开一个新的终端窗口并启动验证器:
solana-test-validator -r
当你准备好将你的代币投入生产时,你需要将其部署到 Solana 集群。无论是部署到主网还是开发网,你都可以通过注册 QuickNode 账户 来获得免费的 QuickNode 端点。
要运行我们的脚本,请使用以下命令:
ts-node create-token.ts
你应该会看到输出,指示成功连接、密钥对生成、空投、铸币创建和代币铸造:
✅ - 已建立与 http://127.0.0.1:8899 的连接
✅ - 已生成密钥对
     铸币权限:7JBobKzJt8BgGwbPwGGGD2HyLMf6nGW1FXvHvd2xUKZ8
     支付者:3eVn4tAFGGP5tW3Rc1Lqq7hEDUFJz8uxFpNa3SJsDtba
     所有者:8nM1gKXDygKUWDCy8PJvAJvQUd11m5coQWUo7v5Zitm1
     铸币账户:9vgOWh6vhd9s33S1JTzS3Hk1mPEp2kPMPNK1sY6lEYvZ
     关联代币账户:6Z9Q5KyFbUZ2hYU2HfxUVPD6XpQUy1rHgLGLwR6sPGNj
✅ - 已向支付者空投 1 SOL:2gkQL7h7hHRWNfNwf2WyuPRmbhVd8oP7Ehfs54Pspqxx7KkYGF3wxjeoiVwLUHMgr9UYKY4PiMymmsGsQqKVWYoC
✅ - 铸币账户已创建并初始化:5JcnmFrYhPcZnmfUPecuBUJw9RVAoHwUQ2xGtcJ8XkHNwZHMWLR13eJcuqfkdbBnfRm1ajFTaF3E7WzQFyCpgCc3
✅ - 代币已铸造到 ATA:3nLePg18vjuVDM5m3z1jFSTPBYNWUHx4eaUprWXKqCu6ZNCYSBUgezp3xKnPeKQAjBRJmtVqc4ij3KvZUakqPa8y
干得好!你已经成功地使用 Solana Web3.js 2.0 创建了一个同质化代币。你应该能够在 本地 Solana 浏览器 中看到你的交易和铸币。
本指南通过创建一个脚本来使用 SPL 代币程序和新的 @solana-program/token 库执行一些基本操作,探索了新的 Solana Web3.js 2.0 库。希望在本指南之后,你开始看到新库的一些强大功能,以及它如何帮助你构建更复杂的应用程序。随着你继续探索 Web3.js 2.0,你会发现更多强大的功能和改进。继续努力!
如果你想继续练习,尝试扩展脚本以执行一些新操作:
getTransferCheckedInstruction 将 SPL 代币转移到另一个账户getBurnCheckedInstruction 销毁 SPL 代币getFreezeAccountInstruction 和 getThawAccountInstruction 冻结和解冻 SPL 代币告诉我们 如果你有任何反馈或新主题的请求。我们非常乐意听取你的意见。
- 原文链接: quicknode.com/guides/sol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
 
                如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!