├── .gitignore ├── assets ├── banner.png ├── logo-t.png └── i.svg ├── tailwind.config.js ├── style.css ├── README.md ├── package.json ├── main.js ├── gasData.js ├── dist ├── bundle.js └── output.css └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store -------------------------------------------------------------------------------- /assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xMacro/gas-numbers-every-solidity-dev-should-know/HEAD/assets/banner.png -------------------------------------------------------------------------------- /assets/logo-t.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xMacro/gas-numbers-every-solidity-dev-should-know/HEAD/assets/logo-t.png -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./*.{html,js}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | } 9 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | #opcodes { 6 | max-height: 400px; 7 | } 8 | #contract-calls{ 9 | max-height: 2650px; 10 | } 11 | .opcode { 12 | margin: 10px 5px; 13 | min-width: 200px; 14 | } 15 | .contract-call { 16 | margin: 10px 5px; 17 | min-width: 200px; 18 | } 19 | .operation-name { 20 | /* display: flex; */ 21 | /* align-items: center; */ 22 | } 23 | 24 | a { 25 | text-decoration: underline; 26 | color: blue; 27 | cursor: pointer; 28 | } 29 | 30 | @media only screen and (max-width: 1000px) { 31 | body { 32 | padding: 2%; 33 | } 34 | #opcodes { 35 | flex-direction: row !important; 36 | max-height: 1000000000px !important; /* nonsensically large number to prevent overlapping */ 37 | } 38 | #contract-calls{ 39 | flex-direction: row !important; 40 | max-height: 1000000000px !important; /* nonsensically large number to prevent overlapping */ 41 | } 42 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gas-numbers-every-solidity-dev-should-know 2 | 3 | The live site can be found at https://0xmacro.com/library/gas-nums 4 | 5 | This project was inspired by Norvig's Latency Numbers, and a post in the Macro discord from a student named Justin Phu, who suggested someone make a version with gas numbers for popular calls and opcodes. 6 | 7 | Opcode gas numbers were sourced from the official Ethereum Docs, and contract-calls were sourced from Etherscan.io and converted into gas units using Wolfram Alpha for calculations. 8 | 9 | 10 | ## dev 11 | Run `npm i` to install necessary node modules 12 | 13 | To run this repo locally, run `npm run build && npm run dev` and then open index.html in your browser. I prefer to do so with VS Code's live server extension. 14 | 15 | This repo uses Browserify / Watchify to keep the simplicity of html & vanilla js webpages, preserving the developer comforts of node, and creating an optimized production bundle. 16 | 17 | ## contribute 18 | 19 | If you'd like to contribute, please create a github issue or open a PR. Keep in mind I will be opinionated about what gets added to the page. -------------------------------------------------------------------------------- /assets/i.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Svg Vector Icons : http://www.onlinewebfonts.com/icon 6 | 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gas-numbers-every-solidity-dev-should-know", 3 | "version": "1.0.0", 4 | "description": "This repo uses Browserify to keep the simplicity of html & vanilla js webpages, while preserving the niceties of node and creating an optimized production bundle. Check out the Browserify docs if you need help getting started: https://github.com/browserify/browserify#usage", 5 | "main": "main.js", 6 | "scripts": { 7 | "build": "npx browserify main.js -o ./dist/bundle.js", 8 | "dev": "npx watchify main.js -o ./dist/bundle.js & npx tailwindcss -i ./style.css -o ./dist/output.css --watch" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/0xMacro/gas-numbers-every-solidity-dev-should-know.git" 13 | }, 14 | "author": "dd0sxx", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/0xMacro/gas-numbers-every-solidity-dev-should-know/issues" 18 | }, 19 | "homepage": "https://github.com/0xMacro/gas-numbers-every-solidity-dev-should-know#readme", 20 | "devDependencies": { 21 | "browserify": "^17.0.0", 22 | "tailwindcss": "^3.1.4", 23 | "watchify": "^4.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const gasData = require('./gasData') 2 | 3 | function calculateGasToSquares (gas, name, color) { 4 | // one square = 2000 units of gas 5 | let numOfSqaures = Math.floor(gas / 2000) 6 | let remainder = gas % 2000 7 | addSquaresToDOM(name, numOfSqaures, remainder, color) 8 | } 9 | 10 | function addSquaresToDOM (elementID, squares, remainder, color) { 11 | const element = document.getElementById(elementID) 12 | let squareBox = document.createElement("div") 13 | squareBox.style.display = 'flex' 14 | // squareBox.style.alignItems = 'center' 15 | squareBox.style.alignSelf = 'start' 16 | squareBox.style.flexWrap = 'wrap' 17 | squareBox.style.maxWidth = '100px' 18 | // squareBox.style.flexDirection = 'row-reverse' 19 | squareBox.style.marginRight = '5px' 20 | for (let i = 0; i < squares; i++) { 21 | let newSquare = square(10, color); 22 | squareBox.appendChild(newSquare) 23 | } 24 | // scoped for legibility, create the remainder square 25 | { 26 | const division = (remainder / 20) 27 | const remainderWidth = (division * 10) / 100 28 | if (remainderWidth > 0) { 29 | const remainderSquare = remainderWidth < 1 ? square(1, color) : square(remainderWidth, color) 30 | squareBox.appendChild(remainderSquare) 31 | } 32 | } 33 | element.prepend(squareBox) 34 | } 35 | 36 | function square (width, color) { 37 | let square = document.createElement("div") 38 | square.style.width = `${width}px` 39 | square.style.height = '10px' 40 | square.style.margin = '1px' 41 | square.style.backgroundColor = color 42 | square.style.display = "block" 43 | return square; 44 | } 45 | 46 | function appendInformation (name, info) { 47 | const element = document.getElementById(name) 48 | let informationBox = document.createElement("div") 49 | 50 | informationBox.style.width = '12px' 51 | informationBox.style.height = '12px' 52 | informationBox.style.margin = '6px 0px 0px 6px' 53 | informationBox.style.padding = '6px' 54 | informationBox.style.backgroundImage = 'url("./assets/i.svg")' 55 | 56 | informationBox.onmouseover = () => { 57 | displayInfoModal(name, info, element) 58 | } 59 | informationBox.onmouseout = () => { 60 | removeInfoModal(name, info, element) 61 | } 62 | 63 | 64 | element.appendChild(informationBox) 65 | } 66 | 67 | function displayInfoModal (name, info, element) { 68 | let informationModal = document.createElement("div") 69 | informationModal.id = `${name}-info-modal` 70 | // let modalText = document.createElement("div") 71 | informationModal.innerText = name + ": " + info 72 | // modalText.style.margin = 'auto' 73 | // modalText.style.height = 'auto' 74 | // modalText.style.width = 'auto' 75 | // informationModal.appendChild(modalText) 76 | 77 | informationModal.style.width = 'auto' 78 | informationModal.style.maxWidth = '500px' 79 | informationModal.style.height = 'auto' 80 | informationModal.style.padding = '15px' 81 | informationModal.style.border = '1px solid black' 82 | informationModal.style.backgroundColor = 'lightgray' 83 | informationModal.style.zIndex = '10' 84 | informationModal.style.position = 'absolute' 85 | informationModal.style.left = `${element.offsetLeft}px` 86 | informationModal.style.marginTop = '30px' 87 | 88 | element.appendChild(informationModal) 89 | } 90 | 91 | function removeInfoModal(name, info, element) { 92 | let infoModal = document.getElementById(`${name}-info-modal`) 93 | infoModal.remove() 94 | } 95 | 96 | 97 | gasData.opcodes.forEach(item => { 98 | calculateGasToSquares(item.gas, item.name, '#0091e6') 99 | if (item.information.length > 0) { 100 | appendInformation(item.name, item.information) 101 | } 102 | }) 103 | gasData.contractCalls.forEach(item => { 104 | calculateGasToSquares(item.gas, item.name, '#fa6132') 105 | }) -------------------------------------------------------------------------------- /gasData.js: -------------------------------------------------------------------------------- 1 | let data = { 2 | types: ["opcodes", "contract calls"], 3 | opcodes: [ 4 | {name: "ADD", gas: 3, information: ""}, 5 | {name: "BALANCE (warm)", gas: 100, information: "The opcodes BALANCE, EXTCODESIZE, EXTCODEHASH have the same pricing function based on making a single account access. See A0-2 (https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-2-access-sets) for details on EIP-2929 and touched_addresses."}, 6 | {name: "BALANCE (cold)", gas: 2600, information: "The opcodes BALANCE, EXTCODESIZE, EXTCODEHASH have the same pricing function based on making a single account access. See A0-2 (https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-2-access-sets) for details on EIP-2929 and touched_addresses."}, 7 | {name: "CALLDATACOPY", gas: 7, information: "gas_cost = 3 + 3 * data_size_words + mem_expansion_cost -- all memory expansion costs are calculated as 1 unit of gas for one word size of memory" }, 8 | {name: "MSTORE", gas: 3, information: "3x Memory Expansion cost, all memory expansion costs are calculated as 1 unit of gas for one word size of memory" }, 9 | {name: "MLOAD", gas: 3, information: "3x Memory Expansion cost" }, 10 | {name: "TIMESTAMP", gas: 2, information: "" }, 11 | {name: "ADDRESS", gas: 2, information: "" }, 12 | {name: "LOG0", gas: 632 , information: "Note that for LOG* operations gas is paid per byte of data (not per word), gas_cost = 375 + 375 * num_topics + 8 * data_size + mem_expansion_cost, where mem_expansion_cost is 1 gas unit for one word, and data_size is 32 for 32 bytes"}, 13 | {name: "LOG4", gas: 2132 , information: "Note that for LOG* operations gas is paid per byte of data (not per word), gas_cost = 375 + 375 * num_topics + 8 * data_size + mem_expansion_cost, where mem_expansion_cost is 1 gas unit for one word, and data_size is 32 for 32 bytes"}, 14 | {name: "SSTORE (clean: zero to nonzero)", gas: 22100, information: "" }, 15 | {name: "SSTORE (clean: nonzero to nonzero)", gas: 5000, information: "" }, 16 | {name: "SSTORE (clean: nonzero to zero)", gas: 5000, gasRefund: 4800, information: "" }, 17 | {name: "SSTORE (dirty: zero to nonzero)", gas: 20000, information: "" }, 18 | {name: "SSTORE (dirty: nonzero to nonzero)", gas: 2900, information: "" }, 19 | {name: "SSTORE (dirty: nonzero to zero)", gas: 2900, gasRefund: 4800, information: "" }, 20 | {name: "SLOAD (cold)", gas: 2100, information: "" }, 21 | {name: "SLOAD (warm)", gas: 100, information: "" }, 22 | {name: "CALL (no-value, warm)", gas: 100 , information: ''}, 23 | {name: "CALL (no-value, cold)", gas: 2600 , information: ''}, 24 | {name: "CALL (no-value, new-address)", gas: 25000 , information: ''}, 25 | {name: "CALL (value, cold)", gas: 11600 , information: ''}, 26 | {name: "CALL (value, warm)", gas: 9100 , information: ''}, 27 | {name: "CALL (value, new-address)", gas: 34000 , information: 'this high cost stems from the addition of the new address to the state trie'}, 28 | {name: "CREATE", gas: 32000, information: "" }, 29 | ], 30 | contractCalls: [ 31 | // calculated numbers on wolframalpha.com 32 | // prices are averages taken from etherscan.io 33 | // 22 gwei, 1,148.93 usd -> 1 eth 34 | // formula used: (eth / usd) * 10 ^ 9 = gwei * gas 35 | {name: "ERC20: Transfer", gas: 64883 }, // ERC20: Transfer $1.64 $1.64 $1.64 36 | {name: "ERC721: Transfer", gas: 84663 }, // ERC721: Transfer $2.14 $2.14 $2.14 37 | {name: "Uniswap V3: Swap", gas: 184361 }, // Uniswap V3: Swap $4.66 $4.66 $4.66 38 | {name: "Uniswap V2: Swap", gas: 152711 }, // Uniswap V2: Swap $3.86 $3.86 $3.86 39 | {name: "SushiSwap: Swap", gas: 140843 }, // SushiSwap: Swap $3.56 $3.56 $3.56 40 | {name: "Curve: Swap", gas: 749314 }, // Curve: Swap $18.94 $18.94 $18.94 41 | {name: "Balancer: Swap", gas: 196230 }, // Balancer: Swap $4.96 $4.96 $4.96 42 | {name: "1inch: Swap", gas: 141634 }, // 1inch: Swap $3.58 $3.58 $3.58 43 | {name: "CoW Protocol: Swap", gas: 343007 }, // CoW Protocol: Swap $8.67 $8.67 $8.67 44 | {name: "OpenSea: Sale", gas: 202164 }, // OpenSea: Sale $5.11 $5.11 $5.11 45 | {name: "SuperRare: Sale", gas: 130556 }, // SuperRare: Sale $3.30 $3.30 $3.30 46 | {name: "Rarible: Sale", gas: 245288 }, // Rarible: Sale $6.20 $6.20 $6.20 47 | {name: "LooksRare: Sale", gas: 326391 }, // LooksRare: Sale $8.25 $8.25 $8.25 48 | {name: "ENS: Register Domain", gas: 266651 }, // ENS: Register Domain $6.74 $6.74 $6.74 49 | {name: "Gnosis Safe: Create Multisig", gas: 288015 }, // Gnosis Safe: Create Multisig $7.28 $7.28 $7.28 50 | {name: "Arbitrum: Deposit", gas: 90994 }, // Arbitrum: Deposit $2.30 $2.30 $2.30 51 | {name: "Optimism: Deposit", gas: 150733 }, // Optimism: Deposit $3.81 $3.81 $3.81 52 | {name: "Polygon: Deposit", gas: 149151 }, // Polygon: Deposit $3.77 $3.77 $3.77 53 | {name: "Beacon Chain: Deposit", gas: 53014 }, // Beacon Chain: Deposit $1.34 $1.34 $1.34 54 | {name: "Tornado.Cash: Deposit", gas: 1012400 }, // Tornado.Cash: Deposit $25.59 $25.59 $25.59 55 | {name: "Tornado.Cash: Withdraw", gas: 360414 }, // Tornado.Cash: Withdraw $9.11 $9.11 $9.11 56 | {name: "dYdX: Borrow", gas: 174075 }, // dYdX: Borrow $4.40 $4.40 $4.40 57 | {name: "MakerDAO: Borrow", gas: 223023 }, // MakerDAO: Borrow $5.89 $5.89 $5.89 58 | {name: "Compound: Collect", gas: 1237520 }, // Compound: Collect $31.28 $31.28 $31.28 59 | {name: "Compound: Borrow", gas: 339842 }, // Compound: Borrow $8.59 $8.59 $8.59 60 | {name: "Compound: Repay", gas: 112358 }, // Compound: Repay $2.84 $2.84 $2.84 61 | {name: "Aave: Borrow", gas: 318478 }, // Aave: Borrow $8.05 $8.05 $8.05 62 | {name: "Aave: Repay", gas: 199395 }, // Aave: Repay $5.04 $5.04 $5.04 63 | {name: "Lido: Stake", gas: 82686 }, //Lido: Stake $2.09 $2.09 $2.09 64 | {name: "Yearn Finance: Deposit", gas: 216011 }, // Yearn Finance: Deposit $5.46 $5.46 $5.46 65 | {name: "Hop Protocol: Bridge", gas: 121457 }, // Hop Protocol: Bridge $3.07 $3.07 $3.07 66 | {name: "Multichain: Bridge", gas: 57761 }, // Multichain: Bridge $1.46 $1.46 $1.46 67 | {name: "Across Protocol: Bridge", gas: 120666 }, // Across Protocol: Bridge $3.05 $3.05 $3.05 68 | {name: "Synapse: Bridge", gas: 107610 }, // Synapse: Bridge $2.72 $2.72 $2.72 69 | ] 70 | } 71 | 72 | module.exports = data 73 | 74 | // decided not to include 75 | // {name: "USDT: Transfer", gas: 54201 }, // USDT: Transfer $1.37 $1.37 $1.37 76 | // {name: "Bancor: Swap", gas: 182779 }, // Bancor: Swap $4.62 $4.62 $4.62 77 | // {name: "KyberSwap: Swap", gas: 144008 }, // KyberSwap: Swap $3.64 $3.64 $3.64 -------------------------------------------------------------------------------- /dist/bundle.js: -------------------------------------------------------------------------------- 1 | (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 1 eth 35 | // formula used: (eth / usd) * 10 ^ 9 = gwei * gas 36 | {name: "ERC20: Transfer", gas: 64883 }, // ERC20: Transfer $1.64 $1.64 $1.64 37 | {name: "ERC721: Transfer", gas: 84663 }, // ERC721: Transfer $2.14 $2.14 $2.14 38 | {name: "Uniswap V3: Swap", gas: 184361 }, // Uniswap V3: Swap $4.66 $4.66 $4.66 39 | {name: "Uniswap V2: Swap", gas: 152711 }, // Uniswap V2: Swap $3.86 $3.86 $3.86 40 | {name: "SushiSwap: Swap", gas: 140843 }, // SushiSwap: Swap $3.56 $3.56 $3.56 41 | {name: "Curve: Swap", gas: 749314 }, // Curve: Swap $18.94 $18.94 $18.94 42 | {name: "Balancer: Swap", gas: 196230 }, // Balancer: Swap $4.96 $4.96 $4.96 43 | {name: "1inch: Swap", gas: 141634 }, // 1inch: Swap $3.58 $3.58 $3.58 44 | {name: "CoW Protocol: Swap", gas: 343007 }, // CoW Protocol: Swap $8.67 $8.67 $8.67 45 | {name: "OpenSea: Sale", gas: 202164 }, // OpenSea: Sale $5.11 $5.11 $5.11 46 | {name: "SuperRare: Sale", gas: 130556 }, // SuperRare: Sale $3.30 $3.30 $3.30 47 | {name: "Rarible: Sale", gas: 245288 }, // Rarible: Sale $6.20 $6.20 $6.20 48 | {name: "LooksRare: Sale", gas: 326391 }, // LooksRare: Sale $8.25 $8.25 $8.25 49 | {name: "ENS: Register Domain", gas: 266651 }, // ENS: Register Domain $6.74 $6.74 $6.74 50 | {name: "Gnosis Safe: Create Multisig", gas: 288015 }, // Gnosis Safe: Create Multisig $7.28 $7.28 $7.28 51 | {name: "Arbitrum: Deposit", gas: 90994 }, // Arbitrum: Deposit $2.30 $2.30 $2.30 52 | {name: "Optimism: Deposit", gas: 150733 }, // Optimism: Deposit $3.81 $3.81 $3.81 53 | {name: "Polygon: Deposit", gas: 149151 }, // Polygon: Deposit $3.77 $3.77 $3.77 54 | {name: "Beacon Chain: Deposit", gas: 53014 }, // Beacon Chain: Deposit $1.34 $1.34 $1.34 55 | {name: "Tornado.Cash: Deposit", gas: 1012400 }, // Tornado.Cash: Deposit $25.59 $25.59 $25.59 56 | {name: "Tornado.Cash: Withdraw", gas: 360414 }, // Tornado.Cash: Withdraw $9.11 $9.11 $9.11 57 | {name: "dYdX: Borrow", gas: 174075 }, // dYdX: Borrow $4.40 $4.40 $4.40 58 | {name: "MakerDAO: Borrow", gas: 223023 }, // MakerDAO: Borrow $5.89 $5.89 $5.89 59 | {name: "Compound: Collect", gas: 1237520 }, // Compound: Collect $31.28 $31.28 $31.28 60 | {name: "Compound: Borrow", gas: 339842 }, // Compound: Borrow $8.59 $8.59 $8.59 61 | {name: "Compound: Repay", gas: 112358 }, // Compound: Repay $2.84 $2.84 $2.84 62 | {name: "Aave: Borrow", gas: 318478 }, // Aave: Borrow $8.05 $8.05 $8.05 63 | {name: "Aave: Repay", gas: 199395 }, // Aave: Repay $5.04 $5.04 $5.04 64 | {name: "Lido: Stake", gas: 82686 }, //Lido: Stake $2.09 $2.09 $2.09 65 | {name: "Yearn Finance: Deposit", gas: 216011 }, // Yearn Finance: Deposit $5.46 $5.46 $5.46 66 | {name: "Hop Protocol: Bridge", gas: 121457 }, // Hop Protocol: Bridge $3.07 $3.07 $3.07 67 | {name: "Multichain: Bridge", gas: 57761 }, // Multichain: Bridge $1.46 $1.46 $1.46 68 | {name: "Across Protocol: Bridge", gas: 120666 }, // Across Protocol: Bridge $3.05 $3.05 $3.05 69 | {name: "Synapse: Bridge", gas: 107610 }, // Synapse: Bridge $2.72 $2.72 $2.72 70 | ] 71 | } 72 | 73 | module.exports = data 74 | 75 | // decided not to include 76 | // {name: "USDT: Transfer", gas: 54201 }, // USDT: Transfer $1.37 $1.37 $1.37 77 | // {name: "Bancor: Swap", gas: 182779 }, // Bancor: Swap $4.62 $4.62 $4.62 78 | // {name: "KyberSwap: Swap", gas: 144008 }, // KyberSwap: Swap $3.64 $3.64 $3.64 79 | },{}],2:[function(require,module,exports){ 80 | const gasData = require('./gasData') 81 | 82 | function calculateGasToSquares (gas, name, color) { 83 | // one square = 2000 units of gas 84 | let numOfSqaures = Math.floor(gas / 2000) 85 | let remainder = gas % 2000 86 | addSquaresToDOM(name, numOfSqaures, remainder, color) 87 | } 88 | 89 | function addSquaresToDOM (elementID, squares, remainder, color) { 90 | const element = document.getElementById(elementID) 91 | let squareBox = document.createElement("div") 92 | squareBox.style.display = 'flex' 93 | // squareBox.style.alignItems = 'center' 94 | squareBox.style.alignSelf = 'start' 95 | squareBox.style.flexWrap = 'wrap' 96 | squareBox.style.maxWidth = '100px' 97 | // squareBox.style.flexDirection = 'row-reverse' 98 | squareBox.style.marginRight = '5px' 99 | for (let i = 0; i < squares; i++) { 100 | let newSquare = square(10, color); 101 | squareBox.appendChild(newSquare) 102 | } 103 | // scoped for legibility, create the remainder square 104 | { 105 | const division = (remainder / 20) 106 | const remainderWidth = (division * 10) / 100 107 | if (remainderWidth > 0) { 108 | const remainderSquare = remainderWidth < 1 ? square(1, color) : square(remainderWidth, color) 109 | squareBox.appendChild(remainderSquare) 110 | } 111 | } 112 | element.prepend(squareBox) 113 | } 114 | 115 | function square (width, color) { 116 | let square = document.createElement("div") 117 | square.style.width = `${width}px` 118 | square.style.height = '10px' 119 | square.style.margin = '1px' 120 | square.style.backgroundColor = color 121 | square.style.display = "block" 122 | return square; 123 | } 124 | 125 | function appendInformation (name, info) { 126 | const element = document.getElementById(name) 127 | let informationBox = document.createElement("div") 128 | 129 | informationBox.style.width = '12px' 130 | informationBox.style.height = '12px' 131 | informationBox.style.margin = '6px 0px 0px 6px' 132 | informationBox.style.padding = '6px' 133 | informationBox.style.backgroundImage = 'url("./assets/i.svg")' 134 | 135 | informationBox.onmouseover = () => { 136 | displayInfoModal(name, info, element) 137 | } 138 | informationBox.onmouseout = () => { 139 | removeInfoModal(name, info, element) 140 | } 141 | 142 | 143 | element.appendChild(informationBox) 144 | } 145 | 146 | function displayInfoModal (name, info, element) { 147 | let informationModal = document.createElement("div") 148 | informationModal.id = `${name}-info-modal` 149 | // let modalText = document.createElement("div") 150 | informationModal.innerText = name + ": " + info 151 | // modalText.style.margin = 'auto' 152 | // modalText.style.height = 'auto' 153 | // modalText.style.width = 'auto' 154 | // informationModal.appendChild(modalText) 155 | 156 | informationModal.style.width = 'auto' 157 | informationModal.style.maxWidth = '500px' 158 | informationModal.style.height = 'auto' 159 | informationModal.style.padding = '15px' 160 | informationModal.style.border = '1px solid black' 161 | informationModal.style.backgroundColor = 'lightgray' 162 | informationModal.style.zIndex = '10' 163 | informationModal.style.position = 'absolute' 164 | informationModal.style.left = `${element.offsetLeft}px` 165 | informationModal.style.marginTop = '30px' 166 | 167 | element.appendChild(informationModal) 168 | } 169 | 170 | function removeInfoModal(name, info, element) { 171 | let infoModal = document.getElementById(`${name}-info-modal`) 172 | infoModal.remove() 173 | } 174 | 175 | 176 | gasData.opcodes.forEach(item => { 177 | calculateGasToSquares(item.gas, item.name, '#0091e6') 178 | if (item.information.length > 0) { 179 | appendInformation(item.name, item.information) 180 | } 181 | }) 182 | gasData.contractCalls.forEach(item => { 183 | calculateGasToSquares(item.gas, item.name, '#fa6132') 184 | }) 185 | },{"./gasData":1}]},{},[2]); 186 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Gas Numbers Every Solidity Dev Should Know 17 | 18 | 19 | 20 | 21 | 23 | 24 |
25 |

Gas Numbers Every Solidity Dev Should Know

26 | 27 |
28 |

Created by Theo Telonis (dd0sxx) for Macro

29 |
30 |

Key:

31 | 36 |
37 |

Opcode gas numbers were sourced from the official Ethereum Docs, and contract-calls were sourced from Etherscan.io and converted into gas units using Wolfram Alpha for calculations.

38 |

Inspired by Norvig's Latency Numbers, and a post in the Macro discord from a student named Justin Phu, who suggested someone make a version with gas numbers for popular calls and opcodes.

39 | 45 |

OPCODES

46 |
47 |
48 |
ADD: 3
49 |
50 |
51 |
BALANCE (warm): 100
52 |
53 |
54 |
BALANCE (cold): 2,600
55 |
56 |
57 |
CALLDATACOPY: 7
58 |
59 |
60 |
MSTORE: 3
61 |
62 |
63 |
MLOAD: 3
64 |
65 |
66 |
TIMESTAMP: 2
67 |
68 |
69 |
ADDRESS: 2
70 |
71 |
72 |
LOG0: 632
73 |
74 |
75 |
LOG4: 2,132
76 |
77 |
78 |
SSTORE (clean: zero to nonzero): 22,100
79 |
80 |
81 |
SSTORE (clean: nonzero to nonzero): 5,000
82 |
83 |
84 |
SSTORE (clean: nonzero to zero): 5,000 (refund: 4,800)
85 |
86 |
87 |
SSTORE (dirty: zero to nonzero): 20,000
88 |
89 |
90 |
SSTORE (dirty: nonzero to nonzero): 2,900
91 |
92 |
93 |
SSTORE (dirty: nonzero to zero): 2,900 (refund: 4,800)
94 |
95 |
96 |
SLOAD (cold): 2,100
97 |
98 |
99 |
SLOAD (warm): 100
100 |
101 |
102 |
CALL (no-value, warm): 100
103 |
104 |
105 |
CALL (no-value, cold): 2,600
106 |
107 |
108 |
CALL (no-value, new-address): 25,000
109 |
110 |
111 |
CALL (value, cold): 11,600
112 |
113 |
114 |
CALL (value, warm): 9,100
115 |
116 |
117 |
CALL (value, new-address): 34,000
118 |
119 |
120 |
CREATE: 32,000
121 |
122 |
123 |

CONTRACT CALLS

124 |
125 |
126 |
ERC20::Transfer: 64,883
127 |
128 |
129 |
ERC721::Transfer: 84,663
130 |
131 |
132 |
Uniswap V3::Swap: 184,361
133 |
134 |
135 |
Uniswap V2::Swap: 152,711
136 |
137 |
138 |
SushiSwap::Swap: 140,843
139 |
140 |
141 |
Curve::Swap: 749,314
142 |
143 |
144 |
Balancer::Swap: 196,230
145 |
146 |
147 |
1inch::Swap: 141,634
148 |
149 |
150 |
CoW Protocol::Swap: 343,007
151 |
152 |
153 |
OpenSea::Sale: 202,164
154 |
155 |
156 |
SuperRare::Sale: 130,556
157 |
158 |
159 |
Rarible::Sale: 245,288
160 |
161 |
162 |
LooksRare::Sale: 326,391
163 |
164 |
165 |
ENS::Register Domain: 266,651
166 |
167 |
168 |
Gnosis Safe::Create Multisig: 288,015
169 |
170 |
171 |
Arbitrum::Deposit: 90,994
172 |
173 |
174 |
Optimism::Deposit: 150,733
175 |
176 |
177 |
Polygon::Deposit: 149,151
178 |
179 |
180 |
Beacon Chain::Deposit: 53,014
181 |
182 |
183 |
Tornado.Cash::Deposit: 1,012,400
184 |
185 |
186 |
Tornado.Cash::Withdraw: 360,414
187 |
188 |
189 |
dYdX::Borrow: 174,075
190 |
191 |
192 |
MakerDAO::Borrow: 223,023
193 |
194 |
195 |
Compound::Collect: 1,237,520
196 |
197 |
198 |
Compound::Borrow: 339,842
199 |
200 |
201 |
Compound::Repay: 112,358
202 |
203 |
204 |
Aave::Borrow: 318,478
205 |
206 |
207 |
Aave::Repay: 199,395
208 |
209 |
210 |
Lido::Stake: 82,686
211 |
212 |
213 |
Yearn Finance::Deposit: 216,011
214 |
215 |
216 |
Hop Protocol::Bridge: 121,457
217 |
218 |
219 |
Multichain::Bridge: 57,761
220 |
221 |
222 |
Across Protocol::Bridge: 120,666
223 |
224 |
225 |
Synapse::Bridge: 107,610
226 |
227 |
228 |

Want to become an expert smart contract developer? Check out the Macro Engineering Fellowship 🚀

229 |

Something missing from this page? Make an issue or PR on our github repo 🤖

230 | 231 | 232 | -------------------------------------------------------------------------------- /dist/output.css: -------------------------------------------------------------------------------- 1 | /* 2 | ! tailwindcss v3.1.8 | MIT License | https://tailwindcss.com 3 | */ 4 | 5 | /* 6 | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 7 | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) 8 | */ 9 | 10 | *, 11 | ::before, 12 | ::after { 13 | box-sizing: border-box; 14 | /* 1 */ 15 | border-width: 0; 16 | /* 2 */ 17 | border-style: solid; 18 | /* 2 */ 19 | border-color: #e5e7eb; 20 | /* 2 */ 21 | } 22 | 23 | ::before, 24 | ::after { 25 | --tw-content: ''; 26 | } 27 | 28 | /* 29 | 1. Use a consistent sensible line-height in all browsers. 30 | 2. Prevent adjustments of font size after orientation changes in iOS. 31 | 3. Use a more readable tab size. 32 | 4. Use the user's configured `sans` font-family by default. 33 | */ 34 | 35 | html { 36 | line-height: 1.5; 37 | /* 1 */ 38 | -webkit-text-size-adjust: 100%; 39 | /* 2 */ 40 | -moz-tab-size: 4; 41 | /* 3 */ 42 | -o-tab-size: 4; 43 | tab-size: 4; 44 | /* 3 */ 45 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 46 | /* 4 */ 47 | } 48 | 49 | /* 50 | 1. Remove the margin in all browsers. 51 | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. 52 | */ 53 | 54 | body { 55 | margin: 0; 56 | /* 1 */ 57 | line-height: inherit; 58 | /* 2 */ 59 | } 60 | 61 | /* 62 | 1. Add the correct height in Firefox. 63 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 64 | 3. Ensure horizontal rules are visible by default. 65 | */ 66 | 67 | hr { 68 | height: 0; 69 | /* 1 */ 70 | color: inherit; 71 | /* 2 */ 72 | border-top-width: 1px; 73 | /* 3 */ 74 | } 75 | 76 | /* 77 | Add the correct text decoration in Chrome, Edge, and Safari. 78 | */ 79 | 80 | abbr:where([title]) { 81 | -webkit-text-decoration: underline dotted; 82 | text-decoration: underline dotted; 83 | } 84 | 85 | /* 86 | Remove the default font size and weight for headings. 87 | */ 88 | 89 | h1, 90 | h2, 91 | h3, 92 | h4, 93 | h5, 94 | h6 { 95 | font-size: inherit; 96 | font-weight: inherit; 97 | } 98 | 99 | /* 100 | Reset links to optimize for opt-in styling instead of opt-out. 101 | */ 102 | 103 | a { 104 | color: inherit; 105 | text-decoration: inherit; 106 | } 107 | 108 | /* 109 | Add the correct font weight in Edge and Safari. 110 | */ 111 | 112 | b, 113 | strong { 114 | font-weight: bolder; 115 | } 116 | 117 | /* 118 | 1. Use the user's configured `mono` font family by default. 119 | 2. Correct the odd `em` font sizing in all browsers. 120 | */ 121 | 122 | code, 123 | kbd, 124 | samp, 125 | pre { 126 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 127 | /* 1 */ 128 | font-size: 1em; 129 | /* 2 */ 130 | } 131 | 132 | /* 133 | Add the correct font size in all browsers. 134 | */ 135 | 136 | small { 137 | font-size: 80%; 138 | } 139 | 140 | /* 141 | Prevent `sub` and `sup` elements from affecting the line height in all browsers. 142 | */ 143 | 144 | sub, 145 | sup { 146 | font-size: 75%; 147 | line-height: 0; 148 | position: relative; 149 | vertical-align: baseline; 150 | } 151 | 152 | sub { 153 | bottom: -0.25em; 154 | } 155 | 156 | sup { 157 | top: -0.5em; 158 | } 159 | 160 | /* 161 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 162 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 163 | 3. Remove gaps between table borders by default. 164 | */ 165 | 166 | table { 167 | text-indent: 0; 168 | /* 1 */ 169 | border-color: inherit; 170 | /* 2 */ 171 | border-collapse: collapse; 172 | /* 3 */ 173 | } 174 | 175 | /* 176 | 1. Change the font styles in all browsers. 177 | 2. Remove the margin in Firefox and Safari. 178 | 3. Remove default padding in all browsers. 179 | */ 180 | 181 | button, 182 | input, 183 | optgroup, 184 | select, 185 | textarea { 186 | font-family: inherit; 187 | /* 1 */ 188 | font-size: 100%; 189 | /* 1 */ 190 | font-weight: inherit; 191 | /* 1 */ 192 | line-height: inherit; 193 | /* 1 */ 194 | color: inherit; 195 | /* 1 */ 196 | margin: 0; 197 | /* 2 */ 198 | padding: 0; 199 | /* 3 */ 200 | } 201 | 202 | /* 203 | Remove the inheritance of text transform in Edge and Firefox. 204 | */ 205 | 206 | button, 207 | select { 208 | text-transform: none; 209 | } 210 | 211 | /* 212 | 1. Correct the inability to style clickable types in iOS and Safari. 213 | 2. Remove default button styles. 214 | */ 215 | 216 | button, 217 | [type='button'], 218 | [type='reset'], 219 | [type='submit'] { 220 | -webkit-appearance: button; 221 | /* 1 */ 222 | background-color: transparent; 223 | /* 2 */ 224 | background-image: none; 225 | /* 2 */ 226 | } 227 | 228 | /* 229 | Use the modern Firefox focus style for all focusable elements. 230 | */ 231 | 232 | :-moz-focusring { 233 | outline: auto; 234 | } 235 | 236 | /* 237 | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) 238 | */ 239 | 240 | :-moz-ui-invalid { 241 | box-shadow: none; 242 | } 243 | 244 | /* 245 | Add the correct vertical alignment in Chrome and Firefox. 246 | */ 247 | 248 | progress { 249 | vertical-align: baseline; 250 | } 251 | 252 | /* 253 | Correct the cursor style of increment and decrement buttons in Safari. 254 | */ 255 | 256 | ::-webkit-inner-spin-button, 257 | ::-webkit-outer-spin-button { 258 | height: auto; 259 | } 260 | 261 | /* 262 | 1. Correct the odd appearance in Chrome and Safari. 263 | 2. Correct the outline style in Safari. 264 | */ 265 | 266 | [type='search'] { 267 | -webkit-appearance: textfield; 268 | /* 1 */ 269 | outline-offset: -2px; 270 | /* 2 */ 271 | } 272 | 273 | /* 274 | Remove the inner padding in Chrome and Safari on macOS. 275 | */ 276 | 277 | ::-webkit-search-decoration { 278 | -webkit-appearance: none; 279 | } 280 | 281 | /* 282 | 1. Correct the inability to style clickable types in iOS and Safari. 283 | 2. Change font properties to `inherit` in Safari. 284 | */ 285 | 286 | ::-webkit-file-upload-button { 287 | -webkit-appearance: button; 288 | /* 1 */ 289 | font: inherit; 290 | /* 2 */ 291 | } 292 | 293 | /* 294 | Add the correct display in Chrome and Safari. 295 | */ 296 | 297 | summary { 298 | display: list-item; 299 | } 300 | 301 | /* 302 | Removes the default spacing and border for appropriate elements. 303 | */ 304 | 305 | blockquote, 306 | dl, 307 | dd, 308 | h1, 309 | h2, 310 | h3, 311 | h4, 312 | h5, 313 | h6, 314 | hr, 315 | figure, 316 | p, 317 | pre { 318 | margin: 0; 319 | } 320 | 321 | fieldset { 322 | margin: 0; 323 | padding: 0; 324 | } 325 | 326 | legend { 327 | padding: 0; 328 | } 329 | 330 | ol, 331 | ul, 332 | menu { 333 | list-style: none; 334 | margin: 0; 335 | padding: 0; 336 | } 337 | 338 | /* 339 | Prevent resizing textareas horizontally by default. 340 | */ 341 | 342 | textarea { 343 | resize: vertical; 344 | } 345 | 346 | /* 347 | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 348 | 2. Set the default placeholder color to the user's configured gray 400 color. 349 | */ 350 | 351 | input::-moz-placeholder, textarea::-moz-placeholder { 352 | opacity: 1; 353 | /* 1 */ 354 | color: #9ca3af; 355 | /* 2 */ 356 | } 357 | 358 | input::placeholder, 359 | textarea::placeholder { 360 | opacity: 1; 361 | /* 1 */ 362 | color: #9ca3af; 363 | /* 2 */ 364 | } 365 | 366 | /* 367 | Set the default cursor for buttons. 368 | */ 369 | 370 | button, 371 | [role="button"] { 372 | cursor: pointer; 373 | } 374 | 375 | /* 376 | Make sure disabled buttons don't get the pointer cursor. 377 | */ 378 | 379 | :disabled { 380 | cursor: default; 381 | } 382 | 383 | /* 384 | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 385 | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) 386 | This can trigger a poorly considered lint error in some tools but is included by design. 387 | */ 388 | 389 | img, 390 | svg, 391 | video, 392 | canvas, 393 | audio, 394 | iframe, 395 | embed, 396 | object { 397 | display: block; 398 | /* 1 */ 399 | vertical-align: middle; 400 | /* 2 */ 401 | } 402 | 403 | /* 404 | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) 405 | */ 406 | 407 | img, 408 | video { 409 | max-width: 100%; 410 | height: auto; 411 | } 412 | 413 | *, ::before, ::after { 414 | --tw-border-spacing-x: 0; 415 | --tw-border-spacing-y: 0; 416 | --tw-translate-x: 0; 417 | --tw-translate-y: 0; 418 | --tw-rotate: 0; 419 | --tw-skew-x: 0; 420 | --tw-skew-y: 0; 421 | --tw-scale-x: 1; 422 | --tw-scale-y: 1; 423 | --tw-pan-x: ; 424 | --tw-pan-y: ; 425 | --tw-pinch-zoom: ; 426 | --tw-scroll-snap-strictness: proximity; 427 | --tw-ordinal: ; 428 | --tw-slashed-zero: ; 429 | --tw-numeric-figure: ; 430 | --tw-numeric-spacing: ; 431 | --tw-numeric-fraction: ; 432 | --tw-ring-inset: ; 433 | --tw-ring-offset-width: 0px; 434 | --tw-ring-offset-color: #fff; 435 | --tw-ring-color: rgb(59 130 246 / 0.5); 436 | --tw-ring-offset-shadow: 0 0 #0000; 437 | --tw-ring-shadow: 0 0 #0000; 438 | --tw-shadow: 0 0 #0000; 439 | --tw-shadow-colored: 0 0 #0000; 440 | --tw-blur: ; 441 | --tw-brightness: ; 442 | --tw-contrast: ; 443 | --tw-grayscale: ; 444 | --tw-hue-rotate: ; 445 | --tw-invert: ; 446 | --tw-saturate: ; 447 | --tw-sepia: ; 448 | --tw-drop-shadow: ; 449 | --tw-backdrop-blur: ; 450 | --tw-backdrop-brightness: ; 451 | --tw-backdrop-contrast: ; 452 | --tw-backdrop-grayscale: ; 453 | --tw-backdrop-hue-rotate: ; 454 | --tw-backdrop-invert: ; 455 | --tw-backdrop-opacity: ; 456 | --tw-backdrop-saturate: ; 457 | --tw-backdrop-sepia: ; 458 | } 459 | 460 | ::-webkit-backdrop { 461 | --tw-border-spacing-x: 0; 462 | --tw-border-spacing-y: 0; 463 | --tw-translate-x: 0; 464 | --tw-translate-y: 0; 465 | --tw-rotate: 0; 466 | --tw-skew-x: 0; 467 | --tw-skew-y: 0; 468 | --tw-scale-x: 1; 469 | --tw-scale-y: 1; 470 | --tw-pan-x: ; 471 | --tw-pan-y: ; 472 | --tw-pinch-zoom: ; 473 | --tw-scroll-snap-strictness: proximity; 474 | --tw-ordinal: ; 475 | --tw-slashed-zero: ; 476 | --tw-numeric-figure: ; 477 | --tw-numeric-spacing: ; 478 | --tw-numeric-fraction: ; 479 | --tw-ring-inset: ; 480 | --tw-ring-offset-width: 0px; 481 | --tw-ring-offset-color: #fff; 482 | --tw-ring-color: rgb(59 130 246 / 0.5); 483 | --tw-ring-offset-shadow: 0 0 #0000; 484 | --tw-ring-shadow: 0 0 #0000; 485 | --tw-shadow: 0 0 #0000; 486 | --tw-shadow-colored: 0 0 #0000; 487 | --tw-blur: ; 488 | --tw-brightness: ; 489 | --tw-contrast: ; 490 | --tw-grayscale: ; 491 | --tw-hue-rotate: ; 492 | --tw-invert: ; 493 | --tw-saturate: ; 494 | --tw-sepia: ; 495 | --tw-drop-shadow: ; 496 | --tw-backdrop-blur: ; 497 | --tw-backdrop-brightness: ; 498 | --tw-backdrop-contrast: ; 499 | --tw-backdrop-grayscale: ; 500 | --tw-backdrop-hue-rotate: ; 501 | --tw-backdrop-invert: ; 502 | --tw-backdrop-opacity: ; 503 | --tw-backdrop-saturate: ; 504 | --tw-backdrop-sepia: ; 505 | } 506 | 507 | ::backdrop { 508 | --tw-border-spacing-x: 0; 509 | --tw-border-spacing-y: 0; 510 | --tw-translate-x: 0; 511 | --tw-translate-y: 0; 512 | --tw-rotate: 0; 513 | --tw-skew-x: 0; 514 | --tw-skew-y: 0; 515 | --tw-scale-x: 1; 516 | --tw-scale-y: 1; 517 | --tw-pan-x: ; 518 | --tw-pan-y: ; 519 | --tw-pinch-zoom: ; 520 | --tw-scroll-snap-strictness: proximity; 521 | --tw-ordinal: ; 522 | --tw-slashed-zero: ; 523 | --tw-numeric-figure: ; 524 | --tw-numeric-spacing: ; 525 | --tw-numeric-fraction: ; 526 | --tw-ring-inset: ; 527 | --tw-ring-offset-width: 0px; 528 | --tw-ring-offset-color: #fff; 529 | --tw-ring-color: rgb(59 130 246 / 0.5); 530 | --tw-ring-offset-shadow: 0 0 #0000; 531 | --tw-ring-shadow: 0 0 #0000; 532 | --tw-shadow: 0 0 #0000; 533 | --tw-shadow-colored: 0 0 #0000; 534 | --tw-blur: ; 535 | --tw-brightness: ; 536 | --tw-contrast: ; 537 | --tw-grayscale: ; 538 | --tw-hue-rotate: ; 539 | --tw-invert: ; 540 | --tw-saturate: ; 541 | --tw-sepia: ; 542 | --tw-drop-shadow: ; 543 | --tw-backdrop-blur: ; 544 | --tw-backdrop-brightness: ; 545 | --tw-backdrop-contrast: ; 546 | --tw-backdrop-grayscale: ; 547 | --tw-backdrop-hue-rotate: ; 548 | --tw-backdrop-invert: ; 549 | --tw-backdrop-opacity: ; 550 | --tw-backdrop-saturate: ; 551 | --tw-backdrop-sepia: ; 552 | } 553 | 554 | .absolute { 555 | position: absolute; 556 | } 557 | 558 | .m-auto { 559 | margin: auto; 560 | } 561 | 562 | .my-auto { 563 | margin-top: auto; 564 | margin-bottom: auto; 565 | } 566 | 567 | .my-5 { 568 | margin-top: 1.25rem; 569 | margin-bottom: 1.25rem; 570 | } 571 | 572 | .mb-5 { 573 | margin-bottom: 1.25rem; 574 | } 575 | 576 | .mt-1 { 577 | margin-top: 0.25rem; 578 | } 579 | 580 | .mb-1 { 581 | margin-bottom: 0.25rem; 582 | } 583 | 584 | .mb-0 { 585 | margin-bottom: 0px; 586 | } 587 | 588 | .mt-2 { 589 | margin-top: 0.5rem; 590 | } 591 | 592 | .block { 593 | display: block; 594 | } 595 | 596 | .flex { 597 | display: flex; 598 | } 599 | 600 | .h-8 { 601 | height: 2rem; 602 | } 603 | 604 | .max-w-5xl { 605 | max-width: 64rem; 606 | } 607 | 608 | .flex-col { 609 | flex-direction: column; 610 | } 611 | 612 | .flex-wrap { 613 | flex-wrap: wrap; 614 | } 615 | 616 | .justify-between { 617 | justify-content: space-between; 618 | } 619 | 620 | .border-2 { 621 | border-width: 2px; 622 | } 623 | 624 | .border { 625 | border-width: 1px; 626 | } 627 | 628 | .border-black { 629 | --tw-border-opacity: 1; 630 | border-color: rgb(0 0 0 / var(--tw-border-opacity)); 631 | } 632 | 633 | .object-contain { 634 | -o-object-fit: contain; 635 | object-fit: contain; 636 | } 637 | 638 | .p-2 { 639 | padding: 0.5rem; 640 | } 641 | 642 | .pt-5 { 643 | padding-top: 1.25rem; 644 | } 645 | 646 | .text-2xl { 647 | font-size: 1.5rem; 648 | line-height: 2rem; 649 | } 650 | 651 | .text-xs { 652 | font-size: 0.75rem; 653 | line-height: 1rem; 654 | } 655 | 656 | .text-sm { 657 | font-size: 0.875rem; 658 | line-height: 1.25rem; 659 | } 660 | 661 | .text-xl { 662 | font-size: 1.25rem; 663 | line-height: 1.75rem; 664 | } 665 | 666 | .font-bold { 667 | font-weight: 700; 668 | } 669 | 670 | .text-neutral-600 { 671 | --tw-text-opacity: 1; 672 | color: rgb(82 82 82 / var(--tw-text-opacity)); 673 | } 674 | 675 | .underline { 676 | -webkit-text-decoration-line: underline; 677 | text-decoration-line: underline; 678 | } 679 | 680 | .underline-offset-2 { 681 | text-underline-offset: 2px; 682 | } 683 | 684 | .underline-offset-4 { 685 | text-underline-offset: 4px; 686 | } 687 | 688 | #opcodes { 689 | max-height: 400px; 690 | } 691 | 692 | #contract-calls{ 693 | max-height: 2650px; 694 | } 695 | 696 | .opcode { 697 | margin: 10px 5px; 698 | min-width: 200px; 699 | } 700 | 701 | .contract-call { 702 | margin: 10px 5px; 703 | min-width: 200px; 704 | } 705 | 706 | .operation-name { 707 | /* display: flex; */ 708 | /* align-items: center; */ 709 | } 710 | 711 | a { 712 | text-decoration: underline; 713 | color: blue; 714 | cursor: pointer; 715 | } 716 | 717 | @media only screen and (max-width: 1000px) { 718 | body { 719 | padding: 2%; 720 | } 721 | 722 | #opcodes { 723 | flex-direction: row !important; 724 | max-height: 1000000000px !important; 725 | /* nonsensically large number to prevent overlapping */ 726 | } 727 | 728 | #contract-calls{ 729 | flex-direction: row !important; 730 | max-height: 1000000000px !important; 731 | /* nonsensically large number to prevent overlapping */ 732 | } 733 | } --------------------------------------------------------------------------------