aelf 백서

bitpro가 원문에서 글자만 모은 내용이에요. 표·그림·수식은 빠지거나 깨질 수 있어요. 전체 41쪽 중 36쪽

string , IsLeftChildNode : boolean , } ) => ( { hash : Hash , isLeftChildNode : IsLeftChildNode , } ) ) ; return { merklePathNodes : formattedMerklePathNodes } ; } catch ( error ) { console . error ( "Error fetching Merkle path:" , error ) ; throw new Error ( "Failed to get Merkle path by transaction ID." ) ; } } ; What This Function Does: ​ Fetches Merkle Path : It sends a request to fetch the merkle path using the transaction ID. Parses Response : It parses the response from the server as JSON. Returns Merkle Path Nodes : It extracts and returns the merkle path of the nodes from the JSON response. Handles Errors : If an error occurs, it clears the transaction status and logs the error. Next, we'll write the Create a Collection on the cross-chain function. Step 5: Write a function to create a collection on the side chain Scroll up to find the comment // step 5 - Create a collection on the dAppChain . Replace the existing createCollectionOnSideChain function with this code snippet: create-nft/index.tsx // step 5 - Create a collection on the dAppChain const createCollectionOnSideChain = async ( transactionId : string , signedTx : string , BlockNumber : number ) => { let crossChainLoadingId ; try { crossChainLoadingId = toast . loading ( "Creating Collection on dAppChain..." ) ; const merklePath = await getMerklePathByTxId ( aelf , transactionId ) ; const tdvwTokenContract = await getTokenContract ( tdvw , wallet ) ; const CROSS_CHAIN_CREATE_TOKEN_PARAMS = { fromChainId : mainchain_from_chain_id , parentChainHeight : "" + BlockNumber , transactionBytes : Buffer . from ( signedTx , "hex" ) . toString ( "base64" ) , merklePath , } ; const signedTx2 = await tdvwTokenContract . CrossChainCreateToken . getSignedTx ( CROSS_CHAIN_CREATE_TOKEN_PARAMS ) ; let done = false ; while ( ! done ) { try { await delay ( 10000 ) ; const { TransactionId } = await tdvw . chain . sendTransaction ( signedTx2 ) ; const txResult = await tdvw . chain . getTxResult ( TransactionId ) ; if ( txResult . Status === "SUCCESS" || txResult . Status === "MINED" ) { done = true ; setIsNftCollectionCreated ( true ) ; toast . update ( crossChainLoadingId , { render : "Collection was Created Successfully On dAppChain" , type : "success" , isLoading : false , } ) ; removeNotification ( crossChainLoadingId ) ; toast . info ( "You Can Create NFT now" ) ; setTransactionStatus ( false ) ; } } catch ( err ) { if ( ( err as { Error : string } ) . Error . includes ( "Cross chain verification failed." ) ) { console . log ( "Exit." ) ; done = true ; toast . update ( crossChainLoadingId , { render : "Please try again to create NFT using new NFT seed" , type : "error" , isLoading : false , } ) ; removeNotification ( crossChainLoadingId ) ; } else { console . error ( "An unexpected error occurred:" , err ) ; } } } return "success" ; } catch ( error ) { handleError ( crossChainLoadingId as number , error ) ; return "error" ; } } ; What This Function Does: ​ Displays Loading Toast : Shows a notification indicating the creation process of the collection on the dAppChain. Fetches Merkle Path : Retrieves the merkle path using the provided transactionId. Prepares and Signs Transaction : Constructs parameters for the cross-chain transaction and signs it. Sends Transaction and Checks Status : Sends the signed transaction and polls for its status every 10 seconds. Updates the notification and state, if successful. Handles Errors : Logs errors and returns "error" if something goes wrong. Final Return : Returns "success" upon successful completion. Create NFT Token ​ Step 1: Write a Function to create NFTs on the mainchain Now, let's write the create NFTs on MainChain function. Scroll down to find the comment // step 6 - Create an NFT on the mainchain . Replace the existing createNFTOnMainChain function with this code snippet: create-nft/index.tsx // step 6 - Create an NFT on the mainchain const createNFTOnMainChain = async ( values : INftParams ) => { let createMainChainNFTLoadingId ; try { createMainChainNFTLoadingId = toast . loading ( "Creating NFT on MainChain..." ) ; // Preparing Parameter for Create Function const createNftMainChainInput = { tokenName : values . tokenName , symbol : values . symbol , totalSupply : values . totalSupply , issuer : currentWalletAddress , isBurnable : true , issueChainId : sidechain_from_chain_id , owner : currentWalletAddress , externalInfo : { } , } ; const resultMainchain = await mainChainSmartContract ?. callSendMethod ( "Create" , currentWalletAddress , createNftMainChainInput ) ; console . log ( "========= result of createNewNft =========" , resultMainchain ) ; toast . update ( createMainChainNFTLoadingId , { render : "NFT Created Successfully on MainChain" , type : "success" , isLoading : false , } ) ; removeNotification ( createMainChainNFTLoadingId ) ; return "success" ; } catch ( error ) { handleError ( createMainChainNFTLoadingId as number , error ) ; return "error" ; } } ; What this function does: ​ Displays Loading Toast: Shows a notification indicating the creation process of the NFT on the mainchain. Prepares Parameters: Constructs input parameters for creating the NFT, including token details and the issuer's information. Calls Smart Contract: Sends a request to the mainchain smart contract to create the NFT using the prepared parameters. Handles Success: Updates the notification to show successful NFT creation. Handles Errors: Displays an error message if the operation fails and logs the error. Final Return: Returns "success" if the NFT is created successfully; otherwise, returns "error" . Step 2: Write the Function for Validate NFT Info Exist Now, let's write the Validate NFT Info Exist function. Scroll down to find the comment // step 7 - Validate an NFT token on the mainchain . Replace the existing validateNftToken function with this code snippet: create-nft/index.tsx // step 7 - Validate an NFT token on the maincgit stashhain const validateNftToken = async ( values : INftParams ) => { let validateNFTLoadingId ; try { // Start Loading before initiate the transaction validateNFTLoadingId = toast . loading ( < CustomToast title = " Transaction is getting validated on aelf blockchain. Please wait! " message = " Validation means transaction runs through a consensus algorithm to be selected or rejected. Once the status changes process will complete. It usually takes some time in distributed systems. " /> ) ; // Create an object with the necessary information for token validation. const validateInput = { symbol : values . symbol , tokenName : values . tokenName , totalSupply : values . totalSupply , issuer : currentWalletAddress , isBurnable : true , issueChainId : sidechain_from_chain_id , owner : currentWalletAddress , externalInfo : { } , } ; // get mainnet contract const aelfTokenContract = await getTokenContract ( aelf , wallet ) ; // prepare Sign the transaction using contract method (ValidateTokenInfoExists Function) const signedTx = aelfTokenContract . ValidateTokenInfoExists . getSignedTx ( validateInput ) ; // send the transaction using signed Transaction const { TransactionId : VALIDATE_TXID } = await aelf . chain . sendTransaction ( signedTx ) ; await delay ( 3000 ) ; // get Validate Result let VALIDATE_TXRESULT = await aelf . chain . getTxResult ( VALIDATE_TXID ) ; await delay ( 3000 ) ; // if dAppChain index has a MainChain height greater than validateTokenInfoExist's let heightDone = false ; while ( ! heightDone ) { await delay ( 5000 ) ; // Wait 5 seconds before checking again // get latest index Hight const sideIndexMainHeight = await GetParentChainHeight ( ) ; if ( // check the latest index Hight is grater than or equal Number ( sideIndexMainHeight ) >= VALIDATE_TXRESULT . Transaction . RefBlockNumber ) { VALIDATE_TXRESULT = await aelf . chain . getTxResult ( VALIDATE_TXID ) ; heightDone = true ; } } console . log ( VALIDATE_TXRESULT , "VALIDATE_TXRESULT=====2" ) ; const merklePath = await getMerklePathByTxId ( aelf , VALIDATE_TXID ) ; toast . update ( validateNFTLoadingId , { render : "Validating NFT Successfully Executed" , type : "success" , isLoading : false , } ) ; removeNotification ( validateNFTLoadingId ) ; // return necessary values return { parentChainHeight : VALIDATE_TXRESULT . BlockNumber , signedTx : signedTx , merklePath : merklePath , } ; } catch ( error ) { handleError ( validateNFTLoadingId as number , error ) ; return "error" ; } } ; Here's what the function does: ​ Displays Loading Toast: Shows a notification indicating that the NFT validation is in progress on the blockchain. Prepares Validation Input: Constructs the input parameters needed for validating the NFT token. Gets Token Contract: Retrieves the token contract instance from the MainChain. Signs and Sends Transaction: Signs the transaction to validate the token info and sends it to the blockchain. Polls for Transaction Result: Waits for the transaction result and ensures the transaction has reached the required block height. Fetches Merkle Path: Retrieves the Merkle path for the validated transaction. Handles Success: Updates the notification to show successful validation and returns necessary values. Handles Errors: Logs errors and returns "error" if something goes wrong. Step 3: Write a Function for Create NFT on dAppChain Now, let's write the Create NFT on dAppChain function. Scroll down to find the comment // step 8 - Create a NFT on dAppChain . Replace the existing createNftTokenOnSideChain function with this code snippet: create-nft/index.tsx // step 8 - Create a NFT on dAppChain. const createNftTokenOnSideChain = async ( values : INftValidateResult ) => { let createSideChainNFTLoadingId ; try { createSideChainNFTLoadingId = toast . loading ( "Creating NFT on SideChain..." ) ; const CROSS_CHAIN_CREATE_TOKEN_PARAMS = { fromChainId : mainchain_from_chain_id , parentChainHeight : values . parentChainHeight , transactionBytes : Buffer . from ( values . signedTx , "hex" ) . toString ( "base64" ) , merklePath : values . merklePath , } ; await sideChainSmartContract ?. callSendMethod ( "CrossChainCreateToken" , currentWalletAddress , CROSS_CHAIN_CREATE_TOKEN_PARAMS ) ; toast . update ( createSideChainNFTLoadingId , { render : "NFT Created Successfully On SideChain" , type : "success" , isLoading : false , } ) ; removeNotification ( createSideChainNFTLoadingId ) ; return "success" ; } catch ( error ) { handleError ( createSideChainNFTLoadingId as number , error ) ; return "error" ; } } ; Here's what the function does: ​ Displays Loading Toast: Shows a notification indicating that the NFT is being created on the dAppChain. Prepares Cross-Chain Transaction Parameters: Constructs the parameters needed for creating the NFT on the dAppChain, including chain IDs, block height, transaction data, and Merkle path. Calls Smart Contract Method: Sends the transaction to the dAppChain smart contract to create the NFT. Handles Success: Updates the notification to show successful NFT creation on the dAppChain. Handles Errors: Logs errors and returns "error" if something goes wrong. Step 4: Write a Function for Issue NFT Token which has been Created on dAppChain. Now, let's write the Issue NFT Function. Scroll down to find the comment // step 9 - Issue a NFT Function which has been Created on dAppChain . Replace the existing issueNftOnSideChain function with this code snippet: create-nft/index.tsx // step 9 - Issue a NFT Function which has been Created on dAppChain const issueNftOnSideChain = async ( values : { symbol : string ; amount : string ; memo : string ; } ) => { let issuingNFTLoadingId try { issuingNFTLoadingId = toast . loading ( "Issuing NFT on SideChain..." ) ; const issueNftInput = { symbol : values . symbol , amount : values . amount , memo : values . memo , to : currentWalletAddress , } ; const result = await sideChainSmartContract ?. callSendMethod ( "Issue" , currentWalletAddress , issueNftInput ) ; console . log ( "========= result of createNewNft =========" , result ) ; toast . update ( issuingNFTLoadingId , { render : "NFT Issue Successfully Executed" , type : "success" , isLoading : false , } ) ; removeNotification ( issuingNFTLoadingId ) ; toast . success ( "You will get NFT on your Wallet! It can take sometimes to get into your wallet" ) ; handleReturnClick ( ) ; return "success" ; } catch ( error ) { handleError ( issuingNFTLoadingId as number , error ) ; setTransactionStatus ( false ) ; return "error" ; } } ; Here's what the function does: ​ Displays Loading Toast: Shows a notification indicating that the NFT is being issued on the dAppChain. Prepares Issuance Input: Constructs the input parameters for issuing the NFT, including symbol, amount, memo, and recipient address. Calls Smart Contract Method: Sends the transaction to the dAppChain smart contract to issue the NFT. Handles Success: Updates the notification to show successful issuance and notifies the user that the NFT will appear in their wallet. Handles Errors: Logs and displays any error messages, updates the transaction status, and returns "error" . Step 5: Create a Function to Call Necessary Functions for NFT Creation Now, let's write the createNftToken Function. Scroll down to find the comment // step 10 - Call Necessary Function for Create NFT . Replace the existing createNftToken function with this code snippet: create-nft/index.tsx // step 10 - Call Necessary Function for Create NFT const createNftToken = async ( values : INftParams ) => { try { const mainChainResult = await createNFTOnMainChain ( values ) ; if ( mainChainResult === "error" ) { setTransactionStatus ( false ) ; return ; } await delay ( 3000 ) ; const validateNFTData : INftValidateResult | "error" = await validateNftToken ( values ) ; if ( validateNFTData === "error" ) { setTransactionStatus ( false ) ; return ; } const sideChainResult = await createNftTokenOnSideChain ( validateNFTData ) ; if ( sideChainResult === "error" ) { setTransactionStatus ( false ) ; return ; } await issueNftOnSideChain ( { symbol : values . symbol , amount : values . totalSupply , memo : "We are issuing nftToken" , } ) ; setTransactionStatus ( false ) ; } catch ( error ) { setTransactionStatus ( false ) ; if ( error instanceof Error ) { toast . error ( error . message ) ; } else { toast . error ( "An unexpected error occurred." ) ; } return "error" ; } } ; Here's what the function does: ​ Creates NFT on MainChain: Calls createNFTOnMainChain to create the NFT on the MainChain. If it fails, it updates the transaction status and exits. Validates NFT Token: Waits for 3 seconds, then calls validateNftToken to validate the NFT. If validation fails, it updates the transaction status and exits. Creates NFT on dAppChain: Calls createNftTokenOnSideChain to create the NFT on the dAppChain using the validated data. If it fails, it updates the transaction status and exits. Issues NFT on dAppChain: Calls issueNftOnSideChain to issue the NFT. Updates the transaction status to false after completion. Handles Errors: Catches and logs any errors, updates the transaction status, and displays an error notification. Configure Submit Form ​ Now, let's write a function to call necessary functions for NFT creation. Scroll down to find the comment //Step 11 - Handle Submit Form . Replace the existing onSubmit function with this code snippet: create-nft/index.tsx //Step 11 - Handle Submit Form const onSubmit = async ( values : z . infer < typeof formSchema > ) => { setTransactionStatus ( true ) ; if ( isNftCollectionCreated ) { // Already Collection Created // create NFT Token await createNftToken ( values ) ; } else { // create NFT Collection on MainChain const createResult = await createNftCollectionOnMainChain ( values ) ; if ( createResult === "error" ) { setTransactionStatus ( false ) ; return ; } // Validate NFT Collection const validateCollectionResult = await validateNftCollectionInfo ( createResult ) ; if ( validateCollectionResult === "error" ) { setTransactionStatus ( false ) ; return ; } // create NFT Collection on dAppChain await createCollectionOnSideChain ( validateCollectionResult . transactionId , validateCollectionResult . signedTx , validateCollectionResult . BlockNumber ) ; } } ; Here's what the function does: ​ Starts Transaction: Sets the transaction status to true. Checks NFT Collection Status: If the NFT collection is already created, calls createNftToken to create the NFT token. Creates and Validates NFT Collection: If the collection isn’t created, calls createNftCollectionOnMainChain to create it. If successful, validates the NFT collection with validateNftCollectionInfo . Creates Collection on dAppChain: If validation is successful, calls createCollectionOnSideChain to create the collection on the dAppChain. Handles Errors: Updates the transaction status to false and exits if any step fails. Fetch NFT Data ​ Let's write the Function for the fetch NFT data from user's Wallet using API. Step 1: Locate the File go to the src/lib/commonFunctions.ts file. Step 2: Write the Helper Functions for fetch the NFT data The commonFunctions.ts file is contains the helpers function for fetch NFT and etc. Find the comment // fetch NFT Data from Indexer API . Replace the existing fetchUserNftData function with this code snippet: commonFunctions.ts // fetch NFT Data from Indexer API export const fetchUserNftData = async ( address : string ) => { const url = 'add_your_aeindexer_api' ; const headers = { 'Content-Type' : 'application/json' } ; const body = JSON . stringify ( { query : ` query { account(input: { chainId: "tDVW", address: " ${ address } " }) { symbol amount address tokenName metadata { chainId block { blockHeight } } } } ` , variables : { } , } ) ; try { const response = await fetch ( url , { method : 'POST' , headers : headers , body : body , } ) ; if ( ! response . ok ) { throw new Error ( ` HTTP error! status: ${ response . status } ` ) ; } const result = await response . json ( ) ; return result . data . account ; } catch ( error ) { console . error ( 'Error fetching data:' , error ) ; return "error" ; } } ; info ℹ️ Note: Ensure that you are updating your aeindexer api with "add_your_aeindexer_api" value in url variable. Here's what the function does: ​ Retrieves NFT Data: The function fetchUserNftData fetches the NFT data for a given owner using AeIndexer API. We have Prepared all necessary function for fetch NFT Data from User's Wallet. Now, Let's call fetchUserNftData on necessary page. Step 3: Call fetchUserNftData Functions on Home Page go to the src/pages/home/index.tsx file. The home/index.tsx file contains the Home Page of NFT dApp Find the comment // get NFT Data from User's wallet . Replace the existing getNFTData function with this code snippet: home/index.tsx // get NFT Data from User's wallet const getNFTData = async ( ) => { const result = await fetchUserNftData ( currentWalletAddress as string ) ; if ( result !== "error" ) { setUserNfts ( result ) ; } setLoading ( false ) ; } ; Here's what the function does: ​ Fetches NFT Data: The f
프로젝트로 돌아가기