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 1)by@johnjvester
355
355

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 1)

John Vester20m2024/02/13
Read on Terminal Reader

Hiểu thêm về ngôn ngữ hợp đồng thông minh của chuỗi khối Flow và Cadence bằng cách xây dựng một trang web mới tập trung vào việc thu thập các đồ sưu tầm kỹ thuật số.
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 1)
John Vester HackerNoon profile picture

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách xây dựng một trang web để thu thập các đồ sưu tầm kỹ thuật số (hoặc NFT) trên blockchain Flow. Chúng tôi sẽ sử dụng ngôn ngữ hợp đồng thông minh Cadence cùng với React để biến tất cả thành hiện thực. Chúng ta cũng sẽ tìm hiểu về Flow, những ưu điểm của nó và những công cụ thú vị mà chúng ta có thể sử dụng.


Đến cuối bài viết này, bạn sẽ có các công cụ và kiến thức cần thiết để tạo ứng dụng phi tập trung của riêng mình trên chuỗi khối Flow.


Hãy đi sâu vào ngay!


Chúng ta đang xây dựng cái gì?

Chúng tôi đang xây dựng một ứng dụng dành cho sưu tầm kỹ thuật số. Mỗi bộ sưu tập là một Mã thông báo không thể thay thế (NFT). (Nếu bạn là người mới và chưa hiểu NFT, hãy xem tại đây.) Ứng dụng của chúng tôi sẽ cho phép bạn thu thập NFT và mỗi mục sẽ là duy nhất so với những mục khác.


Để thực hiện tất cả những điều này, chúng tôi sẽ sử dụng Tiêu chuẩn NonFungibleToken của Flow, đây là một bộ quy tắc giúp chúng tôi quản lý các mục kỹ thuật số đặc biệt này (tương tự như ERC-721 trong Ethereum).

Điều kiện tiên quyết

Trước khi bắt đầu, hãy nhớ cài đặt Flow CLI trên hệ thống của bạn. Nếu bạn chưa làm như vậy, hãy làm theo các hướng dẫn cài đặt sau.

Đang cài đặt

Nếu bạn đã sẵn sàng khởi động dự án của mình, trước tiên, hãy nhập thiết lập luồng lệnh.


Lệnh này thực hiện một số phép thuật đằng sau hậu trường để thiết lập nền tảng cho dự án của bạn. Nó tạo ra một hệ thống thư mục và thiết lập một tệp có tên flow.json để định cấu hình dự án của bạn, đảm bảo mọi thứ đều được sắp xếp và sẵn sàng hoạt động!


Cấu trúc dự án

Dự án sẽ chứa thư mục cadence và tệp flow.json . (Tệp flow.json là tệp cấu hình cho dự án của bạn, được duy trì tự động.)

Thư mục Cadence chứa các mục sau:

  • /hợp đồng: Chứa tất cả các hợp đồng Cadence.
  • /scripts: Chứa tất cả các tập lệnh Cadence.
  • /giao dịch: Lưu trữ tất cả các giao dịch Cadence.


Thực hiện theo các bước bên dưới để sử dụng Tiêu chuẩn Flow NFT.

Bước 1: Tạo một tập tin.

Đầu tiên, hãy chuyển đến thư mục flow-collectibles-portal và tìm thư mục cadence . Sau đó, mở thư mục contracts . Tạo một tệp mới và đặt tên là NonFungibleToken.cdc .

Bước 2: Sao chép và dán.

Bây giờ, hãy mở liên kết có tên NonFungibleToken chứa tiêu chuẩn NFT. Sao chép tất cả nội dung từ tệp đó và dán vào tệp mới bạn vừa tạo ("NonFungibleToken.cdc").


Đó là nó! Bạn đã thiết lập thành công các tiêu chuẩn cho dự án của mình.

Bây giờ, hãy viết một số mã!


Tuy nhiên, trước khi đi sâu vào mã hóa, điều quan trọng là các nhà phát triển phải thiết lập một mô hình tinh thần về cách cấu trúc mã của họ.


Ở cấp cao nhất, cơ sở mã của chúng tôi bao gồm ba thành phần chính:

  1. NFT: Mỗi bộ sưu tập được thể hiện dưới dạng NFT.


  2. Bộ sưu tập: Bộ sưu tập đề cập đến một nhóm NFT do một người dùng cụ thể sở hữu.


  3. Hàm và biến toàn cầu: Đây là các hàm và biến được xác định ở cấp độ toàn cầu cho hợp đồng thông minh và không được liên kết với bất kỳ tài nguyên cụ thể nào.

Cấu trúc hợp đồng thông minh

Cấu trúc cơ bản của hợp đồng thông minh

Tạo một tệp mới có tên Collectibles.cdc bên trong cadence/contracts . Đây là nơi chúng ta sẽ viết mã.


Cấu trúc hợp đồng

 import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ pub var totalSupply: UInt64 // other code will come here init(){ self.totalSupply = 0 } }


Hãy chia nhỏ từng dòng mã:


  1. Trước tiên, chúng tôi cần tiêu chuẩn hóa rằng chúng tôi đang xây dựng NFT bằng cách đưa vào cái gọi là "NonFungibleToken". Đây là tiêu chuẩn NFT do Flow xây dựng nhằm xác định bộ chức năng sau đây phải có trong mỗi hợp đồng thông minh NFT.


  2. Sau khi nhập, hãy tạo hợp đồng của chúng tôi. Để làm điều đó, chúng tôi sử dụng pub contract [contract name] . Sử dụng cùng một cú pháp mỗi lần bạn tạo hợp đồng mới. Bạn có thể điền contract name bằng bất cứ tên nào bạn muốn gọi cho hợp đồng của mình. Trong trường hợp của chúng tôi, hãy gọi nó là Collectibles .


  3. Tiếp theo, chúng tôi muốn đảm bảo rằng hợp đồng của chúng tôi tuân theo một bộ chức năng và quy tắc nhất định của NonFungibleToken. Để làm điều đó, chúng tôi thêm giao diện NonFungibleToken với sự trợ giúp của `:`.
    Như thế này ( `pub contract Collectibles: NonFungibleToken{}` )


  4. Mỗi hợp đồng PHẢI có hàm init() . Nó được gọi khi hợp đồng ban đầu được triển khai. Điều này tương tự như những gì Solidity gọi là Trình xây dựng.


  5. Bây giờ, hãy tạo một biến toàn cục có tên totalSupply với kiểu dữ liệu UInt64 . Biến này sẽ theo dõi tổng số Đồ sưu tầm của bạn.


  6. Bây giờ, khởi tạo totalSupply với giá trị 0 .


Đó là nó! Chúng tôi thiết lập nền tảng cho hợp đồng Collectibles của mình. Bây giờ, chúng ta có thể bắt đầu thêm nhiều tính năng và chức năng hơn để khiến nó trở nên thú vị hơn nữa.


Trước khi tiếp tục, vui lòng xem đoạn mã để hiểu cách chúng tôi xác định các biến trong Cadence:


NFT tài nguyên

Thêm mã sau vào hợp đồng thông minh của bạn:


 import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ // above code… pub resource NFT: NonFungibleToken.INFT{ pub let id: UInt64 pub var name: String pub var image: String init(_id:UInt64, _name:String, _image:String){ self.id = _id self.name = _name self.image = _image } } // init()... }


Như bạn đã thấy trước đây, hợp đồng triển khai giao diện chuẩn NFT, được biểu thị bằng pub contract Collectibles: NonFungibleToken . Tương tự, các tài nguyên cũng có thể triển khai các giao diện tài nguyên khác nhau.


Vì vậy, hãy thêm giao diện NonFungibleToken.INFT vào Tài nguyên NFT, giao diện này bắt buộc phải tồn tại một thuộc tính công cộng có tên id trong tài nguyên.

Dưới đây là các biến chúng tôi sẽ sử dụng trong tài nguyên NFT:


  • id: Duy trì ID của NFT
  • name: Tên của NFT.
  • image: URL hình ảnh của NFT.


Sau khi xác định biến, hãy nhớ khởi tạo biến trong hàm init() .


Hãy tiếp tục và tạo một tài nguyên khác có tên là Collection Resource .

Tài nguyên sưu tập

Trước tiên, bạn cần hiểu cách hoạt động Collection Resources .


Nếu bạn cần lưu trữ một tập tin nhạc và một vài bức ảnh trên máy tính xách tay của mình, bạn sẽ làm gì?


Thông thường, bạn sẽ điều hướng đến một ổ đĩa cục bộ (giả sử là D-Drive của bạn) và tạo thư mục music và thư mục photos . Sau đó, bạn sẽ sao chép và dán các tệp nhạc và ảnh vào thư mục đích của mình.

Tương tự, đây là cách hoạt động của các bộ sưu tập kỹ thuật số của bạn trên Flow.


Hãy tưởng tượng máy tính xách tay của bạn là Flow Blockchain Account , D-Drive của bạn là Account Storage và Thư mục là Collection .


Vì vậy, khi tương tác với bất kỳ dự án nào để mua NFT, dự án sẽ tạo collection của nó trong account storage của bạn, tương tự như việc tạo một thư mục trên D-Drive của bạn. Khi bạn tương tác với 10 dự án NFT khác nhau, bạn sẽ có 10 bộ sưu tập khác nhau trong tài khoản của mình.


Nó giống như có một không gian cá nhân để lưu trữ và sắp xếp kho báu kỹ thuật số độc đáo của bạn!


 import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ //Above code NFT Resource… // Collection Resource pub resource Collection{ } // Below code… }


Mỗi collection có một biến ownedNFTs để chứa NFT Resources .


 pub resource Collection { pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } }


Giao diện tài nguyên

Giao diện resource trong Flow tương tự như giao diện trong các ngôn ngữ lập trình khác. Nó nằm trên một tài nguyên và đảm bảo rằng tài nguyên triển khai nó có chức năng cần thiết như được xác định bởi giao diện.


Nó cũng có thể được sử dụng để hạn chế quyền truy cập vào toàn bộ tài nguyên và hạn chế hơn về mặt sửa đổi quyền truy cập so với chính tài nguyên đó.


Trong tiêu chuẩn NonFungibleToken , có một số giao diện tài nguyên như INFT , Provider , ReceiverCollectionPublic .


Mỗi giao diện này có các chức năng và trường cụ thể cần được triển khai bởi tài nguyên sử dụng chúng.


Trong hợp đồng này, chúng tôi sẽ sử dụng ba giao diện này từ NonFungibleToken: Provider , ReceiverCollectionPublic . Các giao diện này xác định các chức năng như deposit , withdraw , borrowNFTgetIDs . Chúng tôi sẽ giải thích chi tiết từng điều này khi chúng tôi tiếp tục.


Chúng tôi cũng sẽ thêm một số sự kiện mà chúng tôi sẽ phát ra từ các hàm này, cũng như khai báo một số biến mà chúng tôi sẽ sử dụng thêm trong hướng dẫn.


 pub contract Collectibles:NonFungibleToken{ // rest of the code… pub event ContractInitialized() pub event Withdraw(id: UInt64, from: Address?) pub event Deposit(id: UInt64, to: Address?) pub let CollectionStoragePath: StoragePath pub let CollectionPublicPath: PublicPath pub resource interface CollectionPublic{ pub fun deposit(token: @NonFungibleToken.NFT) pub fun getIDs(): [UInt64] pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT } pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } } }


Rút


Bây giờ, hãy tạo withdraw() theo yêu cầu của giao diện.


 pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } init()... }


Với sự trợ giúp của chức năng này, bạn có thể di chuyển tài nguyên NFT ra khỏi bộ sưu tập. Nếu nó:


  • Thất bại : Hoảng sợ và ném ra lỗi.


  • Thành công : Nó phát ra sự kiện rút tiền và trả lại tài nguyên cho người gọi.


Sau đó, người gọi có thể sử dụng tài nguyên này và lưu nó vào bộ nhớ tài khoản của họ.


Tiền gửi

Bây giờ là lúc dùng hàm deposit()NonFungibleToken.Receiver yêu cầu.


 pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } init()... }


Vay và GetID


Bây giờ, hãy tập trung vào hai hàm mà NonFungibleToken.CollectionPublic: borrowNFT()getID() .


 pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT { if self.ownedNFTs[id] != nil { return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)! } panic("NFT not found in collection.") } pub fun getIDs(): [UInt64]{ return self.ownedNFTs.keys } init()... }


Hàm hủy diệt

Điều cuối cùng chúng ta cần cho Tài nguyên Bộ sưu tập là một hàm hủy.


 destroy (){ destroy self.ownedNFTs }


Vì tài nguyên Bộ sưu tập chứa các tài nguyên khác (tài nguyên NFT), nên chúng ta cần chỉ định một hàm hủy. Hàm hủy sẽ chạy khi đối tượng bị phá hủy. Điều này đảm bảo rằng tài nguyên không bị "vô gia cư" khi tài nguyên gốc của chúng bị phá hủy. Chúng tôi không cần hàm hủy cho tài nguyên NFT vì nó không chứa bất kỳ tài nguyên nào khác.


Hãy xem mã nguồn tài nguyên bộ sưu tập hoàn chỉnh:


 import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ pub var totalSupply: UInt64 pub resource NFT: NonFungibleToken.INFT{ pub let id: UInt64 pub var name: String pub var image: String init(_id:UInt64, _name:String, _image:String){ self.id = _id self.name = _name self.image = _image } } pub resource interface CollectionPublic{ pub fun deposit(token: @NonFungibleToken.NFT) pub fun getIDs(): [UInt64] pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT } pub event ContractInitialized() pub event Withdraw(id: UInt64, from: Address?) pub event Deposit(id: UInt64, to: Address?) pub let CollectionStoragePath: StoragePath pub let CollectionPublicPath: PublicPath pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } destroy (){ destroy self.ownedNFTs } pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT { if self.ownedNFTs[id] != nil { return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)! } panic("NFT not found in collection.") } pub fun getIDs(): [UInt64]{ return self.ownedNFTs.keys } } init(){ self.CollectionPublicPath = /public/NFTCollection self.CollectionStoragePath = /storage/NFTCollection self.totalSupply = 0 emit ContractInitialized() } }


Bây giờ, chúng tôi đã hoàn thành tất cả các tài nguyên. Tiếp theo, chúng ta sẽ xem xét chức năng toàn cầu.

Chức năng toàn cầu

Chức năng toàn cầu là các chức năng được xác định ở cấp độ toàn cầu của hợp đồng thông minh, nghĩa là chúng không phải là một phần của bất kỳ tài nguyên nào. Chúng có thể được công chúng truy cập và yêu cầu, đồng thời tiết lộ chức năng cốt lõi của hợp đồng thông minh cho công chúng.


  1. createEmptyCollection : Hàm này khởi tạo một Collectibles.Collection trống vào bộ nhớ tài khoản người gọi.


  2. checkCollection : Chức năng tiện dụng này giúp bạn khám phá xem tài khoản của bạn đã có tài nguyên bộ collection hay chưa.


  3. mintNFT : Chức năng này cực kỳ thú vị vì nó cho phép mọi người tạo NFT.


 // pub resource Collection… pub fun createEmptyCollection(): @Collection{ return <- create Collection() } pub fun checkCollection(_addr: Address): Bool{ return getAccount(_addr) .capabilities.get<&{Collectibles.CollectionPublic}> (Collectibles.CollectionPublicPath)! .check() } pub fun mintNFT(name:String, image:String): @NFT{ Collectibles.totalSupply = Collectibles.totalSupply + 1 let nftId = Collectibles.totalSupply var newNFT <- create NFT(_id:nftId, _name:name, _image:image) return <- newNFT } init()...


Kết thúc hợp đồng thông minh

Và bây giờ, CUỐI CÙNG, với mọi thứ đã sẵn sàng, chúng ta đã viết xong hợp đồng thông minh của mình. Hãy xem mã cuối cùng ở đây .


Bây giờ, hãy xem cách người dùng tương tác với các hợp đồng thông minh được triển khai trên chuỗi khối Flow.


Có hai bước để tương tác với chuỗi khối Flow:


  1. Thay đổi trạng thái bằng cách chạy các giao dịch.
  2. Truy vấn blockchain bằng cách chạy một tập lệnh.

Thay đổi trạng thái bằng cách chạy giao dịch

Giao dịch là dữ liệu được ký bằng mật mã chứa một bộ hướng dẫn tương tác với hợp đồng thông minh để cập nhật trạng thái Dòng. Nói một cách đơn giản, đây giống như một lệnh gọi hàm thay đổi dữ liệu trên blockchain. Các giao dịch thường liên quan đến một số chi phí, có thể thay đổi tùy thuộc vào blockchain bạn đang sử dụng.


Một giao dịch bao gồm nhiều giai đoạn tùy chọn: prepare , pre , execute và giai đoạn post .


Bạn có thể đọc thêm về điều này trong tài liệu tham khảo Cadence về giao dịch . Mỗi giai đoạn đều có một mục đích; hai giai đoạn quan trọng nhất là prepareexecute .


Prepare Phase : Giai đoạn này được sử dụng để truy cập dữ liệu và thông tin bên trong tài khoản của người ký (được loại AuthAccount cho phép).


Execute Phase : Giai đoạn này được sử dụng để thực hiện các hành động.


Bây giờ, hãy tạo một giao dịch cho dự án của chúng ta.


Thực hiện theo các bước bên dưới để tạo giao dịch trong thư mục dự án của bạn.

Bước 1: Tạo một tập tin.

Đầu tiên, hãy vào thư mục dự án và mở thư mục cadence . Bên trong nó, mở thư mục transaction và tạo một tệp mới có tên Create_Collection.cdcmint_nft.cdc

Bước 2: Thêm Mã giao dịch Tạo bộ sưu tập.

 import Collectibles from "../contracts/Collectibles.cdc" transaction { prepare(signer: AuthAccount) { 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) } } }


Hãy chia nhỏ mã này theo từng dòng:


  1. Giao dịch này tương tác với hợp đồng thông minh Collectibles. Sau đó, nó sẽ kiểm tra xem người gửi (người ký) có tài nguyên Bộ sưu tập được lưu trữ trong tài khoản của họ hay không bằng cách mượn tham chiếu đến tài nguyên Bộ sưu tập từ đường dẫn lưu trữ được chỉ định Collectibles.CollectionStoragePath . Nếu tham chiếu bằng 0 thì có nghĩa là người ký chưa có bộ sưu tập.


  2. Nếu người ký không có bộ sưu tập thì nó sẽ tạo một bộ sưu tập trống bằng cách gọi hàm createEmptyCollection() .


  3. Sau khi tạo bộ sưu tập trống, hãy đặt nó vào tài khoản của người ký theo đường dẫn lưu trữ được chỉ định Collectibles.CollectionStoragePath .


Việc này sẽ thiết lập liên kết giữa tài khoản của người ký và bộ sưu tập mới được tạo bằng cách sử dụng link() .

Bước 3: Thêm Mã giao dịch Mint NFT.

 import NonFungibleToken from "../contracts/NonFungibleToken.cdc" import Collectibles from "../contracts/Collectibles.cdc" transaction(name:String, image:String){ let receiverCollectionRef: &{NonFungibleToken.CollectionPublic} prepare(signer:AuthAccount){ 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) } }


Hãy chia nhỏ mã này theo từng dòng:

  1. Trước tiên, chúng tôi nhập hợp đồng NonFungibleTokenCollectibles contract .


  2. transaction(name: String, image: String) Dòng này xác định một giao dịch mới. Nó nhận vào hai đối số, tên và hình ảnh, cả hai đều thuộc loại Chuỗi. Các đối số này được sử dụng để truyền tên và hình ảnh của NFT đang được tạo.


  3. let receiverCollectionRef: &{NonFungibleToken.CollectionPublic} Dòng này khai báo một biến mới receiverCollectionRef. Nó tham chiếu đến một bộ sưu tập công khai các NFT thuộc loại NonFungibleToken.CollectionPublic . Tài liệu tham khảo này sẽ được sử dụng để tương tác với bộ sưu tập nơi chúng tôi sẽ gửi NFT mới được đúc.


  4. prepare(signer: AuthAccount) Dòng này bắt đầu khối chuẩn bị, khối này được thực thi trước giao dịch. Nó cần một người ký đối số thuộc loại AuthAccount . AuthAccount đại diện cho tài khoản của người ký giao dịch.


  5. Nó mượn một tham chiếu đến Collectibles.Collection từ bộ lưu trữ của người ký bên trong khối chuẩn bị. Nó sử dụng hàm mượn để truy cập tham chiếu đến bộ sưu tập và lưu trữ nó trong biến receiverCollectionRef .


    Nếu không tìm thấy tham chiếu (ví dụ: nếu bộ sưu tập không tồn tại trong bộ lưu trữ của người ký), nó sẽ đưa ra thông báo lỗi “không thể mượn tham chiếu Bộ sưu tập”.


  6. Khối execute chứa logic thực thi chính cho giao dịch. Mã bên trong khối này sẽ được thực thi sau khi khối prepare hoàn tất thành công.


  7. nft <- Collectibles.mintNFT(_name: name, image: image) Bên trong khối execute , dòng này gọi hàm mintNFT từ hợp đồng Collectibles với các đối số tên và hình ảnh được cung cấp. Chức năng này dự kiến sẽ tạo ra một NFT mới với tên và hình ảnh đã cho. Ký hiệu <- cho biết NFT đang được nhận dưới dạng một đối tượng có thể di chuyển được (tài nguyên).


  8. self.receiverCollectionRef.deposit(token: <-nft) Dòng này gửi NFT mới được tạo vào bộ sưu tập được chỉ định. Nó sử dụng chức năng gửi tiền trên receiverCollectionRef để chuyển quyền sở hữu NFT từ tài khoản thực thi giao dịch sang bộ sưu tập. Biểu tượng <- ở đây cũng chỉ ra rằng NFT đang được di chuyển dưới dạng tài nguyên trong quá trình deposit .

Truy vấn Blockchain bằng cách chạy tập lệnh

Chúng tôi sử dụng tập lệnh để xem hoặc đọc dữ liệu từ blockchain. Tập lệnh là miễn phí và không cần ký.

Thực hiện theo các bước bên dưới để tạo tập lệnh trong thư mục dự án của bạn.

Bước 1: Tạo một tập tin.

Đầu tiên, hãy vào thư mục dự án và mở thư mục cadence . Bên trong nó, mở thư mục script và tạo một tệp mới có tên view_nft.cdc .

Bước 2: Xem tập lệnh NFT

 import NonFungibleToken from "../contracts/NonFungibleToken.cdc" import Collectibles from "../contracts/Collectibles.cdc" 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) }


Hãy chia nhỏ mã này theo từng dòng:


  1. Đầu tiên, chúng tôi nhập hợp đồng NonFungibleTokenCollectibles .


  2. pub fun main(acctAddress: Address, id: UInt64): &NonFungibleToken.NFT? Dòng này xác định điểm vào của tập lệnh, đây là một hàm công khai có tên main. Hàm này có hai tham số:


  • acctAddress : Tham số loại Address đại diện cho địa chỉ của tài khoản trên chuỗi khối Flow.


  • id : Tham số loại UInt64 đại diện cho mã định danh duy nhất của NFT trong bộ sưu tập.


  1. Sau đó, chúng tôi sử dụng getCapability để tìm nạp khả năng Collectibles.Collection cho acctAddress được chỉ định. Khả năng là tham chiếu đến tài nguyên cho phép truy cập vào các chức năng và dữ liệu của nó. Trong trường hợp này, nó đang tìm nạp khả năng cho loại tài nguyên Collectibles.Collection .


  2. Sau đó, chúng tôi mượn NFT từ bộ collectionRef bằng cách sử dụng hàm borrowNFT . Hàm borrowNFT lấy tham số id , đây là mã định danh duy nhất của NFT trong bộ sưu tập. Chức năng borrow trên một khả năng cho phép đọc dữ liệu tài nguyên.


  3. Cuối cùng, chúng tôi trả về NFT từ hàm.

Bước 3: Triển khai Testnet

Bây giờ là lúc triển khai hợp đồng thông minh của chúng tôi trên mạng thử nghiệm Flow.


1. Thiết lập tài khoản Flow.


Chạy lệnh sau trong terminal để tạo tài khoản Flow:


 flow keys generate


Hãy nhớ ghi lại khóa chung và khóa riêng của bạn.


Tiếp theo, chúng ta sẽ đi đến vòi dòng chảy , tạo một địa chỉ mới dựa trên khóa của chúng tôi và nạp tiền vào tài khoản của chúng tôi bằng một số mã thông báo thử nghiệm. Hoàn tất các bước sau để tạo tài khoản của bạn:


  1. Dán khóa công khai của bạn vào trường đầu vào được chỉ định.


  2. Giữ Thuật toán Chữ ký và Băm được đặt thành mặc định.


  3. Hoàn thành Captcha.


  4. Nhấp vào Tạo tài khoản.


Sau khi thiết lập tài khoản, chúng tôi nhận được một cuộc đối thoại với địa chỉ Flow mới chứa 1.000 mã thông báo Flow thử nghiệm. Sao chép địa chỉ để chúng tôi có thể sử dụng nó trong tương lai .


2. Cấu hình dự án.


Bây giờ, hãy cấu hình dự án của chúng tôi. Ban đầu, khi chúng tôi thiết lập dự án, nó sẽ tạo một tệp flow.json .


Đây là tệp cấu hình cho Flow CLI và xác định cấu hình cho các hành động mà Flow CLI có thể thực hiện cho bạn. Hãy coi điều này gần tương đương với hardhat.config.js trên Ethereum.


Bây giờ, hãy mở trình soạn thảo mã, sao chép và dán mã bên dưới vào tệp flow.json của bạn.


 { "contracts": { "Collectibles": "./cadence/contracts/Collectibles.cdc", "NonFungibleToken": { "source": "./cadence/contracts/NonFungibleToken.cdc", "aliases": { "testnet": "0x631e88ae7f1d7c20" } } }, "networks": { "testnet": "access.devnet.nodes.onflow.org:9000" }, "accounts": { "testnet-account": { "address": "ENTER YOUR ADDRESS FROM FAUCET HERE", "key": "ENTER YOUR GENERATED PRIVATE KEY HERE" } }, "deployments": { "testnet": { "testnet-account": [ "Collectibles" ] } } }


  1. Sao chép và dán.

Dán khóa riêng đã tạo của bạn vào vị trí (khóa: “NHẬP KHÓA RIÊNG TƯ ĐƯỢC TẠO CỦA BẠN TẠI ĐÂY”) trong mã.


  1. Hành hình.

Bây giờ, hãy thực thi mã trên testnet. Đi đến thiết bị đầu cuối và chạy đoạn mã sau:


 flow project deploy --network testnet


5. Chờ xác nhận.


Sau khi gửi giao dịch, bạn sẽ nhận được ID giao dịch. Đợi giao dịch được xác nhận trên testnet, cho biết hợp đồng thông minh đã được triển khai thành công.


Kiểm tra hợp đồng đã triển khai của bạn tại đây .


Kiểm tra mã đầy đủ trên GitHub .

Suy nghĩ cuối cùng và xin chúc mừng!

Chúc mừng! Bây giờ bạn đã xây dựng một cổng sưu tầm trên chuỗi khối Flow và triển khai nó trên mạng thử nghiệm. Cái gì tiếp theo? Bây giờ, bạn có thể bắt tay vào xây dựng giao diện người dùng mà chúng tôi sẽ trình bày trong phần 2 của loạt bài này.


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


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