App.js

App.js has the following functions:

  • Use the injected web3 objected to connect to the Ganache blockchain and set the network in the navigation bar.
  • Asynchronously access MetaMask for account authorization.
  • Define the Transfer, Approve, and Mint methods for interacting with the token contracts.
  • Set the state and pass the relevant props to the container component before each operation (Approve, Mint, and Transfer) is carried out.

Let's look at the code:

  1. We will start writing App.js by first importing React, Web3, and the app components, as shown here:
import React, { Component } from 'react';
import Web3 from 'web3'
import Tokens20 from './Tokens/all20';
import Tokens721 from './Tokens/all721';
import Nav from './Components/Nav';
import Description from './Components/Description';
import Container from './Components/Container';
import InstallMetamask from './Components/InstallMetamask';
  1. Next, we will define the constructor and set the initial values for the state variables. Check the constructor method in the App.js code available at the following link for reference: https://github.com/PacktPublishing/Blockchain-Development-for-Finance-Projects/blob/master/Chapter%202/Chapter%202/tokenwallet/src/App.js.

In the constructor method, we do the following:

  • We import the token interfaces we created earlier and set the app name.
  • We define the state variables for each operation being carried out, namely, approveDetail20, approveDetail721, mintDetail20, mintDetail721, transferDetail20, and transferDetail721.
  • We also set the default and initial values for the form fields. We use bind to enable the child components to change the state. 
  • The account parameter stores the account of the Ethereum wallet being used for submitting transactions to the blockchain.
  1. Next, we will define the ComponentDidMount() section to indicate the tasks to carry out after App is rendered, as shown in the following:
componentDidMount(){

var account;

if (window.Ethereum) {
const Ethereum = window.Ethereum;
window.web3 = new Web3(Ethereum);
this.web3 = new Web3(Ethereum);

Ethereum.enable().then((accounts) => {
account = accounts[0];
this.web3.eth.defaultAccount = account ;

Post November 2018, MetaMask does not inject the Ethereum provider with user accounts by default. Also, while the legacy window.web3 option is still available (after disabling privacy mode in settings), it is not recommended to use it as it will be phased out in the long run. The Ethereum provider is now available at window.Ethereum in the new version. To access the user accounts, the DApp must asynchronously call the Ethereum.enable() method. This method requests access from the MetaMask app and the user must explicitly grant access to the DApp for using his or her MetaMask wallet. After granting permission, the method returns an array of the user's account with the active/current account at the 0th location. 

Hence, for our app, we first check whether the window.Ethereum object is available. To provide compatibility with legacy code, we map the window.Ethereum object to window.web3. We also map the current app's Ethereum provider to window.Ethereum. Next, we asynchronously call MetaMask to ask for permission to the injected Ethereum provider with the user's accounts.

  1. As shown in the following, we will set the local account parameter to the first account in the array of accounts returned by the Ethereum.enable method. We also set the default account for window.web3
let app = this;

this.setState({
account
});

this.setNetwork();
this.setGasPrice();

From the preceding code, we can make the following observations:

  • We initialized the this object for our app. We also set the account state variable to the default account.
  • We also called the setNetwork (to set the Navbar to our local Ganache blockchain) and setGasPrice methods (to get the default gas price from the network) once we have access to the injected web3
  1. Next, we will use the Tokens20 parameter to loop through all of the tokens listed in all20.js. For each ERC20 token, we set the contract parameter using its ABI and address. We call the balanceOf method to get the balance for each token for our primary account. We will fetch all of the other parameters from the token's component file. Finally, each token's details are pushed into the token20 state array. Let's have a look at the following code:
Tokens20.forEach((token) => {
let erc20Token = new this.web3.eth.Contract(token.abi,token.address);

erc20Token.methods.balanceOf(account).call().then(function(response){

if(response) {
let decimal = token.decimal;
let precision = '1e' + decimal;
let balance = response / precision;
let name = token.name;
let symbol = token.symbol;
let icon = token.icon;
let abi = token.abi;
let address = token.address;

balance = balance >= 0 ? balance : 0;

let tokens20 = app.state.tokens20;

if(balance > 0) tokens20.push({
decimal,
balance,
name,
symbol,
icon,
abi,
address,
});

app.setState({
tokens20
})
}
});
});
  1. We will similarly loop through all of the ERC721 tokens available in all721.js. The only difference being that, for ERC721, we fetch tokenId and the mapped metadata for each token. We do this by accessing the getter method for MDTrack (the public hashmap for tracking token ID for an address) and the tokenURI method available in the base ERC721 contract:
Tokens721.forEach((token721) => {
let erc721Token = new this.web3.eth.Contract(token721.abi,token721.address);

erc721Token.methods.MDTrack(account).call().then(function (response) {
if(response) {
let name = token721.name;
let symbol = token721.symbol;
let icon = token721.icon;
let abi = token721.abi;
let address = token721.address;
let tokenid = response;

tokenid = tokenid >= 0 ? tokenid : 0;
if(tokenid!==0)
{
erc721Token.methods.tokenURI(tokenid).call().then(function (response) {
if(response) {
let metadata = response;
let tokens721 = app.state.tokens721;

tokens721.push({

name,
symbol,
tokenid,
icon,
abi,
address,
metadata,
});

app.setState({
tokens721
})
}
});
}
}
})
})
  1. Next, we define the individual methods for each operation. The Transfer method is used to transfer token between Ethereum addresses. You can find the code for the Transfer method at the App.js code at the link here: https://github.com/PacktPublishing/Blockchain-Development-for-Finance-Projects/blob/master/Chapter%202/Chapter%202/tokenwallet/src/App.js.

From the code, we can make the following observations:

  • The Transfer method starts by setting the inProgress state variable to true so child components can recognize that the current state is a transfer in progress.
  • After establishing defaultAccount, we initialize our contract object depending on whether the token is ERC20 or ERC721. We do this by checking whether the transferDetail721 state variable is storing any metadata.
  • Next, we assign the values of the state variables to our local variables and then call our token contract for the transfer.
  • For our ERC20 tokens, this is the transferFrom method. For ERC721, this is the transferNFT method.
  • On successful response, we reset the app using the resetApp method, which resets the state variables and sets inProgress to false.
  1. Now, we will write the mint method. The mint method is similar to the Transfer method. It is invoked when the user clicks the mint button on the mint token screen:

You can find the code for the mint method in the App.js file code at the following link: https://github.com/PacktPublishing/Blockchain-Development-for-Finance-Projects/blob/master/Chapter%202/Chapter%202/tokenwallet/src/App.js.

  • The code checks whether the user is minting an ERC20 or an ERC721 token and searches the respective state variable for the token's details.
  • If the token is an ERC20 token, it calls the mint method defined in the base ERC20 contract.
  • For non-fungible tokens, it calls the createNFT method defined in our Condos contract for creating non-fungible tokens and allocating token metadata.
  • It also toggles the inProgress state parameter on and off when minting is in process.
  1. Next, we will write the Approve method:

Please check the App.js file at the following link for the code for the Approve method: https://github.com/PacktPublishing/Blockchain-Development-for-Finance-Projects/blob/master/Chapter%202/Chapter%202/tokenwallet/src/App.js.

  • The approve method checks whether the user is approving an ERC20 token or an ERC721 token.
  • This it does by checking the approveDetail20 state variable. Accordingly, it calls the approve function from the ERC20 base class or the approve function from the ERC721 base class.
  • In the case of the ERC20 contract, it needs to send the account to approve and balance. In the case of ERC721, it needs to send tokenid and the account to approve.
  1. Lastly, we will build the render function:

You can find the render method at this link for the App.js file: https://github.com/PacktPublishing/Blockchain-Development-for-Finance-Projects/blob/master/Chapter%202/Chapter%202/tokenwallet/src/App.js.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.101.95