paint-brush
Akış ve Ritim Kullanılarak Dijital Koleksiyon Portalı Nasıl Oluşturulur (Bölüm 2)ile@johnjvester
222 okumalar

Akış ve Ritim Kullanılarak Dijital Koleksiyon Portalı Nasıl Oluşturulur (Bölüm 2)

ile John Vester15m2024/02/27
Read on Terminal Reader

Çok uzun; Okumak

Flow blok zincirindeki Koleksiyon portalı ve test ağına dağıtılmasıyla artık bu serinin sonunda React'ı kullanarak ön uç oluşturmaya odaklanabiliriz.
featured image - Akış ve Ritim Kullanılarak Dijital Koleksiyon Portalı Nasıl Oluşturulur (Bölüm 2)
John Vester HackerNoon profile picture
0-item


Koleksiyon portalınızı oluşturmanın son adımına hoş geldiniz! (bölüm 1 için buraya bakın)


Bu bölümde bulmacanın son parçası olan ön ucu oluşturmaya odaklanacağız.


İşte başaracağımız şey:


  1. Flow Cüzdanını bağlayın.
  2. Hesabınızı başlatın ve NFT'nizi oluşturun.
  3. Koleksiyonunuzdaki NFT kimliğini kontrol edin.
  4. Koleksiyonunuzda bulunan NFT ID'nizle NFT'yi görüntüleyin.


Ön ucu oluşturmak için Next.js'yi kullanacağız.


Başlayalım!


1. Kurulum

Kurulum

Proje flow-collectible-portal dizininizi açın. O zaman koş
Terminalde npx create-next-app@latest frontend ve enter tuşuna basın.


Bu size çeşitli seçenekler sunacaktır. Bu eğitimde Typescript , ESLint veya TailwindCSS kullanmayacağız ve bu makalenin yazıldığı sırada src dizinini ve App router'ı kullanacağız.


Artık yeni bir web uygulamanız hazır.

Ön uç klasörünüz şu şekilde görünür:



2. Yapılandırma

Flow blockchain ile etkileşime geçmek için cüzdan bağlantılarını yönetmek, komut dosyalarını çalıştırmak ve uygulamamızdaki işlemleri göndermek için Flow Client Library'yi (FCL) kullanacağız. Tam Cadence fonksiyonlarını yazmamıza ve bunları Javascript fonksiyonları olarak çalıştırmamıza izin verecektir.


Başlamak için aşağıdaki komutu çalıştırarak uygulamamız için FCL'yi yükleyelim:


 npm install @onflow/fcl --save


FCL'yi kurduktan sonra yapılandırmamız gerekiyor. İşte yapmanız gerekenler:


  1. app klasörünün içinde flow adında yeni bir klasör oluşturun ve config.js adlı bir dosya ekleyin.
  2. Bu dosyada, Erişim Düğümü ve cüzdan bulma uç noktasının belirtilmesi gibi FCL yapılandırmasını ayarlayın. Bu, bir test ağı veya yerel bir emülatör kullanmak arasında seçim yapmanıza yardımcı olur.
  3. Ayrıca Bölüm 1'de uyguladığımız Koleksiyon sözleşme adresini de belirtmek isteyeceksiniz.


Aşağıdaki kodu config.js dosyasına ekleyin:


 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", });


Artık uygulamanızda FCL'yi kullanmaya hazırsınız.


3. Kimlik Doğrulama

Bir uygulamada kullanıcının kimliğini doğrulamak için çeşitli işlevleri kullanabilirsiniz:


  1. Oturum açmak için fcl.logIn() öğesini çağırın.
  2. Kaydolmak için fcl.signUp() öğesini arayın.
  3. Oturumu kapatmak için fcl.unauthenticate() öğesini çağırın.


Bu fcl işlevlerini ön uçta nasıl uygulayabileceğimizi öğrenelim.


Öncelikle aşağıdaki kodu app dizini içerisindeki page.js dosyamıza ekleyeceğiz. Bu, bazı bağımlılıkları içe aktaracak, uygulamamızın bazı bölümleri için bazı başlangıç useState ayarlayacak ve temel bir kullanıcı arayüzü oluşturacaktır.


Güzel göründüğünden emin olmak için uygulama dizini içindeki page.module.css dosyasını silin ve bunun yerine page.css adında bir dosya oluşturun. Daha sonra bu dosyanın içeriğini içine yapıştırın. Artık başlangıç sayfamızı yazabiliriz.


 "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> ); }


Bu kodu ekledikten sonra her şeyin doğru şekilde yüklendiğinden emin olmak için npm run dev çalıştırın.


4. Flow blok zincirini sorgulama

Flow blok zincirini sorgulamak için fcl nasıl kullanabileceğimizi derinlemesine incelemeden önce, bu Cadence komut dosyası kodlarını page.js dosyasındaki handleInput işlevinden sonra ekleyin.


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


Cadence betiklerimiz kullanıma hazır olduğundan, artık bazı Javascript fonksiyonlarını bildirebilir ve Cadence sabitlerini `fcl` sorgularına aktarabiliriz.


 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); }


Şimdi yazdığımız tüm fonksiyonlara bir göz atalım. Dikkat edilmesi gereken iki şey var:


  1. fcl.query
  2. Ve args: (arg,t) => [arg(addr,t.Address)], satır.


Komut dosyaları, Solidity'deki view işlevlerine benzer olduğundan ve çalıştırılması için herhangi bir gas ücreti gerektirmediğinden, aslında sadece blok zincirini sorguluyoruz. Bu yüzden Flow'da komut dosyalarını çalıştırmak için fcl.query kullanıyoruz.


Bir şeyi sorgulamak için bir argüman iletmeliyiz. Bunun için argümanı temsil eden bir dize değeri alan bir fonksiyon olan arg'yi ve Cadence'in sahip olduğu tüm farklı veri türlerini içeren bir nesne olan t kullanıyoruz. Böylece arg ilettiğimiz argümanın nasıl kodlanacağını ve kodunun nasıl çözüleceğini anlatabiliriz.

5. Flow blok zincirini mutasyona uğratmak

Önceki işlevlerimiz yalnızca "salt okunur" iken, sonraki işlevlerimizde blockchain durumunu değiştirebilecek ve ona yazabilecek eylemler olacak; diğer adıyla "bir NFT nane."


Bunu yapmak için sabit olarak başka bir Cadence betiği yazacağız.


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


Şimdi page.js dosyasına işlem kodundan sonra aşağıdaki fonksiyonu ekleyin.


 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); }


İşleve gelince, fcl.mutate sözdizimi fcl.query ile aynıdır. Ancak aşağıdakiler gibi birkaç ekstra parametre sağlıyoruz:


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


  • Bunlar, işlem için hangi hesabın ödeme yapacağını (ödeyen), işlemi yayınlayacağını (teklif eden) ve yetkilendirmeye ihtiyacımız olan hesapları tanımlayan Flow'a özgü şeylerdir. (Bir hesaba birden fazla anahtarın eklenmesi durumunda, çoklu imzalı bir cüzdan gibi davranabilir.)
  • fcl.authz şu anda bağlı olan hesabı ifade eder.
  • limit , Ethereum dünyasındaki maksimum hesaplama miktarına bir üst sınır koyan gasLimit gibidir. Hesaplama sınırı aşarsa işlem başarısız olur.


Az önce yaptığımız mintNFT fonksiyonunu çağıracak ve işleyecek bir fonksiyon daha eklememiz gerekecek.


 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. Son kod

Ana işlevlerimiz mevcut olduğundan artık bunları kullanıcı arayüzümüze ekleyebiliriz.


Ancak bunu yapmadan önce başlangıç durumunun yüklenmesine yardımcı olmak için bazı useEffect çağrıları ekleyeceğiz. Bunları mevcut useEffect çağrısının hemen üstüne ekleyebilirsiniz.


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


Artık kullanıcı arayüzü ile return bölümümüze döndüğümüzde, fonksiyonlarımızı uygulamanın uygun bölümlerine ekleyebiliriz.


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


Buradaki son kodu kontrol edin.


Artık uygulama tamamlandıktan sonra nasıl kullanılacağını inceleyelim!


Öncelikle sağ üstteki “Cüzdanı Bağla” butonuna tıklayarak cüzdanınızı bağlayın.


Artık bir NFT üretebilirsiniz! NFT'nizin adını girin ve kullanmak istediğiniz görselin bağlantısını yapıştırın. "Nane"ye tıkladıktan sonra cüzdanınızla bir işlem imzalamanız istenecektir.


İşlemin tamamlanması biraz zaman alabilir. Tamamlandıktan sonra, NFT'lerinizin kimliklerini görüntülemek için alt düğmeye tıklayabilmeniz gerekir. Bu sizin ilkinizse, kimlik yalnızca “1” olmalıdır.


Artık NFT'nizin kimliğini kopyalayıp Görünüm bölümüne yapıştırabilir ve "NFT'yi Görüntüle"ye tıklayabilirsiniz.


Çözüm

Tebrikler! Koleksiyon portalı projesinin 2. bölümünü tamamladınız. Özetle, Koleksiyon portalımızın ön yüzünü oluşturmaya odaklandık.


Bunu şu şekilde yaptık:


  • Next.js ile uygulama oluşturma
  • Flow Cüzdanını Bağlama
  • Basım için kendi NFT'lerimizi oluşturma
  • NFT'nizi görüntüleme


Gerçekten harika bir gün geçirin!