Skip to content

Instantly share code, notes, and snippets.

@tatsuyasusukida
Created August 17, 2022 01:50
Show Gist options
  • Save tatsuyasusukida/2613ee1174b8dddbe26613583c7a8744 to your computer and use it in GitHub Desktop.
Save tatsuyasusukida/2613ee1174b8dddbe26613583c7a8744 to your computer and use it in GitHub Desktop.
How to read and write smart contracts from a web page
NEXT_PUBLIC_CONTRACT_ADDRESS="0x037f3Aed2C172baAe64792A56e9a5f84a16005fb"
{
"_format": "hh-sol-artifact-1",
"contractName": "MyHelloWorld",
"sourceName": "contracts/MyHelloWorld.sol",
"abi": [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "message",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_message",
"type": "string"
}
],
"name": "setMessage",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b506040518060400160405280600c81526020017f48656c6c6f20576f726c642100000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610166565b82805461006e90610134565b90600052602060002090601f01602090048101928261009057600085556100d7565b82601f106100a957805160ff19168380011785556100d7565b828001600101855582156100d7579182015b828111156100d65782518255916020019190600101906100bb565b5b5090506100e491906100e8565b5090565b5b808211156101015760008160009055506001016100e9565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061014c57607f821691505b602082108114156101605761015f610105565b5b50919050565b6104a4806101756000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063368b87721461003b578063e21f37ce14610057575b600080fd5b6100556004803603810190610050919061031a565b610075565b005b61005f61008f565b60405161006c91906103eb565b60405180910390f35b806000908051906020019061008b92919061011d565b5050565b6000805461009c9061043c565b80601f01602080910402602001604051908101604052809291908181526020018280546100c89061043c565b80156101155780601f106100ea57610100808354040283529160200191610115565b820191906000526020600020905b8154815290600101906020018083116100f857829003601f168201915b505050505081565b8280546101299061043c565b90600052602060002090601f01602090048101928261014b5760008555610192565b82601f1061016457805160ff1916838001178555610192565b82800160010185558215610192579182015b82811115610191578251825591602001919060010190610176565b5b50905061019f91906101a3565b5090565b5b808211156101bc5760008160009055506001016101a4565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610227826101de565b810181811067ffffffffffffffff82111715610246576102456101ef565b5b80604052505050565b60006102596101c0565b9050610265828261021e565b919050565b600067ffffffffffffffff821115610285576102846101ef565b5b61028e826101de565b9050602081019050919050565b82818337600083830152505050565b60006102bd6102b88461026a565b61024f565b9050828152602081018484840111156102d9576102d86101d9565b5b6102e484828561029b565b509392505050565b600082601f830112610301576103006101d4565b5b81356103118482602086016102aa565b91505092915050565b6000602082840312156103305761032f6101ca565b5b600082013567ffffffffffffffff81111561034e5761034d6101cf565b5b61035a848285016102ec565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561039d578082015181840152602081019050610382565b838111156103ac576000848401525b50505050565b60006103bd82610363565b6103c7818561036e565b93506103d781856020860161037f565b6103e0816101de565b840191505092915050565b6000602082019050818103600083015261040581846103b2565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061045457607f821691505b602082108114156104685761046761040d565b5b5091905056fea26469706673582212208b7f340fe47b5b5142d61ce22ee85f40040d02df70fd1f5075b56e594521d32364736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063368b87721461003b578063e21f37ce14610057575b600080fd5b6100556004803603810190610050919061031a565b610075565b005b61005f61008f565b60405161006c91906103eb565b60405180910390f35b806000908051906020019061008b92919061011d565b5050565b6000805461009c9061043c565b80601f01602080910402602001604051908101604052809291908181526020018280546100c89061043c565b80156101155780601f106100ea57610100808354040283529160200191610115565b820191906000526020600020905b8154815290600101906020018083116100f857829003601f168201915b505050505081565b8280546101299061043c565b90600052602060002090601f01602090048101928261014b5760008555610192565b82601f1061016457805160ff1916838001178555610192565b82800160010185558215610192579182015b82811115610191578251825591602001919060010190610176565b5b50905061019f91906101a3565b5090565b5b808211156101bc5760008160009055506001016101a4565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610227826101de565b810181811067ffffffffffffffff82111715610246576102456101ef565b5b80604052505050565b60006102596101c0565b9050610265828261021e565b919050565b600067ffffffffffffffff821115610285576102846101ef565b5b61028e826101de565b9050602081019050919050565b82818337600083830152505050565b60006102bd6102b88461026a565b61024f565b9050828152602081018484840111156102d9576102d86101d9565b5b6102e484828561029b565b509392505050565b600082601f830112610301576103006101d4565b5b81356103118482602086016102aa565b91505092915050565b6000602082840312156103305761032f6101ca565b5b600082013567ffffffffffffffff81111561034e5761034d6101cf565b5b61035a848285016102ec565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561039d578082015181840152602081019050610382565b838111156103ac576000848401525b50505050565b60006103bd82610363565b6103c7818561036e565b93506103d781856020860161037f565b6103e0816101de565b840191505092915050565b6000602082019050818103600083015261040581846103b2565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061045457607f821691505b602082108114156104685761046761040d565b5b5091905056fea26469706673582212208b7f340fe47b5b5142d61ce22ee85f40040d02df70fd1f5075b56e594521d32364736f6c63430008090033",
"linkReferences": {},
"deployedLinkReferences": {}
}
import { useEffect, useState } from "react"
export function ConnectSection ({onConnect}) {
const [address, setAddress] = useState('')
const onAccountsChanged = ([walletAddress]) => {
setAddress(walletAddress || '')
onConnect && onConnect(walletAddress)
}
useEffect(() => {
(async () => {
if (window.ethereum) {
const method = 'eth_accounts'
const walletAddresses = await window.ethereum.request({method})
onAccountsChanged(walletAddresses)
}
})()
}, [])
useEffect(() => {
if (window.ethereum) {
window.ethereum.on('accountsChanged', onAccountsChanged)
return () => {
window.ethereum.removeListener('accountsChanged', onAccountsChanged)
}
}
})
const onClickConnect = async () => {
const method = 'eth_requestAccounts'
const walletAddresses = await window.ethereum.request({method})
onAccountsChanged(walletAddresses)
}
return (
<section>
<h2>Connect</h2>
<button onClick={onClickConnect}>Connect</button>
<dl>
<dt>Wallet address</dt>
<dd>{address}</dd>
</dl>
</section>
)
}
import { ethers } from "ethers"
import { abi } from "./abi"
export function createContract () {
const contractAddress = process.env.NEXT_PUBLIC_CONTRACT_ADDRESS as string
const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()
const contract = new ethers.Contract(contractAddress, abi, signer)
return contract
}
import type { NextPage } from 'next'
import Head from 'next/head'
import { useEffect, useState } from 'react'
import { InstallSection } from '../components/install'
import { ConnectSection } from '../components/connect'
import { ReadSection } from '../components/read'
import { WriteSection } from '../components/write'
const Home: NextPage = () => {
const [isInstalled, setIsInstalled] = useState(false)
const [isConnected, setIsConnected] = useState(false)
useEffect(() => {
setIsInstalled(!!window.ethereum)
}, [])
const onConnect = (walletAddress) => {
setIsConnected(!!walletAddress)
}
return (
<div>
<Head>
<title>How to read and write smart contracts from a web page</title>
</Head>
<h1>How to read and write smart contracts from a web page</h1>
{!isInstalled && (
<InstallSection></InstallSection>
)}
{isInstalled && (
<>
<ConnectSection onConnect={onConnect}></ConnectSection>
{isConnected && (
<>
<ReadSection></ReadSection>
<WriteSection></WriteSection>
</>
)}
</>
)}
</div>
)
}
export default Home
export function InstallSection () {
return (
<section>
<h2>Install MetaMask</h2>
<a href="https://metamask.io/">MetaMask</a>
</section>
)
}
import { useState } from "react"
import { createContract } from "../lib/create-contract"
export function ReadSection () {
const [message, setMessage] = useState(null)
const onClickRead = async () => {
const contract = createContract()
const message = await contract.message()
setMessage(message)
}
return (
<section>
<h2>Read</h2>
<button onClick={onClickRead}>Read</button>
<dl>
<dt>Message</dt>
<dd>{message}</dd>
</dl>
</section>
)
}
import { useState } from "react"
import { createContract } from "../lib/create-contract"
export function WriteSection () {
const [message, setMessage] = useState('Hello World!')
const [transaction, setTransaction] = useState('')
const onClickWrite = async (event: any) => {
event.preventDefault()
const contract = createContract()
const {hash} = await contract.setMessage(message)
setTransaction(`https://goerli.etherscan.io/tx/${hash}`)
}
const onChangeMessage = (event: any) => {
setMessage(event.target.value)
}
return (
<section>
<h2>Write</h2>
<form>
<input type="text" name="message" id="message" value={message} onChange={onChangeMessage} />
<button type="submit" onClick={onClickWrite}>Write</button>
</form>
<dl>
<dt>Transaction</dt>
<dd>
<a href={transaction} target="_blank">{transaction}</a>
</dd>
</dl>
</section>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment