Created
November 9, 2023 20:14
-
-
Save tavakyan/3652f1f726e0fe6e7704fb19cad4acf3 to your computer and use it in GitHub Desktop.
EVM Opcodes Solidity library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.8.19; | |
| /** | |
| * @title EvmOpcodes contract to look up gas for an operation | |
| * @dev Library for managing EVM opcodes, including their gas costs. | |
| */ | |
| contract EvmOpcodes { | |
| // Mapping from opcode name to its gas cost | |
| mapping(string => uint) private opcodes; | |
| /** | |
| * @dev Constructor to initialize the opcodes with their respective gas costs. | |
| */ | |
| constructor() { | |
| opcodes["STOP"] = 0; | |
| opcodes["ADD"] = 3; | |
| opcodes["MUL"] = 5; | |
| opcodes["SUB"] = 3; | |
| opcodes["DIV"] = 5; | |
| opcodes["SDIV"] = 5; | |
| opcodes["MOD"] = 5; | |
| opcodes["SMOD"] = 5; | |
| opcodes["ADDMOD"] = 8; | |
| opcodes["MULMOD"] = 8; | |
| opcodes["EXP"] = 10; | |
| opcodes["SIGNEXTEND"] = 5; | |
| opcodes["LT"] = 3; | |
| opcodes["GT"] = 3; | |
| opcodes["SLT"] = 3; | |
| opcodes["SGT"] = 3; | |
| opcodes["EQ"] = 3; | |
| opcodes["ISZERO"] = 3; | |
| opcodes["AND"] = 3; | |
| opcodes["OR"] = 3; | |
| opcodes["XOR"] = 3; | |
| opcodes["NOT"] = 3; | |
| opcodes["BYTE"] = 3; | |
| opcodes["SHL"] = 3; | |
| opcodes["SHR"] = 3; | |
| opcodes["SAR"] = 3; | |
| opcodes["SHA3"] = 30; | |
| opcodes["ADDRESS"] = 2; | |
| opcodes["BALANCE"] = 100; | |
| opcodes["ORIGIN"] = 2; | |
| opcodes["CALLER"] = 2; | |
| opcodes["CALLVALUE"] = 2; | |
| opcodes["CALLDATALOAD"] = 3; | |
| opcodes["CALLDATASIZE"] = 2; | |
| opcodes["CALLDATACOPY"] = 3; | |
| opcodes["CODESIZE"] = 2; | |
| opcodes["CODECOPY"] = 3; | |
| opcodes["GASPRICE"] = 2; | |
| opcodes["EXTCODESIZE"] = 100; | |
| opcodes["EXTCODECOPY"] = 100; | |
| opcodes["RETURNDATASIZE"] = 2; | |
| opcodes["RETURNDATACOPY"] = 3; | |
| opcodes["EXTCODEHASH"] = 100; | |
| opcodes["BLOCKHASH"] = 20; | |
| opcodes["COINBASE"] = 2; | |
| opcodes["TIMESTAMP"] = 2; | |
| opcodes["NUMBER"] = 2; | |
| opcodes["PREVRANDAO"] = 2; | |
| opcodes["GASLIMIT"] = 2; | |
| opcodes["CHAINID"] = 2; | |
| opcodes["SELFBALANCE"] = 5; | |
| opcodes["BASEFEE"] = 2; | |
| opcodes["POP"] = 2; | |
| opcodes["MLOAD"] = 3; | |
| opcodes["MSTORE"] = 3; | |
| opcodes["MSTORE8"] = 3; | |
| opcodes["SLOAD"] = 100; | |
| opcodes["SSTORE"] = 100; | |
| opcodes["JUMP"] = 8; | |
| opcodes["JUMPI"] = 10; | |
| opcodes["PC"] = 2; | |
| opcodes["MSIZE"] = 2; | |
| opcodes["GAS"] = 2; | |
| opcodes["JUMPDEST"] = 1; | |
| // Expanding PUSH1 to PUSH32 | |
| for (uint i = 1; i <= 32; ++i) { | |
| opcodes[string(abi.encodePacked("PUSH", i.toString()))] = 3; | |
| } | |
| // Expanding DUP1 to DUP16 | |
| for (uint i = 1; i <= 16; ++i) { | |
| opcodes[string(abi.encodePacked("DUP", i.toString()))] = 3; | |
| } | |
| // Expanding SWAP1 to SWAP16 | |
| for (uint i = 1; i <= 16; ++i) { | |
| opcodes[string(abi.encodePacked("SWAP", i.toString()))] = 3; | |
| } | |
| opcodes["LOG0"] = 375; | |
| opcodes["LOG1"] = 750; | |
| opcodes["LOG2"] = 1125; | |
| opcodes["LOG3"] = 1500; | |
| opcodes["LOG4"] = 1875; | |
| opcodes["CREATE"] = 32000; | |
| opcodes["CALL"] = 100; | |
| opcodes["CALLCODE"] = 100; | |
| opcodes["RETURN"] = 0; | |
| opcodes["DELEGATECALL"] = 100; | |
| opcodes["CREATE2"] = 32000; | |
| opcodes["STATICCALL"] = 100; | |
| opcodes["REVERT"] = 0; | |
| opcodes["INVALID"] = uint(~0); | |
| opcodes["SELFDESTRUCT"] = 5000; | |
| } | |
| /** | |
| * @notice Retrieves the gas cost of a specified opcode. | |
| * @param opcodeName The name of the opcode. | |
| * @return The gas cost associated with the opcode. | |
| * @dev Reverts if the opcode does not exist. | |
| */ | |
| function getGasCost(string memory opcodeName) public view returns (uint) { | |
| require(opcodes[opcodeName] != 0, "Opcode not found"); | |
| return opcodes[opcodeName]; | |
| } | |
| /** | |
| * @notice Calculates the total gas cost for an array of opcode names. | |
| * @param opcodeNames An array of opcode names. | |
| * @return totalGasCost The total gas cost for the opcodes. | |
| * @dev Assumes that all opcode names in the array are valid. | |
| */ | |
| function getTotalGasCost(string[] memory opcodeNames) public view returns (uint totalGasCost) { | |
| totalGasCost = 0; | |
| for (uint i = 0; i < opcodeNames.length; ++i) { | |
| // Using the existing getGasCost function to retrieve each opcode's gas cost | |
| totalGasCost += getGasCost(opcodeNames[i]); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment