MetaMask 合约交互永远排队

时间:2021-05-30 04:41:08

标签: javascript reactjs solidity web3 metamask

我在 Matic Mumbai 测试网上部署了一个智能合约,我正在尝试使用 Web3 从 React Web 应用程序与其交互。我的智能合约中有一个名为 buySucc(多肉植物的缩写)的应付函数。当我使用 Web3 从我的 React Web 应用程序调用该函数时,MetaMask 会弹出我能够确认的交易。之后,我在元掩码中看到一个待处理的发送交易和一个排队的合约交互。几秒钟后,我在前端得到 Error: Receipt missing or blockHash null,合约交互在 MetaMask 中永远排队。 我还使用 ganache-cli 将智能合约部署到了孟买测试网的本地分支。使用本质上相同的函数调用运行一个简单的 Node.js 脚本可以完美运行,这让我感到非常困惑。
在查看 https://ethereum.stackexchange.com/questions/43691/metamask-issue-with-payable-transactions-using-truffle-and-web3 后,我尝试将 gas 限制提高到 2000000,但这没有用。

这是我的代码:
智能合约:SuccOwnership.sol

...

function _createSucc(
        uint256 _parent1Id,
        uint256 _parent2Id,
        uint256 _genes,
        address _owner
    ) internal returns (uint256) {
        uint256 watersNeededIndex = 0;
        if (_parent1Id != 0) {
            watersNeededIndex = succs[_parent1Id].watersNeededIndex / 2;
        } else if (_parent2Id != 0) {
            watersNeededIndex = succs[_parent2Id].watersNeededIndex / 2;
        }
        succs.push(
            Succ(
                _genes,
                uint64(block.timestamp),
                0,
                0,
                uint8(watersNeededIndex),
                false
            )
        );
        uint256 _newSuccIndex = succs.length - 1;
        _safeMint(_owner, _newSuccIndex);
        emit newSucc(_owner, _newSuccIndex, _parent1Id, _parent2Id, _genes);
        return _newSuccIndex;
        // return 0;
    }

    function buySucc(uint256 _genes, uint256 _price)
        external
        payable
        returns (uint256)
    {
        require(msg.value == _price, "Wrong price paid for succulent");
        return _createSucc(0, 0, _genes, msg.sender);
    }

...

(作为旁注,我知道价格是外部 buySucc 函数的参数并不安全和奇怪,但我还没有开始实施价格确定:'))< br/> App.js:

import {
    getAccount,
    getSuccContract,
    buySucc,
    getPotContract,
    getPotAdmin,
    getSuccIds,
} from './backend/backend.js'
/* more imports */

export default function App() {
    const web3 = new Web3(Web3.givenProvider || "https://rpc-mumbai.matic.today/")

    const default_plants = new Array(12).fill(null);

    const [plants, setPlants] = useState(default_plants);
    const [pots, setPots] = useState();
    const [account, setAccount] = useState();
    const [succContract, setSuccContract] = useState();

    async function setupBlockchain() {
        const account = await getAccount(web3)
        setAccount(account);
        const succContract = await getSuccContract(web3);
        setSuccContract(succContract);
        const potContract = await getPotContract(web3);
        const admin = await getPotAdmin(potContract);
        console.log(admin)
    }
    
    //Works
    async function getPlants() {
        if(!account || !succContract) {
            console.log('connect account first')
        }
        const plantIds = await getSuccIds(web3, account, succContract);
        console.log(plantIds)
    }
    
    //Doesn't work
    async function buyPlant() {
        if(!account || !succContract) {
            console.log('connect account first')
        }
        buySucc(web3, succContract, account, 0, 0)
    }

    return (...);

后端.js:

import {
    SUCC_OWNERSHIP_ADDRESS,
    SUCC_OWNERSHIP_ABI,
    POT_OWNERSHIP_ADDRESS,
    POT_OWNERSHIP_ABI
} from "../config.js"

export async function getAccount(web3) {
    const accounts = await web3.eth.getAccounts();
    return accounts[0];
}

export async function getSuccContract(web3) {
    return new web3.eth.Contract(SUCC_OWNERSHIP_ABI, SUCC_OWNERSHIP_ADDRESS);
}

//This works
export async function getSuccIds(web3, account, contract) {
    const succIds = await contract.methods.succsOfOwner(account).call();
    return succIds
}

//This doesn't work
export async function buySucc(web3, contract, account, dna, price) {
    const newSucc = await contract.methods.buySucc(0, web3.utils.toWei('1')).send({
        from: account,
        value: web3.utils.toWei('1')
    });
    return newSucc
}

具有排队合约交互的 MetaMask 屏幕截图

Screenshot

0 个答案:

没有答案
相关问题