DEV Community

Cover image for Tutorial: Ethereum BlockChain Development (2)
Yongchang He
Yongchang He

Posted on

Tutorial: Ethereum BlockChain Development (2)

Part 2: Build the test React App and realize making transactions locally using MetaMask Wallet.

The purpose of building this blog is to write down the detailed operation history and my memo for learning the dApps.

If you are also interested and want to get hands dirty, just follow these steps below and have fun!~

Previous Blog

Tutorial: Ethereum BlockChain Development (1)

Getting started

Previously we have deployed the running test network (including 20 accounts) as well as the smart contract (related with Account #0). Our next step is to use MetaMask to connect to our smart contract account: Account #0.
Image description
Image description

We need to install MetaMask chrome extension , then click Get Started , Create a Wallet , I Agree with Help us improve MetaMask, create your own password, Remind me later, then close the popping Start swapping window, and lastly pin MetaMask to your browser.
Image description
Image description

Let's click on the pinned MetaMask icon and change networks to Localhost8545. Click on Show/hide test networks to show test networks.

Image description

Next, copy the Private Key of Account #0, and go back to your MetaMask account and import account by pasting your private key string.
Image description

Image description
Image description

After clicking Import, we will have ETH in current account.
Image description

Next let's switch to terminal window and type npm start command. This will open up the React App web Server. (For me I have already done this step and I answered n to the terminal). We can test by opening up a new chrome window and going to. localhost:3000:

npm start
Enter fullscreen mode Exit fullscreen mode

Image description

Image description

Then we open up our code at directory /REACT-DAPP/src/App.js . First import dependencies at top page:

import { useState } from 'react';
import { ethers } from 'ethers';
import './App.css';
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json';
Enter fullscreen mode Exit fullscreen mode

Then add variable greeterAddress, and assign the deployed contract address to it:
Image description

const greeterAddress = "0x5fbdb2315678afecb367f032d93f642f64180aa3";
Enter fullscreen mode Exit fullscreen mode

Next we will give users a form to input/rewrite their messages in the BlockChain.

Add this code into function App() but right above return function:

const [greeting, setGreetingValue] = useState()
Enter fullscreen mode Exit fullscreen mode

Next let's create functions: requestAccount() fetchGreeting() and setGreeting() that right above return function.

Annotations have been added amongst lines of codes in case that we want to know specifically what operations we have done.

  async function requestAccount(){
    // Aims to connect to the Metamask wallet of the user and create a transaction
    // Request users' account information from MetaMask wallet
    // This will prompt the user to connect to one of their MetaMask account
    // if they have already connected and return array of their accounts
    await window.ethereum.request({ method: 'eth_requestAccounts' });
  }
Enter fullscreen mode Exit fullscreen mode
  async function fetchGreeting(){
    // When Ethereum window is exist
    // Waiting for the MetaMash extension to be connected
    // If MetaMask is not installed on that user's broswer, 
    //window.ethereum will be rejected
    if (typeof window.ethereum !== 'undefined'){
        // Create a new provider using Ethers
        // In our case we use Web3Provider
        const provider = new ethers.providers.Web3Provider(window.ethereum)
        // When We have the provider instance, we can now create contract instance
        // We should pass in greetAddress, Greeter.abi and provider
        const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
        try{
          // Read value from BlockChain, and assign it to variable data
          const data = await contract.greet()
          // Show data to console
          console.log('data: ', data)
        }catch (err) {
          console.log("Error: ", err)
        }
    }
  }
Enter fullscreen mode Exit fullscreen mode
  async function setGreeting(){
    // To check if users have typed in a greeting
    // If no greeting function stop without writing empty string
    if (!greeting) return
    // When Ethereum window is exist
    if (typeof window.ethereum !== 'undefined'){
      // Wait for the user to go ahead and enable the account to be used
      await requestAccount()
      // Create another new provider using Ethers
      // In our case we use Web3Provider
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      // Await to sign a transaction using a signer
      const signer = provider.getSigner();
      // Create contract instance and pass in contract address, abi and signer
      const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer);
      // Passing in greeting variable 
      const transaction = await contract.setGreeting(greeting);
      setGreetingValue('')
      // Waiting the transaction to be confirmed on the BlockChain
      await transaction.wait()
      // Refresh value
      fetchGreeting()
    }
  }
