Contracts
Smart Contracts are what power most dApps, and it's common that you'll need to read data from them, in addition to write data to them using transactions.
For more details, we recommend reading the ethers documentation on contracts.
Defining a contract
Defining a contract requires two pieces of information:
- The address that the contract is deployed to. Note that this address may change based on the network that you are connected to.
 - The ABI of the contract.
- This can be defined as an output when running the Solidity compiler.
 - If you are using Hardhat, you can use the ABI exporter plugin to generate this.
 
 
import { useContract } from "ethereal-react";
const CONTRACT_ADDRESS = "0x0000000000000000000000000000000000000000";
const CONTRACT_ABI = [
  "function setGreeting(string memory greeting)",
  "function greeting() view returns (string memory)",
];
const contract = useContract(CONTRACT_ADDRESS, CONTRACT_ABI);
We include common ABIs for well-known contract types (ERC-20 and ERC-721 tokens).
For full TypeScript support, you can also use a generated TypeChain factory in place of a contract ABI. For more details, you can read the TypeChain docs.
Reading data from contracts
You can read data easily from any contract that has a view function on it. To do so, use the useReadContract hook.
The hook takes the following arguments:
- The contract, loaded via the 
useContracthook. - The function name on the contract to invoke. Should be a 
viewfunction. 
Any additional arguments will be passed to the contract function.
import { useContract, useReadContract } from "ethereal-react";
function Greeting() {
  const contract = useContract(CONTRACT_ADDRESS, CONTRACT_ABI);
  const greeting = useReadContract(contract, "greeting");
  return <div>Current greeting: {greeting}</div>;
}
Writing data to contracts (transactions)
You can write data to any contract by using the useWriteContract hook. The hook takes the following arguments:
- The contract, loaded via the 
useContracthook. - The function name on the contract to invoke.
 
The hook returns a tuple containg the following elements:
- A mutation function, which can be called to call the contract. This will prompt the user to initiate a transaction on Ethereum. Any arguments passed to this function will be passed to the contract function.
 - An object containing the current status of the mutation. This contains a 
loadingboolean, anerrorproperty, and adatapayload for when the transaction is completed. 
import { useContract, useWriteContract } from "ethereal-react";
function UpdateGreeting() {
  const contract = useContract(CONTRACT_ADDRESS, CONTRACT_ABI);
  const [setGreeting, { loading }] = useWriteContract(contract, "setGreeting");
  return (
    <button onClick={() => setGreeting("Hello, docs!")}>Update Greeting</button>
  );
}
Waiting for transactions
The useWriteContract hook initiates a transaction, but it does not wait for it to be confirmed to the blockchain. If you wish to wait for the transaction to be confirmed, you can use the useWaitForTransaction hook. This will cause the component to suspend while the transaction is confirmed. You can also specify the number of confirmations that you wish to wait for.
import { Suspense } from "react";
import {
  useContract,
  useReadContract,
  useWriteContract,
  useWaitForTransaction,
} from "ethereal-react";
function Greeting({ transaction }) {
  // Wait for the transaction to be confirmed:
  useWaitForTransaction(transaction);
  const contract = useContract(CONTRACT_ADDRESS, CONTRACT_ABI);
  const greeting = useReadContract(contract, "greeting");
  return <div>Current greeting: {greeting}</div>;
}
function UpdateGreeting() {
  const contract = useContract(CONTRACT_ADDRESS, CONTRACT_ABI);
  const [setGreeting, { loading, data }] = useWriteContract(
    contract,
    "setGreeting"
  );
  // Once this transaction has started, render the updated greeting:
  if (data) {
    return (
      <Suspense
        fallback={<div>Waiting for transaction to be confirmed...</div>}
      >
        <Greeting transaction={data} />
      </Suspense>
    );
  }
  return (
    <button onClick={() => setGreeting("Hello, docs!")}>Update Greeting</button>
  );
}