paint-brush
Cách xây dựng cổng sưu tầm kỹ thuật số bằng cách sử dụng Flow và Cadence (Phần 2)by@johnjvester
213

Cách xây dựng cổng sưu tầm kỹ thuật số bằng cách sử dụng Flow và Cadence (Phần 2)

John Vester15m2024/02/27
Read on Terminal Reader

Với cổng Collectibles trên chuỗi khối Flow và được triển khai trên mạng thử nghiệm, giờ đây chúng ta có thể tập trung vào việc tạo giao diện người dùng bằng React trong phần kết của loạt bài này.
featured image - Cách xây dựng cổng sưu tầm kỹ thuật số bằng cách sử dụng Flow và Cadence (Phần 2)
John Vester HackerNoon profile picture
0-item


Chào mừng bạn đến với bước cuối cùng trong quá trình tạo cổng sưu tầm của bạn! (phần 1 xem tại đây )


Trong phần này, chúng ta sẽ tập trung vào việc xây dựng giao diện người dùng—mảnh ghép cuối cùng.


Đây là những gì chúng ta sẽ đạt được:


  1. Kết nối Ví Flow.
  2. Khởi tạo tài khoản của bạn và đúc NFT của bạn.
  3. Kiểm tra ID NFT trong Bộ sưu tập của bạn.
  4. Xem NFT bằng ID NFT bạn có trong Bộ sưu tập của mình.


Chúng tôi sẽ sử dụng Next.js để xây dựng giao diện người dùng.


Bắt đầu nào!


1. Cài đặt

Đang cài đặt

Mở thư mục flow-collectible-portal dự án của bạn. Sau đó chạy
npx create-next-app@latest frontend trong terminal và nhấn enter .


Điều này sẽ cung cấp cho bạn một số tùy chọn. Trong hướng dẫn này, chúng tôi sẽ không sử dụng Typescript , ESLint hoặc TailwindCSS và chúng tôi sẽ sử dụng thư mục src và bộ định tuyến Ứng dụng tại thời điểm viết bài này.


Bây giờ bạn đã có sẵn một ứng dụng web mới.

Thư mục lối vào của bạn trông như thế này:



2. Cấu hình

Để tương tác với chuỗi khối Flow, chúng tôi sẽ sử dụng Thư viện ứng dụng khách Flow (FCL) để quản lý các kết nối ví, chạy tập lệnh và gửi giao dịch trong ứng dụng của chúng tôi. Nó sẽ cho phép chúng ta viết các hàm Cadence hoàn chỉnh và chạy chúng dưới dạng các hàm Javascript.


Để bắt đầu, hãy cài đặt FCL cho ứng dụng của chúng tôi bằng cách chạy lệnh sau:


 npm install @onflow/fcl --save


Sau khi cài đặt FCL, chúng ta cần cấu hình nó. Đây là những gì bạn cần làm:


  1. Bên trong thư mục app , tạo một thư mục mới có tên flow và thêm tệp có tên config.js .
  2. Trong tệp này, hãy thiết lập cấu hình cho FCL, chẳng hạn như chỉ định Nút truy cập và điểm cuối khám phá ví. Điều này giúp bạn lựa chọn giữa việc sử dụng testnet hoặc trình mô phỏng cục bộ.
  3. Bạn cũng sẽ muốn chỉ định địa chỉ hợp đồng sưu tầm mà chúng tôi đã triển khai trong Phần 1.


Thêm mã sau vào tệp config.js :


 import { config } from "@onflow/fcl"; config({ "app.detail.title": "Flow Name Service", "app.detail.icon": "https://placekitten.com/g/200/200", "accessNode.api": "https://rest-testnet.onflow.org", "discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn", "0xCollectibles": "ADD YOUR CONTRACT ACCOUNT ADDRESS", "0xNonFungibleToken": "0x631e88ae7f1d7c20", });


Bây giờ bạn đã sẵn sàng sử dụng FCL trong ứng dụng của mình.


3. Xác thực

Để xác minh danh tính của người dùng trong ứng dụng, bạn có thể sử dụng một số chức năng:


  1. Để đăng nhập, hãy gọi fcl.logIn() .
  2. Để đăng ký, hãy gọi fcl.signUp() .
  3. Để đăng xuất, hãy gọi fcl.unauthenticate() .


Hãy tìm hiểu cách chúng tôi có thể triển khai các hàm fcl này trong giao diện người dùng của bạn.


Đầu tiên, chúng ta sẽ thêm đoạn mã sau vào tệp page.js bên trong thư mục ứng dụng. Điều này sẽ nhập một số phần phụ thuộc, thiết lập một số useState ban đầu cho các phần của ứng dụng của chúng tôi và xây dựng giao diện người dùng cơ bản.


Để đảm bảo nó trông đẹp mắt, hãy xóa tệp page.module.css bên trong thư mục ứng dụng và thay vào đó tạo một tệp có tên page.css. Sau đó dán nội dung của tập tin này vào bên trong nó. Bây giờ chúng ta có thể viết ra trang đầu tiên của mình.


 "use client"; import React, { useState, useEffect, useRef } from "react"; import * as fcl from "@onflow/fcl"; import "./page.css"; import "./flow/config"; export default function Page() { const [currentUser, setCurrentUser] = useState({ loggedIn: false, addr: undefined, }); const urlInputRef = useRef(); const nameInputRef = useRef(); const idInputRef = useRef(); const [isInitialized, setIsInitialized] = useState(); const [collectiblesList, setCollectiblesList] = useState([]); const [loading, setLoading] = useState(false); const [ids, setIds] = useState([]); const [nft, setNFT] = useState({}); useEffect(() => fcl.currentUser.subscribe(setCurrentUser), []); function handleInputChange(event) { const inputValue = event.target.value; if (/^\d+$/.test(inputValue)) { idInputRef.current = +inputValue; } else { console.error("Invalid input. Please enter a valid integer."); } } return ( <div> <div className="navbar"> <h1>Flow Collectibles Portal</h1> <span>Address: {currentUser?.addr ?? "NO Address"}</span> <button onClick={currentUser.addr ? fcl.unauthenticate : fcl.logIn}> {currentUser.addr ? "Log Out" : "Connect Wallet"} </button> </div> {currentUser.loggedIn ? ( <div className="main"> <div className="mutate"> <h1>Mutate Flow Blockchain</h1> <form onSubmit={(event) => { event.preventDefault(); }} > <input type="text" placeholder="enter name of the NFT" ref={nameInputRef} /> <input type="text" placeholder="enter a url" ref={urlInputRef} /> <button type="submit">Mint</button> </form> <mark>Your Collection will be initialized while minting NFT.</mark> </div> <div className="query"> <h1>Query Flow Blockchain</h1> <mark>Click below button to check 👇</mark> <button>Check Collection</button> <p> Is your collection initialized: {isInitialized ? "Yes" : "No"} </p> <button onClick={viewIds}> View NFT IDs you hold in your collection </button> <p>NFT Id: </p> </div> <div className="view"> <h1>View Your NFT</h1> <input type="text" placeholder="enter your NFT ID" onChange={handleInputChange} /> <button>View NFT</button> <div className="nft-card"> <p>NFT id: </p> <p>NFT name: </p> <img src="" alt="" /> </div> </div> </div> ) : ( <div className="main-2"> <h1>Connect Wallet to mint NFT!!</h1> </div> )} </div> ); }


Sau khi thêm mã này, hãy chạy npm run dev để đảm bảo mọi thứ tải chính xác.


4. Truy vấn chuỗi khối Flow

Trước khi đi sâu vào cách chúng ta có thể sử dụng fcl để truy vấn chuỗi khối Flow, hãy thêm các mã tập lệnh Cadence này sau hàm handleInput trong tệp page.js


 const CHECK_COLLECTION = ` import NonFungibleToken from 0xNonFungibleToken import Collectibles from 0xCollectibles pub fun main(address: Address): Bool? { return Collectibles.checkCollection(_addr: address) }` const GET_NFT_ID = ` import NonFungibleToken from 0xNonFungibleToken import Collectibles from 0xCollectibles pub fun main(user: Address): [UInt64] { let collectionCap = getAccount(user).capabilities.get <&{Collectibles.CollectionPublic}>(/public/NFTCollection) ?? panic("This public capability does not exist.") let collectionRef = collectionCap.borrow()! return collectionRef.getIDs() } ` const GET_NFT = ` import NonFungibleToken from 0xNonFungibleToken import Collectibles from 0xCollectibles pub fun main(user: Address, id: UInt64): &NonFungibleToken.NFT? { let collectionCap= getAccount(user).capabilities.get<&{Collectibles.CollectionPublic}>(/public/NFTCollection) ?? panic("This public capability does not exist.") let collectionRef = collectionCap.borrow()! return collectionRef.borrowNFT(id: id) }


Khi các tập lệnh Cadence của chúng tôi đã sẵn sàng hoạt động, giờ đây chúng tôi có thể khai báo một số hàm Javascript và chuyển các hằng số Cadence vào các truy vấn `fcl` .


 async function checkCollectionInit() { const isInit = await fcl.query({ cadence: CHECK_COLLECTION, args: (arg,t) => [arg(currentUser?.addr, t.Address)], }); console.log(isInit); } async function viewNFT() { console.log(idInputRef.current); const nfts = await fcl.query({ cadence: GET_NFT, args: (arg,t) => [arg(currentUser?.addr,t.Address), arg(idInputRef.current, t.UInt64)] }); setNFT(nfts); console.log(nfts); } async function viewIds() { const ids = await fcl.query({ cadence: GET_NFT_ID, args: (arg,t) => [arg(currentUser?.addr,t.Address)] }); setIds(ids); console.log(ids); }


Bây giờ chúng ta hãy xem tất cả các chức năng chúng tôi đã viết. Có hai điều cần chú ý:


  1. fcl.query
  2. args: (arg,t) => [arg(addr,t.Address)], line.


Vì các tập lệnh tương tự như các chức năng view trong Solidity và không yêu cầu bất kỳ khoản phí gas nào để chạy nên về cơ bản chúng tôi chỉ đang truy vấn chuỗi khối. Vì vậy chúng tôi sử dụng fcl.query để chạy tập lệnh trên Flow.


Để truy vấn một cái gì đó, chúng ta cần truyền một đối số. Để làm được điều đó, chúng tôi sử dụng arg, là một hàm lấy giá trị chuỗi đại diện cho đối số và t , là một đối tượng chứa tất cả các kiểu dữ liệu khác nhau mà Cadence có. Vì vậy, chúng ta có thể cho arg biết cách mã hóa và giải mã đối số mà chúng ta đang truyền.

5. Thay đổi chuỗi khối Flow

Mặc dù các chức năng trước đây của chúng tôi chỉ là “chỉ đọc”, nhưng các chức năng tiếp theo của chúng tôi sẽ có các hành động có thể thay đổi trạng thái blockchain và ghi vào nó; hay còn gọi là “đúc NFT.”


Để làm điều này, chúng ta sẽ viết một tập lệnh Cadence khác dưới dạng hằng số.


 const MINT_NFT = ` import NonFungibleToken from 0xNonFungibleToken import Collectibles from 0xCollectibles transaction(name:String, image:String){ let receiverCollectionRef: &{NonFungibleToken.CollectionPublic} prepare(signer:AuthAccount){ // initialise account if signer.borrow<&Collectibles.Collection>(from: Collectibles.CollectionStoragePath) == nil { let collection <- Collectibles.createEmptyCollection() signer.save(<-collection, to: Collectibles.CollectionStoragePath) let cap = signer.capabilities.storage.issue<&{Collectibles.CollectionPublic}>(Collectibles.CollectionStoragePath) signer.capabilities.publish( cap, at: Collectibles.CollectionPublicPath) } //takes the receiver collection refrence self.receiverCollectionRef = signer.borrow<&Collectibles.Collection>(from: Collectibles.CollectionStoragePath) ?? panic("could not borrow Collection reference") } execute{ let nft <- Collectibles.mintNFT(name:name, image:image) self.receiverCollectionRef.deposit(token: <-nft) } }


Bây giờ hãy thêm hàm bên dưới sau mã giao dịch vào tệp page.js


 async function mint() { try{ const txnId = await fcl.mutate({ cadence: MINT_NFT, args: (arg,t) => [arg(name,t.String), arg(image, t.String)], payer: fcl.authz, proposer: fcl.authz, authorizations: [fcl.authz], limit:999,}); } catch(error){ console.error('Minting failed:' error) } console.log(txnId); }


Về hàm, cú pháp fcl.mutate giống với fcl.query . Tuy nhiên, chúng tôi cung cấp một số thông số bổ sung như sau:


 payer: fcl.authz, proposer: fcl.authz, authorizations: [fcl.authz], limit: 50,


  • Đây là những thứ cụ thể theo Dòng xác định tài khoản nào sẽ thanh toán cho giao dịch (người trả tiền), truyền phát giao dịch (người đề xuất) và tài khoản mà chúng tôi cần ủy quyền. (Trong trường hợp một tài khoản có nhiều khóa được đính kèm, nó có thể hoạt động giống như một ví nhiều chữ ký.)
  • fcl.authz đề cập đến tài khoản hiện được kết nối.
  • limit giống như gasLimit trong thế giới Ethereum, đặt giới hạn trên cho số lượng tính toán tối đa. Nếu tính toán vượt quá giới hạn thì giao dịch sẽ thất bại.


Chúng ta sẽ cần thêm một hàm nữa để gọi và xử lý hàm mintNFT mà chúng ta vừa tạo.


 const saveCollectible = async () => { if (urlInputRef.current.value.length > 0 && nameInputRef.current.value.length > 0) { try { setLoading(true); const transaction = await mintNFT(nameInputRef.current.value, urlInputRef.current.value); console.log('transactionID:', transaction); // Handle minting success (if needed) } catch (error) { console.error('Minting failed:', error); // Handle minting failure (if needed) } finally { setLoading(false); } } else { console.log('Empty input. Try again.'); } };


6. Mã cuối cùng

Với các chức năng chính đã có, giờ đây chúng tôi có thể cắm chúng vào giao diện người dùng của mình.


Tuy nhiên, trước khi thực hiện điều đó, chúng tôi sẽ thêm một số lệnh gọi useEffect để giúp tải trạng thái ban đầu. Bạn có thể thêm những thứ này ngay phía trên lệnh gọi useEffect hiện có.


 useEffect(() => { checkCollectionInit(); viewNFT(); }, [currentUser]); useEffect(() => { if (currentUser.loggedIn) { setCollectiblesList(collectiblesList); console.log('Setting collectibles...'); } }, [currentUser]);


Bây giờ quay lại phần return với giao diện người dùng, chúng ta có thể thêm các chức năng của mình vào các phần thích hợp của ứng dụng.


 return ( <div> <div className="navbar"> <h1>Flow Collectibles Portal</h1> <span>Address: {currentUser?.addr ?? "NO Address"}</span> <button onClick={currentUser.addr ? fcl.unauthenticate : fcl.logIn}> {currentUser.addr ? "Log Out" : "Connect Wallet"} </button> </div> {currentUser.loggedIn ? ( <div className="main"> <div className="mutate"> <h1>Mutate Flow Blockchain</h1> <form onSubmit={(event) => { event.preventDefault(); saveCollectible(); }} > <input type="text" placeholder="enter name of the NFT" ref={nameInputRef} /> <input type="text" placeholder="enter a url" ref={urlInputRef} /> <button type="submit">Mint</button> </form> <mark>Your Collection will be initialized while minting NFT.</mark> </div> <div className="query"> <h1>Query Flow Blockchain</h1> <mark>Click below button to check 👇</mark> <button onClick={checkCollectionInit}>Check Collection</button> <p> Is your collection initialized: {isInitialized ? "Yes" : "No"} </p> <button onClick={viewIds}> View NFT IDs you hold in your collection </button> <p>NFT Id: </p> {ids.map((id) => ( <p key={id}>{id}</p> ))} </div> <div className="view"> <h1>View Your NFT</h1> <input type="text" placeholder="enter your NFT ID" onChange={handleInputChange} /> <button onClick={viewNFT}>View NFT</button> <div className="nft-card"> <p>NFT id: {nft.id}</p> <p>NFT name: {nft.name}</p> <img src={nft.image} alt={nft.name} /> </div> </div> </div> ) : ( <div className="main-2"> <h1>Connect Wallet to mint NFT!!</h1> </div> )} </div> );


Kiểm tra mã cuối cùng ở đây .


Bây giờ khi ứng dụng đã hoàn tất, hãy cùng tìm hiểu cách sử dụng nó!


Trước tiên, hãy kết nối ví của bạn bằng cách nhấp vào nút “Kết nối ví” ở trên cùng bên phải.


Bây giờ bạn có thể đúc NFT! Nhập tên NFT của bạn và dán vào liên kết tới hình ảnh bạn muốn sử dụng. Sau khi bạn nhấp vào “mint”, nó sẽ nhắc bạn ký một giao dịch bằng ví của mình.


Có thể mất một chút thời gian để giao dịch hoàn tất. Sau khi hoàn tất, bạn có thể nhấp vào nút dưới cùng để xem ID NFT của mình. Nếu đây là lần đầu tiên của bạn thì ID sẽ chỉ là “1”.


Bây giờ bạn có thể sao chép ID NFT của mình, dán nó vào phần Xem và nhấp vào “Xem NFT”.


Phần kết luận

Làm tốt! Bạn đã hoàn thành phần 2 của dự án cổng thông tin sưu tầm. Tóm lại, chúng tôi tập trung vào việc xây dựng giao diện người dùng của cổng thông tin sưu tầm của mình.


Chúng tôi đã làm điều này bằng cách:


  • Tạo một ứng dụng với Next.js
  • Kết nối ví Flow
  • Tạo NFT của riêng chúng tôi để khai thác
  • Xem NFT của bạn


Chúc bạn có một ngày thật tuyệt vời!


Cũng được xuất bản ở đây.