Published on
Solana

ทดลองสร้าง Token บน Solana ด้วย SPL Token CLI

create-token-with-solana-spl-cli

สวัสดีครับ วันนี้มาแนะนำบทความสร้าง Token (SPL Token) บน Solana ผ่านการใช้งาน SPL Token CLI กันครับ

ทั้งหมดเป็น Devnet นะครับ และไม่ควรใช้ Wallet จริง ควรเป็น Wallet (Keypair) ที่ถูก generate มาใหม่ หรือใช้ develop เท่านั้น

สิ่งที่ต้องมี

ติดตั้ง Solana CLI

sh -c "$(curl -sSfL https://release.solana.com/stable/install)"

สามารถดูวิธีการติดตั้ง Solana หรือ เขียน Solana Program จากบล็อกก่อนหน้านี้ของผมได้ครับ

ติดตั้ง Rust ผ่าน Rustup

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

ติดตั้ง spl-token

$ cargo install spl-token-cli

เช็ค version ของแต่ละตัว ว่าติดตั้งเรียบร้อยแล้ว

rustup --version
cargo --version
solana version
spl-token --version

Create Wallet

เริ่มต้นสร้าง wallet ของเราขึ้นมาก่อน

solana-keygen new

จะมีข้อความขึ้น เพื่อให้เราใส่ BIP39 Passphrase เพื่อเพิ่ม security อีกชั้น ซึ่งเรากด enter เฉยๆ เพื่อไม่ต้องใส่ก็ได้ เพราะเป็นแค่ dev (แต่ถ้าเป็นกระเป๋าที่ใช้งานจริงๆ แนะนำให้ใส่นะครับ ซึ่ง BIP39 มีคำอะไรบ้างดูทีนี่)

Generating a new keypair

For added security, enter a BIP39 passphrase

NOTE! This passphrase improves security of the recovery seed phrase NOT the
keypair file itself, which is stored as insecure plain text

BIP39 Passphrase (empty for none):

ตัว Solana จะทำการ generate Wallet ให้เรา โดยเราจะได้ pubkey ที่เป็น wallet address และ seed phrase 12 คำ

แต่ถ้าหากเราอยากกำหนดไฟล์ output เราสามารถระบุ option ให้มันได้ครับ แบบนี้

solana-keygen new -o ~/Desktop/test-account.json

ตัวอย่าง สมมติเราเสร็จได้ pubkey มา ถ้าเราลืมว่า pubkey เราคืออะไร สามารถเช็คได้ด้วยคำสั่ง

solana address -k <path/to/keypair.json>

เช่น

solana address -k ~/.config/solana/id.json

สุดท้าย เราสามารถ grind หรือสร้าง pubkey ให้เป็นแบบที่เราต้องการได้ เช่น ให้ pubkey ขึ้นต้นด้วยคำที่เราต้อง หรือลงท้ายด้วยคำที่เราต้องการ

solana-keygen grind --starts-with hi:1

มันก็จะ generate pubkey ที่ขึ้นต้นด้วย hi ให้เรา ยิ่งคำที่ต้องการค้นหาเยอะเท่าไหร่ ก็ใช้เวลาหานานขึ้น และโอกาสที่จะเจอก็น้อยครับ

# ถ้าอยากให้ output 12 คำ ด้วย ก็ใช้ --use-mnemonic
solana-keygen grind --use-mnemonic --starts-with hi:1

# output file ได้เหมือนปกติ
solana-keygen grind --starts-with hi:1 -o my-wallet.json

Config devnet

ในบทความนี้เราจะใช้ devnet ในการทดสอบ ข้อดีคือเราจะเห็น result ทั้งผ่าน Command Line และ Explorer

โดยในตัวอย่าง ผมจะสร้าง account ขึ้นมาใหม่ และจะใช้ address นี้อ้างอิง จะได้เห็นภาพไปด้วยกันนะครับ

solana-keygen grind --starts-with Hi:1

Wrote keypair to HiHhPVf9hLNuLADjXyZQNtG5rgWuqG1AxQt7iqWNpjps.json

pubkey ผมคือ HiHhPVf9hLNuLADjXyZQNtG5rgWuqG1AxQt7iqWNpjps

ต่อมา config network เป็น devnet

solana config set --url https://api.devnet.solana.com

และ set keypair path เป็นที่อยู่ของกระเป๋า dev ที่ผมเพิ่งสร้าง (ผมสร้างไว้ Desktop)

solana config set --keypair ~/Desktop/HiHhPVf9hLNuLADjXyZQNtG5rgWuqG1AxQt7iqWNpjps.json

เมื่อเรา set url และ keypair เสร็จ จะได้ผลลัพธ์ของ solana config ประมาณด้านล่างนี้ (ต่างกันที่ตำแหน่งที่เก็บไฟล์น และชื่อไฟล์ นะครับ)

Config File: /Users/chai/.config/solana/cli/config.yml
RPC URL: https://api.devnet.solana.com
WebSocket URL: wss://api.devnet.solana.com/ (computed)
Keypair Path: /Users/chai/Desktop/HiHhPVf9hLNuLADjXyZQNtG5rgWuqG1AxQt7iqWNpjps.json
Commitment: confirmed

ต่อมาทำการ airdrop ให้ account ที่เราเพิ่งสร้าง

solana airdrop 2 <wallet_address>

ก็จะได้เป็น

solana airdrop 2 HiHhPVf9hLNuLADjXyZQNtG5rgWuqG1AxQt7iqWNpjps

เป็นการส่งเงิน 2 SOL ไปให้ Account ที่เราระบุไว้

  • เมื่อลองไปเช็คใน Explorer ก็จะเห็น Transaction History หรือใช้ Solscan

จะเห็น airdrop transaction (ผมส่งไป 2 ครั้ง) และ Balance (SOL) คือ 4 SOL

Solana Explorer

Create Token

เมื่อมีเงินใน Balance ต่อมาคือสร้าง Token ด้วยคำสั่ง

spl-token create-token

จะได้ผลลัพธ์เป็นแบบนี้

Creating token 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB

Signature: 4ytyJ8GRhWPBLiqtiteai4qCZ7ZSBtwVpyNCLo8vYgk6zsVApkoiza6eHUoF6dMoGsaQWezGVQFiSc7xbWLMyhB2

โดยที่ 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB คือ Token Address ของเราครับ

ลองเข้าไปค้นหาใน Solana Explorer จะเห็นว่า Supply เราเป็น 0 หรือใช้ Cli ด้วยคำสั่ง

spl-token supply 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB

จะเห็น supply เป็น 0 และลองเช็ค balance ดู

spl-token balance 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB

ไม่สามารถทำได้ เพราะไม่มี token account ที่เก็บข้อมูล balance นั่นเอง (ตัวที่ spl-token สร้างเป็นแค่ token ธรรมดา มี metadata)

สิ่งที่เราต้องทำคือทำการ mint เพื่อให้มี supply แต่ว่าเราจะ mint ได้ เราต้องสร้าง account ขึ้นมาเพื่อเก็บ balance ของ token เรา ใช้คำสั่ง

spl-token create-account 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB

จะได้ผลลัพธ์เป็น:

Creating account Fj8Ptsjjp6x1AK75BKV9mfediGMvk3BFWGGqnTQ4XSPF

Signature: 3XG8WgS44pUrkQSN8ZrnL3R1LPpRbBamdGHe8586LYDvWgKzSCpVRawxG9pka3btE6ycQHrvVaZ3gNqh2TrkbyoR

ตัว Fj8Ptsjjp6x1AK75BKV9mfediGMvk3BFWGGqnTQ4XSPF คือ Account ที่เอาไว้เก็บ state balance ของ token ครับ (ตรงนี้อาจจะสับสน แนะนำดูเรื่อง Solana Accounts เพิ่มเติมนะครับ)

ทีนี้เราสามารถเช็ค balance ของ Token เราได้แล้ว

spl-token balance 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB

ณ ตอนนี้ เรามี 3 Addresses ละนะครับ เผื่อหลายคนสับสน

  • Wallet Address (กระเป๋าเรา): HiHhPVf9hLNuLADjXyZQNtG5rgWuqG1AxQt7iqWNpjps
  • Token Address (Token ของเรา): 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB
  • Token Account Address: Fj8Ptsjjp6x1AK75BKV9mfediGMvk3BFWGGqnTQ4XSPF

ทำการ Mint token ออกมาซัก 100,000

spl-token mint 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB 100000

ลองเช็ค supply ผ่าน Explorer หรือ Cli:

spl-token supply 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB

เช็คว่าเรามี token ใน account (wallet เรา) นี้เท่าไหร่

spl-token accounts

ได้ผลลัพธ์เป็น

Token                                         Balance
---------------------------------------------------------------
8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB  100000

หรือถ้า Explorer จะเป็น link นี้

