{"content":{"title":"在Solana发行元数据代币（纯JS完成）","body":"<!--StartFragment-->\r\n\r\n**教学视频链接：**\r\n\r\n* Bilibili [https://www.bilibili.com/video/BV1Wv421i7GM/?share_source=copy_web\\&vd_source=c147db41bce0140aa28781d353032bab](https://www.bilibili.com/video/BV1LF4m1c7Xk/?spm_id_from=333.999.0.0\\&vd_source=2979dcefbf505a6422797470b6fbbfad)\r\n* Youtube [https://youtu.be/bfw_uhrvqjc?si=vuY1likrBvZ5ftPa](https://www.youtube.com/watch?v=ORFes1Xebug)\r\n\r\n**欢迎添加我的联系方式：ruichao_web3**\r\n\r\n<!--EndFragment-->\r\n\r\n\r\n<!--StartFragment-->\r\n\r\n### 一、安装 Node.js\r\n\r\n是Javascript的运行环境，到官网下载安装即可 https\\://nodejs.org/\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n### 二、项目初始化，安装需要的库\r\n\r\n\r\n\r\n\r\n新建文件夹，初始化项目\r\n\r\n```\r\nnpm init -y\r\n```\r\n\r\n\r\n\r\n\r\n然后使用 npm install 指令安装以下各库\r\n\r\n* @metaplex-foundation/umi\r\n* @metaplex-foundation/mpl-token-metadata\r\n* @metaplex-foundation/umi-bundle-defaults\r\n* @solana/web3.js\r\n\r\n\r\n\r\n\r\n看该文档体会Solana Token、NFT是怎么构建的\r\n\r\nhttps\\://developers.metaplex.com/token-metadata\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n### 三、新建index.js文件，导入库和模块\r\n\r\n```\r\nimport { percentAmount, generateSigner, signerIdentity, createSignerFromKeypair } from '@metaplex-foundation/umi'import { TokenStandard, createAndMint ,mplTokenMetadata} from '@metaplex-foundation/mpl-token-metadata'import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'import { Keypair } from \"@solana/web3.js\"import { readFileSync } from 'fs'\r\n```\r\n\r\n\r\n\r\n\r\n\r\n\r\n### 四、实例化umi，连接到Solana devnet网络\r\n\r\n```\r\nconst umi = createUmi('your_devnet_rpc');\r\n```\r\n\r\n\r\n\r\n\r\n这里的节点推荐使白嫖 QiuckNode，用过都说好，访问 quicknode.com，一步步注册即可，免费套餐跑测试代码都用\r\n\r\n![](https://infura-ipfs.mora.host/ipfs/QmcjqFArxE9iwABSJV3AQ6sYn99mSEweaQmhByNC21rTaS)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n### 五、实例化钱包、获取签名者\r\n\r\n使用上一节在本机创建的 id.json 私钥文件，实例化用户钱包\r\n\r\n```\r\nconst userKeypair = Keypair.fromSecretKey(    Buffer.from(JSON.parse(readFileSync('./id.json', \"utf-8\"))))​\r\n```\r\n\r\n此时获取的 \\_keypair 有两个成员，publicKey 与 secretKey\r\n\r\n![](https://infura-ipfs.mora.host/ipfs/QmZdXd3HQ1qyMcQS3jDJi7cmz7rDvg7V5shzssE4ZxEcN2)\r\n\r\n使用其 secretKey ，生成 UMI 签名者（Signer）\r\n\r\n```\r\nconst userWallet = umi.eddsa.createKeypairFromSecretKey(userKeypair.secretKey);​const userWalletSigner = createSignerFromKeypair(umi, userWallet);\r\n```\r\n\r\n\r\n\r\n\r\n\r\n### 六、定义元数据\r\n\r\n将您的令牌信息在线化，我推荐使用 pinata\r\n\r\nhttps\\://www\\.pinata.cloud/\r\n\r\n\r\n\r\n\r\n注册登录，来到仪表盘\r\n\r\n![](https://infura-ipfs.mora.host/ipfs/QmUBLmEz8GVNVKqcj14LbRoFqjqh4uhgNm6JYpPbzcXnS9)\r\n\r\n![](https://infura-ipfs.mora.host/ipfs/Qmcz8XcN2A31m51ANMc7B7nY2qbjCiBcKaU9CtNoS2Xj1e)\r\n\r\nTokenInfo.json\r\n\r\n```\r\n{    \"name\": \"Per aspera ad astra\",    \"symbol\": \"PAA\",    \"description\": \"「循此苦旅，以達星辰」\",    \"image\": \"https://white-historical-basilisk-887.mypinata.cloud/ipfs/QmS7kMQG1gHptsd4NAEVYDhMJ7SGa23hpJ63RYh69FqPGk\"}\r\n```\r\n\r\n各字段分别为 名称、简称、介绍、头像的在线链接\r\n\r\n\r\n\r\n\r\n```\r\nconst metadata = {    name: \"Per aspera ad astra\",    symbol: \"PAA\",    uri: \"https://white-historical-basilisk-887.mypinata.cloud/ipfs/QmVd6xVRqg9sJQP1zkUVizZ7jah6zD7j6fSPn9F7MRjZMo\",}\r\n```\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n### 七、杂项配置\r\n\r\n```\r\n// 生成 Mint 签名者const mint = generateSigner(umi);​// 使用 use 方法配置 UMI 的签名者和元数据模块umi.use(signerIdentity(userWalletSigner))   .use(mplTokenMetadata())\r\n```\r\n\r\n\r\n\r\n### 八、成功\r\n\r\n```\r\ncreateAndMint(umi, {    mint,    authority: umi.identity,    name: metadata.name,    symbol: metadata.symbol,    uri: metadata.uri,    sellerFeeBasisPoints: percentAmount(0),    decimals: 9,    amount: 666_000000000,    tokenOwner: userWallet.publicKey,    tokenStandard: TokenStandard.Fungible,    }).sendAndConfirm(umi).then(() => {    console.log(\"Successfully minted tokens (\", mint.publicKey, \")\");})\r\n```\r\n\r\n重要字段的含义为：\r\n\r\n* sellerFeeBasisPoints: percentAmount(0) 卖方费用为0\r\n* amount: 666\\_000000000,最终数量为666，后面的0对应小数精度\r\n* tokenStandard: TokenStandard.Fungible,令牌标准，此处为可替代令牌\r\n\r\n\r\n\r\n\r\n执行 index.js 代码\r\n\r\n```\r\nnode .\\index.js\r\n```\r\n\r\n![](https://infura-ipfs.mora.host/ipfs/QmdutDfQbUcq7DWG3Qmxuz1T4ZvDvW83YRRCAdT9mtEK31)\r\n\r\n得到带有元数据的新令牌\r\n\r\nEpnTRJksPN5GicrhpLDHhW67dArQuYPnf8B1rWx7u96k\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n区块浏览器验证\r\n\r\n![](https://infura-ipfs.mora.host/ipfs/QmWyncpfwfCcGVe72jQwvM2rQh92D93t8tb8mj5GeEnFyx)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n### 九、全部代码\r\n\r\n```javascript\r\n// 引入各模块\r\nimport { percentAmount, generateSigner, signerIdentity, createSignerFromKeypair } from '@metaplex-foundation/umi'\r\nimport { TokenStandard, createAndMint ,mplTokenMetadata} from '@metaplex-foundation/mpl-token-metadata'\r\nimport { createUmi } from '@metaplex-foundation/umi-bundle-defaults'\r\nimport { Keypair } from \"@solana/web3.js\"\r\nimport { readFileSync } from 'fs'\r\n\r\n// 连接到 Solana devnet\r\nconst umi = createUmi('https://hidden-purple-arrow.solana-devnet.quiknode.pro/206956a59552f9a87a253f7172eb7f58c9246801/')\r\n\r\n\r\n// 使用 id.json 本地的私钥文件，实例化钱包\r\nconst userKeypair = Keypair.fromSecretKey(\r\n    Buffer.from(JSON.parse(readFileSync('./id.json', \"utf-8\")))\r\n)\r\n// 获取签名者\r\nconst userWallet = umi.eddsa.createKeypairFromSecretKey(userKeypair.secretKey);\r\nconst userWalletSigner = createSignerFromKeypair(umi, userWallet);\r\n\r\n// 构建元数据\r\nconst metadata = {\r\n    name: \"Per aspera ad astra\",\r\n    symbol: \"PAA\",\r\n    uri: \"https://white-historical-basilisk-887.mypinata.cloud/ipfs/QmVd6xVRqg9sJQP1zkUVizZ7jah6zD7j6fSPn9F7MRjZMo\",\r\n}\r\n\r\n// 生成 Mint 签名者\r\nconst mint = generateSigner(umi);\r\n\r\n// 使用 use 方法配置 UMI 的签名者和元数据模块\r\numi.use(signerIdentity(userWalletSigner))\r\n   .use(mplTokenMetadata())\r\n\r\n\r\n// 打包发送 令牌铸造的交易\r\ncreateAndMint(umi, {\r\n    mint,\r\n    authority: umi.identity,\r\n    name: metadata.name,\r\n    symbol: metadata.symbol,\r\n    uri: metadata.uri,\r\n    sellerFeeBasisPoints: percentAmount(0),\r\n    decimals: 9,\r\n    amount: 666_000000000,\r\n    tokenOwner: userWallet.publicKey,\r\n    tokenStandard: TokenStandard.Fungible,\r\n    }).sendAndConfirm(umi).then(() => {\r\n    console.log(\"Successfully minted tokens (\", mint.publicKey, \")\");\r\n})\r\n```\r\n\r\n<!--EndFragment-->"},"author":{"user":"https://learnblockchain.cn/people/6803","address":"0x513Dd2b49363C8506B037afd487e3a7d18bbfEC0"},"history":"bafkreibvpko5wui7rjwayha7k2ejjlsoljac7ayjp52a6vsi4pb7lemexy","timestamp":1741396382,"version":1}