Enter fullscreen mode Exit fullscreen mode

Then update return function:

  return (
    <div className="App">
      <header className="App-header">
        <button onClick={fetchGreeting}>Fetch Greeting</button>
        <button onClick={setGreeting}>Set Greeting</button>
        <input
          onChange={e => setGreetingValue(e.target.value)}
          placeholder="Set greeting"
          value={greeting}
        />
      </header>
    </div>
  );
Enter fullscreen mode Exit fullscreen mode

As a whole: App.js:

import { useState } from 'react';
import { ethers } from 'ethers';
import './App.css';
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'

// Store the contract Address into variable
const greeterAddress = "0x5fbdb2315678afecb367f032d93f642f64180aa3";


function App() {
  const [greeting, setGreetingValue] = useState('')

  async function requestAccount(){
    // Aims to connect to the Metamask wallet of the user and create a transaction
    // Request users' account information from MetaMask wallet
    // This will prompt the user to connect to one of their MetaMask account
    // if they have already connected and return array of their accounts
    await window.ethereum.request({ method: 'eth_requestAccounts' });
  }

  async function fetchGreeting(){
    // When Ethereum window is exist
    // Waiting for the MetaMash extension to be connected
    // If MetaMask is not installed on that user's browser, 
    //window.ethereum will be rejected
    if (typeof window.ethereum !== 'undefined'){
        // Create a new provider using Ethers
        // In our case we use Web3Provider
        const provider = new ethers.providers.Web3Provider(window.ethereum)
        // When We have the provider instance, we can now create contract instance
        // We should pass in greetAddress, Greeter.abi and provider
        const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
        try{
          // Read value from BlockChain, and assign it to variable data
          const data = await contract.greet()
          // Show data to console
          console.log('data: ', data)
        }catch (err) {
          console.log("Error: ", err)
        }
    }
  }

  async function setGreeting(){
    // To check if users have typed in a greeting
    // If no greeting function stop without writing empty string
    if (!greeting) return
    // When Ethereum window is exist
    if (typeof window.ethereum !== 'undefined'){
      // Wait for the user to go ahead and enable the account to be used
      await requestAccount()
      // Create another new provider using Ethers
      // In our case we use Web3Provider
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      // Await to sign a transaction using a signer
      const signer = provider.getSigner();
      // Create contract instance and pass in contract address, abi and signer
      const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer);
      // Passing in greeting variable 
      const transaction = await contract.setGreeting(greeting);
      setGreetingValue('')
      // Waiting the transaction to be confirmed on the BlockChain
      await transaction.wait()
      // Refresh value
      fetchGreeting()
    }
  }

  return (
    <div className="App">
      <header className="App-header">
        <button onClick={fetchGreeting}>Fetch Greeting</button>
        <button onClick={setGreeting}>Set Greeting</button>
        <input
          onChange={e => setGreetingValue(e.target.value)}
          placeholder="Set greeting"
          value={greeting}
        />
      </header>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Lastly, let's start the React Server and test our code:

npm start
Enter fullscreen mode Exit fullscreen mode

We should be able to launch React App test webpage(localhost:3000) , and also be able to make updates to the greeting by signing the contract with MetaMask wallet and spending the fake Ether:

Image description

Image description

So Cool!

References:

https://dribbble.com/shots/14225432-Coder
https://dev.to/dabit3/the-complete-guide-to-full-stack-ethereum-development-3j13
https://www.youtube.com/watch?v=a0osIaAOFSE

Top comments (0)