Để tiếp tục với series bài viết về Blockchain Solana thì hôm nay mình sẽ giới thiệu và hướng dẫn các bạn xây dựng hệ thống Backend để gọi đến Solana thông qua Web3 để đúc NFT (mint NFT).
Bài viết sẽ gồm các 2 phần:
- Phần 1:
- Thiết kế hệ thống
- Dựng hệ thống Backend API bằng Nodejs
- Build và deploy SmartContract mint NFT
- Phần 2:
- Code API kết nối SmartContract
- Code API thực hiện mint NFT
Chúng ta bắt đầu phần 1 nhé.
I. Thiết kế hệ thống
Có rất nhiều bài viết hướng dẫn xây dựng hệ thống Frontend dùng JS để kết nối tới Solana Network thông qua Web3, tuy nhiên nếu hệ thống Frontend thì khi muốn thao tác lưu lại các thông tin mà Solana trả về thì chúng ta lại cần gọi tiếp các API lên các hệ thống Backend. Vì vậy, mình sẽ thiết kế 1 hệ thống Backend API để có thể gọi lên Solana Network, sau khi nhận được kết quả thì có thể lưu vào Database luôn mà ko cần gọi thêm các API khác nữa. Database mình đang dùng ở đây là MongoDB.
Tổng quát thiết kế hệ thống:
II. Dựng hệ thống Backend API bằng NodeJS
Trong bài viết này, mình sẽ sử dụng NodeJS, cụ thể là framework Express để viết API Backend. Để thực hiện phần này, mình đang sử dụng môi trường như sau:
- Hệ điều hành: Windows 10
- Database: MongoDB (cài bản mới nhất tại https://www.mongodb.com/docs/manual/installation/)
- NodeJS: https://nodejs.org/en/
- Công cụ lập trình: Git, IDE (Inteliji), Yarn
Sau khi cài đặt môi trường, chúng ta bắt đầu dựng hệ thống nhé.
Bước 1: Dựng base API:
$ git clone https://github.com/hagopj13/node-express-boilerplate vnlab-nft-certificate-backend
Cloning into 'vnlab-nft-certificate-backend'...
remote: Enumerating objects: 1494, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 1494 (delta 0), reused 0 (delta 0), pack-reused 1491
Receiving objects: 100% (1494/1494), 1.09 MiB | 3.03 MiB/s, done.
Resolving deltas: 100% (882/882), done.
$ cd vnlab-nft-certificate-backend/
$ yarn install
yarn install v1.22.19
...
husky - Git hooks installed
Done in 20.13s.
Bước 2: Config .env
Copy file môi trường và sửa nội dung file .env:
$ cp .env.example .env
Sau khi sửa lại file .env, nội dung file sẽ như thế này :
# Port number
PORT=3000
# URL of the Mongo DB
MONGODB_URL=mongodb://127.0.0.1:27017/node-boilerplate
# JWT
# JWT secret key
JWT_SECRET=thisisasamplesecret
# Number of minutes after which an access token expires
JWT_ACCESS_EXPIRATION_MINUTES=3000
# Number of days after which a refresh token expires
JWT_REFRESH_EXPIRATION_DAYS=30
# Number of minutes after which a reset password token expires
JWT_RESET_PASSWORD_EXPIRATION_MINUTES=1000
# Number of minutes after which a verify email token expires
JWT_VERIFY_EMAIL_EXPIRATION_MINUTES=10
# SMTP configuration options for the email service
# For testing, you can use a fake SMTP service like Ethereal: https://ethereal.email/create
#SMTP_HOST=email-server
#SMTP_PORT=587
#SMTP_USERNAME=email-server-username
#SMTP_PASSWORD=email-server-password
#EMAIL_FROM=support@yourapp.com
Để hiểu hơn về các cài đặt, các bạn có thể đọc thêm trong file README.md của mã nguồn.
Bước 3: Test hệ thống vừa dựng
Sau khi chỉnh sửa xong file .env và lưu lại, chúng ta chạy hệ thống vừa dựng:
$ yarn dev
yarn run v1.22.19
$ cross-env NODE_ENV=development nodemon src/index.js
[nodemon] 2.0.9
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
info: Connected to MongoDB
info: Listening to port 3000
warn: Unable to connect to email server. Make sure you have configured the SMTP options in .env
Mở trình duyệt và truy cập url: http://localhost:3000/v1/docs/ . Đây là trang tài liệu API được viết sẵn bằng Swagger, có giao diện để chúng ta có thể test API.
Thử test API auth/register để lấy token:
Curl:
'http://localhost:3000/v1/auth/register' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"name": "fake name",
"email": "fake2@example.com",
"password": "password1"
}'
Response:
{
"user": {
"role": "user",
"isEmailVerified": false,
"name": "fake name",
"email": "fake2@example.com",
"id": "632838d9df923b6c08bc2e4c"
},
"tokens": {
"access": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2MzI4MzhkOWRmOTIzYjZjMDhiYzJlNGMiLCJpYXQiOjE2NjM1ODAzNzcsImV4cCI6MTY2Mzc2MDM3NywidHlwZSI6ImFjY2VzcyJ9.7uHRxjZ_Iomb4WuE6s9Skm8rR5h0YrrTtYOUX9iF_6Q",
"expires": "2022-09-21T11:39:37.618Z"
},
"refresh": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2MzI4MzhkOWRmOTIzYjZjMDhiYzJlNGMiLCJpYXQiOjE2NjM1ODAzNzcsImV4cCI6MTY2NjE3MjM3NywidHlwZSI6InJlZnJlc2gifQ.au5qEFvGiTqmh5aR53tu_snTLRqca2Z09yLlmFrrheM",
"expires": "2022-10-19T09:39:37.620Z"
}
}
}
Token này dùng để gọi các API khác, các lần sau cần lấy token, các bạn sử dụng API auth/login để lấy nhé. Như vậy là chúng ta đã dựng xong code base API bằng NodeJS để chuẩn bị viết API cho việc gọi lên Solana network.
III. Build và deploy SmartContract để mint NFT
Để hiểu hơn về smartcontract solana, các bạn có thể đọc thêm bài này: [Solana Blockchain] Phát triển ứng dụng Blockchain trên Solana Network bằng Anchor Framework (1). Mình có tham khảo bài viết này để dựng hệ thống với môi trường như sau:
- Hệ điều hành: Ubuntu 20.10 (Cài đặt trên máy ảo của windows 10)
- solana-cli 1.9.22
- anchor-cli 0.24.2
- Công cụ deploy: Git, npm, yarn
Bước 1: Tạo các Account và setup môi trường
Tạo Token Account dùng để trả phí cho việc deploy và thực thi các giao dịch
Nếu bạn chưa có Token Account bạn có thể tạo bằng command sau
solana-keygen new
Mặc định thì keypair được lưu tại ~/.config/solana/id.json
Chỉ định DevNet để deploy Smart Contract
$ solana config set --url devnet
Config File: /home/vagrant/.config/solana/cli/config.yml
RPC URL: https://api.devnet.solana.com
WebSocket URL: wss://api.devnet.solana.com/ (computed)
Keypair Path: /home/vagrant/.config/solana/id.json
Commitment: confirmed
Airdrop để lấy Sol trả phí cho các giao dịch:
$ solana airdrop 2
Requesting airdrop of 2 SOL
Signature: 62L46ZdVUd2WMgJcU9rszedJ2ZyNVrCFrkTTieBSC65NPqfGp2MKGVXJGZfJYvScAhM9ghW7QmR7yFhnXhh99NQT
2.80521464 SOL
Bước 2: Dựng source code logic của smart-contract:
$ git clone https://github.com/gmo-vietnamlab/sol-mint-nft.git vnlab-sol-mint-nft
Cloning into 'vnlab-sol-mint-nft'...
remote: Enumerating objects: 145, done.
remote: Counting objects: 100% (145/145), done.
remote: Compressing objects: 100% (122/122), done.
remote: Total 145 (delta 55), reused 90 (delta 5), pack-reused 0
Receiving objects: 100% (145/145), 666.45 KiB | 2.40 MiB/s, done.
Resolving deltas: 100% (55/55), done.
$ cd vnlab-sol-mint-nft/
$ yarn
yarn install v1.22.19
warning package.json: No license field
warning No license field
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
warning "@project-serum/anchor > @solana/web3.js > sinon-chai@3.7.0" has unmet peer dependency "sinon@>=4.0.0".
[4/4] Building fresh packages...
success Saved lockfile.
Done in 12.11s.
Bước 3: Build Smartcontract bằng anchor:
$ anchor build
BPF SDK: /home/vagrant/.local/share/solana/install/releases/stable-0fd793565846b0c12cfe2797ca0f087f7609bdf2/solana-release/bin/sdk/bpf
...
...
To deploy this program:
$ solana program deploy /home/vagrant/vm-playbook/vnlab-sol-mint-nft/target/deploy/sol_mint_nft.so
The program address will default to this keypair (override with --program-id):
/home/vagrant/vm-playbook/vnlab-sol-mint-nft/target/deploy/sol_mint_nft-keypair.json
$ anchor keys list
sol_mint_nft: D8zZ4Vh5tjfotLQYES8xGtYkaeU5BDrhyFesjHxiFe7E
Thay key D8zZ4Vh5tjfotLQYES8xGtYkaeU5BDrhyFesjHxiFe7E
vào declare_id!()
của file vnlab-sol-mint-nft/programs/sol-mint-nft/src/lib.rs
:
declare_id!("D8zZ4Vh5tjfotLQYES8xGtYkaeU5BDrhyFesjHxiFe7E");
Sau đó build lại:
$ anchor build
BPF SDK: /home/vagrant/.local/share/solana/install/releases/stable-0fd793565846b0c12cfe2797ca0f087f7609bdf2/solana-release/bin/sdk/bpf
...
...
To deploy this program:
$ solana program deploy /home/vagrant/vm-playbook/vnlab-sol-mint-nft/target/deploy/sol_mint_nft.so
The program address will default to this keypair (override with --program-id):
/home/vagrant/vm-playbook/vnlab-sol-mint-nft/target/deploy/sol_mint_nft-keypair.json
Bước 4: Deploy Smartcontract:
$ solana program deploy /home/vagrant/vm-playbook/vnlab-sol-mint-nft/target/deploy/sol_mint_nft.so
Program Id: D8zZ4Vh5tjfotLQYES8xGtYkaeU5BDrhyFesjHxiFe7E
Ở bước này, các bạn cần lưu lại 2 thông tin sau để phục vụ cho các bước sau:
- File idl:
vnlab-sol-mint-nft/target/idl/sol_mint_nft.json
- Program Id:
D8zZ4Vh5tjfotLQYES8xGtYkaeU5BDrhyFesjHxiFe7E
Như vậy, sau bước này là chúng ta đã tạo được smart-contract để mint NFT, và đẩy lên Solana Devnet. Các bạn có thể kiểm tra smart-contract này ở đây: https://explorer.solana.com/address/D8zZ4Vh5tjfotLQYES8xGtYkaeU5BDrhyFesjHxiFe7E?cluster=devnet
IV. Mã nguồn và bài viết tham khảo
Trong bài viết này, mình đã hướng dẫn các bạn cách dựng API backend bằng nodejs, và build, deploy 1 smart-contract để chuẩn bị cho việc viết API mint NFT ở phần 2.
Mã nguồn cho bài viết, các bạn có thể xem ở đây:
- Backend: https://github.com/gmo-vietnamlab/nft-certificate-backend
- Smart-contract: https://github.com/gmo-vietnamlab/sol-mint-nft
Trong bài viết có sử dụng open source và một số tài liệu tham khảo: