BaseBase
0x26...65Db
Anybody Problem

Anybody Problem

收藏品
底价
0.000187 ETH
$2,345.34
大小
167 件
5,416 版
所有者
2,155
40% 独特的所有者
此合同的源代码已经过验证!
合同元数据
编译器
0.8.15+commit.e14f2714
语言
Solidity
合同源代码
文件 1 的 26:Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}
合同源代码
文件 2 的 26:AnybodyProblem.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {Groth16Verifier as Groth16Verifier2} from './Game_2_20Verifier.sol';
import {Groth16Verifier as Groth16Verifier3} from './Game_3_20Verifier.sol';
import {Groth16Verifier as Groth16Verifier4} from './Game_4_20Verifier.sol';
import {Groth16Verifier as Groth16Verifier5} from './Game_5_20Verifier.sol';
import {Groth16Verifier as Groth16Verifier6} from './Game_6_20Verifier.sol';

import '@openzeppelin/contracts/token/common/ERC2981.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/token/ERC1155/ERC1155.sol';
import './Speedruns.sol';
import './ExternalMetadata.sol';

contract AnybodyProblem is Ownable, ERC2981 {
    uint256 public constant LEVELS = 5;
    uint256 public constant SECONDS_IN_A_DAY = 86400;
    uint256 public constant SECONDS_IN_A_WEEK = SECONDS_IN_A_DAY * 7;
    uint256 public constant FIRST_SUNDAY_AT_6_PM_UTC = 324000;

    bool public paused = false;
    uint256 public priceToMint = 0.0025 ether;
    uint256 public priceToSave = 0 ether;
    uint256 public discount = 2;
    address payable public proceedRecipient;
    address public externalMetadata;
    address payable public speedruns;
    // uint256 public constant maxTick = 25 * 60; // 25 fps * 60 sec = 1,500 ticks max
    // level duration is numberOfBaddies * 10sec (multiplied by 25 because of 25 FPS)
    uint256[5] public maxTicksByLevelIndex = [
        1 * 10 * 25,
        2 * 10 * 25,
        3 * 10 * 25,
        4 * 10 * 25,
        5 * 10 * 25
    ];
    uint256 public constant speedFactor = 2;
    uint256 public constant scalingFactor = 10 ** 3;
    uint256 public constant maxVector = 10 * speedFactor;
    uint256 public constant maxVectorScaled = maxVector * scalingFactor;
    uint256 public constant windowWidth = 1000 * scalingFactor;
    uint256 public constant startingRadius = 2;

    struct Run {
        address owner;
        bool solved; // redundant by accumulating A
        uint256 accumulativeTime; // redundant by accumulating C
        bytes32 seed;
        uint256 day;
        Level[] levels;
    }
    struct Level {
        bool solved; // redundant A
        uint256 time; // redundant C
        bytes32 seed;
        uint256[5] tmpInflightMissile;
        Body[6] tmpBodyData;
    }
    struct Body {
        uint256 bodyIndex;
        uint256 px;
        uint256 py;
        uint256 vx;
        uint256 vy;
        uint256 radius;
        bytes32 seed;
    }

    mapping(uint256 => uint256[3]) public fastestByDay; // day => [fastest, 2nd fastest, 3rd fastest runId]
    address[3] public mostGames;
    address[3] public longestStreak;

    struct Record {
        uint256 total;
        uint256 lastPlayed;
        uint256 streak;
    }
    mapping(address => Record) public gamesPlayed;
    mapping(address => mapping(uint256 => uint256[7])) public weeklyRecords;
    mapping(uint256 => address[3]) public fastestByWeek;

    // NOTE: initialize with length of 1 so Runs are not 0 indexed (runId == index of the run array)
    Run[] public runs = new Run[](1);

    // mapping is body count to tickcount to address
    mapping(uint256 => mapping(uint256 => address)) public verifiers;
    mapping(bytes32 => bool) public usedProofs;

    constructor(
        address payable proceedRecipient_,
        address payable speedruns_,
        address externalMetadata_,
        address[] memory verifiers_,
        uint256[] memory verifiersTicks,
        uint256[] memory verifiersBodies
    ) {
        updateProceedRecipient(proceedRecipient_);
        updateSpeedrunsAddress(speedruns_);
        updateExternalMetadata(externalMetadata_);
        for (uint256 i = 0; i < verifiers_.length; i++) {
            require(verifiersTicks[i] > 0, 'Invalid verifier');
            require(verifiers_[i] != address(0), 'Invalid verifier');
            verifiers[verifiersBodies[i]][verifiersTicks[i]] = verifiers_[i];
        }
    }

    receive() external payable {
        revert('no receive thank you');
    }

    fallback() external {
        revert('no fallback thank you');
    }

    event RunCreated(uint256 runId, uint256 day, bytes32 seed);
    event RunSolved(
        address indexed player,
        uint256 indexed runId,
        uint256 accumulativeTime,
        uint256 day
    );
    event LevelCreated(uint256 runId, uint256 level, bytes32 seed, uint256 day);
    event LevelSolved(
        address indexed player,
        uint256 indexed runId,
        uint256 indexed level,
        uint256 time,
        uint256 day
    );
    event EthMoved(
        address indexed to,
        bool indexed success,
        bytes returnData,
        uint256 amount
    );

    // NOTE: the only publicly available function that isn't protected by a modifier
    function batchSolve(
        uint256 runId,
        bool alsoMint,
        uint256 day,
        uint256[] memory tickCounts,
        uint[2][] memory a,
        uint[2][2][] memory b,
        uint[2][] memory c,
        uint[][] memory input
    ) public payable {
        if (day == 0) {
            day = currentDay();
        }
        require(
            day % SECONDS_IN_A_DAY == 0,
            'One problem per day, invalid day'
        );
        require(day <= currentDay(), 'Cannot solve future problems');
        require(!paused, 'Contract is paused');
        if (runId == 0) {
            runId = addNewRun(day);
            addNewLevelData(runId);
        }
        require(
            runs[runId].owner == msg.sender,
            'Only the owner of the run can solve it'
        );
        require(!runs[runId].solved, 'Run already solved');

        require(
            day == runs[runId].day,
            'Can only solve runs on the current day'
        );

        for (uint256 i = 0; i < input.length; i++) {
            verifyLevelChunk(
                runId,
                alsoMint,
                tickCounts[i],
                day,
                a[i],
                b[i],
                c[i],
                input[i]
            );
        }
        // TODO: decide whether this is necessary
        // require(runs[runId].solved, "Must solve all levels to complete run");
    }

    function runCount() public view returns (uint256) {
        return runs.length - 1;
    }

    function getLevelsData(
        uint256 runId
    ) public view returns (Level[] memory levels) {
        return runs[runId].levels;
    }

    function generateLevelData(
        uint256 day,
        uint256 level
    ) public view virtual returns (Body[6] memory bodyData, uint256 bodyCount) {
        // NOTE: <= becuase level 5 has 6 bodies
        for (uint256 i = 0; i <= level; i++) {
            bytes32 dayLevelIndexSeed = getLevelSeed(day, level, i);
            bodyData[i] = getRandomValues(dayLevelIndexSeed, i, day);
        }
        bodyCount = level + 1;
    }

    function getLevelSeed(
        uint256 day,
        uint256 level,
        uint256 bodyIndex
    ) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(day, level, bodyIndex));
    }

    function getRandomValues(
        bytes32 dayLevelIndexSeed,
        uint256 index,
        uint256 day
    ) public pure returns (Body memory) {
        // NOTE: this function uses a seed consisting of the day + bodyIndex which means
        // that all problems of the same level on the same day will have bodies with the same
        // positions, velocities and radii.
        Body memory body;

        body.bodyIndex = index;
        body.seed = dayLevelIndexSeed;

        body.radius = genRadius(index);

        bytes32 rand = keccak256(abi.encodePacked(dayLevelIndexSeed));
        body.px = randomRange(0, windowWidth, rand, day);

        rand = keccak256(abi.encodePacked(rand));
        body.py = randomRange(0, windowWidth, rand, day);

        rand = keccak256(abi.encodePacked(rand));
        // this is actually a range of -1/2 to 1/2 of maxVector since negative offset
        // -maxVector = 0
        // 0 = maxVector
        // maxVector = 2 * maxVector
        body.vx = randomRange(
            maxVectorScaled / 2,
            (3 * maxVectorScaled) / 2,
            rand,
            day
        );

        rand = keccak256(abi.encodePacked(rand));
        body.vy = randomRange(
            maxVectorScaled / 2,
            (3 * maxVectorScaled) / 2,
            rand,
            day
        );

        return body;
    }

    function genRadius(uint256 index) public pure returns (uint256) {
        uint8[6] memory radii = [36, 27, 23, 19, 15, 11]; // n * 4 + 2
        return radii[index % radii.length] * scalingFactor;
    }

    function randomRange(
        uint256 min,
        uint256 max,
        bytes32 seed,
        uint256 day
    ) public pure returns (uint256) {
        uint256 fuckup = day == 1723766400 ? 0 : 1;
        if (min == max) {
            return min;
        } else if (min < max) {
            uint256 range = max - min + fuckup;
            return (uint256(seed) % range) + min;
        } else {
            uint256 range = 359 - (min - max + fuckup);
            uint256 output = uint256(seed) % range;
            if (output < max) {
                return output;
            } else {
                return min - max + output;
            }
        }
    }

    function currentLevel(uint256 runId) public view returns (uint256) {
        return runs[runId].levels.length;
    }

    function generateSeed(
        uint256 id,
        uint256 index
    ) public view returns (bytes32) {
        return
            keccak256(abi.encodePacked(id, index, blockhash(block.number - 1)));
    }

    // TODO: fix day and week so that days and week begin at same time
    function currentWeek() public view returns (uint256) {
        return
            block.timestamp -
            ((block.timestamp - FIRST_SUNDAY_AT_6_PM_UTC) % SECONDS_IN_A_WEEK);
    }

    function timeUntilEndOfWeek() public view returns (uint256) {
        return currentWeek() + SECONDS_IN_A_WEEK - block.timestamp;
    }

    function currentDay() public view returns (uint256) {
        return block.timestamp - (block.timestamp % SECONDS_IN_A_DAY);
    }

    function addNewLevelData(uint256 runId) internal {
        uint256 day = runs[runId].day;
        uint256 level = currentLevel(runId) + 1;
        Level memory levelData;
        levelData.seed = generateSeed(runId, level);
        (levelData.tmpBodyData, ) = generateLevelData(day, level);
        runs[runId].levels.push(levelData);
        emit LevelCreated(runId, level, levelData.seed, day);
    }

    function addNewRun(uint256 day) internal returns (uint256 runId) {
        runId = runs.length;
        Run memory run;
        run.owner = msg.sender;
        run.seed = generateSeed(runId, 0);
        run.day = day;
        runs.push(run);
        emit RunCreated(runId, day, run.seed);
        return runId;
    }

    function verifyLevelChunk(
        uint256 runId,
        bool alsoMint,
        uint256 tickCount,
        uint256 day,
        uint[2] memory a,
        uint[2][2] memory b,
        uint[2] memory c,
        uint[] memory input
    ) internal {
        bytes32 proofHash = keccak256(abi.encodePacked(a, b, c, input));
        require(!usedProofs[proofHash], 'Proof already used');
        usedProofs[proofHash] = true;

        (uint256 intendedLevel, uint256 dummyCount) = getLevelFromInputs(input);
        uint256 level = currentLevel(runId);

        require(intendedLevel == level, 'Previous level not yet complete');

        uint256 levelIndex = level - 1;
        require(!runs[runId].levels[levelIndex].solved, 'Level already solved');

        uint256 bodyCount = level + 1;
        address verifier = verifiers[bodyCount + dummyCount][tickCount];
        require(verifier != address(0), 'Invalid verifier, address == 0');
        require(
            address(uint160(input[5 + (bodyCount + dummyCount) * 5 + 1])) ==
                msg.sender,
            'Owner of this proof is not the sender'
        );

        // confirm current inflightMissile == previous outflightMissile
        // or confirm that curren inflightMissile (x, y) == (0, windowHeight)
        uint256[5] memory storedOutflightMissile = runs[runId]
            .levels[levelIndex]
            .tmpInflightMissile;
        uint256[5] memory newInflightMissile = [
            input[5 + 2 * (bodyCount + dummyCount) * 5 + 2 + 0],
            input[5 + 2 * (bodyCount + dummyCount) * 5 + 2 + 1],
            input[5 + 2 * (bodyCount + dummyCount) * 5 + 2 + 2],
            input[5 + 2 * (bodyCount + dummyCount) * 5 + 2 + 3],
            input[5 + 2 * (bodyCount + dummyCount) * 5 + 2 + 4]
        ];
        // if there is an inflight missile, it either needs to match the outflight or start
        // from the corner
        if (newInflightMissile[4] != 0) {
            bool matchesStoredOutflightMissile = storedOutflightMissile[0] ==
                newInflightMissile[0] &&
                storedOutflightMissile[1] == newInflightMissile[1] &&
                storedOutflightMissile[2] == newInflightMissile[2] &&
                storedOutflightMissile[3] == newInflightMissile[3] &&
                storedOutflightMissile[4] == newInflightMissile[4];

            bool newMissile = newInflightMissile[0] == 0 &&
                newInflightMissile[1] == windowWidth;
            require(
                newMissile || matchesStoredOutflightMissile,
                'Invalid inflightMissile'
            );
        }
        // update inflightMissile with new outflight missile
        uint256[5] memory newOutflightMissile = [
            input[0],
            input[1],
            input[2],
            input[3],
            input[4]
        ];
        runs[runId].levels[levelIndex].tmpInflightMissile = newOutflightMissile;

        uint256 time = input[5 + (bodyCount + dummyCount) * 5];

        verifyProof((bodyCount + dummyCount), verifier, a, b, c, input);

        Level memory levelData = runs[runId].levels[levelIndex];

        levelData.time += time;
        require(
            levelData.time <= maxTicksByLevelIndex[levelIndex],
            'Time limit exceeded'
        );

        uint256 bodiesGone;
        Body memory bodyData;
        for (uint256 i = 0; i < bodyCount; i++) {
            bodyData = levelData.tmpBodyData[i];

            verifyBodyDataMatches(bodyData, input, (bodyCount + dummyCount), i);
            bodyData = extractBodyData(bodyData, input, i);

            if (i == 0) {
                require(
                    bodyData.radius != 0,
                    'You shot the body you should protect'
                );
            }
            if (bodyData.radius == 0) {
                bodiesGone++;
            }
            levelData.tmpBodyData[i] = bodyData;
        }
        runs[runId].levels[levelIndex] = levelData;
        if (bodiesGone == level) {
            runs[runId].levels[levelIndex].solved = true;
            emit LevelSolved(msg.sender, runId, level, levelData.time, day);
            runs[runId].accumulativeTime += levelData.time;
            if (level == LEVELS) {
                runs[runId].solved = true;
                if (alsoMint) {
                    mint(priceToSave + (priceToMint / discount), day);
                } else if (priceToSave > 0) {
                    makePayment(priceToSave);
                }
                emit RunSolved(
                    msg.sender,
                    runId,
                    runs[runId].accumulativeTime,
                    day
                );
                gamesPlayed[msg.sender].total++;
                addToLeaderboard(runId);
            } else {
                addNewLevelData(runId);
            }
        }
    }

    function makePayment(uint256 payment) internal {
        require(msg.value >= payment, 'Incorrect payment');
        require(proceedRecipient != address(0), 'Invalid recipient');
        (bool sent, bytes memory data) = proceedRecipient.call{value: payment}(
            ''
        );
        emit EthMoved(proceedRecipient, sent, data, payment);
    }

    function mint(uint256 payment, uint256 day) internal {
        require(day == currentDay(), 'Can only mint on the current day');
        makePayment(payment);
        Speedruns(speedruns).__mint(msg.sender, day, 1, '');
    }

    function mint() public payable {
        mint(priceToMint, currentDay());
    }

    function addToLeaderboard(uint256 runId) internal {
        addToFastestByDay(runId);
        addToLongestStreak(runId);
        addToMostPlayed();
    }

    function addToLongestStreak(uint256 runId) internal {
        uint256 day = runs[runId].day;
        Record memory record = gamesPlayed[msg.sender];
        if (record.lastPlayed + SECONDS_IN_A_DAY != day) {
            record.streak = 1;
        } else {
            record.streak++;
        }
        record.lastPlayed = day;
        gamesPlayed[msg.sender] = record;

        for (uint256 i = 0; i < longestStreak.length; i++) {
            if (record.streak > gamesPlayed[longestStreak[i]].streak) {
                for (uint256 j = longestStreak.length - 1; j > i; j--) {
                    longestStreak[j] = longestStreak[j - 1];
                }
                longestStreak[i] = msg.sender;
                break;
            }
        }
    }

    function addToMostPlayed() internal {
        Record memory record = gamesPlayed[msg.sender];
        for (uint256 i = 0; i < mostGames.length; i++) {
            if (record.total > gamesPlayed[mostGames[i]].total) {
                for (uint256 j = mostGames.length - 1; j > i; j--) {
                    mostGames[j] = mostGames[j - 1];
                }
                mostGames[i] = msg.sender;
                break;
            }
        }
    }

    function addToFastestByDay(uint256 runId) internal {
        Run memory run = runs[runId];
        for (uint256 i = 0; i < fastestByDay[run.day].length; i++) {
            Run memory recordRun = runs[fastestByDay[run.day][i]];
            // if run is faster, or if previous run is unset
            if (
                run.accumulativeTime < recordRun.accumulativeTime ||
                recordRun.accumulativeTime == 0
            ) {
                for (uint256 j = fastestByDay[run.day].length - 1; j > i; j--) {
                    fastestByDay[run.day][j] = fastestByDay[run.day][j - 1];
                }
                fastestByDay[run.day][i] = runId;
                emitMetadataUpdate(run.day);
                break;
            }
        }
    }

    function extractBodyData(
        Body memory bodyData,
        uint[] memory input,
        uint256 i
    ) public pure returns (Body memory) {
        bodyData.px = input[5 + i * 5 + 0];
        bodyData.py = input[5 + i * 5 + 1];
        bodyData.vx = input[5 + i * 5 + 2];
        bodyData.vy = input[5 + i * 5 + 3];
        bodyData.radius = input[5 + i * 5 + 4];
        return bodyData;
    }

    function verifyBodyDataMatches(
        Body memory bodyData,
        uint[] memory input,
        uint256 bodyCount,
        uint256 i
    ) public pure {
        // px
        // confirm previously stored values were used as input to the proof
        // uint256 pxIndex = 5 * bodyCount + i * 5 + 0 + 1 (for time);
        require(
            bodyData.px == input[5 + 5 * bodyCount + i * 5 + 0 + 2],
            'Invalid position x'
        );
        // py
        // confirm previously stored values were used as input to the proof
        // uint256 pyIndex = 5 * bodyCount + i * 5 + 1 + 1 (for time);
        require(
            bodyData.py == input[5 + 5 * bodyCount + i * 5 + 1 + 2],
            'Invalid position y'
        );
        // vx
        // confirm previously stored values were used as input to the proof
        // uint256 vxIndex = 5 * bodyCount + i * 5 + 2 + 1 (for time);
        require(
            bodyData.vx == input[5 + 5 * bodyCount + i * 5 + 2 + 2],
            'Invalid vector x'
        );
        // vy
        // confirm previously stored values were used as input to the proof
        // uint256 vyIndex = 5 * bodyCount + i * 5 + 3 + 1 (for time);
        require(
            bodyData.vy == input[5 + 5 * bodyCount + i * 5 + 3 + 2],
            'Invalid vector y'
        );
        // radius
        // confirm previously stored values were used as input to the proof
        // uint256 radiusIndex = 5 * bodyCount + i * 5 + 4 + 1 (for time);
        require(
            bodyData.radius == input[5 + 5 * bodyCount + i * 5 + 4 + 2],
            'Invalid radius'
        );
    }

    function verifyProof(
        uint256 bodyCount,
        address verifier,
        uint[2] memory a,
        uint[2][2] memory b,
        uint[2] memory c,
        uint[] memory input
    ) public view {
        if (bodyCount == 2) {
            require(
                Groth16Verifier2(verifier).verifyProof(
                    a,
                    b,
                    c,
                    convertTo32(input)
                ),
                'Invalid 2 body proof'
            );
        } else if (bodyCount == 3) {
            require(
                Groth16Verifier3(verifier).verifyProof(
                    a,
                    b,
                    c,
                    convertTo42(input)
                ),
                'Invalid 3 body proof'
            );
        } else if (bodyCount == 4) {
            require(
                Groth16Verifier4(verifier).verifyProof(
                    a,
                    b,
                    c,
                    convertTo52(input)
                ),
                'Invalid 4 body proof'
            );
        } else if (bodyCount == 5) {
            require(
                Groth16Verifier5(verifier).verifyProof(
                    a,
                    b,
                    c,
                    convertTo62(input)
                ),
                'Invalid 5 body proof'
            );
        } else if (bodyCount == 6) {
            require(
                Groth16Verifier6(verifier).verifyProof(
                    a,
                    b,
                    c,
                    convertTo72(input)
                ),
                'Invalid 6 body proof'
            );
        } else {
            revert('Invalid number of bodies');
        }
    }

    function getLevelFromInputs(
        uint[] memory input
    ) public pure returns (uint256 bodyCount, uint256 dummyCount) {
        // 0—4: missile output
        // 5—9: body 1 output
        // 10—14: body 2 output
        // 15: time output (5 + bodyCount * 5 + 1)
        // 16: address input (5 + bodyCount * 5 + 2)
        // 17—21: body 1 input
        // 22—26: body 2 input
        // 27—31: missile input (5 + 2 * bodyCount * 5 + 2)

        // inputLength = bodyCount * 5 * 2 + 1 + 1 + 5 + 5;
        // inputLength = 10 * bodyCount + 12;
        // 10 * bodyCount = inputLength - 12;
        bodyCount = ((input.length - 12) / 10) - 1;
        dummyCount = 0;
        uint256 tally = 0;
        // start i at end of input array but before the final 5 elements of the missile input
        // count backwards checking every 5 whether a body is completely empty
        // if so consider this a "dummy" body and remove it from the count
        for (uint256 i = input.length - 1 - 5; i > input.length / 2; i--) {
            if (tally % 5 == 0) {
                if (
                    input[i] == 0 && // radius
                    input[i - 1] == 20000 && // vy
                    input[i - 2] == 20000 && // vx
                    input[i - 3] == 0 && // py
                    input[i - 4] == 0 // px
                ) {
                    dummyCount++;
                }
            }
            tally++;
        }

        return (bodyCount - dummyCount, dummyCount);
    }

    function convertTo22(
        uint[] memory input
    ) public pure returns (uint[22] memory) {
        uint[22] memory input_;
        for (uint256 i = 0; i < 22; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo32(
        uint[] memory input
    ) public pure returns (uint[32] memory) {
        uint[32] memory input_;
        for (uint256 i = 0; i < 32; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo42(
        uint[] memory input
    ) public pure returns (uint[42] memory) {
        uint[42] memory input_;
        for (uint256 i = 0; i < 42; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo52(
        uint[] memory input
    ) public pure returns (uint[52] memory) {
        uint[52] memory input_;
        for (uint256 i = 0; i < 52; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo62(
        uint[] memory input
    ) public pure returns (uint[62] memory) {
        uint[62] memory input_;
        for (uint256 i = 0; i < 62; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo72(
        uint[] memory input
    ) public pure returns (uint[72] memory) {
        uint[72] memory input_;
        for (uint256 i = 0; i < 72; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo82(
        uint[] memory input
    ) public pure returns (uint[82] memory) {
        uint[82] memory input_;
        for (uint256 i = 0; i < 82; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo92(
        uint[] memory input
    ) public pure returns (uint[92] memory) {
        uint[92] memory input_;
        for (uint256 i = 0; i < 92; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo102(
        uint[] memory input
    ) public pure returns (uint[102] memory) {
        uint[102] memory input_;
        for (uint256 i = 0; i < 102; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    function convertTo112(
        uint[] memory input
    ) public pure returns (uint[112] memory) {
        uint[112] memory input_;
        for (uint256 i = 0; i < 112; i++) {
            input_[i] = input[i];
        }
        return input_;
    }

    // Speedruns NFT functions

    function speedrunsSupportsInterface(
        bytes4 interfaceId
    ) public pure returns (bool) {
        return
            interfaceId == type(IERC165).interfaceId ||
            interfaceId == type(IERC1155).interfaceId ||
            interfaceId == type(IERC1155MetadataURI).interfaceId ||
            interfaceId == type(IERC2981).interfaceId ||
            interfaceId == bytes4(0x49064906); // IERC4906 MetadataUpdate
    }

    function speedrunsTokenURI(uint256 id) public view returns (string memory) {
        return ExternalMetadata(externalMetadata).getMetadata(id);
    }

    function emitBatchMetadataUpdate() public onlyOwner {
        bytes32 topic = keccak256('BatchMetadataUpdate(uint256,uint256)');
        uint256 today = currentDay();
        bytes memory data = abi.encode(0, today);
        bytes32[] memory topics = new bytes32[](1);
        topics[0] = topic;
        Speedruns(speedruns).emitGenericEvent(topics, data);
    }

    function emitMetadataUpdate(uint256 tokenId) internal {
        bytes32 topic = keccak256('MetadataUpdate(uint256)');
        bytes memory data = abi.encode(tokenId);
        bytes32[] memory topics = new bytes32[](1);
        topics[0] = topic;
        Speedruns(speedruns).emitGenericEvent(topics, data);
    }

    // function emitBatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId) internal {
    //   bytes32 topic = keccak256("BatchMetadataUpdate(uint256,uint256)");
    //   bytes memory data = abi.encode(_fromTokenId, _toTokenId);
    //     bytes32[] memory topics = new bytes32[](1);
    //     topics[0] = topic;
    //   Speedruns(speedruns).emitGenericEvent(topics, data);
    // }
    // function exampleEmitMultipleIndexEvent(uint256 _fromTokenId, uint256 _toTokenId, address who) internal {
    //     bytes32 topic = keccak256("BatchMetadataUpdateIndexed(uint256,uint256,address)");
    //     bytes32 topicFrom = bytes32(abi.encode(_fromTokenId));
    //     bytes32 topicTo = bytes32(abi.encode(_toTokenId));
    //     bytes memory data = abi.encode(who);
    //     bytes32[] memory topics = new bytes32[](3);
    //     topics[0] = topic;
    //     topics[1] = topicFrom;
    //     topics[2] = topicTo;
    //     Speedruns(speedruns).emitGenericEvent(topics, data);
    // }
    function updateExternalMetadata(
        address externalMetadata_
    ) public onlyOwner {
        externalMetadata = externalMetadata_;
    }

    function updateProceedRecipient(
        address payable proceedRecipient_
    ) public onlyOwner {
        proceedRecipient = proceedRecipient_;
    }

    function updateSpeedrunsAddress(
        address payable speedruns_
    ) public onlyOwner {
        speedruns = speedruns_;
    }

    function updateVerifier(
        address verifier_,
        uint256 verifierBodies,
        uint256 verifierTicks
    ) public onlyOwner {
        verifiers[verifierBodies][verifierTicks] = verifier_;
    }

    /// @dev if mint fails to send eth to splitter, admin can recover
    // This should not be necessary but Berlin hardfork broke split before so this
    // is extra precaution.
    function recoverUnsuccessfulPayment(address payable _to) public onlyOwner {
        uint256 amount = address(this).balance;
        (bool sent, bytes memory data) = _to.call{value: amount}('');
        emit EthMoved(_to, sent, data, amount);
    }

    function updateDiscount(uint256 discount_) public onlyOwner {
        discount = discount_;
    }

    function updatePriceToSave(uint256 priceToSave_) public onlyOwner {
        priceToSave = priceToSave_;
    }

    function updatePriceToMint(uint256 priceToMint_) public onlyOwner {
        priceToMint = priceToMint_;
    }

    function updatePaused(bool paused_) public onlyOwner {
        paused = paused_;
    }
}
合同源代码
文件 3 的 26:BokkyPooBahsDateTimeLibrary.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.9.0;

// ----------------------------------------------------------------------------
// BokkyPooBah's DateTime Library v1.01
//
// A gas-efficient Solidity date and time library
//
// https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
//
// Tested date range 1970/01/01 to 2345/12/31
//
// Conventions:
// Unit      | Range         | Notes
// :-------- |:-------------:|:-----
// timestamp | >= 0          | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
// year      | 1970 ... 2345 |
// month     | 1 ... 12      |
// day       | 1 ... 31      |
// hour      | 0 ... 23      |
// minute    | 0 ... 59      |
// second    | 0 ... 59      |
// dayOfWeek | 1 ... 7       | 1 = Monday, ..., 7 = Sunday
//
//
// Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
// ----------------------------------------------------------------------------

library BokkyPooBahsDateTimeLibrary {

    uint constant SECONDS_PER_DAY = 24 * 60 * 60;
    uint constant SECONDS_PER_HOUR = 60 * 60;
    uint constant SECONDS_PER_MINUTE = 60;
    int constant OFFSET19700101 = 2440588;

    uint constant DOW_MON = 1;
    uint constant DOW_TUE = 2;
    uint constant DOW_WED = 3;
    uint constant DOW_THU = 4;
    uint constant DOW_FRI = 5;
    uint constant DOW_SAT = 6;
    uint constant DOW_SUN = 7;

    // ------------------------------------------------------------------------
    // Calculate the number of days from 1970/01/01 to year/month/day using
    // the date conversion algorithm from
    //   https://aa.usno.navy.mil/faq/JD_formula.html
    // and subtracting the offset 2440588 so that 1970/01/01 is day 0
    //
    // days = day
    //      - 32075
    //      + 1461 * (year + 4800 + (month - 14) / 12) / 4
    //      + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
    //      - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
    //      - offset
    // ------------------------------------------------------------------------
    function _daysFromDate(uint year, uint month, uint day) internal pure returns (uint _days) {
        require(year >= 1970);
        int _year = int(year);
        int _month = int(month);
        int _day = int(day);

        int __days = _day
          - 32075
          + 1461 * (_year + 4800 + (_month - 14) / 12) / 4
          + 367 * (_month - 2 - (_month - 14) / 12 * 12) / 12
          - 3 * ((_year + 4900 + (_month - 14) / 12) / 100) / 4
          - OFFSET19700101;

        _days = uint(__days);
    }

    // ------------------------------------------------------------------------
    // Calculate year/month/day from the number of days since 1970/01/01 using
    // the date conversion algorithm from
    //   http://aa.usno.navy.mil/faq/docs/JD_Formula.php
    // and adding the offset 2440588 so that 1970/01/01 is day 0
    //
    // int L = days + 68569 + offset
    // int N = 4 * L / 146097
    // L = L - (146097 * N + 3) / 4
    // year = 4000 * (L + 1) / 1461001
    // L = L - 1461 * year / 4 + 31
    // month = 80 * L / 2447
    // dd = L - 2447 * month / 80
    // L = month / 11
    // month = month + 2 - 12 * L
    // year = 100 * (N - 49) + year + L
    // ------------------------------------------------------------------------
    function _daysToDate(uint _days) internal pure returns (uint year, uint month, uint day) {
        int __days = int(_days);

        int L = __days + 68569 + OFFSET19700101;
        int N = 4 * L / 146097;
        L = L - (146097 * N + 3) / 4;
        int _year = 4000 * (L + 1) / 1461001;
        L = L - 1461 * _year / 4 + 31;
        int _month = 80 * L / 2447;
        int _day = L - 2447 * _month / 80;
        L = _month / 11;
        _month = _month + 2 - 12 * L;
        _year = 100 * (N - 49) + _year + L;

        year = uint(_year);
        month = uint(_month);
        day = uint(_day);
    }

    function timestampFromDate(uint year, uint month, uint day) internal pure returns (uint timestamp) {
        timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
    }
    function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (uint timestamp) {
        timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
    }
    function timestampToDate(uint timestamp) internal pure returns (uint year, uint month, uint day) {
        (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }
    function timestampToDateTime(uint timestamp) internal pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
        (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
        uint secs = timestamp % SECONDS_PER_DAY;
        hour = secs / SECONDS_PER_HOUR;
        secs = secs % SECONDS_PER_HOUR;
        minute = secs / SECONDS_PER_MINUTE;
        second = secs % SECONDS_PER_MINUTE;
    }

    function isValidDate(uint year, uint month, uint day) internal pure returns (bool valid) {
        if (year >= 1970 && month > 0 && month <= 12) {
            uint daysInMonth = _getDaysInMonth(year, month);
            if (day > 0 && day <= daysInMonth) {
                valid = true;
            }
        }
    }
    function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (bool valid) {
        if (isValidDate(year, month, day)) {
            if (hour < 24 && minute < 60 && second < 60) {
                valid = true;
            }
        }
    }
    function isLeapYear(uint timestamp) internal pure returns (bool leapYear) {
        (uint year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
        leapYear = _isLeapYear(year);
    }
    function _isLeapYear(uint year) internal pure returns (bool leapYear) {
        leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
    }
    function isWeekDay(uint timestamp) internal pure returns (bool weekDay) {
        weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
    }
    function isWeekEnd(uint timestamp) internal pure returns (bool weekEnd) {
        weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
    }
    function getDaysInMonth(uint timestamp) internal pure returns (uint daysInMonth) {
        (uint year, uint month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
        daysInMonth = _getDaysInMonth(year, month);
    }
    function _getDaysInMonth(uint year, uint month) internal pure returns (uint daysInMonth) {
        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
            daysInMonth = 31;
        } else if (month != 2) {
            daysInMonth = 30;
        } else {
            daysInMonth = _isLeapYear(year) ? 29 : 28;
        }
    }
    // 1 = Monday, 7 = Sunday
    function getDayOfWeek(uint timestamp) internal pure returns (uint dayOfWeek) {
        uint _days = timestamp / SECONDS_PER_DAY;
        dayOfWeek = (_days + 3) % 7 + 1;
    }

    function getYear(uint timestamp) internal pure returns (uint year) {
        (year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }
    function getMonth(uint timestamp) internal pure returns (uint month) {
        (,month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }
    function getDay(uint timestamp) internal pure returns (uint day) {
        (,,day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }
    function getHour(uint timestamp) internal pure returns (uint hour) {
        uint secs = timestamp % SECONDS_PER_DAY;
        hour = secs / SECONDS_PER_HOUR;
    }
    function getMinute(uint timestamp) internal pure returns (uint minute) {
        uint secs = timestamp % SECONDS_PER_HOUR;
        minute = secs / SECONDS_PER_MINUTE;
    }
    function getSecond(uint timestamp) internal pure returns (uint second) {
        second = timestamp % SECONDS_PER_MINUTE;
    }

    function addYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
        (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
        year += _years;
        uint daysInMonth = _getDaysInMonth(year, month);
        if (day > daysInMonth) {
            day = daysInMonth;
        }
        newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
        require(newTimestamp >= timestamp);
    }
    function addMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
        (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
        month += _months;
        year += (month - 1) / 12;
        month = (month - 1) % 12 + 1;
        uint daysInMonth = _getDaysInMonth(year, month);
        if (day > daysInMonth) {
            day = daysInMonth;
        }
        newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
        require(newTimestamp >= timestamp);
    }
    function addDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
        newTimestamp = timestamp + _days * SECONDS_PER_DAY;
        require(newTimestamp >= timestamp);
    }
    function addHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
        newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
        require(newTimestamp >= timestamp);
    }
    function addMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
        newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
        require(newTimestamp >= timestamp);
    }
    function addSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
        newTimestamp = timestamp + _seconds;
        require(newTimestamp >= timestamp);
    }

    function subYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
        (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
        year -= _years;
        uint daysInMonth = _getDaysInMonth(year, month);
        if (day > daysInMonth) {
            day = daysInMonth;
        }
        newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
        require(newTimestamp <= timestamp);
    }
    function subMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
        (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
        uint yearMonth = year * 12 + (month - 1) - _months;
        year = yearMonth / 12;
        month = yearMonth % 12 + 1;
        uint daysInMonth = _getDaysInMonth(year, month);
        if (day > daysInMonth) {
            day = daysInMonth;
        }
        newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
        require(newTimestamp <= timestamp);
    }
    function subDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
        newTimestamp = timestamp - _days * SECONDS_PER_DAY;
        require(newTimestamp <= timestamp);
    }
    function subHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
        newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
        require(newTimestamp <= timestamp);
    }
    function subMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
        newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
        require(newTimestamp <= timestamp);
    }
    function subSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
        newTimestamp = timestamp - _seconds;
        require(newTimestamp <= timestamp);
    }

    function diffYears(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _years) {
        require(fromTimestamp <= toTimestamp);
        (uint fromYear,,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
        (uint toYear,,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
        _years = toYear - fromYear;
    }
    function diffMonths(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _months) {
        require(fromTimestamp <= toTimestamp);
        (uint fromYear, uint fromMonth,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
        (uint toYear, uint toMonth,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
        _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
    }
    function diffDays(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _days) {
        require(fromTimestamp <= toTimestamp);
        _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
    }
    function diffHours(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _hours) {
        require(fromTimestamp <= toTimestamp);
        _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
    }
    function diffMinutes(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _minutes) {
        require(fromTimestamp <= toTimestamp);
        _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
    }
    function diffSeconds(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _seconds) {
        require(fromTimestamp <= toTimestamp);
        _seconds = toTimestamp - fromTimestamp;
    }
}
合同源代码
文件 4 的 26:Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
合同源代码
文件 5 的 26:ERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;

import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

    // Mapping from account to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_) {
        _setURI(uri_);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC1155).interfaceId ||
            interfaceId == type(IERC1155MetadataURI).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: address zero is not a valid owner");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] memory accounts,
        uint256[] memory ids
    ) public view virtual override returns (uint256[] memory) {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC1155-isApprovedForAll}.
     */
    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[account][operator];
    }

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not token owner or approved"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not token owner or approved"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `amount` tokens of token type `id`.
     */
    function _burn(address from, uint256 id, uint256 amount) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }

        emit TransferSingle(operator, from, address(0), id, amount);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
        }

        emit TransferBatch(operator, from, address(0), ids, amounts);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `ids` and `amounts` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}
合同源代码
文件 6 的 26:ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}
合同源代码
文件 7 的 26:ERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

import "../../interfaces/IERC2981.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}
合同源代码
文件 8 的 26:ExternalMetadata.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/access/Ownable.sol';
import 'base64-sol/base64.sol';
import './AnybodyProblem.sol';
import './BokkyPooBahsDateTimeLibrary.sol';
import './StringsExtended.sol';
import './ThemeGroupBlues.sol';

/// @title ExternalMetadata
/// @notice
/// @author @okwme & @dataexcess
/// @dev The updateable and replaceable problemMetadata contract

contract ExternalMetadata is Ownable {
    using BokkyPooBahsDateTimeLibrary for uint;
    address payable public anybodyProblem;
    address payable public speedruns;
    ThemeGroup public themeGroup;
    address public assets1;
    address public assets2;
    address public assets3;
    address public assets4;
    address public assets5;

    struct AssetData {
        address assetAddress;
        string functionName;
    }

    mapping(ThemeGroup.ThemeLayer => uint256) private svgShapeCategorySizes;
    mapping(ThemeGroup.ThemeLayer => AssetData[]) private svgShapes;

    constructor(address themeGroup_) {
        themeGroup = ThemeGroup(themeGroup_);
    }

    function setAssets(address[5] memory assets) public onlyOwner {
        assets1 = assets[0];
        assets2 = assets[1];
        assets3 = assets[2];
        assets4 = assets[3];
        assets5 = assets[4];
    }

    function readValueFromContract(
        address contractAddress,
        string memory functionName
    ) public view returns (string memory) {
        (bool success, bytes memory data) = contractAddress.staticcall(
            abi.encodeWithSignature(functionName)
        );
        require(success, 'Failed to read value from contract');
        return abi.decode(data, (string));
    }

    function setupSVGPaths() public onlyOwner {
        AssetData[] storage faceShapes = svgShapes[ThemeGroup.ThemeLayer.Face];
        AssetData[] storage coreShapes = svgShapes[ThemeGroup.ThemeLayer.Core];
        AssetData[] storage bgShapes = svgShapes[ThemeGroup.ThemeLayer.BG];
        AssetData[] storage fgShapes = svgShapes[ThemeGroup.ThemeLayer.FG];

        svgShapeCategorySizes[ThemeGroup.ThemeLayer.Face] = 14;
        svgShapeCategorySizes[ThemeGroup.ThemeLayer.BG] = 10;
        svgShapeCategorySizes[ThemeGroup.ThemeLayer.FG] = 10;
        svgShapeCategorySizes[ThemeGroup.ThemeLayer.Core] = 1;

        faceShapes.push(
            AssetData({assetAddress: assets5, functionName: 'FACE_SHAPE_1()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets4, functionName: 'FACE_SHAPE_2()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets4, functionName: 'FACE_SHAPE_3()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets4, functionName: 'FACE_SHAPE_4()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets4, functionName: 'FACE_SHAPE_5()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets4, functionName: 'FACE_SHAPE_6()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets4, functionName: 'FACE_SHAPE_7()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets4, functionName: 'FACE_SHAPE_8()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets5, functionName: 'FACE_SHAPE_9()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets5, functionName: 'FACE_SHAPE_10()'})
        );
        coreShapes.push(
            AssetData({assetAddress: assets2, functionName: 'CORE_SHAPE_1()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets5, functionName: 'FACE_SHAPE_11()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets5, functionName: 'FACE_SHAPE_12()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets5, functionName: 'FACE_SHAPE_13()'})
        );
        faceShapes.push(
            AssetData({assetAddress: assets5, functionName: 'FACE_SHAPE_14()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_1()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_2()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_3()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_4()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_5()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_6()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_7()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_8()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_9()'})
        );
        bgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'BG_SHAPE_10()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets2, functionName: 'FG_SHAPE_1()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets2, functionName: 'FG_SHAPE_2()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets1, functionName: 'FG_SHAPE_3()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets2, functionName: 'FG_SHAPE_4()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets2, functionName: 'FG_SHAPE_5()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets3, functionName: 'FG_SHAPE_6()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets3, functionName: 'FG_SHAPE_7()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets3, functionName: 'FG_SHAPE_8()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets2, functionName: 'FG_SHAPE_9()'})
        );
        fgShapes.push(
            AssetData({assetAddress: assets2, functionName: 'FG_SHAPE_10()'})
        );
    }

    /// @dev generates the problemMetadata
    /// @param date the date
    function getMetadata(uint256 date) public view returns (string memory) {
        string memory svg = getSVG(date);
        return
            string(
                abi.encodePacked(
                    'data:application/json;base64,',
                    Base64.encode(
                        abi.encodePacked(
                            '{"name":"',
                            getName(date),
                            '",',
                            '"description": "Anybody Problem (https://anybody.gg)",',
                            '"image": "',
                            svg,
                            '",',
                            '"image_url": "',
                            svg,
                            '",',
                            '"home_url": "https://anybody.gg",',
                            '"external_url": "https://anybody.gg",',
                            '"animation_url": "https://nft.anybody.gg/#',
                            StringsExtended.toString(date),
                            getBestTimeEncoded(date),
                            '",',
                            '"attributes": ',
                            getAttributes(date),
                            '}'
                        )
                    )
                )
            );
    }

    function getBestTimeEncoded(
        uint256 date
    ) public view returns (string memory) {
        uint256 bestRunId = AnybodyProblem(anybodyProblem).fastestByDay(
            date,
            0
        );

        AnybodyProblem.Level[] memory levels = AnybodyProblem(anybodyProblem)
            .getLevelsData(bestRunId);

        string memory encoded = '{"levels":[';

        for (uint256 i = 0; i < levels.length; i++) {
            AnybodyProblem.Level memory level = levels[i];
            encoded = string(
                abi.encodePacked(
                    encoded,
                    '{"events": [{"time":',
                    StringsExtended.toString(level.time),
                    '}]}',
                    (i == levels.length - 1 ? '' : ',')
                )
            );
        }
        encoded = Base64.encode(abi.encodePacked(encoded, ']}'));
        return string(abi.encodePacked('-', encoded));
    }

    function getName(uint256 date) public pure returns (string memory) {
        (uint year, uint month, uint day) = BokkyPooBahsDateTimeLibrary
            .timestampToDate(date);
        return
            string(
                abi.encodePacked(
                    StringsExtended.toString(year),
                    '-',
                    StringsExtended.toString(month),
                    '-',
                    StringsExtended.toString(day)
                )
            );
    }

    function getHTML(uint256 date) public view returns (string memory) {
        return
            string(
                abi.encodePacked(
                    'data:text/html;base64,',
                    Base64.encode(
                        abi.encodePacked(
                            "<html><body><img src='",
                            getSVG(date),
                            "'></body></html>"
                        )
                    )
                )
            );
    }

    /// @dev function to generate a SVG String
    function getSVG(uint256 date) public view returns (string memory) {
        return
            string(
                abi.encodePacked(
                    'data:image/svg+xml;base64,',
                    Base64.encode(
                        abi.encodePacked(
                            '<?xml version="1.0" encoding="utf-8"?>',
                            '<svg xmlns="http://www.w3.org/2000/svg"  height="100%" width="100%" viewBox="0 0 1000 1000" style="background-color:transparent;">',
                            getPath(date),
                            // '<text x="50" y="550" class="name">',
                            // getName(date),
                            // '</text>','
                            '</svg>'
                        )
                    )
                )
            );
    }

    function getPath(uint256 date) internal view returns (string memory) {
        string memory path = string(
            abi.encodePacked(
                '<style>',
                '#id-hero ',
                '{ ',
                'transform-origin: 300px 300px; ',
                'transform: translate(200px, 200px) scale(1.8); ',
                '}',
                '</style>'
                '<g id="id-hero">',
                getHeroBodyPath(date),
                '</g>'
            )
        );

        return path;
    }

    function getHeroBodyPath(
        uint256 day
    ) internal view returns (string memory) {
        //FACE SHAPE
        uint256 extraSeed = day == 1723766400 ? 19 : 0;

        bytes32 rand = keccak256(abi.encodePacked(day, extraSeed));
        uint256 pathIdxFace = randomRange(
            0,
            svgShapeCategorySizes[ThemeGroup.ThemeLayer.Face] - 1,
            rand,
            day
        );
        AssetData memory pathFaceData = svgShapes[ThemeGroup.ThemeLayer.Face][
            pathIdxFace
        ];
        string memory pathFace = readValueFromContract(
            pathFaceData.assetAddress,
            pathFaceData.functionName
        );

        //BACKGROUND SHAPE
        rand = keccak256(abi.encodePacked(rand));
        uint256 pathIdxBG = randomRange(
            0,
            svgShapeCategorySizes[ThemeGroup.ThemeLayer.BG] - 1,
            rand,
            day
        );
        AssetData memory pathBGData = svgShapes[ThemeGroup.ThemeLayer.BG][
            pathIdxBG
        ];
        string memory pathBG = readValueFromContract(
            pathBGData.assetAddress,
            pathBGData.functionName
        );

        //FOREGROUND SHAPE
        rand = keccak256(abi.encodePacked(rand));
        uint256 pathIdxFG = randomRange(
            0,
            svgShapeCategorySizes[ThemeGroup.ThemeLayer.FG] - 1,
            rand,
            day
        );
        AssetData memory pathFGData = svgShapes[ThemeGroup.ThemeLayer.FG][
            pathIdxFG
        ];
        string memory pathFG = readValueFromContract(
            pathFGData.assetAddress,
            pathFGData.functionName
        );

        //CORE SHAPE
        rand = keccak256(abi.encodePacked(rand));
        uint256 pathIdxCore = randomRange(
            0,
            svgShapeCategorySizes[ThemeGroup.ThemeLayer.Core] - 1,
            rand,
            day
        );
        AssetData memory pathCoreData = svgShapes[ThemeGroup.ThemeLayer.Core][
            pathIdxCore
        ];
        string memory pathCore = readValueFromContract(
            pathCoreData.assetAddress,
            pathCoreData.functionName
        );

        //DAILY COLOR THEME
        rand = keccak256(abi.encodePacked(rand));
        uint8 themegroupsAmount = themeGroup.themeCount();
        ThemeGroup.ThemeName currentDayTheme = ThemeGroup.ThemeName(
            randomRange(0, themegroupsAmount - 1, rand, day)
        );

        //BACKGROUND COLOR (Hue, Saturation, Lightness)
        uint256[3] memory colorsBGValues;
        (colorsBGValues, rand) = getHeroBodyLayerColor(
            rand,
            currentDayTheme,
            ThemeGroup.ThemeLayer.BG,
            day
        );
        string memory colorsBG = string(
            abi.encodePacked(
                'hsl(',
                StringsExtended.toString(colorsBGValues[0]),
                ',',
                StringsExtended.toString(colorsBGValues[1]),
                '%,',
                StringsExtended.toString(colorsBGValues[2]),
                '%)'
            )
        );

        //CORE COLOR
        uint256[3] memory colorsCoreValues;
        (colorsCoreValues, rand) = getHeroBodyLayerColor(
            rand,
            currentDayTheme,
            ThemeGroup.ThemeLayer.Core,
            day
        );
        string memory colorsCore = string(
            abi.encodePacked(
                'hsl(',
                StringsExtended.toString(colorsCoreValues[0]),
                ',',
                StringsExtended.toString(colorsCoreValues[1]),
                '%,',
                StringsExtended.toString(colorsCoreValues[2]),
                '%)'
            )
        );

        //FOREGROUND COLOR
        uint256[3] memory colorsFGValues;
        (colorsFGValues, rand) = getHeroBodyLayerColor(
            rand,
            currentDayTheme,
            ThemeGroup.ThemeLayer.FG,
            day
        );
        string memory colorsFG = string(
            abi.encodePacked(
                'hsl(',
                StringsExtended.toString(colorsFGValues[0]),
                ',',
                StringsExtended.toString(colorsFGValues[1]),
                '%,',
                StringsExtended.toString(colorsFGValues[2]),
                '%)'
            )
        );

        string memory path = string(
            abi.encodePacked(
                getRotationAnimation(
                    'BG',
                    '300px 300px',
                    '0px, 0px',
                    '12',
                    '0',
                    'reverse'
                ),
                '<g id="id-BG" fill="',
                colorsBG,
                '" >',
                pathBG,
                '</g>',
                getRotationAnimation(
                    'Core',
                    '113px 113px',
                    '187px, 187px',
                    '34',
                    '0',
                    'normal'
                ),
                '<g id="id-Core" fill="',
                colorsCore,
                '" >',
                pathCore,
                '</g>',
                getRotationAnimation(
                    'FG',
                    '300px 300px',
                    '0px,0px',
                    '8',
                    '0',
                    pathIdxFG == 9
                        ? 'reverse'
                        : pathIdxFG == 1 || pathIdxFG == 8
                        ? 'none'
                        : 'normal'
                ),
                '<g id="id-FG" fill="',
                colorsFG,
                '" >',
                pathFG,
                '</g>',
                '<g id="id-Face">',
                pathFace,
                '</g>'
            )
        );

        return path;
    }

    function getRotationAnimation(
        string memory bodyId,
        string memory transformOrigin,
        string memory translation,
        string memory duration,
        string memory delay,
        string memory direction
    ) internal pure returns (string memory) {
        string memory none = 'none';
        if (
            keccak256(abi.encodePacked(direction)) ==
            keccak256(abi.encodePacked(none))
        ) return '';
        string memory path = string(
            abi.encodePacked(
                '<style> @keyframes move',
                bodyId,
                ' ',
                '{ ',
                '0% { ',
                'transform-origin: ',
                transformOrigin,
                ';',
                'transform: translate(',
                translation,
                ') rotate(0deg); }',
                '100% {',
                'transform-origin: ',
                transformOrigin,
                ';',
                'transform: translate(',
                translation,
                ') rotate(360deg); }',
                '} ',
                '#id-',
                bodyId,
                ' ',
                '{ ',
                'animation: move',
                bodyId,
                ' ',
                duration,
                's infinite linear; ',
                'animation-delay: ',
                delay,
                's; ',
                'animation-direction: ',
                direction,
                '; ',
                '}',
                '</style>'
            )
        );
        return path;
    }

    function getFastestTime(
        uint256 date,
        uint256 placeIndex
    ) public view returns (address, string memory sec) {
        uint256 runId = AnybodyProblem(anybodyProblem).fastestByDay(
            date,
            placeIndex
        );
        (address player, , uint256 timeCompleted, , ) = AnybodyProblem(
            anybodyProblem
        ).runs(runId);

        uint256 precision = 1000;
        uint256 fps = 25;
        timeCompleted = (timeCompleted * precision) / fps;
        uint256 timeSeconds = timeCompleted / precision;
        uint256 timeMs = (timeCompleted - timeSeconds * precision) / 10;

        return (
            player,
            string(
                abi.encodePacked(
                    StringsExtended.toString(timeSeconds),
                    '.',
                    StringsExtended.toString(timeMs)
                )
            )
        );
    }

    /// @dev generates the attributes as JSON String
    function getAttributes(uint256 date) public view returns (string memory) {
        (uint year, uint month, ) = BokkyPooBahsDateTimeLibrary.timestampToDate(
            date
        );

        (address fastestAddress, string memory fastestTime) = getFastestTime(
            date,
            0
        );
        (
            address secondFastestAddress,
            string memory secondFastestTime
        ) = getFastestTime(date, 1);
        (
            address thirdFastestAddress,
            string memory thirdFastestTime
        ) = getFastestTime(date, 2);

        return
            string(
                abi.encodePacked(
                    '[',
                    '{"trait_type":"Galaxy","value":"BASED"},',
                    '{"trait_type":"Day","value":"',
                    StringsExtended.toString(date),
                    '"}, {"trait_type":"Year-Month","value":"',
                    StringsExtended.toString(year),
                    '-',
                    Math.log10(month) + 1 == 1 ? '0' : '',
                    StringsExtended.toString(month),
                    '"}, {"trait_type":"1st Place","value":"0x',
                    StringsExtended.toHexString(fastestAddress),
                    '"}, {"trait_type":"1st Place Time (s)","value":"',
                    fastestTime,
                    '"}, {"trait_type":"2nd Place","value":"0x',
                    StringsExtended.toHexString(secondFastestAddress),
                    '"}, {"trait_type":"2nd Place Time (s)","value":"',
                    secondFastestTime,
                    '"}, {"trait_type":"3rd Place","value":"0x',
                    StringsExtended.toHexString(thirdFastestAddress),
                    '"}, {"trait_type":"3rd Place Time (s)","value":"',
                    thirdFastestTime,
                    '"}]'
                )
            );
    }

    function getHeroBodyLayerColor(
        bytes32 seed,
        ThemeGroup.ThemeName theme,
        ThemeGroup.ThemeLayer layer,
        uint256 day
    ) public view returns (uint256[3] memory, bytes32) {
        bytes32 rand = keccak256(abi.encodePacked(seed));
        ThemeGroup.ThemeSpecs memory themeSpecs = themeGroup.getColourThemes(
            theme,
            layer
        );

        uint256 hue = randomRange(
            themeSpecs.hueStart,
            themeSpecs.hueEnd,
            rand,
            day
        );

        rand = keccak256(abi.encodePacked(rand));
        uint256 sat = randomRange(
            themeSpecs.saturationStart,
            themeSpecs.saturationEnd,
            rand,
            day
        );

        rand = keccak256(abi.encodePacked(rand));
        uint256 light = randomRange(
            themeSpecs.lightnessStart,
            themeSpecs.lightnessEnd,
            rand,
            day
        );

        return ([hue, sat, light], rand);
    }

    function getBaddieBodyColor(
        uint256 day,
        uint256 bodyIndex
    ) internal view returns (uint256[3] memory hsl) {
        bytes32 rand = keccak256(abi.encodePacked(day, bodyIndex));
        uint256 hue = randomRange(0, 359, rand, day);
        rand = keccak256(abi.encodePacked(rand));
        uint256 saturation = randomRange(90, 100, rand, day);

        rand = keccak256(abi.encodePacked(rand));
        uint256 lightness = randomRange(55, 60, rand, day);

        return [hue, saturation, lightness];
    }

    function randomRange(
        uint256 min,
        uint256 max,
        bytes32 seed,
        uint256 day
    ) internal view returns (uint256) {
        return AnybodyProblem(anybodyProblem).randomRange(min, max, seed, day);
    }

    function updateAnybodyProblemAddress(
        address payable anybodyProblem_
    ) public onlyOwner {
        anybodyProblem = anybodyProblem_;
    }

    function updateSpeedrunsAddress(
        address payable speedruns_
    ) public onlyOwner {
        speedruns = speedruns_;
    }
}
合同源代码
文件 9 的 26:Game_2_20Verifier.sol
// SPDX-License-Identifier: GPL-3.0
/*
    Copyright 2021 0KIMS association.

    This file is generated with [snarkJS](https://github.com/iden3/snarkjs).

    snarkJS is a free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    snarkJS is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.7.0 <0.9.0;

contract Groth16Verifier {
    // Scalar field size
    uint256 constant r    = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
    // Base field size
    uint256 constant q   = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

    // Verification Key data
    uint256 constant alphax  = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
    uint256 constant alphay  = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
    uint256 constant betax1  = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
    uint256 constant betax2  = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
    uint256 constant betay1  = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
    uint256 constant betay2  = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
    uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
    uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
    uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
    uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
    uint256 constant deltax1 = 3136603502168491328860857292144042173370901022523286501959359064905261692158;
    uint256 constant deltax2 = 14501596552561454257272137471296787946153525452411979884862804076210817133442;
    uint256 constant deltay1 = 12079152112885988800143438359896348224567638249115758631523665029201749711481;
    uint256 constant deltay2 = 8439099726707293829088830270999405398642206151378773698955055306878901369081;

    
    uint256 constant IC0x = 10296704630556964942352704255928474644428871861963360277798568119037340355041;
    uint256 constant IC0y = 10652527585963811705479996054834571881715686906080860372319501821393143051047;
    
    uint256 constant IC1x = 783209922758193550762376688886524988848579268947969646262149250647443920991;
    uint256 constant IC1y = 451514454262903568901753457735480452436847575606758715125272489904424835843;
    
    uint256 constant IC2x = 7305904156212092225918038682329626581322662708077027365984879297070612589639;
    uint256 constant IC2y = 11343453987094244151470506481355361382229823277987848603173827782832819165468;
    
    uint256 constant IC3x = 18714027504238812788006356987260544253558412293354981434963266731649195968464;
    uint256 constant IC3y = 9712823252006497842310462306063189570040100109973566249040501596187690960427;
    
    uint256 constant IC4x = 13185986776420634220880640888907924043139507353845662861195470574813878613493;
    uint256 constant IC4y = 6071770124994462103155377406161745879658166158811316073249689782226730147946;
    
    uint256 constant IC5x = 6421772531737522824656006136306092303693081346802616704649417642590513902501;
    uint256 constant IC5y = 17980458412491246028614993571954320749983256634974829382453777859666273055910;
    
    uint256 constant IC6x = 20032559977071493799797263024830697764435927139009782325887370901092058507941;
    uint256 constant IC6y = 17415462403974143137677155565304371820054524622350886457076870577241588201158;
    
    uint256 constant IC7x = 3689651601094859327902262874399682346958049488304907782807269516979589845001;
    uint256 constant IC7y = 467982521521267392579874606673112078943678359559842120314256609122936914905;
    
    uint256 constant IC8x = 680084101004599376574196393809751462312762127095736951494632155070347472846;
    uint256 constant IC8y = 11106411465255953245332535686487551207479222021198639644511151779972543446672;
    
    uint256 constant IC9x = 11849116917998379178867222413439232136580621472852895601251957686885569760905;
    uint256 constant IC9y = 12237543789352654226317675579210251877865323571388607349454996897861830154487;
    
    uint256 constant IC10x = 6902072458530886619901401207459409387048128274854143897942266399499163960435;
    uint256 constant IC10y = 16859632165464569524273249671848391610088618673238711288785750234495924246646;
    
    uint256 constant IC11x = 17849629687542106148530364452151398365853579555653471830808813537023350549770;
    uint256 constant IC11y = 21010490623299352168518787055917160620845215323472486637963704004525632508130;
    
    uint256 constant IC12x = 14698895375354806620214135741920207426633741626024998193952569649407025300577;
    uint256 constant IC12y = 5281335237351458237648123976583030495176715440099675208103216457588039063630;
    
    uint256 constant IC13x = 18902016712926938990929837419825893434790028841276958287514057803296024146602;
    uint256 constant IC13y = 20183131048417223044929093939216564058398266071161218249456359260697739075507;
    
    uint256 constant IC14x = 17932968870904000916991372568575307466024926641369261126502762719043305551296;
    uint256 constant IC14y = 16019434510208690075856210494929418818099985778654314622380989485267917652146;
    
    uint256 constant IC15x = 19175751300952640621027391292506077829600389500649157037666957185502937342324;
    uint256 constant IC15y = 19938965000582791026729024043296808801014247044668705707378146912299390071898;
    
    uint256 constant IC16x = 3405997340773860169762349085947197701092675378225339444104518081680479681815;
    uint256 constant IC16y = 20720603366837817476484629316365007551534425025644435927087642033381501973344;
    
    uint256 constant IC17x = 7604911533703714817658672937424127699056071271970208302556415851003475695072;
    uint256 constant IC17y = 14390218411216220898658721304112585544320862116735777420450159535420439217873;
    
    uint256 constant IC18x = 1759246628522822558668931869535877112078759779213616497072545882623038533647;
    uint256 constant IC18y = 10135865712017529376143402368081630504622529489555701876437756478408226753911;
    
    uint256 constant IC19x = 13196739596153582710369435974197188128500299741992305608155162708158275530350;
    uint256 constant IC19y = 6228863376986142217971702101510209965697835181624242995867250089960741437961;
    
    uint256 constant IC20x = 3174239564411896143433615446357974414447588390869831407527210803854052969303;
    uint256 constant IC20y = 7830978404419296256657607204104592144203818339840701306601094869675343708224;
    
    uint256 constant IC21x = 1695012907506167271917135195956620639841724092721178947762509126866685253108;
    uint256 constant IC21y = 14439276941914622536617800164998501393338100880577949744110297600834256095793;
    
    uint256 constant IC22x = 15501124207355961361233506923826815065838340788024905320685776289060971323236;
    uint256 constant IC22y = 11283407687804128231592114477521899982225908707063250586189730689411159019522;
    
    uint256 constant IC23x = 14336588653359393054956463414814825225360602738852020837604422640752952243817;
    uint256 constant IC23y = 20667188372004962677651629545371157785402633009139685703586463828250880776504;
    
    uint256 constant IC24x = 6644812510510739114401308833632679612119021837175703882731965488639761835022;
    uint256 constant IC24y = 14546039680818095948756566577166149718067745527839349630139779143260678681488;
    
    uint256 constant IC25x = 6925495309869931276695923541279980519760187650607006785419664601285310623903;
    uint256 constant IC25y = 13859182840516686383132542853014017036183749240101437010308802743516290812589;
    
    uint256 constant IC26x = 13091979348451077928204798295401182061740295632013369504481982100639146737201;
    uint256 constant IC26y = 20448540168586219616494085581475512101106862973830946848463915510807492862763;
    
    uint256 constant IC27x = 17391697762030294097740989843409607841086553162756030068497465472149015268307;
    uint256 constant IC27y = 1084665757397547882249210732017126332324447069284856530622548216478047625129;
    
    uint256 constant IC28x = 5735574371421854862001476940068058294101213832602385101650949272437263276835;
    uint256 constant IC28y = 20344400500267544196639187360184646105317350987237689464783422949508403317617;
    
    uint256 constant IC29x = 11291617500958547591271701409295758471486149050492845811798366289761587522238;
    uint256 constant IC29y = 8770094684361249755527006162571038876789326185533496786391684958270613820428;
    
    uint256 constant IC30x = 2878987551438018304540527266520967876180491607327900680613026364163338829046;
    uint256 constant IC30y = 19079581342731415419916248904633507531807737583595034745241791662517746148746;
    
    uint256 constant IC31x = 1541680783956968853728237035900846206769346002453555853773212110457029010463;
    uint256 constant IC31y = 11035701298038576502978236520621370351250214109759687638977161013025447142258;
    
    uint256 constant IC32x = 18869895148017568089125598220977161333107074654200924646269950517253912808392;
    uint256 constant IC32y = 8791129967665717609952779159017118143287264249797093143404605303158451245981;
    
 
    // Memory data
    uint16 constant pVk = 0;
    uint16 constant pPairing = 128;

    uint16 constant pLastMem = 896;

    function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[32] calldata _pubSignals) public view returns (bool) {
        assembly {
            function checkField(v) {
                if iszero(lt(v, q)) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }
            
            // G1 function to multiply a G1 value(x,y) to value in an address
            function g1_mulAccC(pR, x, y, s) {
                let success
                let mIn := mload(0x40)
                mstore(mIn, x)
                mstore(add(mIn, 32), y)
                mstore(add(mIn, 64), s)

                success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }

                mstore(add(mIn, 64), mload(pR))
                mstore(add(mIn, 96), mload(add(pR, 32)))

                success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }

            function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
                let _pPairing := add(pMem, pPairing)
                let _pVk := add(pMem, pVk)

                mstore(_pVk, IC0x)
                mstore(add(_pVk, 32), IC0y)

                // Compute the linear combination vk_x
                
                g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
                
                g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
                
                g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
                
                g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
                
                g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
                
                g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))
                
                g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))
                
                g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))
                
                g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))
                
                g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288)))
                
                g1_mulAccC(_pVk, IC11x, IC11y, calldataload(add(pubSignals, 320)))
                
                g1_mulAccC(_pVk, IC12x, IC12y, calldataload(add(pubSignals, 352)))
                
                g1_mulAccC(_pVk, IC13x, IC13y, calldataload(add(pubSignals, 384)))
                
                g1_mulAccC(_pVk, IC14x, IC14y, calldataload(add(pubSignals, 416)))
                
                g1_mulAccC(_pVk, IC15x, IC15y, calldataload(add(pubSignals, 448)))
                
                g1_mulAccC(_pVk, IC16x, IC16y, calldataload(add(pubSignals, 480)))
                
                g1_mulAccC(_pVk, IC17x, IC17y, calldataload(add(pubSignals, 512)))
                
                g1_mulAccC(_pVk, IC18x, IC18y, calldataload(add(pubSignals, 544)))
                
                g1_mulAccC(_pVk, IC19x, IC19y, calldataload(add(pubSignals, 576)))
                
                g1_mulAccC(_pVk, IC20x, IC20y, calldataload(add(pubSignals, 608)))
                
                g1_mulAccC(_pVk, IC21x, IC21y, calldataload(add(pubSignals, 640)))
                
                g1_mulAccC(_pVk, IC22x, IC22y, calldataload(add(pubSignals, 672)))
                
                g1_mulAccC(_pVk, IC23x, IC23y, calldataload(add(pubSignals, 704)))
                
                g1_mulAccC(_pVk, IC24x, IC24y, calldataload(add(pubSignals, 736)))
                
                g1_mulAccC(_pVk, IC25x, IC25y, calldataload(add(pubSignals, 768)))
                
                g1_mulAccC(_pVk, IC26x, IC26y, calldataload(add(pubSignals, 800)))
                
                g1_mulAccC(_pVk, IC27x, IC27y, calldataload(add(pubSignals, 832)))
                
                g1_mulAccC(_pVk, IC28x, IC28y, calldataload(add(pubSignals, 864)))
                
                g1_mulAccC(_pVk, IC29x, IC29y, calldataload(add(pubSignals, 896)))
                
                g1_mulAccC(_pVk, IC30x, IC30y, calldataload(add(pubSignals, 928)))
                
                g1_mulAccC(_pVk, IC31x, IC31y, calldataload(add(pubSignals, 960)))
                
                g1_mulAccC(_pVk, IC32x, IC32y, calldataload(add(pubSignals, 992)))
                

                // -A
                mstore(_pPairing, calldataload(pA))
                mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))

                // B
                mstore(add(_pPairing, 64), calldataload(pB))
                mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
                mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
                mstore(add(_pPairing, 160), calldataload(add(pB, 96)))

                // alpha1
                mstore(add(_pPairing, 192), alphax)
                mstore(add(_pPairing, 224), alphay)

                // beta2
                mstore(add(_pPairing, 256), betax1)
                mstore(add(_pPairing, 288), betax2)
                mstore(add(_pPairing, 320), betay1)
                mstore(add(_pPairing, 352), betay2)

                // vk_x
                mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
                mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))


                // gamma2
                mstore(add(_pPairing, 448), gammax1)
                mstore(add(_pPairing, 480), gammax2)
                mstore(add(_pPairing, 512), gammay1)
                mstore(add(_pPairing, 544), gammay2)

                // C
                mstore(add(_pPairing, 576), calldataload(pC))
                mstore(add(_pPairing, 608), calldataload(add(pC, 32)))

                // delta2
                mstore(add(_pPairing, 640), deltax1)
                mstore(add(_pPairing, 672), deltax2)
                mstore(add(_pPairing, 704), deltay1)
                mstore(add(_pPairing, 736), deltay2)


                let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)

                isOk := and(success, mload(_pPairing))
            }

            let pMem := mload(0x40)
            mstore(0x40, add(pMem, pLastMem))

            // Validate that all evaluations ∈ F
            
            checkField(calldataload(add(_pubSignals, 0)))
            
            checkField(calldataload(add(_pubSignals, 32)))
            
            checkField(calldataload(add(_pubSignals, 64)))
            
            checkField(calldataload(add(_pubSignals, 96)))
            
            checkField(calldataload(add(_pubSignals, 128)))
            
            checkField(calldataload(add(_pubSignals, 160)))
            
            checkField(calldataload(add(_pubSignals, 192)))
            
            checkField(calldataload(add(_pubSignals, 224)))
            
            checkField(calldataload(add(_pubSignals, 256)))
            
            checkField(calldataload(add(_pubSignals, 288)))
            
            checkField(calldataload(add(_pubSignals, 320)))
            
            checkField(calldataload(add(_pubSignals, 352)))
            
            checkField(calldataload(add(_pubSignals, 384)))
            
            checkField(calldataload(add(_pubSignals, 416)))
            
            checkField(calldataload(add(_pubSignals, 448)))
            
            checkField(calldataload(add(_pubSignals, 480)))
            
            checkField(calldataload(add(_pubSignals, 512)))
            
            checkField(calldataload(add(_pubSignals, 544)))
            
            checkField(calldataload(add(_pubSignals, 576)))
            
            checkField(calldataload(add(_pubSignals, 608)))
            
            checkField(calldataload(add(_pubSignals, 640)))
            
            checkField(calldataload(add(_pubSignals, 672)))
            
            checkField(calldataload(add(_pubSignals, 704)))
            
            checkField(calldataload(add(_pubSignals, 736)))
            
            checkField(calldataload(add(_pubSignals, 768)))
            
            checkField(calldataload(add(_pubSignals, 800)))
            
            checkField(calldataload(add(_pubSignals, 832)))
            
            checkField(calldataload(add(_pubSignals, 864)))
            
            checkField(calldataload(add(_pubSignals, 896)))
            
            checkField(calldataload(add(_pubSignals, 928)))
            
            checkField(calldataload(add(_pubSignals, 960)))
            
            checkField(calldataload(add(_pubSignals, 992)))
            
            checkField(calldataload(add(_pubSignals, 1024)))
            

            // Validate all evaluations
            let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)

            mstore(0, isValid)
             return(0, 0x20)
         }
     }
 }
合同源代码
文件 10 的 26:Game_3_20Verifier.sol
// SPDX-License-Identifier: GPL-3.0
/*
    Copyright 2021 0KIMS association.

    This file is generated with [snarkJS](https://github.com/iden3/snarkjs).

    snarkJS is a free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    snarkJS is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.7.0 <0.9.0;

contract Groth16Verifier {
    // Scalar field size
    uint256 constant r    = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
    // Base field size
    uint256 constant q   = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

    // Verification Key data
    uint256 constant alphax  = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
    uint256 constant alphay  = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
    uint256 constant betax1  = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
    uint256 constant betax2  = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
    uint256 constant betay1  = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
    uint256 constant betay2  = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
    uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
    uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
    uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
    uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
    uint256 constant deltax1 = 18533209262862866581986214323148360117214657480077537597090519370133798674723;
    uint256 constant deltax2 = 5499985838220465301505788523608176854013408118016740468867040644389750440111;
    uint256 constant deltay1 = 2383040566022215476446371517286233610111674910382815348216986101258667433712;
    uint256 constant deltay2 = 3987058514690776342428842401888299196724022885315323694697967929704830520849;

    
    uint256 constant IC0x = 10590898211021847813249057118576418891456664995753673917849949553276702743917;
    uint256 constant IC0y = 17186526665122069371029219678331885554450587030483542875009976870411167574505;
    
    uint256 constant IC1x = 19271452977481257658824248657518621718461155763304692815040855493061543862452;
    uint256 constant IC1y = 19094766293589019125304668545648831340649273601537219560464139444917062785566;
    
    uint256 constant IC2x = 21270867873766430812084090234250310600840621175426559996693226377599899951908;
    uint256 constant IC2y = 1928021822526667651384797200219417208442277053047541299663521413654695968649;
    
    uint256 constant IC3x = 9252293913033702805318413089495776273133966670282188879636129586503505153966;
    uint256 constant IC3y = 15978968365359868689886906885319360483654164321345280441269866724780076681399;
    
    uint256 constant IC4x = 7903571928618946270152721916914567427440688208766179272326354721589016319123;
    uint256 constant IC4y = 4714686909322520078622447014126009126990007170503545397274754336526170640212;
    
    uint256 constant IC5x = 6710706563546192193108739344679485423986486091136738835906417999840092323976;
    uint256 constant IC5y = 6012179918666678656742888109056657075675031623250959238596825185513899760041;
    
    uint256 constant IC6x = 17290240902305981629228103239691975269909759211416495794133661693643305529494;
    uint256 constant IC6y = 21020992849919173181692091812485070699251709056934143596689146825138164412556;
    
    uint256 constant IC7x = 10210930139981664724679066919792097784965046346429046374088478923459254054103;
    uint256 constant IC7y = 14324817542937574222396890375352573759223826296621143753307852763671680846459;
    
    uint256 constant IC8x = 15718210258191598480371694255004134059115998667171020097141987895923578282139;
    uint256 constant IC8y = 10909302387229346230531324466002001882614179713516427474598252730278029621947;
    
    uint256 constant IC9x = 3797713336539198026491658835863610991729503521415260796829196849917489835066;
    uint256 constant IC9y = 7122261366019643008618565891829344622116329925184399160454584839562533950159;
    
    uint256 constant IC10x = 18812467260403410921106007579913109853092062813528754711027409543505083794952;
    uint256 constant IC10y = 18372651965841275599103329863874162296439834360370714455549817163641907165062;
    
    uint256 constant IC11x = 2572621055973660579705270498414937905825292847327147303104976278775912685550;
    uint256 constant IC11y = 9170285193356889646748917486964177696526567033074694631721494139512429465390;
    
    uint256 constant IC12x = 10234121315208424612675423264444186481382693469403593840362827397797257420319;
    uint256 constant IC12y = 20570557377830467809924431090028745119161574881998453843287509920060370144741;
    
    uint256 constant IC13x = 17947206108676700977038548821728383868632528776665579058594740758949034912385;
    uint256 constant IC13y = 14903721980987168563340545648702288144817797896870948001094054572115704574719;
    
    uint256 constant IC14x = 1018882807310948814852022461525975513555079242676856865866493004110626510057;
    uint256 constant IC14y = 5999772063470580350195195793336544329959723610489311233525467907103110300021;
    
    uint256 constant IC15x = 7789091026150004636486401320600462600890781701315152040696816080156466948481;
    uint256 constant IC15y = 12287413286145699191728909608264796537557655046921353455095630262247075750794;
    
    uint256 constant IC16x = 7312435239649608533716845986385886109136893012347496794517740385602748766002;
    uint256 constant IC16y = 18580067398207643367652756302382041945025909833822822314933175915406850350714;
    
    uint256 constant IC17x = 11167218814216218016994066650839307310752809546166011552299274902050212714314;
    uint256 constant IC17y = 14408882299809014064888837036655131794273119610129174259694216501618702869063;
    
    uint256 constant IC18x = 12575500546767311299926325177671870579333072529492337979570522515296669325246;
    uint256 constant IC18y = 7559267817727642108304985375845850817874135874011945069820671954847124900948;
    
    uint256 constant IC19x = 17712384993903872409239694019504519304159974473320087231498405168251803106345;
    uint256 constant IC19y = 20829638719076851599418058211553260250542550873531984915229607239864495151595;
    
    uint256 constant IC20x = 1815062468107384137606209888941936220792976997551512218892751903489259440645;
    uint256 constant IC20y = 3613121308835183792953375057261251978512357705736030330705766321092966487273;
    
    uint256 constant IC21x = 9079633328261468946631349246549053923581625101828306793950666300899909447345;
    uint256 constant IC21y = 20081248224743823200233808012643680482135414271758091564383443509404909168307;
    
    uint256 constant IC22x = 1957751462915521535972988984227232836738151137651154542204996296274360931740;
    uint256 constant IC22y = 20317760065401557351240108106155822141829174967984422745538423615490640801790;
    
    uint256 constant IC23x = 10042601431369008662129632903078206519112118466754637980044200914720425654869;
    uint256 constant IC23y = 4361949690406088364475145634837538237725592877836412419774776797471670219195;
    
    uint256 constant IC24x = 21696718980146329831726972586050894020892664955303096381350900620127051391404;
    uint256 constant IC24y = 18047183937107195268422999169697646282477264364379974088475398300381018565081;
    
    uint256 constant IC25x = 9007102349803211253502012050108306964475924943015270165997927222021967932772;
    uint256 constant IC25y = 6018509061085836378563344893730355172564824894018576546823291105298009019106;
    
    uint256 constant IC26x = 5266199248295728161998519227205538601453594746646061789614832486229602226633;
    uint256 constant IC26y = 7071742194232673056403697325531021053107888696964902772171026020777253200412;
    
    uint256 constant IC27x = 16782748034427716312679465957861461203801125312497001173936191126550218327340;
    uint256 constant IC27y = 4551981819927429412807614185066576073159940186532346685552739536693439689461;
    
    uint256 constant IC28x = 20487249035441605532298662589835220795745415839278311981048387342614456126327;
    uint256 constant IC28y = 11831300708142413479083556401253104109301008661484050347119381024958473580724;
    
    uint256 constant IC29x = 18749693049077336282081719359667675151593926927626435596044699116373059228036;
    uint256 constant IC29y = 7652816452044555314962464944612797725861968394157925231741454251159137741911;
    
    uint256 constant IC30x = 12805745936624264935280216215831985805851782069076466895937008776093823044988;
    uint256 constant IC30y = 11422109498939885723186372691780199603490234198003569249044850062528282248820;
    
    uint256 constant IC31x = 16578234744928601615727187473699682407629029748094258422704061270227387513325;
    uint256 constant IC31y = 4265596541255335739361979408500271579268173311696240004454512699859003424177;
    
    uint256 constant IC32x = 21570305522441315342670763108253321802618373530707818018203968432783030470599;
    uint256 constant IC32y = 11528867205115980796548371417681507596232967883439104059508419372728667022432;
    
    uint256 constant IC33x = 21779605576390895016679313673884198209156233379467239082920658918136991224330;
    uint256 constant IC33y = 20755527279158605249563161171812611989299305278402319409385561601803194846084;
    
    uint256 constant IC34x = 18587462362207994719156888723902133552222555110142089301098201323411226625852;
    uint256 constant IC34y = 8097392338554457401744720067481193626954198937338978007069328147703065340495;
    
    uint256 constant IC35x = 9857315954614149430845297718376348867130835117427735501181173373418338778131;
    uint256 constant IC35y = 14762178045833756622632459473949111241714547638993644530603868684378914257107;
    
    uint256 constant IC36x = 20055425162750087071657238783522347467047586056757418130550224481462658770440;
    uint256 constant IC36y = 6863065171148489117937464384261136790901424348033928282892322560346613320441;
    
    uint256 constant IC37x = 15711308198158898986655351037021421649759536770215597257030450915559273703617;
    uint256 constant IC37y = 14666222368579587025841815778152294478548612828161587529593702631655158204574;
    
    uint256 constant IC38x = 10081670318595106876059409706228386462195455278989574880149614560724813509823;
    uint256 constant IC38y = 7054242741593053891458477634976894900839731342696176500751016601607232218435;
    
    uint256 constant IC39x = 15153539396582877429301916005200270418318249759786543126110670521372341150573;
    uint256 constant IC39y = 13696926320435527374082696979111931439503289282260437717972518245838292822738;
    
    uint256 constant IC40x = 11695472715687301021079559053916526933488229363746632736982716372935116843482;
    uint256 constant IC40y = 5212565098850063000387511149058273217949714372848381123012844971796900818348;
    
    uint256 constant IC41x = 11618552564290727127881228575572366016348291459317002860476373472668393901211;
    uint256 constant IC41y = 2134091061482246683968341479892084368680489908360729016042591572993535997753;
    
    uint256 constant IC42x = 12790476612829036558517474629858052356977328991034292578725274246485543957265;
    uint256 constant IC42y = 17533284574688570053293207879555766642708992273976230526077495253857036507263;
    
 
    // Memory data
    uint16 constant pVk = 0;
    uint16 constant pPairing = 128;

    uint16 constant pLastMem = 896;

    function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[42] calldata _pubSignals) public view returns (bool) {
        assembly {
            function checkField(v) {
                if iszero(lt(v, q)) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }
            
            // G1 function to multiply a G1 value(x,y) to value in an address
            function g1_mulAccC(pR, x, y, s) {
                let success
                let mIn := mload(0x40)
                mstore(mIn, x)
                mstore(add(mIn, 32), y)
                mstore(add(mIn, 64), s)

                success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }

                mstore(add(mIn, 64), mload(pR))
                mstore(add(mIn, 96), mload(add(pR, 32)))

                success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }

            function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
                let _pPairing := add(pMem, pPairing)
                let _pVk := add(pMem, pVk)

                mstore(_pVk, IC0x)
                mstore(add(_pVk, 32), IC0y)

                // Compute the linear combination vk_x
                
                g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
                
                g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
                
                g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
                
                g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
                
                g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
                
                g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))
                
                g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))
                
                g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))
                
                g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))
                
                g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288)))
                
                g1_mulAccC(_pVk, IC11x, IC11y, calldataload(add(pubSignals, 320)))
                
                g1_mulAccC(_pVk, IC12x, IC12y, calldataload(add(pubSignals, 352)))
                
                g1_mulAccC(_pVk, IC13x, IC13y, calldataload(add(pubSignals, 384)))
                
                g1_mulAccC(_pVk, IC14x, IC14y, calldataload(add(pubSignals, 416)))
                
                g1_mulAccC(_pVk, IC15x, IC15y, calldataload(add(pubSignals, 448)))
                
                g1_mulAccC(_pVk, IC16x, IC16y, calldataload(add(pubSignals, 480)))
                
                g1_mulAccC(_pVk, IC17x, IC17y, calldataload(add(pubSignals, 512)))
                
                g1_mulAccC(_pVk, IC18x, IC18y, calldataload(add(pubSignals, 544)))
                
                g1_mulAccC(_pVk, IC19x, IC19y, calldataload(add(pubSignals, 576)))
                
                g1_mulAccC(_pVk, IC20x, IC20y, calldataload(add(pubSignals, 608)))
                
                g1_mulAccC(_pVk, IC21x, IC21y, calldataload(add(pubSignals, 640)))
                
                g1_mulAccC(_pVk, IC22x, IC22y, calldataload(add(pubSignals, 672)))
                
                g1_mulAccC(_pVk, IC23x, IC23y, calldataload(add(pubSignals, 704)))
                
                g1_mulAccC(_pVk, IC24x, IC24y, calldataload(add(pubSignals, 736)))
                
                g1_mulAccC(_pVk, IC25x, IC25y, calldataload(add(pubSignals, 768)))
                
                g1_mulAccC(_pVk, IC26x, IC26y, calldataload(add(pubSignals, 800)))
                
                g1_mulAccC(_pVk, IC27x, IC27y, calldataload(add(pubSignals, 832)))
                
                g1_mulAccC(_pVk, IC28x, IC28y, calldataload(add(pubSignals, 864)))
                
                g1_mulAccC(_pVk, IC29x, IC29y, calldataload(add(pubSignals, 896)))
                
                g1_mulAccC(_pVk, IC30x, IC30y, calldataload(add(pubSignals, 928)))
                
                g1_mulAccC(_pVk, IC31x, IC31y, calldataload(add(pubSignals, 960)))
                
                g1_mulAccC(_pVk, IC32x, IC32y, calldataload(add(pubSignals, 992)))
                
                g1_mulAccC(_pVk, IC33x, IC33y, calldataload(add(pubSignals, 1024)))
                
                g1_mulAccC(_pVk, IC34x, IC34y, calldataload(add(pubSignals, 1056)))
                
                g1_mulAccC(_pVk, IC35x, IC35y, calldataload(add(pubSignals, 1088)))
                
                g1_mulAccC(_pVk, IC36x, IC36y, calldataload(add(pubSignals, 1120)))
                
                g1_mulAccC(_pVk, IC37x, IC37y, calldataload(add(pubSignals, 1152)))
                
                g1_mulAccC(_pVk, IC38x, IC38y, calldataload(add(pubSignals, 1184)))
                
                g1_mulAccC(_pVk, IC39x, IC39y, calldataload(add(pubSignals, 1216)))
                
                g1_mulAccC(_pVk, IC40x, IC40y, calldataload(add(pubSignals, 1248)))
                
                g1_mulAccC(_pVk, IC41x, IC41y, calldataload(add(pubSignals, 1280)))
                
                g1_mulAccC(_pVk, IC42x, IC42y, calldataload(add(pubSignals, 1312)))
                

                // -A
                mstore(_pPairing, calldataload(pA))
                mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))

                // B
                mstore(add(_pPairing, 64), calldataload(pB))
                mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
                mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
                mstore(add(_pPairing, 160), calldataload(add(pB, 96)))

                // alpha1
                mstore(add(_pPairing, 192), alphax)
                mstore(add(_pPairing, 224), alphay)

                // beta2
                mstore(add(_pPairing, 256), betax1)
                mstore(add(_pPairing, 288), betax2)
                mstore(add(_pPairing, 320), betay1)
                mstore(add(_pPairing, 352), betay2)

                // vk_x
                mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
                mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))


                // gamma2
                mstore(add(_pPairing, 448), gammax1)
                mstore(add(_pPairing, 480), gammax2)
                mstore(add(_pPairing, 512), gammay1)
                mstore(add(_pPairing, 544), gammay2)

                // C
                mstore(add(_pPairing, 576), calldataload(pC))
                mstore(add(_pPairing, 608), calldataload(add(pC, 32)))

                // delta2
                mstore(add(_pPairing, 640), deltax1)
                mstore(add(_pPairing, 672), deltax2)
                mstore(add(_pPairing, 704), deltay1)
                mstore(add(_pPairing, 736), deltay2)


                let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)

                isOk := and(success, mload(_pPairing))
            }

            let pMem := mload(0x40)
            mstore(0x40, add(pMem, pLastMem))

            // Validate that all evaluations ∈ F
            
            checkField(calldataload(add(_pubSignals, 0)))
            
            checkField(calldataload(add(_pubSignals, 32)))
            
            checkField(calldataload(add(_pubSignals, 64)))
            
            checkField(calldataload(add(_pubSignals, 96)))
            
            checkField(calldataload(add(_pubSignals, 128)))
            
            checkField(calldataload(add(_pubSignals, 160)))
            
            checkField(calldataload(add(_pubSignals, 192)))
            
            checkField(calldataload(add(_pubSignals, 224)))
            
            checkField(calldataload(add(_pubSignals, 256)))
            
            checkField(calldataload(add(_pubSignals, 288)))
            
            checkField(calldataload(add(_pubSignals, 320)))
            
            checkField(calldataload(add(_pubSignals, 352)))
            
            checkField(calldataload(add(_pubSignals, 384)))
            
            checkField(calldataload(add(_pubSignals, 416)))
            
            checkField(calldataload(add(_pubSignals, 448)))
            
            checkField(calldataload(add(_pubSignals, 480)))
            
            checkField(calldataload(add(_pubSignals, 512)))
            
            checkField(calldataload(add(_pubSignals, 544)))
            
            checkField(calldataload(add(_pubSignals, 576)))
            
            checkField(calldataload(add(_pubSignals, 608)))
            
            checkField(calldataload(add(_pubSignals, 640)))
            
            checkField(calldataload(add(_pubSignals, 672)))
            
            checkField(calldataload(add(_pubSignals, 704)))
            
            checkField(calldataload(add(_pubSignals, 736)))
            
            checkField(calldataload(add(_pubSignals, 768)))
            
            checkField(calldataload(add(_pubSignals, 800)))
            
            checkField(calldataload(add(_pubSignals, 832)))
            
            checkField(calldataload(add(_pubSignals, 864)))
            
            checkField(calldataload(add(_pubSignals, 896)))
            
            checkField(calldataload(add(_pubSignals, 928)))
            
            checkField(calldataload(add(_pubSignals, 960)))
            
            checkField(calldataload(add(_pubSignals, 992)))
            
            checkField(calldataload(add(_pubSignals, 1024)))
            
            checkField(calldataload(add(_pubSignals, 1056)))
            
            checkField(calldataload(add(_pubSignals, 1088)))
            
            checkField(calldataload(add(_pubSignals, 1120)))
            
            checkField(calldataload(add(_pubSignals, 1152)))
            
            checkField(calldataload(add(_pubSignals, 1184)))
            
            checkField(calldataload(add(_pubSignals, 1216)))
            
            checkField(calldataload(add(_pubSignals, 1248)))
            
            checkField(calldataload(add(_pubSignals, 1280)))
            
            checkField(calldataload(add(_pubSignals, 1312)))
            
            checkField(calldataload(add(_pubSignals, 1344)))
            

            // Validate all evaluations
            let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)

            mstore(0, isValid)
             return(0, 0x20)
         }
     }
 }
合同源代码
文件 11 的 26:Game_4_20Verifier.sol
// SPDX-License-Identifier: GPL-3.0
/*
    Copyright 2021 0KIMS association.

    This file is generated with [snarkJS](https://github.com/iden3/snarkjs).

    snarkJS is a free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    snarkJS is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.7.0 <0.9.0;

contract Groth16Verifier {
    // Scalar field size
    uint256 constant r    = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
    // Base field size
    uint256 constant q   = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

    // Verification Key data
    uint256 constant alphax  = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
    uint256 constant alphay  = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
    uint256 constant betax1  = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
    uint256 constant betax2  = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
    uint256 constant betay1  = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
    uint256 constant betay2  = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
    uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
    uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
    uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
    uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
    uint256 constant deltax1 = 4786718060322028134879265544112222515359212254263380946526138887786298491865;
    uint256 constant deltax2 = 14284686619318039763876282582613146087463941480513040098192043776656731569984;
    uint256 constant deltay1 = 14067465406090720002126483866879142092245901339950450773461185883120934565390;
    uint256 constant deltay2 = 3468322591116915092294787723713528417259980547248340262872661674239376154162;

    
    uint256 constant IC0x = 15046595439312856173205748223705472130379456345985747985255645424732913065947;
    uint256 constant IC0y = 4928008414097513183062872571448902318442172640130732004989233665227465678951;
    
    uint256 constant IC1x = 8464143199004313929807407394891002615499831667844604192834247989362121945780;
    uint256 constant IC1y = 6637576083690565777148025180064387071173944718631126255561465552574288855010;
    
    uint256 constant IC2x = 16125987308292681730970994564655263166171635332647953139462101350318103785467;
    uint256 constant IC2y = 16858503788473935456077457906583206840917828383116157414379846633536219085641;
    
    uint256 constant IC3x = 14313310488880268693414506559300826734325916807412678369117840057555145181719;
    uint256 constant IC3y = 4364608412344337762515373752635855408255976527231717212745237001547520755850;
    
    uint256 constant IC4x = 15407446080737000944165996148443512157717768661738408842478777832516685659736;
    uint256 constant IC4y = 18999371303350545578914292150223841947137901430589101337944874624438722018767;
    
    uint256 constant IC5x = 15787362168788929070076274759811818266000126096541245834954293837757123803672;
    uint256 constant IC5y = 4554587253816770929841462164848827606166288967637322530860650135626934180606;
    
    uint256 constant IC6x = 14026852815743469302175514862317218570281893826270879206950245767896692362271;
    uint256 constant IC6y = 11266223917704693739031432449296569752875030508642728917680319617046387922734;
    
    uint256 constant IC7x = 19202034036854058516062431246925304947389093386891855457798569053199597142027;
    uint256 constant IC7y = 7694722120851049641833455086083781350899494650621073669226580715628534734210;
    
    uint256 constant IC8x = 21276265643485520581476492995323883255600896167424829285186720903079528867419;
    uint256 constant IC8y = 11951116736725367805485880956194371788065718968337144597065646749326235841902;
    
    uint256 constant IC9x = 11486261754691830790294713108812430388835057527738200978292232363554514306298;
    uint256 constant IC9y = 2536467799429353007989063310972331216129921292234710206495264846342957867774;
    
    uint256 constant IC10x = 20852516911106541117994702757478029105182880597300350959067783318454845354258;
    uint256 constant IC10y = 8956945846996717710799595871951331327055313720068123948119223041166014464067;
    
    uint256 constant IC11x = 19543681799079129521332127553630286454594637228954699405790323991453862031866;
    uint256 constant IC11y = 18535729327755153781305836950226598442483133009952994309337389189590130381575;
    
    uint256 constant IC12x = 6913502880591932535900832779477751923391735835714750824276810364877958608617;
    uint256 constant IC12y = 15614933775205868627734876850095421704923117547259797286649154642998516857242;
    
    uint256 constant IC13x = 12520449026411700936512496948387911184418830513176476808217060980270303473318;
    uint256 constant IC13y = 5597569296965558081661297618473218529514651699130418242621867002195104475138;
    
    uint256 constant IC14x = 8108749677295733111940397210782720307057333474880036828007025162375578855531;
    uint256 constant IC14y = 17324109986743409276555371831190960228120577159506422249930142612383313196015;
    
    uint256 constant IC15x = 5735594154662395393250285516367023149290025652457043932369128275814291961453;
    uint256 constant IC15y = 7212789948838801160598299917028581591637075748909844648818086248989180743681;
    
    uint256 constant IC16x = 2465021185702822358445480735762456067950746012152477209318894699350537202456;
    uint256 constant IC16y = 11235036006965116133886196324471068051309392569836662233372765206045574728634;
    
    uint256 constant IC17x = 1532611073563284322091227891271449085760581582328345371996134743849912322406;
    uint256 constant IC17y = 12572065088896829928587848044389002480792591929584775437570648875775063316532;
    
    uint256 constant IC18x = 4832199066489022701008944054370584179736263879281006629535703240239836494760;
    uint256 constant IC18y = 3322761973876720266093407856541451415620033578289105167836615451043884299487;
    
    uint256 constant IC19x = 6477204666818752643696008954793704749992962337893677778119541057416146934136;
    uint256 constant IC19y = 4799116128509696070200692102117251145206138812709377934545758217035711166591;
    
    uint256 constant IC20x = 2423295053537140162446813840795188900015867705776673060805049766456140126687;
    uint256 constant IC20y = 11484662685652523500052580450677156563482352642501735735127840815288456367735;
    
    uint256 constant IC21x = 21307180609147623681835305445463255517846641447794444141517154698479639739836;
    uint256 constant IC21y = 18630876282777855499890917324802543278828534127351160495083580134575793799494;
    
    uint256 constant IC22x = 18421866507609491586315753713576219040492981467738880983374053002219712059673;
    uint256 constant IC22y = 7135303675540220992879243733763333712930569771819559185582247756693080382283;
    
    uint256 constant IC23x = 3432466761071702265096417339195178965668471416487350912347100430207039223909;
    uint256 constant IC23y = 7411424524359816486685383720828658442879043627957011018183310194807300798528;
    
    uint256 constant IC24x = 19920369347981594126940613269366958560812791669930928051692353683484740478555;
    uint256 constant IC24y = 13740594638103533891677655962114599216590604669737325504343707386155982838730;
    
    uint256 constant IC25x = 7754624383038357375238500172234665626221981590096410244218418136558114988475;
    uint256 constant IC25y = 20568419626095830534730775615852031211555756736691709229473018507696554084610;
    
    uint256 constant IC26x = 17551262839147078891527051163002499675919965812464312784845154026885899444389;
    uint256 constant IC26y = 9885310983493860088016538489041349779442906656231089118649877622808061393110;
    
    uint256 constant IC27x = 2394326163601752155068123253251364486118445863161294173832198171072201922230;
    uint256 constant IC27y = 18341057046990445323090650743389979897286830763467361976095701056022000174113;
    
    uint256 constant IC28x = 10693185593835991542386636719902160070127426257149506425365125992183544931793;
    uint256 constant IC28y = 1002130151672757634834200484734939209167207843279947946218938916433127091775;
    
    uint256 constant IC29x = 20322526454308322904524859992376143804900164095251974146449313516757416012365;
    uint256 constant IC29y = 3465544886716188902542378974861077402776339858775735072190757314248924135008;
    
    uint256 constant IC30x = 5173008682393508371314942178297392544561016754330034116203034270522742033013;
    uint256 constant IC30y = 9167250893624496202385917892950424875176635257043009735067459043967407729781;
    
    uint256 constant IC31x = 2454835672121244679423723154291919481539908350979420096326914201734842432773;
    uint256 constant IC31y = 3671409987648745482330925198042624150577379386018351527924219864245697405951;
    
    uint256 constant IC32x = 15825538693135171987609007892388495344514727031182661193897655861558331272146;
    uint256 constant IC32y = 15811827421045973219133138666104569537996281910493506891392646384590530310800;
    
    uint256 constant IC33x = 10356545487847034611096995203493141626141945787834874308932944352366216791825;
    uint256 constant IC33y = 20247405912725065845367410452619901036885282347607696932521858816138489729323;
    
    uint256 constant IC34x = 18877529189380569562333927133586852922444631658871840666763300048602099365049;
    uint256 constant IC34y = 21506915568065939810916799394078887532771032677606380288026661042678130815842;
    
    uint256 constant IC35x = 3946853043450878718072021880099632823422258997643777480558409752483506274835;
    uint256 constant IC35y = 17699507219511166464002425934411050160971546730895149467739987863561638677107;
    
    uint256 constant IC36x = 7759633475934721735165914007323142354262112832707324493691996371252044106845;
    uint256 constant IC36y = 12772195284833990116770566639630889850759022657279142879797922015457510069186;
    
    uint256 constant IC37x = 6000486013516153344623913894299041815798964485530199484036562555638162797061;
    uint256 constant IC37y = 16810898475522236433974127368391926629304086008811304546492879302185455577534;
    
    uint256 constant IC38x = 17250918941785807887471827267168946744067428781991753683884791681863679539123;
    uint256 constant IC38y = 14986580681870521782100008346941652536248381341294750159038099171712338458882;
    
    uint256 constant IC39x = 9642183373495639390807037152811455512806767073464004410021635704015973371498;
    uint256 constant IC39y = 14104732585068773859654024361666519454409560348168743114782403577666485706764;
    
    uint256 constant IC40x = 21182066820889334649668566257247293192197312506440176738962144002839644529705;
    uint256 constant IC40y = 14323703356626024555682025897704396761244459540692336007676223433899932054775;
    
    uint256 constant IC41x = 934173240076885459939525525009340722347543984198523036695921222170868732170;
    uint256 constant IC41y = 2674620850831173583240795888361625368506873265006662713947042831368089605099;
    
    uint256 constant IC42x = 21367975828083516640944819267567441544682442772864975763308074478498606729447;
    uint256 constant IC42y = 5807706528353130871336373313985339946419090598647781626740255377670432517343;
    
    uint256 constant IC43x = 19344169946610238097150084159443888089730706368148062379013512835102226801979;
    uint256 constant IC43y = 15715506818585097995089876077382197356938140105566779555202868561978042904099;
    
    uint256 constant IC44x = 5795119927611542639303716200034352211129132692996851709950641160343365865757;
    uint256 constant IC44y = 11889441635527659502210677708209642996538996664825693129152700789394396410931;
    
    uint256 constant IC45x = 15121180139436797448489612864099309868947051658303031311891592187450252074687;
    uint256 constant IC45y = 15232322798985503730254397303994608600942459881126536959634377151862314412966;
    
    uint256 constant IC46x = 12258505567898956092759255919113556819992883406626287986408579505236429651620;
    uint256 constant IC46y = 16931705502936219463207156719907366384179365477212920076150807819712953391550;
    
    uint256 constant IC47x = 19456473554535656037518784029902766911006055962730558234546773669922586740879;
    uint256 constant IC47y = 6942140149235948595245879839538234334926741405348344092765966396436093864289;
    
    uint256 constant IC48x = 12077265590753981905882175016239279630449495610488663647566121417679888061089;
    uint256 constant IC48y = 9378855242695408668995112209641107633551967876046428534735385051866048105653;
    
    uint256 constant IC49x = 18170275273186013318744863434632398875029472919400448359939195265453499953687;
    uint256 constant IC49y = 20216093057993808700998224103866855018828416912720541040596447344528145291854;
    
    uint256 constant IC50x = 1428850726429391143163289308883524033454858965813657947120270084082416901902;
    uint256 constant IC50y = 18010877943990606791020193916355207213656393762441204001349040886591968642291;
    
    uint256 constant IC51x = 1522759780385766226621109426161411499973010045581991860521348234433462459383;
    uint256 constant IC51y = 2543085865632156175866223120754492312255679699709237293324025139572359907479;
    
    uint256 constant IC52x = 16024144416594370496108462435759773021929306297582790674041639775483674901588;
    uint256 constant IC52y = 15612758880738362824470744575867467660780727422979565184732263118340453054584;
    
 
    // Memory data
    uint16 constant pVk = 0;
    uint16 constant pPairing = 128;

    uint16 constant pLastMem = 896;

    function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[52] calldata _pubSignals) public view returns (bool) {
        assembly {
            function checkField(v) {
                if iszero(lt(v, q)) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }
            
            // G1 function to multiply a G1 value(x,y) to value in an address
            function g1_mulAccC(pR, x, y, s) {
                let success
                let mIn := mload(0x40)
                mstore(mIn, x)
                mstore(add(mIn, 32), y)
                mstore(add(mIn, 64), s)

                success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }

                mstore(add(mIn, 64), mload(pR))
                mstore(add(mIn, 96), mload(add(pR, 32)))

                success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }

            function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
                let _pPairing := add(pMem, pPairing)
                let _pVk := add(pMem, pVk)

                mstore(_pVk, IC0x)
                mstore(add(_pVk, 32), IC0y)

                // Compute the linear combination vk_x
                
                g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
                
                g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
                
                g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
                
                g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
                
                g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
                
                g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))
                
                g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))
                
                g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))
                
                g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))
                
                g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288)))
                
                g1_mulAccC(_pVk, IC11x, IC11y, calldataload(add(pubSignals, 320)))
                
                g1_mulAccC(_pVk, IC12x, IC12y, calldataload(add(pubSignals, 352)))
                
                g1_mulAccC(_pVk, IC13x, IC13y, calldataload(add(pubSignals, 384)))
                
                g1_mulAccC(_pVk, IC14x, IC14y, calldataload(add(pubSignals, 416)))
                
                g1_mulAccC(_pVk, IC15x, IC15y, calldataload(add(pubSignals, 448)))
                
                g1_mulAccC(_pVk, IC16x, IC16y, calldataload(add(pubSignals, 480)))
                
                g1_mulAccC(_pVk, IC17x, IC17y, calldataload(add(pubSignals, 512)))
                
                g1_mulAccC(_pVk, IC18x, IC18y, calldataload(add(pubSignals, 544)))
                
                g1_mulAccC(_pVk, IC19x, IC19y, calldataload(add(pubSignals, 576)))
                
                g1_mulAccC(_pVk, IC20x, IC20y, calldataload(add(pubSignals, 608)))
                
                g1_mulAccC(_pVk, IC21x, IC21y, calldataload(add(pubSignals, 640)))
                
                g1_mulAccC(_pVk, IC22x, IC22y, calldataload(add(pubSignals, 672)))
                
                g1_mulAccC(_pVk, IC23x, IC23y, calldataload(add(pubSignals, 704)))
                
                g1_mulAccC(_pVk, IC24x, IC24y, calldataload(add(pubSignals, 736)))
                
                g1_mulAccC(_pVk, IC25x, IC25y, calldataload(add(pubSignals, 768)))
                
                g1_mulAccC(_pVk, IC26x, IC26y, calldataload(add(pubSignals, 800)))
                
                g1_mulAccC(_pVk, IC27x, IC27y, calldataload(add(pubSignals, 832)))
                
                g1_mulAccC(_pVk, IC28x, IC28y, calldataload(add(pubSignals, 864)))
                
                g1_mulAccC(_pVk, IC29x, IC29y, calldataload(add(pubSignals, 896)))
                
                g1_mulAccC(_pVk, IC30x, IC30y, calldataload(add(pubSignals, 928)))
                
                g1_mulAccC(_pVk, IC31x, IC31y, calldataload(add(pubSignals, 960)))
                
                g1_mulAccC(_pVk, IC32x, IC32y, calldataload(add(pubSignals, 992)))
                
                g1_mulAccC(_pVk, IC33x, IC33y, calldataload(add(pubSignals, 1024)))
                
                g1_mulAccC(_pVk, IC34x, IC34y, calldataload(add(pubSignals, 1056)))
                
                g1_mulAccC(_pVk, IC35x, IC35y, calldataload(add(pubSignals, 1088)))
                
                g1_mulAccC(_pVk, IC36x, IC36y, calldataload(add(pubSignals, 1120)))
                
                g1_mulAccC(_pVk, IC37x, IC37y, calldataload(add(pubSignals, 1152)))
                
                g1_mulAccC(_pVk, IC38x, IC38y, calldataload(add(pubSignals, 1184)))
                
                g1_mulAccC(_pVk, IC39x, IC39y, calldataload(add(pubSignals, 1216)))
                
                g1_mulAccC(_pVk, IC40x, IC40y, calldataload(add(pubSignals, 1248)))
                
                g1_mulAccC(_pVk, IC41x, IC41y, calldataload(add(pubSignals, 1280)))
                
                g1_mulAccC(_pVk, IC42x, IC42y, calldataload(add(pubSignals, 1312)))
                
                g1_mulAccC(_pVk, IC43x, IC43y, calldataload(add(pubSignals, 1344)))
                
                g1_mulAccC(_pVk, IC44x, IC44y, calldataload(add(pubSignals, 1376)))
                
                g1_mulAccC(_pVk, IC45x, IC45y, calldataload(add(pubSignals, 1408)))
                
                g1_mulAccC(_pVk, IC46x, IC46y, calldataload(add(pubSignals, 1440)))
                
                g1_mulAccC(_pVk, IC47x, IC47y, calldataload(add(pubSignals, 1472)))
                
                g1_mulAccC(_pVk, IC48x, IC48y, calldataload(add(pubSignals, 1504)))
                
                g1_mulAccC(_pVk, IC49x, IC49y, calldataload(add(pubSignals, 1536)))
                
                g1_mulAccC(_pVk, IC50x, IC50y, calldataload(add(pubSignals, 1568)))
                
                g1_mulAccC(_pVk, IC51x, IC51y, calldataload(add(pubSignals, 1600)))
                
                g1_mulAccC(_pVk, IC52x, IC52y, calldataload(add(pubSignals, 1632)))
                

                // -A
                mstore(_pPairing, calldataload(pA))
                mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))

                // B
                mstore(add(_pPairing, 64), calldataload(pB))
                mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
                mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
                mstore(add(_pPairing, 160), calldataload(add(pB, 96)))

                // alpha1
                mstore(add(_pPairing, 192), alphax)
                mstore(add(_pPairing, 224), alphay)

                // beta2
                mstore(add(_pPairing, 256), betax1)
                mstore(add(_pPairing, 288), betax2)
                mstore(add(_pPairing, 320), betay1)
                mstore(add(_pPairing, 352), betay2)

                // vk_x
                mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
                mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))


                // gamma2
                mstore(add(_pPairing, 448), gammax1)
                mstore(add(_pPairing, 480), gammax2)
                mstore(add(_pPairing, 512), gammay1)
                mstore(add(_pPairing, 544), gammay2)

                // C
                mstore(add(_pPairing, 576), calldataload(pC))
                mstore(add(_pPairing, 608), calldataload(add(pC, 32)))

                // delta2
                mstore(add(_pPairing, 640), deltax1)
                mstore(add(_pPairing, 672), deltax2)
                mstore(add(_pPairing, 704), deltay1)
                mstore(add(_pPairing, 736), deltay2)


                let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)

                isOk := and(success, mload(_pPairing))
            }

            let pMem := mload(0x40)
            mstore(0x40, add(pMem, pLastMem))

            // Validate that all evaluations ∈ F
            
            checkField(calldataload(add(_pubSignals, 0)))
            
            checkField(calldataload(add(_pubSignals, 32)))
            
            checkField(calldataload(add(_pubSignals, 64)))
            
            checkField(calldataload(add(_pubSignals, 96)))
            
            checkField(calldataload(add(_pubSignals, 128)))
            
            checkField(calldataload(add(_pubSignals, 160)))
            
            checkField(calldataload(add(_pubSignals, 192)))
            
            checkField(calldataload(add(_pubSignals, 224)))
            
            checkField(calldataload(add(_pubSignals, 256)))
            
            checkField(calldataload(add(_pubSignals, 288)))
            
            checkField(calldataload(add(_pubSignals, 320)))
            
            checkField(calldataload(add(_pubSignals, 352)))
            
            checkField(calldataload(add(_pubSignals, 384)))
            
            checkField(calldataload(add(_pubSignals, 416)))
            
            checkField(calldataload(add(_pubSignals, 448)))
            
            checkField(calldataload(add(_pubSignals, 480)))
            
            checkField(calldataload(add(_pubSignals, 512)))
            
            checkField(calldataload(add(_pubSignals, 544)))
            
            checkField(calldataload(add(_pubSignals, 576)))
            
            checkField(calldataload(add(_pubSignals, 608)))
            
            checkField(calldataload(add(_pubSignals, 640)))
            
            checkField(calldataload(add(_pubSignals, 672)))
            
            checkField(calldataload(add(_pubSignals, 704)))
            
            checkField(calldataload(add(_pubSignals, 736)))
            
            checkField(calldataload(add(_pubSignals, 768)))
            
            checkField(calldataload(add(_pubSignals, 800)))
            
            checkField(calldataload(add(_pubSignals, 832)))
            
            checkField(calldataload(add(_pubSignals, 864)))
            
            checkField(calldataload(add(_pubSignals, 896)))
            
            checkField(calldataload(add(_pubSignals, 928)))
            
            checkField(calldataload(add(_pubSignals, 960)))
            
            checkField(calldataload(add(_pubSignals, 992)))
            
            checkField(calldataload(add(_pubSignals, 1024)))
            
            checkField(calldataload(add(_pubSignals, 1056)))
            
            checkField(calldataload(add(_pubSignals, 1088)))
            
            checkField(calldataload(add(_pubSignals, 1120)))
            
            checkField(calldataload(add(_pubSignals, 1152)))
            
            checkField(calldataload(add(_pubSignals, 1184)))
            
            checkField(calldataload(add(_pubSignals, 1216)))
            
            checkField(calldataload(add(_pubSignals, 1248)))
            
            checkField(calldataload(add(_pubSignals, 1280)))
            
            checkField(calldataload(add(_pubSignals, 1312)))
            
            checkField(calldataload(add(_pubSignals, 1344)))
            
            checkField(calldataload(add(_pubSignals, 1376)))
            
            checkField(calldataload(add(_pubSignals, 1408)))
            
            checkField(calldataload(add(_pubSignals, 1440)))
            
            checkField(calldataload(add(_pubSignals, 1472)))
            
            checkField(calldataload(add(_pubSignals, 1504)))
            
            checkField(calldataload(add(_pubSignals, 1536)))
            
            checkField(calldataload(add(_pubSignals, 1568)))
            
            checkField(calldataload(add(_pubSignals, 1600)))
            
            checkField(calldataload(add(_pubSignals, 1632)))
            
            checkField(calldataload(add(_pubSignals, 1664)))
            

            // Validate all evaluations
            let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)

            mstore(0, isValid)
             return(0, 0x20)
         }
     }
 }
合同源代码
文件 12 的 26:Game_5_20Verifier.sol
// SPDX-License-Identifier: GPL-3.0
/*
    Copyright 2021 0KIMS association.

    This file is generated with [snarkJS](https://github.com/iden3/snarkjs).

    snarkJS is a free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    snarkJS is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.7.0 <0.9.0;

contract Groth16Verifier {
    // Scalar field size
    uint256 constant r    = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
    // Base field size
    uint256 constant q   = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

    // Verification Key data
    uint256 constant alphax  = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
    uint256 constant alphay  = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
    uint256 constant betax1  = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
    uint256 constant betax2  = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
    uint256 constant betay1  = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
    uint256 constant betay2  = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
    uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
    uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
    uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
    uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
    uint256 constant deltax1 = 8734036001815013789387956221424295259835800660772809432193070508969314903013;
    uint256 constant deltax2 = 19997722084839327560903539111271195674615748072810553820156786004293748944324;
    uint256 constant deltay1 = 314957742065747096468478121887560533118395187355507414568290174300459154882;
    uint256 constant deltay2 = 17968920681257086163776057866013754773505862330377640331189132980938329421004;

    
    uint256 constant IC0x = 7814031753617899662386110205704260138240762274825846221340836882342286897040;
    uint256 constant IC0y = 4609052355533804277177062667684269951076947445537442333521512755036042406759;
    
    uint256 constant IC1x = 10696684465666204378809006016594065564116118335127206511083147667837930622092;
    uint256 constant IC1y = 14238265092678586835952661043369445342651970496661774805635947999204519080751;
    
    uint256 constant IC2x = 2847113930282281029603032167827823933319615352634428223307152944076778577448;
    uint256 constant IC2y = 21824080898627948969750827151025772515260172693739954585972530660681242533183;
    
    uint256 constant IC3x = 13017289661921195536640077950693883567637427320912022307784919348071228450028;
    uint256 constant IC3y = 11785139709312149862912918571935354592520615298578321375395099260722102057527;
    
    uint256 constant IC4x = 18567355953558606724995915252208076481426323385695441579136201675324589884351;
    uint256 constant IC4y = 17823270637430195978277355462770080670483139236488150507716422307361920502269;
    
    uint256 constant IC5x = 21731667982139143776888276797432852151290854021331468868889913676054995378022;
    uint256 constant IC5y = 7709176721578827080046021272176907596338786477605587190538568770741406492049;
    
    uint256 constant IC6x = 18420861010876406061168955994324254541742330394259751752167835879896812974053;
    uint256 constant IC6y = 3168615285942322986762188887258933952845510538736410250436014039255870904628;
    
    uint256 constant IC7x = 1896032352595191851146698658859489538611000668316766557052390393223092400853;
    uint256 constant IC7y = 14259236194860772013472160457434322086059904899579771379901584177569917572350;
    
    uint256 constant IC8x = 11222190986411629808956192153843861202833570315671209372343906329289836014240;
    uint256 constant IC8y = 19088257445519718564674826648232838354047495512646101200488284358650536508726;
    
    uint256 constant IC9x = 12361951066815393535787532545597279640812259811153434641506115186990506996577;
    uint256 constant IC9y = 9705183176122554723749541151975172300681517591179604919773938814901024386339;
    
    uint256 constant IC10x = 18163882697909794067956547618334585140547488942432884771436738756058257740896;
    uint256 constant IC10y = 15223760798658643929394026534638339733099853052962921145769780121914831949690;
    
    uint256 constant IC11x = 6296818565107997565666931832461829514053868613665639120855666185421614434786;
    uint256 constant IC11y = 1027145084132544850410873312893043638391590333813482403475226049572467202251;
    
    uint256 constant IC12x = 7119067033276753036951590241961420153403225989919546386656275511454832556572;
    uint256 constant IC12y = 17598427466405225083990264990532293489139812770912785535261337497039604933656;
    
    uint256 constant IC13x = 20411176507356250177773593864856011896261347734646636920319907696751748473807;
    uint256 constant IC13y = 8595669988923174655080412903917518113994070482773239452924333095671116117782;
    
    uint256 constant IC14x = 5282525028358605186200422787413023004524719805030309349664745829854124424267;
    uint256 constant IC14y = 16681289056024607906606136958032101018742548287223379689635728899951821620580;
    
    uint256 constant IC15x = 17467768959551115312780379486282239161439370808192163988080843072427307651980;
    uint256 constant IC15y = 18630864494670657048569954834188463534233114218188718117372429286692568381815;
    
    uint256 constant IC16x = 2698135033634804214765909375713718337048150496006926180023111455749603872438;
    uint256 constant IC16y = 20796543606303864825758648414138571664368601741562496468612953057133457862875;
    
    uint256 constant IC17x = 18214909603192344607255367978116511320316601066518705064767635001072640575658;
    uint256 constant IC17y = 737176752514234593583800897351538775825551829260333281842196088310822114180;
    
    uint256 constant IC18x = 18128393105179179729699066086730506289758684069574553264598377324958396464357;
    uint256 constant IC18y = 12674462348999945842150321800214215971341332814537942162386058845890683907468;
    
    uint256 constant IC19x = 21002600520812582973635915523423006332194532507137805498797721241198127743307;
    uint256 constant IC19y = 19631109621260128582217299502507395207162059621035926958332258152903201027011;
    
    uint256 constant IC20x = 21678701252640883480671797684452413481728682503157029285819935623621774684543;
    uint256 constant IC20y = 20581285919493385896380025999903082574603649425897172616806459092148445671886;
    
    uint256 constant IC21x = 14641222149593398472814757744392324349409195100766957781172039573496662064337;
    uint256 constant IC21y = 4033685109204662481645465912748697788083631695389928329132160584442106344353;
    
    uint256 constant IC22x = 9560128060616797182375236703179566304606316836290849295742412098647727378743;
    uint256 constant IC22y = 10892264179213055285648254001539087292722779432816273018892495130453033135761;
    
    uint256 constant IC23x = 7335134125248584205179158324848298907851324527187042616008437890320395968539;
    uint256 constant IC23y = 16432426354138114857833076175489761881174471502827708219413747578430916785411;
    
    uint256 constant IC24x = 21711229032065352889553525545460260972916847169648885456747184013700791657181;
    uint256 constant IC24y = 13081863007484953989355233858860820630165744238820587418902666676547154558995;
    
    uint256 constant IC25x = 17540630810898659095047075593549738749356275980360720422678178639449742229874;
    uint256 constant IC25y = 1739702349156787540578550194129165427910564861546143398047378657950514638729;
    
    uint256 constant IC26x = 8044135518734207835573052879612315840137407314295999067625839083319337628409;
    uint256 constant IC26y = 9415014159148635384422677872343731325355385936976712535925848801384901069245;
    
    uint256 constant IC27x = 5289399421303989506993173079249176692244146875503666652344817692752786765649;
    uint256 constant IC27y = 5970237716807648914668414311487057826335598168373478622176992716902778966534;
    
    uint256 constant IC28x = 21793600769511250312349060361277099835743895140643920502106650208709936628469;
    uint256 constant IC28y = 16540038161883732215976446015092004554740070813684287305910967808956102820153;
    
    uint256 constant IC29x = 8107825211821428692050848564334225245186020707593327423076263465808404738337;
    uint256 constant IC29y = 1027668412755245971151234530225208571596340205021414245440120047097554537102;
    
    uint256 constant IC30x = 999064182237195179599469261798797478774487356522889092489512451231554885171;
    uint256 constant IC30y = 19554565433410504802811682311192044058811174578451512450699889556950077044263;
    
    uint256 constant IC31x = 117491871034317569658191461822660113998847863132109928807077476576364040916;
    uint256 constant IC31y = 4716662330230268239973738434353721606708068737336184492045599228922134587883;
    
    uint256 constant IC32x = 6580636405504151985652766432171909844892723968268892560808062116476781941220;
    uint256 constant IC32y = 9545623131318006793562670447782253110736292516949580040308626451831549026774;
    
    uint256 constant IC33x = 18477545217722294920212031327600314531661625054488576087446472249720101810332;
    uint256 constant IC33y = 19352147006222785143192663161184926573341838845969208097712031670233818141510;
    
    uint256 constant IC34x = 17784458613588350748907755857390389214035805394787622404237679591776016433152;
    uint256 constant IC34y = 3846761073438561441987182368481551739561641557733444248926645802217019124239;
    
    uint256 constant IC35x = 16138133838849231068918171656673560346138307647428504957569590935095432028593;
    uint256 constant IC35y = 4585316301511840891776126752905460471611941310927441146782805589445476641719;
    
    uint256 constant IC36x = 3470568612686281363066460013427316517269394310421400626332370919073516793160;
    uint256 constant IC36y = 9427353715934875991524740820834237597061385232784461320015106955834734071144;
    
    uint256 constant IC37x = 12015686012725694140958737573053004350578364075467720219625528587774927526462;
    uint256 constant IC37y = 5664736046493617597046113388438567907912644158224416750499513991622252949513;
    
    uint256 constant IC38x = 20435744935524983290328301476953901624820599704541632949301840437046562419577;
    uint256 constant IC38y = 5109296181997182447171307008979107285288308091117257399537867945760444348391;
    
    uint256 constant IC39x = 19607900204847527609966492657803538951139120633107033630415287638550017803446;
    uint256 constant IC39y = 8598595213334743996929243172047111787481119240069002719533025948224424693466;
    
    uint256 constant IC40x = 17717990932511396906778596461796078358880657502313236865201952601063642329976;
    uint256 constant IC40y = 10206972138132618071236483524890012835354234252901754596591818783464233740088;
    
    uint256 constant IC41x = 9480334339249772325773543167070450913374745410297542538249742776160346116518;
    uint256 constant IC41y = 17195495811193860008028627087473704594921988530080549572329419187810905174098;
    
    uint256 constant IC42x = 15657806698623176729501770165542110642804746648623868454658386607476150287499;
    uint256 constant IC42y = 13930140987597232169085988302333958099396749202850986590492361384397228050377;
    
    uint256 constant IC43x = 19554103335019864407977345846589981181314147304335220533898839007105780868944;
    uint256 constant IC43y = 11058836138992830208977659280526845220458891780893014240097235277116747595001;
    
    uint256 constant IC44x = 19363601009423602403373009453215975117385123806976818505921130208183418476187;
    uint256 constant IC44y = 9022490347462062263723593014194708243957984661958563643430489769697326645223;
    
    uint256 constant IC45x = 15067991963943208199106939575479165090903166976805917330528546970162386242591;
    uint256 constant IC45y = 6486467959896482926702361378448421185995984000289616212350099501147461329080;
    
    uint256 constant IC46x = 7185009392004033368919029452709425313651998297897034703627792160113915847528;
    uint256 constant IC46y = 14032438201959863444008008532534082470565578875302070246239409453901471239459;
    
    uint256 constant IC47x = 5696407851274091028130733662906775214128218141248855833987324665173388587567;
    uint256 constant IC47y = 12109462740993315430897717482544038695861466137932640529050229002729427741796;
    
    uint256 constant IC48x = 5723240048141022604398192974884878240757258767502651513549241673828632566892;
    uint256 constant IC48y = 9355894925566818623777079611879958426131816858161233228218922949321403597055;
    
    uint256 constant IC49x = 221521872302102530154029805702175186523061052017921483589625496900654144206;
    uint256 constant IC49y = 20560152768054819396476550080875014765381580660982773896318566381453953394935;
    
    uint256 constant IC50x = 14060804017477490349165271641877240143919384298119496187453378053678594550223;
    uint256 constant IC50y = 63528629700789450203708424000951666721530729685689424640755145349607829097;
    
    uint256 constant IC51x = 11780923602953156521396169148304215905589982479750254152347082270763212464134;
    uint256 constant IC51y = 20025911240730692091167010698691878377992831729588090065175815089290475650458;
    
    uint256 constant IC52x = 241211031822693760010842408879434928798686490013496817542969340823867291275;
    uint256 constant IC52y = 16926869533420301398532693816478843362280051170456009265269015985503734919749;
    
    uint256 constant IC53x = 19260640662971718289553188347872670463256363627908660909209092594704896771506;
    uint256 constant IC53y = 4423849772393632599848301003450680868358523783491001042264872970866641950864;
    
    uint256 constant IC54x = 6222244369051324109483338223962129460401550283897698454284693085064796388977;
    uint256 constant IC54y = 2720757903163014449724453140961453596052420372598046330917951718362873762565;
    
    uint256 constant IC55x = 17867464546527585162620803502456647410089155747718317317334914948638699962639;
    uint256 constant IC55y = 10172464589059420186336048669579123143036712542741166613670006124222258810959;
    
    uint256 constant IC56x = 16722471434556079579457223319365139170051351053617462019106338494561595443461;
    uint256 constant IC56y = 14478000852509654472231421494822786704923378896212246423044785099993926224506;
    
    uint256 constant IC57x = 17312075566315081073205677147682860480897167729822592127513772063196791013612;
    uint256 constant IC57y = 10355783836390867534202690910957866990138192890066672630770841424414237861800;
    
    uint256 constant IC58x = 19312629637100238091936617525364204661011803984919085126704267955060158105643;
    uint256 constant IC58y = 21450640025269790053500283678730795364311772540432873146735345860611308206810;
    
    uint256 constant IC59x = 16707625364245738864594790137180773274267700735914856852997691553342082428076;
    uint256 constant IC59y = 4684942129523828933208794264263170036580273181054320456098799336158607297553;
    
    uint256 constant IC60x = 13565611801734272144635125068276938038075754572466850908329430613397967501296;
    uint256 constant IC60y = 20977408710697791844154386516856741766613492568384964054971582236205095965213;
    
    uint256 constant IC61x = 12912762324630269987235660386172113833335066878825203172614204602139695248920;
    uint256 constant IC61y = 495611073748334014751124171053277196132580442674402805354812085407301996789;
    
    uint256 constant IC62x = 12419144980851313640607180144861703935233438726821622982652416016043025046016;
    uint256 constant IC62y = 20080991322463584274904527829595181308987697324818313575327428438133689883870;
    
 
    // Memory data
    uint16 constant pVk = 0;
    uint16 constant pPairing = 128;

    uint16 constant pLastMem = 896;

    function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[62] calldata _pubSignals) public view returns (bool) {
        assembly {
            function checkField(v) {
                if iszero(lt(v, q)) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }
            
            // G1 function to multiply a G1 value(x,y) to value in an address
            function g1_mulAccC(pR, x, y, s) {
                let success
                let mIn := mload(0x40)
                mstore(mIn, x)
                mstore(add(mIn, 32), y)
                mstore(add(mIn, 64), s)

                success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }

                mstore(add(mIn, 64), mload(pR))
                mstore(add(mIn, 96), mload(add(pR, 32)))

                success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }

            function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
                let _pPairing := add(pMem, pPairing)
                let _pVk := add(pMem, pVk)

                mstore(_pVk, IC0x)
                mstore(add(_pVk, 32), IC0y)

                // Compute the linear combination vk_x
                
                g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
                
                g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
                
                g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
                
                g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
                
                g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
                
                g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))
                
                g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))
                
                g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))
                
                g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))
                
                g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288)))
                
                g1_mulAccC(_pVk, IC11x, IC11y, calldataload(add(pubSignals, 320)))
                
                g1_mulAccC(_pVk, IC12x, IC12y, calldataload(add(pubSignals, 352)))
                
                g1_mulAccC(_pVk, IC13x, IC13y, calldataload(add(pubSignals, 384)))
                
                g1_mulAccC(_pVk, IC14x, IC14y, calldataload(add(pubSignals, 416)))
                
                g1_mulAccC(_pVk, IC15x, IC15y, calldataload(add(pubSignals, 448)))
                
                g1_mulAccC(_pVk, IC16x, IC16y, calldataload(add(pubSignals, 480)))
                
                g1_mulAccC(_pVk, IC17x, IC17y, calldataload(add(pubSignals, 512)))
                
                g1_mulAccC(_pVk, IC18x, IC18y, calldataload(add(pubSignals, 544)))
                
                g1_mulAccC(_pVk, IC19x, IC19y, calldataload(add(pubSignals, 576)))
                
                g1_mulAccC(_pVk, IC20x, IC20y, calldataload(add(pubSignals, 608)))
                
                g1_mulAccC(_pVk, IC21x, IC21y, calldataload(add(pubSignals, 640)))
                
                g1_mulAccC(_pVk, IC22x, IC22y, calldataload(add(pubSignals, 672)))
                
                g1_mulAccC(_pVk, IC23x, IC23y, calldataload(add(pubSignals, 704)))
                
                g1_mulAccC(_pVk, IC24x, IC24y, calldataload(add(pubSignals, 736)))
                
                g1_mulAccC(_pVk, IC25x, IC25y, calldataload(add(pubSignals, 768)))
                
                g1_mulAccC(_pVk, IC26x, IC26y, calldataload(add(pubSignals, 800)))
                
                g1_mulAccC(_pVk, IC27x, IC27y, calldataload(add(pubSignals, 832)))
                
                g1_mulAccC(_pVk, IC28x, IC28y, calldataload(add(pubSignals, 864)))
                
                g1_mulAccC(_pVk, IC29x, IC29y, calldataload(add(pubSignals, 896)))
                
                g1_mulAccC(_pVk, IC30x, IC30y, calldataload(add(pubSignals, 928)))
                
                g1_mulAccC(_pVk, IC31x, IC31y, calldataload(add(pubSignals, 960)))
                
                g1_mulAccC(_pVk, IC32x, IC32y, calldataload(add(pubSignals, 992)))
                
                g1_mulAccC(_pVk, IC33x, IC33y, calldataload(add(pubSignals, 1024)))
                
                g1_mulAccC(_pVk, IC34x, IC34y, calldataload(add(pubSignals, 1056)))
                
                g1_mulAccC(_pVk, IC35x, IC35y, calldataload(add(pubSignals, 1088)))
                
                g1_mulAccC(_pVk, IC36x, IC36y, calldataload(add(pubSignals, 1120)))
                
                g1_mulAccC(_pVk, IC37x, IC37y, calldataload(add(pubSignals, 1152)))
                
                g1_mulAccC(_pVk, IC38x, IC38y, calldataload(add(pubSignals, 1184)))
                
                g1_mulAccC(_pVk, IC39x, IC39y, calldataload(add(pubSignals, 1216)))
                
                g1_mulAccC(_pVk, IC40x, IC40y, calldataload(add(pubSignals, 1248)))
                
                g1_mulAccC(_pVk, IC41x, IC41y, calldataload(add(pubSignals, 1280)))
                
                g1_mulAccC(_pVk, IC42x, IC42y, calldataload(add(pubSignals, 1312)))
                
                g1_mulAccC(_pVk, IC43x, IC43y, calldataload(add(pubSignals, 1344)))
                
                g1_mulAccC(_pVk, IC44x, IC44y, calldataload(add(pubSignals, 1376)))
                
                g1_mulAccC(_pVk, IC45x, IC45y, calldataload(add(pubSignals, 1408)))
                
                g1_mulAccC(_pVk, IC46x, IC46y, calldataload(add(pubSignals, 1440)))
                
                g1_mulAccC(_pVk, IC47x, IC47y, calldataload(add(pubSignals, 1472)))
                
                g1_mulAccC(_pVk, IC48x, IC48y, calldataload(add(pubSignals, 1504)))
                
                g1_mulAccC(_pVk, IC49x, IC49y, calldataload(add(pubSignals, 1536)))
                
                g1_mulAccC(_pVk, IC50x, IC50y, calldataload(add(pubSignals, 1568)))
                
                g1_mulAccC(_pVk, IC51x, IC51y, calldataload(add(pubSignals, 1600)))
                
                g1_mulAccC(_pVk, IC52x, IC52y, calldataload(add(pubSignals, 1632)))
                
                g1_mulAccC(_pVk, IC53x, IC53y, calldataload(add(pubSignals, 1664)))
                
                g1_mulAccC(_pVk, IC54x, IC54y, calldataload(add(pubSignals, 1696)))
                
                g1_mulAccC(_pVk, IC55x, IC55y, calldataload(add(pubSignals, 1728)))
                
                g1_mulAccC(_pVk, IC56x, IC56y, calldataload(add(pubSignals, 1760)))
                
                g1_mulAccC(_pVk, IC57x, IC57y, calldataload(add(pubSignals, 1792)))
                
                g1_mulAccC(_pVk, IC58x, IC58y, calldataload(add(pubSignals, 1824)))
                
                g1_mulAccC(_pVk, IC59x, IC59y, calldataload(add(pubSignals, 1856)))
                
                g1_mulAccC(_pVk, IC60x, IC60y, calldataload(add(pubSignals, 1888)))
                
                g1_mulAccC(_pVk, IC61x, IC61y, calldataload(add(pubSignals, 1920)))
                
                g1_mulAccC(_pVk, IC62x, IC62y, calldataload(add(pubSignals, 1952)))
                

                // -A
                mstore(_pPairing, calldataload(pA))
                mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))

                // B
                mstore(add(_pPairing, 64), calldataload(pB))
                mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
                mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
                mstore(add(_pPairing, 160), calldataload(add(pB, 96)))

                // alpha1
                mstore(add(_pPairing, 192), alphax)
                mstore(add(_pPairing, 224), alphay)

                // beta2
                mstore(add(_pPairing, 256), betax1)
                mstore(add(_pPairing, 288), betax2)
                mstore(add(_pPairing, 320), betay1)
                mstore(add(_pPairing, 352), betay2)

                // vk_x
                mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
                mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))


                // gamma2
                mstore(add(_pPairing, 448), gammax1)
                mstore(add(_pPairing, 480), gammax2)
                mstore(add(_pPairing, 512), gammay1)
                mstore(add(_pPairing, 544), gammay2)

                // C
                mstore(add(_pPairing, 576), calldataload(pC))
                mstore(add(_pPairing, 608), calldataload(add(pC, 32)))

                // delta2
                mstore(add(_pPairing, 640), deltax1)
                mstore(add(_pPairing, 672), deltax2)
                mstore(add(_pPairing, 704), deltay1)
                mstore(add(_pPairing, 736), deltay2)


                let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)

                isOk := and(success, mload(_pPairing))
            }

            let pMem := mload(0x40)
            mstore(0x40, add(pMem, pLastMem))

            // Validate that all evaluations ∈ F
            
            checkField(calldataload(add(_pubSignals, 0)))
            
            checkField(calldataload(add(_pubSignals, 32)))
            
            checkField(calldataload(add(_pubSignals, 64)))
            
            checkField(calldataload(add(_pubSignals, 96)))
            
            checkField(calldataload(add(_pubSignals, 128)))
            
            checkField(calldataload(add(_pubSignals, 160)))
            
            checkField(calldataload(add(_pubSignals, 192)))
            
            checkField(calldataload(add(_pubSignals, 224)))
            
            checkField(calldataload(add(_pubSignals, 256)))
            
            checkField(calldataload(add(_pubSignals, 288)))
            
            checkField(calldataload(add(_pubSignals, 320)))
            
            checkField(calldataload(add(_pubSignals, 352)))
            
            checkField(calldataload(add(_pubSignals, 384)))
            
            checkField(calldataload(add(_pubSignals, 416)))
            
            checkField(calldataload(add(_pubSignals, 448)))
            
            checkField(calldataload(add(_pubSignals, 480)))
            
            checkField(calldataload(add(_pubSignals, 512)))
            
            checkField(calldataload(add(_pubSignals, 544)))
            
            checkField(calldataload(add(_pubSignals, 576)))
            
            checkField(calldataload(add(_pubSignals, 608)))
            
            checkField(calldataload(add(_pubSignals, 640)))
            
            checkField(calldataload(add(_pubSignals, 672)))
            
            checkField(calldataload(add(_pubSignals, 704)))
            
            checkField(calldataload(add(_pubSignals, 736)))
            
            checkField(calldataload(add(_pubSignals, 768)))
            
            checkField(calldataload(add(_pubSignals, 800)))
            
            checkField(calldataload(add(_pubSignals, 832)))
            
            checkField(calldataload(add(_pubSignals, 864)))
            
            checkField(calldataload(add(_pubSignals, 896)))
            
            checkField(calldataload(add(_pubSignals, 928)))
            
            checkField(calldataload(add(_pubSignals, 960)))
            
            checkField(calldataload(add(_pubSignals, 992)))
            
            checkField(calldataload(add(_pubSignals, 1024)))
            
            checkField(calldataload(add(_pubSignals, 1056)))
            
            checkField(calldataload(add(_pubSignals, 1088)))
            
            checkField(calldataload(add(_pubSignals, 1120)))
            
            checkField(calldataload(add(_pubSignals, 1152)))
            
            checkField(calldataload(add(_pubSignals, 1184)))
            
            checkField(calldataload(add(_pubSignals, 1216)))
            
            checkField(calldataload(add(_pubSignals, 1248)))
            
            checkField(calldataload(add(_pubSignals, 1280)))
            
            checkField(calldataload(add(_pubSignals, 1312)))
            
            checkField(calldataload(add(_pubSignals, 1344)))
            
            checkField(calldataload(add(_pubSignals, 1376)))
            
            checkField(calldataload(add(_pubSignals, 1408)))
            
            checkField(calldataload(add(_pubSignals, 1440)))
            
            checkField(calldataload(add(_pubSignals, 1472)))
            
            checkField(calldataload(add(_pubSignals, 1504)))
            
            checkField(calldataload(add(_pubSignals, 1536)))
            
            checkField(calldataload(add(_pubSignals, 1568)))
            
            checkField(calldataload(add(_pubSignals, 1600)))
            
            checkField(calldataload(add(_pubSignals, 1632)))
            
            checkField(calldataload(add(_pubSignals, 1664)))
            
            checkField(calldataload(add(_pubSignals, 1696)))
            
            checkField(calldataload(add(_pubSignals, 1728)))
            
            checkField(calldataload(add(_pubSignals, 1760)))
            
            checkField(calldataload(add(_pubSignals, 1792)))
            
            checkField(calldataload(add(_pubSignals, 1824)))
            
            checkField(calldataload(add(_pubSignals, 1856)))
            
            checkField(calldataload(add(_pubSignals, 1888)))
            
            checkField(calldataload(add(_pubSignals, 1920)))
            
            checkField(calldataload(add(_pubSignals, 1952)))
            
            checkField(calldataload(add(_pubSignals, 1984)))
            

            // Validate all evaluations
            let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)

            mstore(0, isValid)
             return(0, 0x20)
         }
     }
 }
合同源代码
文件 13 的 26:Game_6_20Verifier.sol
// SPDX-License-Identifier: GPL-3.0
/*
    Copyright 2021 0KIMS association.

    This file is generated with [snarkJS](https://github.com/iden3/snarkjs).

    snarkJS is a free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    snarkJS is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.7.0 <0.9.0;

contract Groth16Verifier {
    // Scalar field size
    uint256 constant r    = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
    // Base field size
    uint256 constant q   = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

    // Verification Key data
    uint256 constant alphax  = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
    uint256 constant alphay  = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
    uint256 constant betax1  = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
    uint256 constant betax2  = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
    uint256 constant betay1  = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
    uint256 constant betay2  = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
    uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
    uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
    uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
    uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
    uint256 constant deltax1 = 10450303609955961691478609618228788013811799899689748865048650848749409222461;
    uint256 constant deltax2 = 17847723700442526468541122171417718435039345641533901750103694387718275165541;
    uint256 constant deltay1 = 8327712960434480175753246176425803549943549358869509101155743365256496493283;
    uint256 constant deltay2 = 1468377889852699208407458932402153599547308472633975301596816490990779724361;

    
    uint256 constant IC0x = 18323742245068371370586577899373640283866705084611449250279313824167348635459;
    uint256 constant IC0y = 15423959839575778940915849759887766963783910574116773436217821502024951856375;
    
    uint256 constant IC1x = 13365809233956280090379183787333602603618910149039521574727252052801514576035;
    uint256 constant IC1y = 6466042609072475177008202148974592311883118892495014196417047906522104953353;
    
    uint256 constant IC2x = 2868425814125744137746187903027450452202631739573918015264451858515304805858;
    uint256 constant IC2y = 9331029368753549816645082671170705263462163289590312693161885228580078244923;
    
    uint256 constant IC3x = 15850727056361095098079195985922938418669967613573990548873282668736411024970;
    uint256 constant IC3y = 1063059487587696409694148583689982647496167283211859556959666928444872144372;
    
    uint256 constant IC4x = 6317943063049487518668509213820070832320195082000409646549810972251019370392;
    uint256 constant IC4y = 21265471452165656457153445492201244405080580520781861193159418619919010604616;
    
    uint256 constant IC5x = 6329840929765456259738312976910222973769113300705129492227048383057475283778;
    uint256 constant IC5y = 21797104217172103588243944589053255159689030380457445747052816575133572627441;
    
    uint256 constant IC6x = 17595371035982775775846065578859566958089532809084842980521183955062964369361;
    uint256 constant IC6y = 18641808861950232675710416667362298048875672347974120516727161798108965215130;
    
    uint256 constant IC7x = 10911747741892052562987028092282233655168613892499407582713774582929149936385;
    uint256 constant IC7y = 1838020106712831665323899703788123837251146437520380947298841881229070860208;
    
    uint256 constant IC8x = 14407795891286210453267729672201838187643838384280456562548413047976014073731;
    uint256 constant IC8y = 12561724650744308527908852127233516323914472488140584359967709639769290520202;
    
    uint256 constant IC9x = 12285202477758205531041710030198487688353698172487034937849469094696263840838;
    uint256 constant IC9y = 11301457847822119098970704674382490155713380254674950640480182817263616399161;
    
    uint256 constant IC10x = 6908288674519481250004910526684388747782436582767207796100583644927467815116;
    uint256 constant IC10y = 3760868040516464211334733261203619813721069472776763773777744054769969492212;
    
    uint256 constant IC11x = 8928481137640880118464067306664798451422375079098102113781011875633364843438;
    uint256 constant IC11y = 15172122693664856743327541636146353700284165640596119008417768943540271341733;
    
    uint256 constant IC12x = 698054629628362387784937753063834639128775291290947758143236537691873051084;
    uint256 constant IC12y = 12679659502491227796552610503910524793183836791061708609326308605012908621841;
    
    uint256 constant IC13x = 20197850889696742251789926359481057983718029018999556243378123634127732013612;
    uint256 constant IC13y = 19360999563750204510323708977459718341649263142480567152722051295174575975010;
    
    uint256 constant IC14x = 9686717544512462483135841295579883250414565630605804300498532497475805525236;
    uint256 constant IC14y = 13377321121834898599761456259115259309181947273481377151154669603682259914180;
    
    uint256 constant IC15x = 8845312816048877400198538632977397457987546285749902219021304589162272845480;
    uint256 constant IC15y = 4826748790399038526545081273532193258367662354250200135071850494910885152355;
    
    uint256 constant IC16x = 2477645743327943794325614840083125736292047288276801945581887862613123178797;
    uint256 constant IC16y = 693053837671564257184109311794663473489633848582177364432471873339432639728;
    
    uint256 constant IC17x = 6304472876030347098414522667792717119213497490002276920123432768499475687245;
    uint256 constant IC17y = 21883266715309969849009155439694069837353190729089434948424071517176167251904;
    
    uint256 constant IC18x = 11072831307079579665176437414512363547694844161330268483207737113541606018520;
    uint256 constant IC18y = 17979386695007600294687118338899552521439927018278142012288096036513743118066;
    
    uint256 constant IC19x = 17669828484893212661210558958889386106295047713719459030339020775234773503555;
    uint256 constant IC19y = 5785838849011591227052334333295469651410521208892403814452380083004810960202;
    
    uint256 constant IC20x = 21237732250759557663695441872784196863507956704403768131193337991262291582129;
    uint256 constant IC20y = 1909539586250553833495230169438553719273957732479520944331376435474421626729;
    
    uint256 constant IC21x = 13431377914814733136029064574339813567941844296323696031100354080719994211234;
    uint256 constant IC21y = 13554541067845458534313419161069305513067444096880603491176887633472952793540;
    
    uint256 constant IC22x = 9438334019143806930356353226173276161766525024221233626861993368932655837689;
    uint256 constant IC22y = 775092971074278403266502132655568470907974221793308103575599938625966945492;
    
    uint256 constant IC23x = 1998049064824991523678411278603536371615891143052958498265715189839773807137;
    uint256 constant IC23y = 2409805339749331175902371126352614532216400684618957048890844381944323955782;
    
    uint256 constant IC24x = 5473874396197361671799347408590739603948479572514073603027369844828117191575;
    uint256 constant IC24y = 2396577272610175540158618635318890227799514280260008711968477115664289861848;
    
    uint256 constant IC25x = 907538969576669328590462295081574128837486483782756947329026537448571351598;
    uint256 constant IC25y = 8252897046702631987832351064600988278017245679835148088661877388560976204944;
    
    uint256 constant IC26x = 13722261010752823779229647646402153612192757620558112000526364263375970478662;
    uint256 constant IC26y = 10178231852784437939201961944994377121562049382911048613844073226474054168335;
    
    uint256 constant IC27x = 12496872582094339381105159042614705875896852222463041727462767622141215067767;
    uint256 constant IC27y = 15615718657874728918614711755647643874207186711434522125537046061200726916026;
    
    uint256 constant IC28x = 20385979485499074623235127251374645025839852384962044363928516725063887461254;
    uint256 constant IC28y = 18199350083301680735789935620114961125296583708706081694810666719149697430290;
    
    uint256 constant IC29x = 7279098722006299320072344138595629472495804601369369248980385459062672982100;
    uint256 constant IC29y = 1653532227866729324598303251183264038427570914143744036202369846942341870809;
    
    uint256 constant IC30x = 4088462530970943490485064577649109267846501969708463751542559834670133245188;
    uint256 constant IC30y = 51221214556529444328186406074705866265955787177781918981313166976946564453;
    
    uint256 constant IC31x = 11475304520693190632343320185669239466355937406676731876039746365719455721904;
    uint256 constant IC31y = 4179466775874821372001573721978876411450395528080657610672920305524169164233;
    
    uint256 constant IC32x = 21374611248910261060156459017400890729969492807517505462596702289096321706383;
    uint256 constant IC32y = 769024473603785865139218540623641507594418159515038552269169139049299704332;
    
    uint256 constant IC33x = 16529870003602294491957164431820549685691777874530284886671946343863811637250;
    uint256 constant IC33y = 13334011906265202159384547904292087102198483147682984975632874689498480731712;
    
    uint256 constant IC34x = 3701356911242115956151427037124640766613704105843831426885939543474998078751;
    uint256 constant IC34y = 19197864967421553361504404904420847332788962991394270957337758454294164319223;
    
    uint256 constant IC35x = 4201801687687828431623596147201377931466439649375476164336457696191401819877;
    uint256 constant IC35y = 5921950173495951557251210081362877258057098524891974324350811210406249063712;
    
    uint256 constant IC36x = 7701377940242009220319669339328775633433341320508550111518850167528798398981;
    uint256 constant IC36y = 15132373047830373625368174752799803099349809490407178978060953152330753299697;
    
    uint256 constant IC37x = 19465960017935624383883384033866086340960014429311258456920821077071235079488;
    uint256 constant IC37y = 212340818740416618097769293890266901743545178610490835369033816751023339379;
    
    uint256 constant IC38x = 17449383664554786502913128040075641790680423161022408179814021453998901078913;
    uint256 constant IC38y = 17669630550798467689348068001717218151423015297033786070645674420402006358578;
    
    uint256 constant IC39x = 8559493823810101532440380811005184292528564573690171277723871773539888428099;
    uint256 constant IC39y = 15449864985453589870936120986920079387327193786965010346528773613129441347373;
    
    uint256 constant IC40x = 10159981855891157027746883600736923180061105619062675340167901599452816983101;
    uint256 constant IC40y = 14454346714257355770873169562357344607800720499579364634216403729501244570456;
    
    uint256 constant IC41x = 17813820252080522423340530837981972749472601699774991221106146170361793553920;
    uint256 constant IC41y = 3899625385740535994990017284819547761773417257735630290222765936481628192149;
    
    uint256 constant IC42x = 4643794074144313876222761919615366593770795620225605843578937870884434426365;
    uint256 constant IC42y = 17169827166471886141150685794968546434734850102167410464302115065228441557586;
    
    uint256 constant IC43x = 10588753794072050242363476573435522081379155052962703677628672471033342263227;
    uint256 constant IC43y = 4763959225284489193942714551804879687713244456097917862823447561496233840634;
    
    uint256 constant IC44x = 5078948671668710559960940358270142557049643185660100278895646305569755161702;
    uint256 constant IC44y = 20775356912511082215338836437270628660687005182114841154656164606900369893908;
    
    uint256 constant IC45x = 17031683009872994670908931729877936418766428424665205909384227038904698104946;
    uint256 constant IC45y = 4336742024335216202237180944356256901216872184910624621863010456313932229267;
    
    uint256 constant IC46x = 17462409834717918126509798305820627602300876267869144128002291816592693912669;
    uint256 constant IC46y = 6698435624348764107395914868566797622392946364781799329191793082178425629313;
    
    uint256 constant IC47x = 18165274469838714652355972358210969162655563398506162735824499589849486689133;
    uint256 constant IC47y = 18828871759593472025285150390378428868158273953381729738918403254623176242896;
    
    uint256 constant IC48x = 11828118290215114281558232541608608457034249251783887943446226655425691609937;
    uint256 constant IC48y = 19437388759887461281019426206002235307276717219264313911219910246300271338824;
    
    uint256 constant IC49x = 14381249146421950568725870026682791937799391288625917423681263135333704676692;
    uint256 constant IC49y = 15153484116125521466329198658010511686254002836462381456543653524150718597692;
    
    uint256 constant IC50x = 19053683402912959882086356516972105348851391981982581867627681509913086008619;
    uint256 constant IC50y = 15348424467466649968780256566760260834085915139502373761204891555035801477925;
    
    uint256 constant IC51x = 6124206069229701309886587779264176491864663483894859105880655289214151874071;
    uint256 constant IC51y = 20675679187197483327374236977954823386954672062541841713347559305347181652364;
    
    uint256 constant IC52x = 3057890517229756353525881532233901877074632547831467109529854203502463733780;
    uint256 constant IC52y = 4671916621344361722290801228384288984474721438668598211918808372730990310672;
    
    uint256 constant IC53x = 19932053628663439399378805154443421680604911410109335708786586384717936557429;
    uint256 constant IC53y = 5231257202631173637297953409825710077439403461553172801170103183159255301242;
    
    uint256 constant IC54x = 8988013090399445578073491230546343284332741164589090356441567483942440768630;
    uint256 constant IC54y = 1717252056223538323125421964561949689805980357303579710920658168540142829020;
    
    uint256 constant IC55x = 15148800287028455254078869724076931043376443349876142139042637522377415677596;
    uint256 constant IC55y = 5227091764381425424991870779266022989667834943787276589000338938897230103338;
    
    uint256 constant IC56x = 7621484358298018082914689984529842540993643376009105427455731653950803716331;
    uint256 constant IC56y = 18811944998236793438483352881748594703355164619107358712014568287890937291426;
    
    uint256 constant IC57x = 13633644766083676508108581413194054191480254211818462335175726489697327623728;
    uint256 constant IC57y = 8500303180918090135813718057596362099350859851849530167935442372920771150861;
    
    uint256 constant IC58x = 5185358035611617318706752612329927865601266928555520204223728284668922180927;
    uint256 constant IC58y = 9390868863742146813473947710642725236423010545292737573761839840779159932301;
    
    uint256 constant IC59x = 7850323306319221042974853809036025440589050704659811459107278790953434075473;
    uint256 constant IC59y = 15548494856329273697640314124289472184333141368066826735563820579537809155770;
    
    uint256 constant IC60x = 12251748079483958596152409097584083323351358383195268154584600318981116771108;
    uint256 constant IC60y = 12770836177518219984427496689770688139550364298287120143136374527817718134868;
    
    uint256 constant IC61x = 6901456004440888073719697952734102580913590506221331756953049987228203097704;
    uint256 constant IC61y = 21347696396284721776687831850978587818736323902496780387745636097049983841005;
    
    uint256 constant IC62x = 14313114525328527522163053051512179326311115173561660303164775209450193224412;
    uint256 constant IC62y = 15373875328110518831887024099257365954818247439490992088248010383667276305916;
    
    uint256 constant IC63x = 17999472399437867162127997350071377618272028534086459352371159963709158617722;
    uint256 constant IC63y = 20823833589243491230620569237318595360304625430392676041374856670413539224926;
    
    uint256 constant IC64x = 865317336933072528587201922658570080299064964561524559291067670675553847344;
    uint256 constant IC64y = 7844382235524498222731841170651156965824233520113776804251239966876335464836;
    
    uint256 constant IC65x = 4330521753188717158011193584377668649531037036639579658365530941601002874577;
    uint256 constant IC65y = 13137640129624948488842711123011862678804574787833617497821578380795693705773;
    
    uint256 constant IC66x = 16694477633531088088953667918569664676992680041046031175336731449806873841043;
    uint256 constant IC66y = 8174925510233107103459991417864894376893542358288614323316892797046204093482;
    
    uint256 constant IC67x = 6775832075121198196701738541686882976128767875245459273606406316736251288302;
    uint256 constant IC67y = 8314595955639824303325369578992103549339801717212401396124891081739909974560;
    
    uint256 constant IC68x = 21326572402890278639055511700210179470212686553835543621670466490995720391395;
    uint256 constant IC68y = 7103284949309660681220501802370278224210592784471862695036767603706343656279;
    
    uint256 constant IC69x = 1709547489890037325836248654018048132709561539402573222948492578784215854436;
    uint256 constant IC69y = 20795742300376857527827826577713794068740166076380246140034740548796609870537;
    
    uint256 constant IC70x = 11540401202529964850059245598153618374182893661404738344491901370408941636091;
    uint256 constant IC70y = 1023930864720576017522315963819929729976391063381766529523063774241429590902;
    
    uint256 constant IC71x = 19863506889290961401770841915783749637320907807902443970018422037295640862604;
    uint256 constant IC71y = 16714576573856942817138781347480387838912370986551776960952634736856862815263;
    
    uint256 constant IC72x = 1752739125693378945378384454880729150484765836622236889929490848039805920925;
    uint256 constant IC72y = 16458501886378377221561072725324792346091404293547145319831160309613028835130;
    
 
    // Memory data
    uint16 constant pVk = 0;
    uint16 constant pPairing = 128;

    uint16 constant pLastMem = 896;

    function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[72] calldata _pubSignals) public view returns (bool) {
        assembly {
            function checkField(v) {
                if iszero(lt(v, q)) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }
            
            // G1 function to multiply a G1 value(x,y) to value in an address
            function g1_mulAccC(pR, x, y, s) {
                let success
                let mIn := mload(0x40)
                mstore(mIn, x)
                mstore(add(mIn, 32), y)
                mstore(add(mIn, 64), s)

                success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }

                mstore(add(mIn, 64), mload(pR))
                mstore(add(mIn, 96), mload(add(pR, 32)))

                success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)

                if iszero(success) {
                    mstore(0, 0)
                    return(0, 0x20)
                }
            }

            function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
                let _pPairing := add(pMem, pPairing)
                let _pVk := add(pMem, pVk)

                mstore(_pVk, IC0x)
                mstore(add(_pVk, 32), IC0y)

                // Compute the linear combination vk_x
                
                g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
                
                g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
                
                g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
                
                g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
                
                g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
                
                g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))
                
                g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))
                
                g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))
                
                g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))
                
                g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288)))
                
                g1_mulAccC(_pVk, IC11x, IC11y, calldataload(add(pubSignals, 320)))
                
                g1_mulAccC(_pVk, IC12x, IC12y, calldataload(add(pubSignals, 352)))
                
                g1_mulAccC(_pVk, IC13x, IC13y, calldataload(add(pubSignals, 384)))
                
                g1_mulAccC(_pVk, IC14x, IC14y, calldataload(add(pubSignals, 416)))
                
                g1_mulAccC(_pVk, IC15x, IC15y, calldataload(add(pubSignals, 448)))
                
                g1_mulAccC(_pVk, IC16x, IC16y, calldataload(add(pubSignals, 480)))
                
                g1_mulAccC(_pVk, IC17x, IC17y, calldataload(add(pubSignals, 512)))
                
                g1_mulAccC(_pVk, IC18x, IC18y, calldataload(add(pubSignals, 544)))
                
                g1_mulAccC(_pVk, IC19x, IC19y, calldataload(add(pubSignals, 576)))
                
                g1_mulAccC(_pVk, IC20x, IC20y, calldataload(add(pubSignals, 608)))
                
                g1_mulAccC(_pVk, IC21x, IC21y, calldataload(add(pubSignals, 640)))
                
                g1_mulAccC(_pVk, IC22x, IC22y, calldataload(add(pubSignals, 672)))
                
                g1_mulAccC(_pVk, IC23x, IC23y, calldataload(add(pubSignals, 704)))
                
                g1_mulAccC(_pVk, IC24x, IC24y, calldataload(add(pubSignals, 736)))
                
                g1_mulAccC(_pVk, IC25x, IC25y, calldataload(add(pubSignals, 768)))
                
                g1_mulAccC(_pVk, IC26x, IC26y, calldataload(add(pubSignals, 800)))
                
                g1_mulAccC(_pVk, IC27x, IC27y, calldataload(add(pubSignals, 832)))
                
                g1_mulAccC(_pVk, IC28x, IC28y, calldataload(add(pubSignals, 864)))
                
                g1_mulAccC(_pVk, IC29x, IC29y, calldataload(add(pubSignals, 896)))
                
                g1_mulAccC(_pVk, IC30x, IC30y, calldataload(add(pubSignals, 928)))
                
                g1_mulAccC(_pVk, IC31x, IC31y, calldataload(add(pubSignals, 960)))
                
                g1_mulAccC(_pVk, IC32x, IC32y, calldataload(add(pubSignals, 992)))
                
                g1_mulAccC(_pVk, IC33x, IC33y, calldataload(add(pubSignals, 1024)))
                
                g1_mulAccC(_pVk, IC34x, IC34y, calldataload(add(pubSignals, 1056)))
                
                g1_mulAccC(_pVk, IC35x, IC35y, calldataload(add(pubSignals, 1088)))
                
                g1_mulAccC(_pVk, IC36x, IC36y, calldataload(add(pubSignals, 1120)))
                
                g1_mulAccC(_pVk, IC37x, IC37y, calldataload(add(pubSignals, 1152)))
                
                g1_mulAccC(_pVk, IC38x, IC38y, calldataload(add(pubSignals, 1184)))
                
                g1_mulAccC(_pVk, IC39x, IC39y, calldataload(add(pubSignals, 1216)))
                
                g1_mulAccC(_pVk, IC40x, IC40y, calldataload(add(pubSignals, 1248)))
                
                g1_mulAccC(_pVk, IC41x, IC41y, calldataload(add(pubSignals, 1280)))
                
                g1_mulAccC(_pVk, IC42x, IC42y, calldataload(add(pubSignals, 1312)))
                
                g1_mulAccC(_pVk, IC43x, IC43y, calldataload(add(pubSignals, 1344)))
                
                g1_mulAccC(_pVk, IC44x, IC44y, calldataload(add(pubSignals, 1376)))
                
                g1_mulAccC(_pVk, IC45x, IC45y, calldataload(add(pubSignals, 1408)))
                
                g1_mulAccC(_pVk, IC46x, IC46y, calldataload(add(pubSignals, 1440)))
                
                g1_mulAccC(_pVk, IC47x, IC47y, calldataload(add(pubSignals, 1472)))
                
                g1_mulAccC(_pVk, IC48x, IC48y, calldataload(add(pubSignals, 1504)))
                
                g1_mulAccC(_pVk, IC49x, IC49y, calldataload(add(pubSignals, 1536)))
                
                g1_mulAccC(_pVk, IC50x, IC50y, calldataload(add(pubSignals, 1568)))
                
                g1_mulAccC(_pVk, IC51x, IC51y, calldataload(add(pubSignals, 1600)))
                
                g1_mulAccC(_pVk, IC52x, IC52y, calldataload(add(pubSignals, 1632)))
                
                g1_mulAccC(_pVk, IC53x, IC53y, calldataload(add(pubSignals, 1664)))
                
                g1_mulAccC(_pVk, IC54x, IC54y, calldataload(add(pubSignals, 1696)))
                
                g1_mulAccC(_pVk, IC55x, IC55y, calldataload(add(pubSignals, 1728)))
                
                g1_mulAccC(_pVk, IC56x, IC56y, calldataload(add(pubSignals, 1760)))
                
                g1_mulAccC(_pVk, IC57x, IC57y, calldataload(add(pubSignals, 1792)))
                
                g1_mulAccC(_pVk, IC58x, IC58y, calldataload(add(pubSignals, 1824)))
                
                g1_mulAccC(_pVk, IC59x, IC59y, calldataload(add(pubSignals, 1856)))
                
                g1_mulAccC(_pVk, IC60x, IC60y, calldataload(add(pubSignals, 1888)))
                
                g1_mulAccC(_pVk, IC61x, IC61y, calldataload(add(pubSignals, 1920)))
                
                g1_mulAccC(_pVk, IC62x, IC62y, calldataload(add(pubSignals, 1952)))
                
                g1_mulAccC(_pVk, IC63x, IC63y, calldataload(add(pubSignals, 1984)))
                
                g1_mulAccC(_pVk, IC64x, IC64y, calldataload(add(pubSignals, 2016)))
                
                g1_mulAccC(_pVk, IC65x, IC65y, calldataload(add(pubSignals, 2048)))
                
                g1_mulAccC(_pVk, IC66x, IC66y, calldataload(add(pubSignals, 2080)))
                
                g1_mulAccC(_pVk, IC67x, IC67y, calldataload(add(pubSignals, 2112)))
                
                g1_mulAccC(_pVk, IC68x, IC68y, calldataload(add(pubSignals, 2144)))
                
                g1_mulAccC(_pVk, IC69x, IC69y, calldataload(add(pubSignals, 2176)))
                
                g1_mulAccC(_pVk, IC70x, IC70y, calldataload(add(pubSignals, 2208)))
                
                g1_mulAccC(_pVk, IC71x, IC71y, calldataload(add(pubSignals, 2240)))
                
                g1_mulAccC(_pVk, IC72x, IC72y, calldataload(add(pubSignals, 2272)))
                

                // -A
                mstore(_pPairing, calldataload(pA))
                mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))

                // B
                mstore(add(_pPairing, 64), calldataload(pB))
                mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
                mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
                mstore(add(_pPairing, 160), calldataload(add(pB, 96)))

                // alpha1
                mstore(add(_pPairing, 192), alphax)
                mstore(add(_pPairing, 224), alphay)

                // beta2
                mstore(add(_pPairing, 256), betax1)
                mstore(add(_pPairing, 288), betax2)
                mstore(add(_pPairing, 320), betay1)
                mstore(add(_pPairing, 352), betay2)

                // vk_x
                mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
                mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))


                // gamma2
                mstore(add(_pPairing, 448), gammax1)
                mstore(add(_pPairing, 480), gammax2)
                mstore(add(_pPairing, 512), gammay1)
                mstore(add(_pPairing, 544), gammay2)

                // C
                mstore(add(_pPairing, 576), calldataload(pC))
                mstore(add(_pPairing, 608), calldataload(add(pC, 32)))

                // delta2
                mstore(add(_pPairing, 640), deltax1)
                mstore(add(_pPairing, 672), deltax2)
                mstore(add(_pPairing, 704), deltay1)
                mstore(add(_pPairing, 736), deltay2)


                let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)

                isOk := and(success, mload(_pPairing))
            }

            let pMem := mload(0x40)
            mstore(0x40, add(pMem, pLastMem))

            // Validate that all evaluations ∈ F
            
            checkField(calldataload(add(_pubSignals, 0)))
            
            checkField(calldataload(add(_pubSignals, 32)))
            
            checkField(calldataload(add(_pubSignals, 64)))
            
            checkField(calldataload(add(_pubSignals, 96)))
            
            checkField(calldataload(add(_pubSignals, 128)))
            
            checkField(calldataload(add(_pubSignals, 160)))
            
            checkField(calldataload(add(_pubSignals, 192)))
            
            checkField(calldataload(add(_pubSignals, 224)))
            
            checkField(calldataload(add(_pubSignals, 256)))
            
            checkField(calldataload(add(_pubSignals, 288)))
            
            checkField(calldataload(add(_pubSignals, 320)))
            
            checkField(calldataload(add(_pubSignals, 352)))
            
            checkField(calldataload(add(_pubSignals, 384)))
            
            checkField(calldataload(add(_pubSignals, 416)))
            
            checkField(calldataload(add(_pubSignals, 448)))
            
            checkField(calldataload(add(_pubSignals, 480)))
            
            checkField(calldataload(add(_pubSignals, 512)))
            
            checkField(calldataload(add(_pubSignals, 544)))
            
            checkField(calldataload(add(_pubSignals, 576)))
            
            checkField(calldataload(add(_pubSignals, 608)))
            
            checkField(calldataload(add(_pubSignals, 640)))
            
            checkField(calldataload(add(_pubSignals, 672)))
            
            checkField(calldataload(add(_pubSignals, 704)))
            
            checkField(calldataload(add(_pubSignals, 736)))
            
            checkField(calldataload(add(_pubSignals, 768)))
            
            checkField(calldataload(add(_pubSignals, 800)))
            
            checkField(calldataload(add(_pubSignals, 832)))
            
            checkField(calldataload(add(_pubSignals, 864)))
            
            checkField(calldataload(add(_pubSignals, 896)))
            
            checkField(calldataload(add(_pubSignals, 928)))
            
            checkField(calldataload(add(_pubSignals, 960)))
            
            checkField(calldataload(add(_pubSignals, 992)))
            
            checkField(calldataload(add(_pubSignals, 1024)))
            
            checkField(calldataload(add(_pubSignals, 1056)))
            
            checkField(calldataload(add(_pubSignals, 1088)))
            
            checkField(calldataload(add(_pubSignals, 1120)))
            
            checkField(calldataload(add(_pubSignals, 1152)))
            
            checkField(calldataload(add(_pubSignals, 1184)))
            
            checkField(calldataload(add(_pubSignals, 1216)))
            
            checkField(calldataload(add(_pubSignals, 1248)))
            
            checkField(calldataload(add(_pubSignals, 1280)))
            
            checkField(calldataload(add(_pubSignals, 1312)))
            
            checkField(calldataload(add(_pubSignals, 1344)))
            
            checkField(calldataload(add(_pubSignals, 1376)))
            
            checkField(calldataload(add(_pubSignals, 1408)))
            
            checkField(calldataload(add(_pubSignals, 1440)))
            
            checkField(calldataload(add(_pubSignals, 1472)))
            
            checkField(calldataload(add(_pubSignals, 1504)))
            
            checkField(calldataload(add(_pubSignals, 1536)))
            
            checkField(calldataload(add(_pubSignals, 1568)))
            
            checkField(calldataload(add(_pubSignals, 1600)))
            
            checkField(calldataload(add(_pubSignals, 1632)))
            
            checkField(calldataload(add(_pubSignals, 1664)))
            
            checkField(calldataload(add(_pubSignals, 1696)))
            
            checkField(calldataload(add(_pubSignals, 1728)))
            
            checkField(calldataload(add(_pubSignals, 1760)))
            
            checkField(calldataload(add(_pubSignals, 1792)))
            
            checkField(calldataload(add(_pubSignals, 1824)))
            
            checkField(calldataload(add(_pubSignals, 1856)))
            
            checkField(calldataload(add(_pubSignals, 1888)))
            
            checkField(calldataload(add(_pubSignals, 1920)))
            
            checkField(calldataload(add(_pubSignals, 1952)))
            
            checkField(calldataload(add(_pubSignals, 1984)))
            
            checkField(calldataload(add(_pubSignals, 2016)))
            
            checkField(calldataload(add(_pubSignals, 2048)))
            
            checkField(calldataload(add(_pubSignals, 2080)))
            
            checkField(calldataload(add(_pubSignals, 2112)))
            
            checkField(calldataload(add(_pubSignals, 2144)))
            
            checkField(calldataload(add(_pubSignals, 2176)))
            
            checkField(calldataload(add(_pubSignals, 2208)))
            
            checkField(calldataload(add(_pubSignals, 2240)))
            
            checkField(calldataload(add(_pubSignals, 2272)))
            
            checkField(calldataload(add(_pubSignals, 2304)))
            

            // Validate all evaluations
            let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)

            mstore(0, isValid)
             return(0, 0x20)
         }
     }
 }
合同源代码
文件 14 的 26:IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] calldata accounts,
        uint256[] calldata ids
    ) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}
合同源代码
文件 15 的 26:IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;

import "../IERC1155.sol";

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}
合同源代码
文件 16 的 26:IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}
合同源代码
文件 17 的 26:IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
合同源代码
文件 18 的 26:IERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

import "../utils/introspection/IERC165.sol";

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(
        uint256 tokenId,
        uint256 salePrice
    ) external view returns (address receiver, uint256 royaltyAmount);
}
合同源代码
文件 19 的 26:Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}
合同源代码
文件 20 的 26:Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
合同源代码
文件 21 的 26:SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}
合同源代码
文件 22 的 26:Speedruns.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/token/ERC1155/ERC1155.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import 'hardhat/console.sol';

import './AnybodyProblem.sol';

contract Speedruns is ERC1155, Ownable {
    address payable public anybodyProblem;

    constructor() ERC1155('') {}

    modifier onlyAnybody() {
        require(msg.sender == anybodyProblem, 'Only Anybody Problem can call');
        _;
    }

    function __mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) external onlyAnybody {
        _mint(to, id, amount, data);
    }

    function __burn(
        address from,
        uint256 id,
        uint256 amount
    ) external onlyAnybody {
        _burn(from, id, amount);
    }

    function __safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        uint256 amount,
        bytes memory data
    ) external onlyAnybody {
        _safeTransferFrom(from, to, tokenId, amount, data);
    }

    function __setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) external onlyAnybody {
        _setApprovalForAll(owner, operator, approved);
    }

    function updateAnybodyProblemAddress(
        address payable anybodyProblem_
    ) public onlyOwner {
        anybodyProblem = anybodyProblem_;
    }

    // fallback and receive both forward undefined methods to the AnybodyProblem contract
    // this allows future functionality to be added to the NFT by augmenting AnybodyProblem
    // caveat: you lose the original msg.sender when calling the AnybodyProblem contract
    receive() external payable {
        (bool success, ) = anybodyProblem.call{value: msg.value}('');
        require(success, 'Call to anybodyProblem failed');
    }

    fallback() external {
        (bool success, ) = anybodyProblem.call(msg.data);
        require(success, 'Call to anybodyProblem failed');
    }

    // override all ERC1155 functions to call the AnybodyProblem contract first
    function uri(
        uint256 tokenId
    ) public view override(ERC1155) returns (string memory) {
        (bool success, bytes memory data) = anybodyProblem.staticcall(
            abi.encodeWithSignature('speedrunsTokenURI(uint256)', tokenId)
        );
        if (success) {
            return abi.decode(data, (string));
        } else {
            return super.uri(tokenId);
        }
    }

    function supportsInterface(
        bytes4 interfaceId
    ) public view override(ERC1155) returns (bool) {
        (bool success, bytes memory data) = anybodyProblem.staticcall(
            abi.encodeWithSignature(
                'speedrunsSupportsInterface(bytes4)',
                interfaceId
            )
        );
        if (success) {
            return abi.decode(data, (bool));
        } else {
            return super.supportsInterface(interfaceId);
        }
    }

    function isApprovedForAll(
        address account,
        address operator
    ) public view override(ERC1155) returns (bool) {
        (bool success, bytes memory data) = anybodyProblem.staticcall(
            abi.encodeWithSignature(
                'speedrunsIsApprovedForAll(address,address)',
                account,
                operator
            )
        );
        if (success) {
            return abi.decode(data, (bool));
        } else {
            return super.isApprovedForAll(account, operator);
        }
    }

    function setApprovalForAll(
        address operator,
        bool approved
    ) public override(ERC1155) {
        (bool success, bytes memory data) = anybodyProblem.call(
            abi.encodeWithSignature(
                'speedrunsSetApprovalForAll(address,bool)',
                operator,
                approved
            )
        );
        if (!success) {
            return super.setApprovalForAll(operator, approved);
        }
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        uint256 amount,
        bytes memory data
    ) public override(ERC1155) {
        (bool success, bytes memory data) = anybodyProblem.call(
            abi.encodeWithSignature(
                'speedrunsSafeTransferFrom(address,address,uint256,uint256,bytes)',
                from,
                to,
                tokenId,
                amount,
                data
            )
        );
        if (!success) {
            return super.safeTransferFrom(from, to, tokenId, amount, data);
        }
    }

    function emitGenericEvent(
        bytes32[] calldata topics,
        bytes calldata logData
    ) external onlyAnybody {
        require(topics.length <= 4, 'Too many topics');
        assembly {
            // Allocate memory for the logData
            let dataPtr := mload(0x40)
            let logDataLength := logData.length
            calldatacopy(dataPtr, logData.offset, logDataLength)

            // Updating the free mem pointer (probably not needed)
            mstore(0x40, add(dataPtr, logDataLength))

            let topicsLength := topics.length
            switch topicsLength
            case 0 {
                log0(dataPtr, logDataLength)
            }
            case 1 {
                log1(dataPtr, logDataLength, calldataload(topics.offset))
            }
            case 2 {
                log2(
                    dataPtr,
                    logDataLength,
                    calldataload(topics.offset),
                    calldataload(add(topics.offset, 32))
                )
            }
            case 3 {
                log3(
                    dataPtr,
                    logDataLength,
                    calldataload(topics.offset),
                    calldataload(add(topics.offset, 32)),
                    calldataload(add(topics.offset, 64))
                )
            }
            case 4 {
                log4(
                    dataPtr,
                    logDataLength,
                    calldataload(topics.offset),
                    calldataload(add(topics.offset, 32)),
                    calldataload(add(topics.offset, 64)),
                    calldataload(add(topics.offset, 96))
                )
            }
        }
    }
}
合同源代码
文件 23 的 26:StringsExtended.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/utils/math/SignedMath.sol";
import "hardhat/console.sol";

/**
 * @dev String operations.
 */
library StringsExtended {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return
            string(
                abi.encodePacked(
                    value < 0 ? "-" : "",
                    toString(SignedMath.abs(value))
                )
            );
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexStringWithPrefix(
        uint256 value,
        uint256 length
    ) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(
        uint256 value,
        uint256 length
    ) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length);
        for (int256 i = 2 * int256(length) - 1; i >= 0; --i) {
            buffer[uint256(i)] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(
        string memory a,
        string memory b
    ) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}
合同源代码
文件 24 的 26:ThemeGroupBlues.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract ThemeGroup {
    enum ThemeLayer {
        BG,
        Core,
        FG,
        Face
    }
    struct ThemeSpecs {
        uint256 hueStart;
        uint256 hueEnd;
        uint256 saturationStart;
        uint256 saturationEnd;
        uint256 lightnessStart;
        uint256 lightnessEnd;
    }
    enum ThemeName {
        BlueBGDark,
        BlueBGLight
    }
    uint8 public constant themeCount = 2;
    mapping(ThemeName => mapping(ThemeLayer => ThemeSpecs)) public colourThemes;

    function getColourThemes(
        ThemeName themeName,
        ThemeLayer themeLayer
    ) public view returns (ThemeSpecs memory) {
        return colourThemes[themeName][themeLayer];
    }

    constructor() {
        setupColorThemes();
    }

    function setupColorThemes() private {
        ThemeSpecs memory bluesGeneric = ThemeSpecs({
            hueStart: 135,
            hueEnd: 105,
            saturationStart: 95,
            saturationEnd: 100,
            lightnessStart: 50,
            lightnessEnd: 60
        });

        // BlueBGDark

        // BlueBGDark BG
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.BG] = bluesGeneric;
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.BG].hueStart = 175;
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.BG].hueEnd = 270;
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.BG].lightnessEnd = 55;

        // BlueBGDark Core
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.Core] = bluesGeneric;
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.Core]
            .saturationStart = 100;
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.Core].lightnessStart = 85;
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.Core].lightnessEnd = 90;

        // BlueBGDark FG
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.FG] = bluesGeneric;
        colourThemes[ThemeName.BlueBGDark][ThemeLayer.FG].lightnessStart = 55;

        // ------------------------------

        //BlueBGLight

        // BlueBGLight BG
        colourThemes[ThemeName.BlueBGLight][ThemeLayer.Core] = bluesGeneric;
        colourThemes[ThemeName.BlueBGLight][ThemeLayer.Core].hueStart = 180;
        colourThemes[ThemeName.BlueBGLight][ThemeLayer.Core].hueEnd = 250;
        colourThemes[ThemeName.BlueBGLight][ThemeLayer.Core]
            .saturationStart = 100;
        colourThemes[ThemeName.BlueBGLight][ThemeLayer.Core]
            .lightnessStart = 55;
        colourThemes[ThemeName.BlueBGLight][ThemeLayer.Core].lightnessEnd = 95;

        // BlueBGLight Core
        colourThemes[ThemeName.BlueBGLight][ThemeLayer.BG] = bluesGeneric;

        // BlueBGLight FG
        colourThemes[ThemeName.BlueBGLight][ThemeLayer.FG] = bluesGeneric;
    }
}
合同源代码
文件 25 的 26:base64.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

/// @title Base64
/// @author Brecht Devos - <brecht@loopring.org>
/// @notice Provides functions for encoding/decoding base64
library Base64 {
    string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    bytes  internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
                                            hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
                                            hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
                                            hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";

    function encode(bytes memory data) internal pure returns (string memory) {
        if (data.length == 0) return '';

        // load the table into memory
        string memory table = TABLE_ENCODE;

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((data.length + 2) / 3);

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {}
            {
                // read 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // write 4 characters
                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(        input,  0x3F))))
                resultPtr := add(resultPtr, 1)
            }

            // padding with '='
            switch mod(mload(data), 3)
            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
        }

        return result;
    }

    function decode(string memory _data) internal pure returns (bytes memory) {
        bytes memory data = bytes(_data);

        if (data.length == 0) return new bytes(0);
        require(data.length % 4 == 0, "invalid base64 decoder input");

        // load the table into memory
        bytes memory table = TABLE_DECODE;

        // every 4 characters represent 3 bytes
        uint256 decodedLen = (data.length / 4) * 3;

        // add some extra buffer at the end required for the writing
        bytes memory result = new bytes(decodedLen + 32);

        assembly {
            // padding with '='
            let lastBytes := mload(add(data, mload(data)))
            if eq(and(lastBytes, 0xFF), 0x3d) {
                decodedLen := sub(decodedLen, 1)
                if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
                    decodedLen := sub(decodedLen, 1)
                }
            }

            // set the actual output length
            mstore(result, decodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 4 characters at a time
            for {} lt(dataPtr, endPtr) {}
            {
               // read 4 characters
               dataPtr := add(dataPtr, 4)
               let input := mload(dataPtr)

               // write 3 bytes
               let output := add(
                   add(
                       shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
                       shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
                   add(
                       shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
                               and(mload(add(tablePtr, and(        input , 0xFF))), 0xFF)
                    )
                )
                mstore(resultPtr, shl(232, output))
                resultPtr := add(resultPtr, 3)
            }
        }

        return result;
    }
}
合同源代码
文件 26 的 26:console.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

library console {
    address constant CONSOLE_ADDRESS =
        0x000000000000000000636F6e736F6c652e6c6f67;

    function _sendLogPayloadImplementation(bytes memory payload) internal view {
        address consoleAddress = CONSOLE_ADDRESS;
        /// @solidity memory-safe-assembly
        assembly {
            pop(
                staticcall(
                    gas(),
                    consoleAddress,
                    add(payload, 32),
                    mload(payload),
                    0,
                    0
                )
            )
        }
    }

    function _castToPure(
      function(bytes memory) internal view fnIn
    ) internal pure returns (function(bytes memory) pure fnOut) {
        assembly {
            fnOut := fnIn
        }
    }

    function _sendLogPayload(bytes memory payload) internal pure {
        _castToPure(_sendLogPayloadImplementation)(payload);
    }

    function log() internal pure {
        _sendLogPayload(abi.encodeWithSignature("log()"));
    }
    function logInt(int256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
    }

    function logUint(uint256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
    }

    function logString(string memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    }

    function logBool(bool p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
    }

    function logAddress(address p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
    }

    function logBytes(bytes memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
    }

    function logBytes1(bytes1 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
    }

    function logBytes2(bytes2 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
    }

    function logBytes3(bytes3 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
    }

    function logBytes4(bytes4 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
    }

    function logBytes5(bytes5 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
    }

    function logBytes6(bytes6 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
    }

    function logBytes7(bytes7 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
    }

    function logBytes8(bytes8 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
    }

    function logBytes9(bytes9 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
    }

    function logBytes10(bytes10 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
    }

    function logBytes11(bytes11 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
    }

    function logBytes12(bytes12 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
    }

    function logBytes13(bytes13 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
    }

    function logBytes14(bytes14 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
    }

    function logBytes15(bytes15 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
    }

    function logBytes16(bytes16 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
    }

    function logBytes17(bytes17 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
    }

    function logBytes18(bytes18 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
    }

    function logBytes19(bytes19 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
    }

    function logBytes20(bytes20 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
    }

    function logBytes21(bytes21 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
    }

    function logBytes22(bytes22 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
    }

    function logBytes23(bytes23 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
    }

    function logBytes24(bytes24 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
    }

    function logBytes25(bytes25 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
    }

    function logBytes26(bytes26 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
    }

    function logBytes27(bytes27 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
    }

    function logBytes28(bytes28 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
    }

    function logBytes29(bytes29 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
    }

    function logBytes30(bytes30 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
    }

    function logBytes31(bytes31 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
    }

    function logBytes32(bytes32 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
    }

    function log(uint256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
    }

    function log(string memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    }

    function log(bool p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
    }

    function log(address p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
    }

    function log(uint256 p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
    }

    function log(uint256 p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
    }

    function log(uint256 p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
    }

    function log(uint256 p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
    }

    function log(string memory p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
    }

    function log(string memory p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
    }

    function log(string memory p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
    }

    function log(string memory p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
    }

    function log(bool p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
    }

    function log(bool p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
    }

    function log(bool p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
    }

    function log(bool p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
    }

    function log(address p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
    }

    function log(address p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
    }

    function log(address p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
    }

    function log(address p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
    }

    function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
    }

    function log(string memory p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
    }

    function log(string memory p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
    }

    function log(string memory p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
    }

    function log(string memory p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
    }

    function log(bool p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
    }

    function log(bool p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
    }

    function log(bool p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
    }

    function log(bool p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
    }

    function log(bool p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
    }

    function log(bool p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
    }

    function log(bool p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
    }

    function log(bool p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
    }

    function log(address p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
    }

    function log(address p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
    }

    function log(address p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
    }

    function log(address p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
    }

    function log(address p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
    }

    function log(address p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
    }

    function log(address p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
    }

    function log(address p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
    }

    function log(address p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
    }

    function log(address p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
    }

    function log(address p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
    }

    function log(address p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
    }

}
设置
{
  "compilationTarget": {
    "contracts/Speedruns.sol": "Speedruns"
  },
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "viaIR": true
}
ABI
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"__burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"__mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"__safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"__setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"anybodyProblem","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"topics","type":"bytes32[]"},{"internalType":"bytes","name":"logData","type":"bytes"}],"name":"emitGenericEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"anybodyProblem_","type":"address"}],"name":"updateAnybodyProblemAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]