Trong bài này tôi sẽ hướng dẫn phát hành 1 NFT trên Aelf
Vấn đề
Trước khi bắt đầu hãy tự tưởng tượng ra business của riêng mình :))
Ứng dụng của tôi muốn phát hành 1 bộ sưu tập (Collections). Mỗi bộ sưu tập sẽ có thể có nhiều item mỗi item sẽ mang 1 số serials khách nhau.
Mỗi Collection và item sẽ có 1 vizualize (Ảnh bìa)
Oke để dễ hình dung chúng ta có sơ đồ sau
Chúng ta sẽ không lưu và phát hành trước bất kỳ thông tin gì về collection
Khi nguời dùng thực hiện trao đổi mua bán item chúng ra sẽ tạo và chuyển cho người dung. Ở bài viết này chúng ta chỉ đi qua demo về luồng thực hiện. Bạn hãy kết hơp với database và hệ thống của riêng mình để tạo môt ứng dụng hoàn chỉnh
Kiến thức nền
Trước khi code có một số thứ chúng ta sẽ cần nắm
Aelf có một trang trao đổi mua bán symbol: https://www.eforest.finance/symbolmarket
Trong môi trường test ta sử dụng trang test: https://test.eforest.finance/symbolmarket
Lưu ý: Có 2 option lựa chọn TOKEN hoăc NFT Collection. Trong bài này chúng ta muốn phát hành NFT nên sẽ chọn NFT
Mỗi token hoặc NFT sẽ có ký hiệu SYMBOL (các chữ cái A – Z).
Để tạo ra được 1 NFT Collection bạn cần mua token SEED. Chỉ khi có token SEED bạn mới tạo được ra được Collection
Quy ước bởi Aelf
- Collection sẽ có dạng SYMBOL-0
- Mỗi item sẽ là SYMBOL-1 với số được tăng dần
VD:
- Seed symbol: DUNGXBUIF
- Collection symbol: DUNGXBUIF-0
- NFT item: DUNGXBUIF-1, DUNGXBUIF-2, ….
Cài ví Portkey để thao tác:
https://chromewebstore.google.com/detail/portkey-wallet/iglbgmakmggfkoidiagnhknlndljlolb?pli=1
Phát hành 1 NFT
Create EOA Account
https://docs.aelf.io/en/latest/reference/cli/methods.html#create-create-a-new-account
VD:
AElf [Info]: Your wallet info is :
AElf [Info]: Mnemonic : crumble defense differ nice engage phrase notable horror skirt belt sadness replace
AElf [Info]: Private Key : 67504a981b821380fecd0fa64e3334ebd85733f189d5cd5b0619e7a7ce1f34cc
AElf [Info]: Public Key : 047eee348e30dd56be980664d21229cb40ad25407baf28cf925aaa381e01f6584e908903f8ed9b36fe2fa0f399044a1dca1dc21e169e6250e480c69bcdd5e5afb5
AElf [Info]: Address : E1RB4MpEoxf9sYVNbW8VuBufE6PRgWEdqDPADBvzBhqkZt9SS
Nhận faucet token
https://faucet-ui-preview.vercel.app
Mua Symbol NFT ở store
https://doc.portkey.finance/docs/QuickStartGuides/LaunchTokenAndNFTCollection/ObtainSEED https://test.eforest.finance/symbolmarket
Kiểm tra portkey wallet
Ta chuyển quyền sở hữu symbol SEED sang tài khoản Admin của hệ thống
Hướng dẫn trên tài liệu của portkey
Giao dịch thành công
https://explorer-test.aelf.io/tx/d9c6add581f84b9e394403cfb8745a78e1934223d4a2a96d072e9063e4d826ce https://explorer-test.aelf.io/token/SEED-2498#balances
Cài đặt code
Code mẫu:
https://github.com/dungxbuif/aelf-mint-nft
const exploreLink = (transactionId) => { if (NODE_ENV === 'producion') { return `https://explorer.aelf.io/tx/${transactionId}#logs`; } return `https://explorer-test.aelf.io/tx/${transactionId}#logs`;}
const runWithTrx = async (fn, des) => {
try {
const { TransactionId } = await fn;
const result = await aelf.chain.getTxResult(TransactionId);
const link = exploreLink(TransactionId);
console.log(`${des} Explore:`, link);
console.log(`${des} Result`, result);
return result;
} catch (error) {
console.log(`${des} Error:`, error);
}
};
Code Helper giúp thực thi và log lại transaction
async function createNftCollection(payload) {
const collectionSymbol = payload.symbol;
let collectionInfo = await AelfConfig.tokenContract.GetTokenInfo.call({
symbol: collectionSymbol,
});
if (collectionInfo) {
throw new Error('Collection already exists');
}
await runWithTrx(
AelfConfig.tokenContract.Create(payload),
`Create Collection ${collectionSymbol}`
);
}
Function tạo Collection
async function mintNft(payload, receiverAddress) {
const symbol = payload.symbol;
let nftInfo = await AelfConfig.tokenContract.GetTokenInfo.call({
symbol,
});
if (nftInfo) {
throw new Error('NFT existed');
}
await runWithTrx(
AelfConfig.tokenContract.Create(payload),
`Mint NFT ${symbol}`
);
const memo = `Issue NFT ${symbol}`;
await new Promise(resolve => setTimeout(resolve, 4000));
return runWithTrx(
AelfConfig.tokenContract.Issue({
symbol: symbol,
amount: 1,
to: receiverAddress,
memo,
}),
memo
);
}
Function giúp mint (Đúc) 1 nft vào blockchain
Chạy thử server
Tạo 1 collection
curl --location 'http://localhost:8080/api/catalogues' \
--header 'Cookie: SESSION=YjE1YjNlNzItMGExMS00NWFkLWE5YjYtYTg2ZWJhZTRkMjVl; SESSION=YzU1ZDA5ZGYtNTRlMS00NTVmLWIzNWYtN2RlOWQ1NmY2ZmE3' \
--header 'Content-Type: application/json' \
--data '{
"symbol": "DUNGXBUIF-0",
"tokenName": "Bộ sưu tập của DUNGXBUIF",
"totalSupply": 1,
"decimals": 0,
"issuer": "E1RB4MpEoxf9sYVNbW8VuBufE6PRgWEdqDPADBvzBhqkZt9SS",
"isBurnable": true,
"issueChainId": 9992731,
"owner": "E1RB4MpEoxf9sYVNbW8VuBufE6PRgWEdqDPADBvzBhqkZt9SS"
}'
ở Payload chính là structure để tạo 1 NFT:
https://docs.aelf.io/en/latest/reference/smart-contract-api/multi-token.html#token-createinput
Mint 1 NFT
Khi người dùng trao đổi NFT chúng ta tiến hành Mint 1 NFT và chuyển đến ví của người dung. Hãy triển khai thêm code với nghiệp vụ để quản lý việc trao đổi
curl --location 'http://localhost:3000/catalogues/mint' \
--header 'Content-Type: application/json' \
--header 'Cookie: SESSION=YzU1ZDA5ZGYtNTRlMS00NTVmLWIzNWYtN2RlOWQ1NmY2ZmE3' \
--data '{
"payload": {
"symbol": "DUNGXBUIF-1",
"tokenName": "Item 1",
"totalSupply": 1,
"decimals": 0,
"issuer": "2qgqjrzT5Lpyr7oDbhyD3BkLx8u7aTZoMeMTAQnWdburJJuxnZ",
"isBurnable": true,
"issueChainId": 9992731,
"owner": "E1RB4MpEoxf9sYVNbW8VuBufE6PRgWEdqDPADBvzBhqkZt9SS"
},
"receiverAddress": “1RB4MpEoxf9sYVNbW8VuBufE6PRgWEdqDPADBvzBhqkZt9SS"
}'
Xong vậy bạn đã sở hữu 1 NFT tại Aelf blockchain.