私のフロントエンドで
すべてのweb3コンポーネントをセットアップしましたが、まだミントボタンが機能していないようですが、接続ボタンが表示され、完全に機能しています。
誰かがここで私を助けてくれたらうれしいです
契約: https://github.com/Rugg-0/Cattos-NFT dapp をデプロイしました: https://github.com/Rugg-0/Cattos
ABIはこれ
[
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "string",
"name": "_symbol",
"type": "string"
},
{
"internalType": "string",
"name": "_initBaseURI",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "approved",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Approval",
"type": "event",
"signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event",
"signature": "0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event",
"signature": "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event",
"signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
},
{
"inputs": [
{
"internalType": "address[100]",
"name": "_users",
"type": "address[100]"
}
],
"name": "add100PresaleUsers",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x546857c7"
},
{
"inputs": [
{
"internalType": "address",
"name": "_user",
"type": "address"
}
],
"name": "addPresaleUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xb2f3e85e"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "approve",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x095ea7b3"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x70a08231"
},
{
"inputs": [],
"name": "baseExtension",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0xc6682862"
},
{
"inputs": [],
"name": "baseURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x6c0360eb"
},
{
"inputs": [],
"name": "cost",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x13faede6"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getApproved",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x081812fc"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0xe985e9c5"
},
{
"inputs": [],
"name": "maxMintAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x239c70ae"
},
{
"inputs": [],
"name": "maxSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0xd5abeb01"
},
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_mintAmount",
"type": "uint256"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "payable",
"type": "function",
"payable": true,
"signature": "0x40c10f19"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x06fdde03"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x8da5cb5b"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "ownerOf",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x6352211e"
},
{
"inputs": [
{
"internalType": "bool",
"name": "_state",
"type": "bool"
}
],
"name": "pause",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x02329a29"
},
{
"inputs": [],
"name": "paused",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x5c975abb"
},
{
"inputs": [],
"name": "presaleCost",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x2a23d07d"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "presaleWallets",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x30b2264e"
},
{
"inputs": [
{
"internalType": "address",
"name": "_user",
"type": "address"
}
],
"name": "removePresaleUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xed931e17"
},
{
"inputs": [
{
"internalType": "address",
"name": "_user",
"type": "address"
}
],
"name": "removeWhitelistUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x30cc7ae0"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x715018a6"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x42842e0e"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xb88d4fde"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xa22cb465"
},
{
"inputs": [
{
"internalType": "string",
"name": "_newBaseExtension",
"type": "string"
}
],
"name": "setBaseExtension",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xda3ef23f"
},
{
"inputs": [
{
"internalType": "string",
"name": "_newBaseURI",
"type": "string"
}
],
"name": "setBaseURI",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x55f804b3"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_newCost",
"type": "uint256"
}
],
"name": "setCost",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x44a0d68a"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_newCost",
"type": "uint256"
}
],
"name": "setPresaleCost",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x8fdcf942"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_newmaxMintAmount",
"type": "uint256"
}
],
"name": "setmaxMintAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x7f00c7a6"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x01ffc9a7"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x95d89b41"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x4f6ccce7"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenOfOwnerByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x2f745c59"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "tokenURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0xc87b56dd"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x18160ddd"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x23b872dd"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xf2fde38b"
},
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"name": "walletOfOwner",
"outputs": [
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0x438b6300"
},
{
"inputs": [
{
"internalType": "address",
"name": "_user",
"type": "address"
}
],
"name": "whitelistUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x4a4c560d"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "whitelisted",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function",
"constant": true,
"signature": "0xd936547e"
},
{
"inputs": [],
"name": "withdraw",
"outputs": [],
"stateMutability": "payable",
"type": "function",
"payable": true,
"signature": "0x3ccfd60b"
}
]
これが minting.TSX dapp コードです
import { useEffect, useState } from 'react';
import { useWeb3React } from '@web3-react/core';
import { ethers } from 'ethers';
import { IconContext } from 'react-icons';
import { FaMinusCircle, FaPlusCircle } from 'react-icons/fa';
import { useContractContext } from '../context/Contract';
import ABI from '../contract/abi.json';
export default function Minting() {
const { chainId, account, active } = useWeb3React();
const { message, errMsg, setMessage } = useContractContext();
const [totalSupply, setTotalSupply] = useState('?');
const [isPending, setIsPending] = useState(false);
const [isMinting, setIsMinting] = useState(false);
const [mintAmount, setMintAmount] = useState(1);
async function claimNFTs() {
if (active && account && !errMsg) {
const cost = process.env.NEXT_PUBLIC_WEI_COST;
const gasLimit = process.env.NEXT_PUBLIC_GAS_LIMIT;
const totalCostWei = (Number(cost) * mintAmount).toString();
const totalGasLimit = (Number(gasLimit) * mintAmount).toString();
setMessage('');
setIsPending(true);
try {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const contract = new ethers.Contract(
process.env.NEXT_PUBLIC_CONTRACT_ADDRESS!,
ABI,
signer
);
const transaction = await contract.mint(mintAmount, {
value: totalCostWei,
gasLimit: totalGasLimit.toString(),
});
setIsPending(false);
setIsMinting(true);
await transaction.wait();
setIsMinting(false);
setMessage(
`Yay! ${mintAmount} ${
process.env.NEXT_PUBLIC_NFT_SYMBOL
} successfully sent to ${account.substring(
0,
6
)}...${account.substring(account.length - 4)}`
);
} catch (error) {
setIsPending(false);
}
}
}
function decrementMintAmount() {
if (mintAmount > 1) {
setMintAmount(mintAmount - 1);
}
}
function incrementMintAmount() {
if (mintAmount < 20) {
setMintAmount(mintAmount + 1);
}
}
useEffect(() => {
async function fetchTotalSupply() {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const contract = new ethers.Contract(
process.env.NEXT_PUBLIC_CONTRACT_ADDRESS!,
ABI,
provider
);
const totalSupply = await contract.totalSupply();
setTotalSupply(totalSupply.toString());
}
if (
active &&
chainId &&
chainId.toString() === process.env.NEXT_PUBLIC_NETWORK_ID
) {
fetchTotalSupply();
} else {
setTotalSupply('?');
}
}, [active, chainId]);
return (
<>
<h2 className="text-4xl text-gray-100 mb-4">Minting</h2>
<div className="space-y-4 mt-4">
<div className="bg-gray-800 border-dashed border-4 border-gray-400 rounded p-8 space-y-4">
<div className="text-3xl font-bold text-center">
{totalSupply} / {process.env.NEXT_PUBLIC_MAX_SUPPLY}
</div>
<div className="text-center">
<p className="text-xl">{`${process.env.NEXT_PUBLIC_DISPLAY_COST} ${process.env.NEXT_PUBLIC_CHAIN} per 1 NFT`}</p>
<p>(excluding gas fees)</p>
</div>
<div className="flex justify-center items-center space-x-4">
<IconContext.Provider value={{ size: '1.5em' }}>
<button
type="button"
className={
mintAmount === 1 ? 'text-gray-500 cursor-default' : ''
}
onClick={decrementMintAmount}
disabled={false}
>
<FaMinusCircle />
</button>
<span className="text-xl">{mintAmount}</span>
<button
type="button"
className={
mintAmount === 10 ? 'text-gray-500 cursor-default' : ''
}
onClick={incrementMintAmount}
disabled={false}
>
<FaPlusCircle />
</button>
</IconContext.Provider>
</div>
<div className="flex justify-center">
{!active || errMsg ? (
<button
type="button"
className={`rounded px-4 py-2 bg-gray-700 font-bold w-40 cursor-not-allowed`}
disabled={true}
onClick={claimNFTs}
>
Buy
</button>
) : (
<>
{isPending || isMinting ? (
<button
type="button"
className="flex justify-center items-center rounded px-4 py-2 bg-red-700 font-bold w-40 cursor-not-allowed"
disabled
>
<svg
className="animate-spin -ml-1 mr-3 h-5 w-5 text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
{isPending && 'Pending'}
{isMinting && 'Minting'}
{!isPending && !isMinting && 'Processing'}
</button>
) : (
<button
type="button"
className={`rounded px-4 py-2 bg-blue-700 hover:bg-blue-600 font-bold w-40`}
onClick={claimNFTs}
>
Buy
</button>
)}
</>
)}
</div>
{message && (
<div className="text-green-500 text-center">{message}</div>
)}
{errMsg && <div className="text-red-500 text-center">{errMsg}</div>}
</div>
<div className="space-y-4">
<p>
Please make sure you are connected to the correct address and the
correct network (SmartBCH Mainnet) before purchasing. The operation
cannot be undone after purchase.
</p>
<p>
We have set the gas limit to 285000 to successfully mint your NFT.
We recommend that you do not lower the gas limit.
</p>
</div>
</div>
</>
);
}