当我尝试在智能合约中调用play()函数时,我会遇到metamask rpc错误

发布于 2025-01-18 22:43:33 字数 9330 浏览 1 评论 0原文

当我尝试使用 ethers.js 从我的智能合约调用 play() 函数时,出现此错误:

MetaMask - RPC Error: Internal JSON-RPC error.
{code: -32603, message: 'Internal JSON-RPC error.', data: {…}}
code: -32603
data:
code: 3
data: "0x4e487b710000000000000000000000000000000000000000000000000000000000000032"
message: "execution reverted"
message: "Internal JSON-RPC error."

我的智能合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

import "./FutNFTTransfer.sol";
import "./VRFConsumer.sol";

contract FutNFTMatch is FutNFTTransfer, VRFConsumer {
    uint256 public levelPercentSuitablePosition = 75;
    uint256 public levelPercentNoPosition = 50;
    mapping(string => string[]) public formationToPositions;
    string[] public formations;
    string[] public allPositions;
    uint256 public lineupFee = 0.2 ether;
    uint256 public matchFee = 3 ether;
    address[] public lineupSet;
    mapping(address => uint256) public ownersToDeposits;

    modifier playersOwned(uint256[11] memory _playerIds) {
        for (uint256 i = 0; i < _playerIds.length; i++) {
            require(ownerOf(_playerIds[i]) == msg.sender, "Players not owned!");
        }
        _;
    }

    modifier lineUpSet(address _owner) {
        require(lineUps[_owner].isValid, "Linup not set");
        _;
    }

    constructor() {
        formations.push("4-3-3");
        formationToPositions["4-3-3"] = [
            "GK",
            "LB",
            "CB",
            "CB",
            "RB",
            "CMF",
            "CMF",
            "CMF",
            "LWF",
            "ST",
            "RWF"
        ];
        formations.push("4-3-3 attack");
        formationToPositions["4-3-3 attack"] = [
            "GK",
            "LB",
            "CB",
            "CB",
            "RB",
            "CMF",
            "AMF",
            "CMF",
            "RWF",
            "ST",
            "LWF"
        ];
        allPositions = [
            "LWF",
            "ST",
            "RWF",
            "CF",
            "AMF",
            "CMF",
            "DMF",
            "LMF",
            "RMF",
            "RB",
            "LB",
            "CB",
            "GK"
        ];
    }

    function setMatchFee(uint256 _fee) public onlyOwner {
        matchFee = _fee;
    }

    function setLineupFee(uint256 _fee) public onlyOwner {
        lineupFee = _fee;
    }

    function getAllFormations() public view returns (string[] memory) {
        return formations;
    }

    function getLineup(address _owner) public view returns (LineUp memory) {
        return lineUps[_owner];
    }

    function deposit() public payable lineUpSet(msg.sender) {
        require(msg.value >= 1 ether, "Not enough funds sent!");
        ownersToDeposits[msg.sender] += msg.value;
        if (ownersToDeposits[msg.sender] < 2 ether) {
            lineupSet.push(msg.sender);
        }
    }

    function _removeFromLineupSet(address _owner) internal {
        address[] memory newLineupSet;
        uint256 subFromIndex = 0;
        for (uint256 i = 0; i < lineupSet.length; i++) {
            if (lineupSet[i] != _owner) {
                newLineupSet[i - subFromIndex] = lineupSet[i];
            } else {
                subFromIndex++;
            }
        }
        lineupSet = newLineupSet;
    }

    function withdrawDeposit(uint256 _price) public payable {
        require(
            ownersToDeposits[msg.sender] >= _price,
            "Enough funds not deposited!"
        );
        address to = payable(msg.sender);
        (bool sent, ) = to.call{value: _price}("");
        ownersToDeposits[msg.sender] -= _price;
        require(sent, "Could not complete the transaction");
        if (ownersToDeposits[msg.sender] < 1 ether) {
            _removeFromLineupSet(msg.sender);
        }
    }

    function addFormation(string memory formation, string[] memory positions)
        public
        onlyOwner
    {
        formationToPositions[formation] = positions;
        formations.push(formation);
    }

    function getPositionsFromFormation(string memory formation)
        public
        view
        returns (string[] memory)
    {
        return formationToPositions[formation];
    }

    function getAllPositions() public view returns (string[] memory) {
        return allPositions;
    }

    function setLevelPercentSuitablePosition(uint256 _percent)
        public
        onlyOwner
    {
        levelPercentSuitablePosition = _percent;
    }

    function setLevelPercentNoPosition(uint256 _percent) public onlyOwner {
        levelPercentNoPosition = _percent;
    }

    function setLineUp(
        uint256[11] memory _playerIds,
        string[11] memory _positions,
        string memory _formation
    ) external payable playersOwned(_playerIds) returns (uint256) {
        require(msg.value == lineupFee, "Required fee not sent!");
        lineUps[msg.sender] = LineUp(_playerIds, _positions, _formation, true);
        return getTeamRating(msg.sender);
    }

    function getTeamRating(address _owner)
        public
        view
        lineUpSet(_owner)
        returns (uint256)
    {
        LineUp memory lineup = lineUps[_owner];
        uint256 sum;
        uint256 count;
        for (uint256 i = 0; i < lineup.playerIds.length; i++) {
            sum += _getPlayerLevel(lineup, i);
            count++;
        }
        return sum / count;
    }

    function _getPlayerLevel(LineUp memory _lineup, uint256 _arrayPosition)
        internal
        view
        returns (uint256)
    {
        Player memory player = super.getPlayer(
            _lineup.playerIds[_arrayPosition]
        );
        string memory position = _lineup.positions[_arrayPosition];
        uint256 level;
        if (
            keccak256(abi.encodePacked(player.preferredPosition)) ==
            keccak256(abi.encodePacked(position))
        ) {
            level = player.level;
        } else {
            level = _getPlayerLevelForUnpreferredPosition(player, position);
        }
        return level;
    }

    function _getPlayerLevelForUnpreferredPosition(
        Player memory _player,
        string memory _position
    ) internal view returns (uint256) {
        uint256 level = (_player.level * levelPercentNoPosition) / 100;
        for (uint256 k = 0; k < _player.suitablePositions.length; k++) {
            if (
                keccak256(abi.encodePacked(_player.suitablePositions[k])) ==
                keccak256(abi.encodePacked(_position))
            ) {
                level = (_player.level * levelPercentSuitablePosition) / 100;
                break;
            }
        }
        return level;
    }

    function getOpponent() public lineUpSet(msg.sender) returns (address) {
        require(lineupSet.length > 1, "Players not available!");
        getRandomNumber();
        randomResult = (randomResult % lineupSet.length) + 1;
        address opponent = lineupSet[randomResult - 1];
        if (msg.sender == opponent) {
            if (randomResult == lineupSet.length) {
                opponent = lineupSet[randomResult - 2];
            } else {
                opponent = lineupSet[randomResult];
            }
        }
        return opponent;
    }

    function play() external payable lineUpSet(msg.sender) {
        require(
            ownersToDeposits[msg.sender] >= 1 ether,
            "Does not have enough funds in deposits!"
        );
        address _opponent = getOpponent();
        uint256 teamRating = getTeamRating(msg.sender);
        uint256 opponentTeamRating = getTeamRating(_opponent);
        uint256 winProbability = 50;
        if (teamRating > opponentTeamRating) {
            winProbability = 50 + ((teamRating - opponentTeamRating) * 3);
        } else {
            winProbability = 50 - ((opponentTeamRating - teamRating) * 3);
        }
        getRandomNumber();
        randomResult = (randomResult % 100) + 1;
        if (randomResult <= winProbability) {
            ownerHistory[msg.sender].winCount++;
            ownerHistory[_opponent].lossCount++;
            ownersToDeposits[_opponent] -= 1 ether;
            if (ownersToDeposits[_opponent] < 1 ether) {
                _removeFromLineupSet(_opponent);
            }
            ownersToDeposits[msg.sender] += 0.5 ether;
        } else {
            ownerHistory[msg.sender].lossCount++;
            ownerHistory[_opponent].winCount++;
            ownersToDeposits[msg.sender] -= 1 ether;
            if (ownersToDeposits[msg.sender] < 1 ether) {
                _removeFromLineupSet(msg.sender);
            }
            ownersToDeposits[_opponent] += 0.5 ether;
        }
    }
}

我的 ethers.js 代码:

const provider: ethers.providers.Web3Provider = new ethers.providers.Web3Provider((window as any).ethereum);
const signer = provider.getSigner();
const matchFee = await this.props.futNFTMatch.matchFee();
const tx = await this.props.futNFTMatch.connect(signer).play();
await tx.wait();

我已满足所有要求语句,但仍然收到此错误。我的代码有问题吗?

如果您需要的话,这里是所有合约: https://github.com/anim7/ FutNFT/tree/master/contracts

I get this error when I try to call play() function from my smart contract using ethers.js:

MetaMask - RPC Error: Internal JSON-RPC error.
{code: -32603, message: 'Internal JSON-RPC error.', data: {…}}
code: -32603
data:
code: 3
data: "0x4e487b710000000000000000000000000000000000000000000000000000000000000032"
message: "execution reverted"
message: "Internal JSON-RPC error."

my smart contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

import "./FutNFTTransfer.sol";
import "./VRFConsumer.sol";

contract FutNFTMatch is FutNFTTransfer, VRFConsumer {
    uint256 public levelPercentSuitablePosition = 75;
    uint256 public levelPercentNoPosition = 50;
    mapping(string => string[]) public formationToPositions;
    string[] public formations;
    string[] public allPositions;
    uint256 public lineupFee = 0.2 ether;
    uint256 public matchFee = 3 ether;
    address[] public lineupSet;
    mapping(address => uint256) public ownersToDeposits;

    modifier playersOwned(uint256[11] memory _playerIds) {
        for (uint256 i = 0; i < _playerIds.length; i++) {
            require(ownerOf(_playerIds[i]) == msg.sender, "Players not owned!");
        }
        _;
    }

    modifier lineUpSet(address _owner) {
        require(lineUps[_owner].isValid, "Linup not set");
        _;
    }

    constructor() {
        formations.push("4-3-3");
        formationToPositions["4-3-3"] = [
            "GK",
            "LB",
            "CB",
            "CB",
            "RB",
            "CMF",
            "CMF",
            "CMF",
            "LWF",
            "ST",
            "RWF"
        ];
        formations.push("4-3-3 attack");
        formationToPositions["4-3-3 attack"] = [
            "GK",
            "LB",
            "CB",
            "CB",
            "RB",
            "CMF",
            "AMF",
            "CMF",
            "RWF",
            "ST",
            "LWF"
        ];
        allPositions = [
            "LWF",
            "ST",
            "RWF",
            "CF",
            "AMF",
            "CMF",
            "DMF",
            "LMF",
            "RMF",
            "RB",
            "LB",
            "CB",
            "GK"
        ];
    }

    function setMatchFee(uint256 _fee) public onlyOwner {
        matchFee = _fee;
    }

    function setLineupFee(uint256 _fee) public onlyOwner {
        lineupFee = _fee;
    }

    function getAllFormations() public view returns (string[] memory) {
        return formations;
    }

    function getLineup(address _owner) public view returns (LineUp memory) {
        return lineUps[_owner];
    }

    function deposit() public payable lineUpSet(msg.sender) {
        require(msg.value >= 1 ether, "Not enough funds sent!");
        ownersToDeposits[msg.sender] += msg.value;
        if (ownersToDeposits[msg.sender] < 2 ether) {
            lineupSet.push(msg.sender);
        }
    }

    function _removeFromLineupSet(address _owner) internal {
        address[] memory newLineupSet;
        uint256 subFromIndex = 0;
        for (uint256 i = 0; i < lineupSet.length; i++) {
            if (lineupSet[i] != _owner) {
                newLineupSet[i - subFromIndex] = lineupSet[i];
            } else {
                subFromIndex++;
            }
        }
        lineupSet = newLineupSet;
    }

    function withdrawDeposit(uint256 _price) public payable {
        require(
            ownersToDeposits[msg.sender] >= _price,
            "Enough funds not deposited!"
        );
        address to = payable(msg.sender);
        (bool sent, ) = to.call{value: _price}("");
        ownersToDeposits[msg.sender] -= _price;
        require(sent, "Could not complete the transaction");
        if (ownersToDeposits[msg.sender] < 1 ether) {
            _removeFromLineupSet(msg.sender);
        }
    }

    function addFormation(string memory formation, string[] memory positions)
        public
        onlyOwner
    {
        formationToPositions[formation] = positions;
        formations.push(formation);
    }

    function getPositionsFromFormation(string memory formation)
        public
        view
        returns (string[] memory)
    {
        return formationToPositions[formation];
    }

    function getAllPositions() public view returns (string[] memory) {
        return allPositions;
    }

    function setLevelPercentSuitablePosition(uint256 _percent)
        public
        onlyOwner
    {
        levelPercentSuitablePosition = _percent;
    }

    function setLevelPercentNoPosition(uint256 _percent) public onlyOwner {
        levelPercentNoPosition = _percent;
    }

    function setLineUp(
        uint256[11] memory _playerIds,
        string[11] memory _positions,
        string memory _formation
    ) external payable playersOwned(_playerIds) returns (uint256) {
        require(msg.value == lineupFee, "Required fee not sent!");
        lineUps[msg.sender] = LineUp(_playerIds, _positions, _formation, true);
        return getTeamRating(msg.sender);
    }

    function getTeamRating(address _owner)
        public
        view
        lineUpSet(_owner)
        returns (uint256)
    {
        LineUp memory lineup = lineUps[_owner];
        uint256 sum;
        uint256 count;
        for (uint256 i = 0; i < lineup.playerIds.length; i++) {
            sum += _getPlayerLevel(lineup, i);
            count++;
        }
        return sum / count;
    }

    function _getPlayerLevel(LineUp memory _lineup, uint256 _arrayPosition)
        internal
        view
        returns (uint256)
    {
        Player memory player = super.getPlayer(
            _lineup.playerIds[_arrayPosition]
        );
        string memory position = _lineup.positions[_arrayPosition];
        uint256 level;
        if (
            keccak256(abi.encodePacked(player.preferredPosition)) ==
            keccak256(abi.encodePacked(position))
        ) {
            level = player.level;
        } else {
            level = _getPlayerLevelForUnpreferredPosition(player, position);
        }
        return level;
    }

    function _getPlayerLevelForUnpreferredPosition(
        Player memory _player,
        string memory _position
    ) internal view returns (uint256) {
        uint256 level = (_player.level * levelPercentNoPosition) / 100;
        for (uint256 k = 0; k < _player.suitablePositions.length; k++) {
            if (
                keccak256(abi.encodePacked(_player.suitablePositions[k])) ==
                keccak256(abi.encodePacked(_position))
            ) {
                level = (_player.level * levelPercentSuitablePosition) / 100;
                break;
            }
        }
        return level;
    }

    function getOpponent() public lineUpSet(msg.sender) returns (address) {
        require(lineupSet.length > 1, "Players not available!");
        getRandomNumber();
        randomResult = (randomResult % lineupSet.length) + 1;
        address opponent = lineupSet[randomResult - 1];
        if (msg.sender == opponent) {
            if (randomResult == lineupSet.length) {
                opponent = lineupSet[randomResult - 2];
            } else {
                opponent = lineupSet[randomResult];
            }
        }
        return opponent;
    }

    function play() external payable lineUpSet(msg.sender) {
        require(
            ownersToDeposits[msg.sender] >= 1 ether,
            "Does not have enough funds in deposits!"
        );
        address _opponent = getOpponent();
        uint256 teamRating = getTeamRating(msg.sender);
        uint256 opponentTeamRating = getTeamRating(_opponent);
        uint256 winProbability = 50;
        if (teamRating > opponentTeamRating) {
            winProbability = 50 + ((teamRating - opponentTeamRating) * 3);
        } else {
            winProbability = 50 - ((opponentTeamRating - teamRating) * 3);
        }
        getRandomNumber();
        randomResult = (randomResult % 100) + 1;
        if (randomResult <= winProbability) {
            ownerHistory[msg.sender].winCount++;
            ownerHistory[_opponent].lossCount++;
            ownersToDeposits[_opponent] -= 1 ether;
            if (ownersToDeposits[_opponent] < 1 ether) {
                _removeFromLineupSet(_opponent);
            }
            ownersToDeposits[msg.sender] += 0.5 ether;
        } else {
            ownerHistory[msg.sender].lossCount++;
            ownerHistory[_opponent].winCount++;
            ownersToDeposits[msg.sender] -= 1 ether;
            if (ownersToDeposits[msg.sender] < 1 ether) {
                _removeFromLineupSet(msg.sender);
            }
            ownersToDeposits[_opponent] += 0.5 ether;
        }
    }
}

my ethers.js code:

const provider: ethers.providers.Web3Provider = new ethers.providers.Web3Provider((window as any).ethereum);
const signer = provider.getSigner();
const matchFee = await this.props.futNFTMatch.matchFee();
const tx = await this.props.futNFTMatch.connect(signer).play();
await tx.wait();

I have satisfied all the require statements, but still I get this error. Is something wrong with my code?

Here are all the contracts if you need them: https://github.com/anim7/FutNFT/tree/master/contracts

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

や莫失莫忘 2025-01-25 22:43:33

尝试以下建议, metAmask

  • 确保已正确添加网络。您可以使用 chainlist 添加自定义网络/代币/代币
  • 确保您拥有该网络的足够的天然令牌来支付汽油,
  • 请确保您确保您正在使用该应用的最新版本或扩展程序

Try the following suggestion provided by MetaMask.

  • ensure the network has been added correctly. You can use Chainlist to add custom network/ tokens
  • ensure you have enough native tokens from that network to pay for gas
  • ensure you are using the latest version of the app or the extension
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文