访问智能合约的任何功能都会出错

问题描述 投票:0回答:1

我尝试访问智能合约中存在的 getAllTransactions() 方法,甚至可以在 console.log() 中看到,但访问它或智能合约的任何其他方法,无论读取或写入方法都会出错。我正在使用 nextjs 应用程序

import { contractABI, contractAddress } from '../utils/transactions/constants'
import dynamic from 'next/dynamic'

let ethereum
export const TransactionContext = createContext()

const TransactProvider = ({ children }) => {
    const [ userAccount, setUserAccount ] = useState('')
    const [ formData, setFormData ] = useState({ 
        addressTo: '', amount: '', keyword: '', message: ''
    })
    const [isLoading, setIsLoading ] = useState(false)
    const [ transactionCount, setTransactionCount ] = useState()
    const [transactions, setTransactions] = useState([])

    const handleChange = (e, name) => {
        setFormData(prevState => ({ ...prevState, [name]: e.target.value }))
    }

    const getContract = () => {
        const provider = new ethers.providers.Web3Provider(ethereum)
        const signer = provider.getSigner()
        const transactionContract = new ethers.Contract(contractAddress, contractABI, signer)
        /*@dev::: built contract */
        // console.log(ethereum)
        // console.log(ethers)
        // console.log({
        //     provider,
        //     signer,
        //     transactionContract
        // })
        // console.log(transactionContract)
        return transactionContract
    }
    
    const getAllTxn = async() => {
        try {
            if (ethereum) {
                const transfer_contract = getContract()
                console.log(Object.keys(transfer_contract.getAllTransactions))
                // promise was not being handled and thus showed that args state for []
                const available_transactions = await transfer_contract.getAllTransactions()
                console.log(available_transactions)
                const structured_transactions = 
                    available_transactions.map((transaction) => ({
                        addressTo: transaction.receiver,
                        addressFrom: transaction.sender,
                        timestamp: new Date(transaction.timestamp.toNumber() * 1000).toLocaleString(),
                        message: transaction.message,
                        keyword: transaction.keyword,
                        amount: parseInt(transaction.amount._hex) / (10 ** 18)
                    }))
                console.log(structured_transactions)
                setTransactions(structured_transactions)
            }
            else {
                console.log('no ethereum object !')
            }
        }
        catch (error) {
            console.log(error)
            throw new Error('error while parsing')
        }
    }
// ...rest of the code follows (context.js)

而我的constants.js 文件是

import abi from './Transfer.json'

const contractABI = abi.abi
const contractAddress= '0x5FbDB2315678afecb367f032d93F642f64180aa3'

export { contractABI, contractAddress }
blockchain smartcontracts
1个回答
0
投票

您似乎缺少依赖项导入。您还需要检查“getAllTxn”以查看以太坊对象是否可用。

这是重构后的代码。应该可以正常工作:

import { createContext, useState, useEffect } from 'react';
import { ethers } from 'ethers';
import { contractABI, contractAddress } from '../utils/transactions/constants';

// Create Ethereum context
export const TransactionContext = createContext();

// Provider component
const TransactProvider = ({ children }) => {
    const [userAccount, setUserAccount] = useState('');
    const [formData, setFormData] = useState({ addressTo: '', amount: '', keyword: '', message: '' });
    const [isLoading, setIsLoading] = useState(false);
    const [transactionCount, setTransactionCount] = useState();
    const [transactions, setTransactions] = useState([]);

    // Function to handle changes in form fields
    const handleChange = (e, name) => {
        setFormData(prevState => ({ ...prevState, [name]: e.target.value }));
    };

    // Function to get Ethereum provider and set user account
    useEffect(() => {
        const fetchEthereum = async () => {
            if (typeof window !== 'undefined' && typeof window.ethereum !== 'undefined') {
                try {
                    await window.ethereum.request({ method: 'eth_requestAccounts' });
                    setUserAccount(window.ethereum.selectedAddress || '');
                } catch (error) {
                    console.error('Error fetching Ethereum provider:', error.message);
                }
            }
        };

        fetchEthereum();
    }, []);

    // Function to get smart contract instance
    const getContract = () => {
        const provider = new ethers.providers.Web3Provider(window.ethereum);
        const signer = provider.getSigner();
        return new ethers.Contract(contractAddress, contractABI, signer);
    };

    // Function to fetch all transactions from smart contract
    const getAllTxn = async () => {
        try {
            if (!window.ethereum) {
                throw new Error('Ethereum object not found. Make sure MetaMask or another Ethereum provider is installed and enabled.');
            }

            const transferContract = getContract();
            console.log(Object.keys(transferContract.getAllTransactions));

            const availableTransactions = await transferContract.getAllTransactions();
            console.log(availableTransactions);

            const structuredTransactions = availableTransactions.map((transaction) => ({
                addressTo: transaction.receiver,
                addressFrom: transaction.sender,
                timestamp: new Date(transaction.timestamp.toNumber() * 1000).toLocaleString(),
                message: transaction.message,
                keyword: transaction.keyword,
                amount: parseInt(transaction.amount._hex) / (10 ** 18)
            }));

            console.log(structuredTransactions);
            setTransactions(structuredTransactions);
        } catch (error) {
            console.error('Error while fetching transactions:', error.message);
            // Handle error appropriately, e.g., show a message to the user
        }
    };

    return (
        <TransactionContext.Provider
            value={{
                userAccount,
                formData,
                isLoading,
                transactionCount,
                transactions,
                handleChange,
                getAllTxn
            }}
        >
            {children}
        </TransactionContext.Provider>
    );
};

export default TransactProvider;
© www.soinside.com 2019 - 2024. All rights reserved.