나도 solana로 밈코인 만들 수 있을까?
솔라나에 밈코인을 발행해보자.
프로젝트 개요
참조
개발환경
- Node.js
- Solana tool suite
- Metaplex
- Phantom
준비
필자는 맥 터미널로 진행합니다.
최신 solana cli를 설치합니다.
[참조: https://docs.solanalabs.com/cli/install]
sh -c "$(curl -sSfL https://release.solana.com/v1.18.4/install)"
현재 필자의 환경
workspace % node -v
v20.8.0
workspace % npm -v
10.1.0
workspace % yarn -v
1.22.19
workspace % ts-node -v
v10.9.2
workspace % solana --version
solana-cli 1.18.4 (src:356c6a38; feat:3352961542, client:SolanaLabs)
~/workspace 에서 진행합니다.
일단, 작업 디렉토리를 생성해요.
workspace % mkdir meme
workspace % cd meme
meme %
밈코인을 만들려면 두가지 리소스가 필요합니다.
- 토큰 이미지 파일
- 메터데이터 json 파일
토큰 이미지는 ai 이미지 생성기에서 돌려 얻어보겠습니다.
자! 이제, 이미지를 https://nft.storage/에 올립니다. ipfs를 사용하는 off-chain 분산 스토리지를 제공하는 무료 서비스입니다.
올라가면, 주소*(View URL)를 볼 수 있어요.
https://bafybeif2gqc72oeefebn77kp4iomrgshfevzxnuyre6eqnu7xara7anlgm.ipfs.nftstorage.link/
제 경우는 위와 같이 나왔어요.
JSON 파일을 준비해 봅시다. 저는 아래와 같이 만들고
{
"name": "Dokdo Coin",
"symbol": "DOK",
"description": "Dokdo Coin",
"image": "https://bafybeif2gqc72oeefebn77kp4iomrgshfevzxnuyre6eqnu7xara7anlgm.ipfs.nftstorage.link"
}
다시, https://nft.storage/ 에 올렸습니다.
https://bafkreico2rt2pdqy57nakinjq4egzyj63w4mu5hixun32nvnim6dzphzmm.ipfs.nftstorage.link/
이제, 위에 주소를 가지고, 토큰을 만들어 보겠습니다.
일단, 두개의 지갑(계좌, Keypair?)이 필요합니다.
- 발행인의 지갑(발행비 결제 및 토큰 소유주)
- 밈코인 자체의 주소가될 Keypair
이왕이면 의미있는 주소였으면 좋겠습니다. 그래서 아래와 같이 만들겠습니다.
# east로 시작하는 주소 생성
workspace % solana-keygen grind --starts-with east:1
# Dokdo로 시작하는 주소 생성
workspace % solana-keygen grind --starts-with Dokdo:1
필자는 아래의 두개의 지갑 파일이 나왔습니다.
eastQhAYNCtxPGhG6YWifPWo1P3FVsSaH97vUSmDHjE.json DokdodChquwPecMeimj7jPGncNHXoHHFdoCEKav5KAp4.json
리소스 준비가 끝났으니, 시작해보겠습니다.
mint.ts라는 파일을 만들겠습니다.
import { percentAmount, generateSigner, signerIdentity, createSignerFromKeypair } from '@metaplex-foundation/umi'
import { TokenStandard, createAndMint } from '@metaplex-foundation/mpl-token-metadata'
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplCandyMachine } from "@metaplex-foundation/mpl-candy-machine";
import "@solana/web3.js";
import secret from './eastQhAYNCtxPGhG6YWifPWo1P3FVsSaH97vUSmDHjE.json';
import dokdo from './DokdodChquwPecMeimj7jPGncNHXoHHFdoCEKav5KAp4.json';
const umi = createUmi('https://api.devnet.solana.com/'); //원하는 endpoint로 변경, 데브넷, 테스트넷, 메인넷
const userWallet = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(secret));
const userWalletSigner = createSignerFromKeypair(umi, userWallet);
const mintKeypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(dokdo));
const mintSigner = createSignerFromKeypair(umi, mintKeypair);
const metadata = {
name: "Dokdo Coin",
symbol: "DOK",
uri: "https://bafkreico2rt2pdqy57nakinjq4egzyj63w4mu5hixun32nvnim6dzphzmm.ipfs.nftstorage.link",
};
const mint = mintSigner;// generateSigner(umi);
umi.use(signerIdentity(userWalletSigner));
umi.use(mplCandyMachine())
createAndMint(umi, {
mint,
authority: umi.identity,
name: metadata.name,
symbol: metadata.symbol,
uri: metadata.uri,
sellerFeeBasisPoints: percentAmount(0),
decimals: 8,
amount: 51751000_000_00000000,
tokenOwner: userWallet.publicKey,
tokenStandard: TokenStandard.Fungible,
}).sendAndConfirm(umi).then(() => {
console.log("Successfully minted 1 million tokens (", mint.publicKey, ")");
});
일단, 환경을 확인해보겠습니다.
meme % solana config get
Config File: /Users/kjaylee/.config/solana/cli/config.yml
RPC URL: https://api.testnet.solana.com
WebSocket URL: wss://api.testnet.solana.com/ (computed)
Keypair Path: /Users/kjaylee/workspace/solana.keys/DTPRZ8VZtcjmb9vxB8VRqsX7QKEp69ASgwHrWTtv7s38.json
Commitment: confirmed
testnet으로 되어 있군요. 제가 주로 쓰는 Keypair(지갑)이 등록되어 있고요.
이 두개를 바꾸겠습니다. devnet으로 해보죠.
[참조: https://solana.com/docs/core/clusters]
meme % solana config set --url https://api.devnet.solana.com
Config File: /Users/kjaylee/.config/solana/cli/config.yml
RPC URL: https://api.devnet.solana.com
WebSocket URL: wss://api.devnet.solana.com/ (computed)
Keypair Path: /Users/kjaylee/workspace/solana.keys/DTPRZ8VZtcjmb9vxB8VRqsX7QKEp69ASgwHrWTtv7s38.json
Commitment: confirmed
meme % solana config set --keypair ./eastQhAYNCtxPGhG6YWifPWo1P3FVsSaH97vUSmDHjE.json
Config File: /Users/kjaylee/.config/solana/cli/config.yml
RPC URL: https://api.devnet.solana.com
WebSocket URL: wss://api.devnet.solana.com/ (computed)
Keypair Path: ./eastQhAYNCtxPGhG6YWifPWo1P3FVsSaH97vUSmDHjE.json
Commitment: confirmed
airdrop부터 하나 받고 하겠습니다.
당연하게도, 돈이 있어야 돈이 발행됩니다.
meme % solana airdrop 1
Requesting airdrop of 1 SOL
Signature: 5ciDBVVhJyi1HqsLZbST9FfMbWvQsLvSikXzFrsRXNfXNY7hrwKkdw8toB4gaKqDyU4NyCjdh8j1CW3pQGtJkTeU
1 SOL
meme % solana account eastQhAYNCtxPGhG6YWifPWo1P3FVsSaH97vUSmDHjE
Public Key: eastQhAYNCtxPGhG6YWifPWo1P3FVsSaH97vUSmDHjE
Balance: 1 SOL
Owner: 11111111111111111111111111111111
Executable: false
Rent Epoch: 18446744073709551615
잘 들어온게 확인이 되죠? 아래, 소수점 표현 8과, amount는 정하시면 됩니다. (대한민국 1인당 1000개?)
...
decimals: 8,
amount: 51751000_000_00000000,
...
이제, 필요한 초기화를 하겠습니다.
meme % yarn init --yes
yarn init v1.22.19
warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications.
success Saved package.json
✨ Done in 0.03s.
meme % tsc --init
Created a new tsconfig.json with:
TS
target: es2016
module: commonjs
strict: true
esModuleInterop: true
skipLibCheck: true
forceConsistentCasingInFileNames: true
You can learn more at https://aka.ms/tsconfig
tsconfig.json 파일을 열어서, 아래 줄을 찾아 주석을 제거해서 활성화해주세요.
"resolveJsonModule": true
필요한 라이브러리 설치
meme % yarn add @solana/web3.js @metaplex-foundation/umi @metaplex-foundation/mpl-token-metadata @metaplex-foundation/umi-bundle-defaults @metaplex-foundation/mpl-candy-machine bs58
밈코인 생성!!
meme % ts-node mint.ts
Successfully minted 1 million tokens ( DokdodChquwPecMeimj7jPGncNHXoHHFdoCEKav5KAp4 )
https://explorer.solana.com/address/DokdodChquwPecMeimj7jPGncNHXoHHFdoCEKav5KAp4?cluster=devnet
짜잔@@~
이 글이 도움이 되어, 자신만의 밈 토큰을 만드셨다면 저에게도 보내 자랑해주세요. 다음 편에는 밈토큰 갤러리 및 교환소를 만들 예정입니다.
GPEh8bJ63xtkvSrxpa8JDSYEMVzh3i9LD6hCtpTwr5th