ต่อมาลองส่ง token ไปให้คนอื่นดู โดยมันมีรูปแบบแบบนี้

spl-token transfer <TOKEN_ADDRESS> <TOKEN_AMOUNT> <RECIPIENT_ADDRESS>

ผมส่ง 888 token ไปให้ account ใหม่ ฉะนั้นก็จะได้เป็นแบบนี้

spl-token transfer --fund-recipient 8CPVtuC9fh3RGztd4ugZsTgDPb57449BpfU1Qucks4iB 888 EjPKhV2bww3NLs9isZQQBia4f6JMFxewfnygaMe7cMBs
  • EjPKhV2bww3NLs9isZQQBia4f6JMFxewfnygaMe7cMBs คือ account ที่ผมส่งเงินไปให้ (ผม solana-keygen new ขึ้นมาใหม่อีก wallet)
  • --fund-recipient ที่ต้องใส่ เพราะปกติ แต่ละ wallet account ต้องมี Associate account สำหรับ token นั้นๆ ก่อน (เหมือนกับที่สร้าง empty account เพื่อเก็บ balance ครับ) สิ่งที่ --fund-recipient ทำคือ มัน สร้าง AssociatedAccount ให้เราอัตโนมัติ นั่นเอง

จริงๆ เราสามารถสร้าง NFT ด้วยนะครับ ก็เหมือนการสร้าง Token ทุกอย่าง

spl-token create-token --decimals 0

เพียงแต่ ปกติตอนเรา create-token ถ้าเราไม่ได้กำหนด option ค่า default ของมันคือ decimals เท่ากับ 9 พอเรากำหนด decimals = 0 นั่นหมายความว่า 1 token ก็คือ 1 NFT นั่นเอง

Phantom Wallet

เราสามารถนำ Wallet ของเราไป import ใช้กับ Phantom Wallet ได้เหมือนปกติเลย จะใช้ 12 คำ หรือ private key ก็ได้

ตัวอย่างการ import private key คือ ในไฟล์ *.json ของเรา ปกติ มันก็เก็บ public + private key อยู่แล้ว เป็น Buffer แบบด้านล่าง

[154,246,53,155,1,2,2,2,3,3,34,43,3,5,23,5,34,5,34, ... ,61,190]

ฉะนั้นไฟล์ Keypair สำคัญมากๆ เพราะมันเก็บ public + private key ใครเข้าถึง ใครอ่านได้ ก็เข้าถึงกระเป๋าได้ครับ

นำไปเพิ่มใน Phantom

Phantom Wallet 1

เปลี่ยน Network เป็น Devnet

Phantom Wallet 2

เพียงแค่นี้เราก็เห็น Token เราใน Phantom แล้ว ลอง transfer token ดูครับ และลองดู transaction ใน Solscan / Explorer เปรียบเทียบดูครับ

SPL Token Registry

หลายคนอาจจะสงสัย ว่าเรากำหนด ชื่อ Name, Symbol ของ Token เรายังไง? คำตอบคือมันไม่ได้ถูกเก็บใน Blockchain แบบ EVM-Based ครับ

สิ่งที่เราต้องทำคือ ไปเพิ่ม JSON shema เช่น กำหนด token, chainId, address, ชื่อ, symbol, logo เป็นต้น ที่ Repo นี้ครับ

ส่วนตัวผมก็ยังไม่เคยเพิ่มไปนะครับ เพราะใช้แค่ Devnet ยังไม่เคยทำ Product ที่เป็น Production จริงๆครับ ซึ่ง devnet ผมก็ไม่อยากเพิ่มให้เปลือง list เปล่าๆ คือมันแค่เทส เลยไม่จำเป็น

สรุป

ตัวอย่างนี้ก็เป็นตัวอย่างง่ายๆ ในการ สร้าง Token (SPL Token) บน Solana นะครับ แม้จะเป็น CLI แต่ก็ทำให้เห็นภาพมากขึ้น จะเห็นว่าทุกๆ Token และทุกๆ account การที่เราจะมี token นั้นๆ ได้ สิ่งที่ต้องทำคือ มี AssociatedAccount

และแต่ละขั้นตอน ถ้าไม่เข้าใจ แนะนำว่าลองเล่น ลองพิมพ์ และดู Solscan หรือ Solana Explorer เปรียบเทียบดูนะครับ เช่นส่วน Instructions จะบอกว่า transaction ทำอะไร เป็นต้น

หวังว่าบทความนี้เป็นประโยชน์นะครับ Happy Coding ❤️

References

Authors
Discord