I have made a lottery contract and now I want to connect it to the front-end which I will create with ReactJS. I have used Truffle framework for the deployment and tests for my contract.
npm i @truffle/contract
Then in utils/loadContract:
import contract from "@truffle/contract"
export const loadContract = async (name, provider) => {
// in truffle, contracts are in "contracts" directory
const res = await fetch(`/contracts/${name}.json`)
const Artifact = await res.json()
const _contract = contract(Artifact)
_contract.setProvider(provider)
let deployedContract = null
try {
deployedContract = await _contract.deployed()
} catch {
console.error("You are connected to the wrong network")
}
return deployedContract
}
Then load the contract inside app.jsx. First:
npm i @metamask/detect-provider
then write your code inside app.js
import detectEthereumProvider from '@metamask/detect-provider'
import { loadContract } from "./utils/load-contract";
import {useEffect, useState } from "react";
const [web3Api, setWeb3Api] = useState({
provider: null,
isProviderLoaded: false,
web3: null,
contract: null
})
// call this function inside useEFfect, if user connects to different account, you will update it
const setAccountListener = provider => {
provider.on("accountsChanged", _ => window.location.reload())
provider.on("chainChanged", _ => window.location.reload())
}
// useEffect is called before your component loaded
// load the contract, set the state, so when your compoent loaded, your state will be ready
useEffect(() => {
const loadProvider = async () => {
// if Metamask installed, this will detect its provider
const provider = await detectEthereumProvider()
// load the contract if provider exists
if (provider) {
// Lottery is not name of the file, it is NAME OF CONTRACT
const contract = await loadContract("Lottery", provider)
setAccountListener(provider)
setWeb3Api({
web3: new Web3(provider),
provider:provider,
// Now you set the contract.
// when your app.js loaded you will be able to call contract methods
contract:contract,
isProviderLoaded: true
})
} else {
setWeb3Api(api => ({...api, isProviderLoaded: true}))
console.error("Please, install Metamask.")
}
}
loadProvider()
}, [])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.