wolflo / evm-opcodes Goto Github PK
View Code? Open in Web Editor NEWA quick reference for EVM opcodes
License: MIT License
A quick reference for EVM opcodes
License: MIT License
My Public Address to Receive BNB 0x79a57369fdC6DFa10Bc319B229372a96Aa82a316
Pay me via Trust Wallet: https://link.trustwallet.com/send?coin=20000714&address=0x79a57369fdC6DFa10Bc319B229372a96Aa82a316
Hi! I really love your guide, which is probably the best on the web about gas cost.
I saw a little typo here
"The memory cost function is linear up to 724 bytes of memory used, at which point additional memory costs substantially more." This refers to the formula: gas_cost = (new_mem_size_words ^ 2 // 512) + (3 * new_mem_size_words) - Cmem(old_state)
.
I think you mean 724 32-bytes of memory. Indeed, the line above states new_mem_size_words = (new_mem_size + 31) // 32
: number of (32-byte) words required for memory after the operation in question
Hi and thanks for this great repo.
Has this been updated to berlin's fork ? If not, when do you plan on doing it?
because they are wrong
Update for the upcoming London hardfork. There is no mainnet block yet, but mid-July seems likely.
The relevant EIPs are probably EIP-3198 (BASEFEE
), EIP-3529 (reduction in refunds), and EIP-3541 (reject new contracts with leading 0xEF byte).
Is the create and create2 gas calculation method wrong?
I think create and create2 gas should include initcode_cost.
For the CREATE and CREATE2 instructions charge an extra gas cost equaling to initcode_cost(initcode). This cost is deducted before the calculation of the resulting contract address and the execution of initcode.(https://eips.ethereum.org/EIPS/eip-3860)
Hi,
Great costs...
On execution of any invalid operation, whether the designated INVALID op or simply an undefined op, all remaining gas is consumed and the state is reverted to the point immediately prior to the beginning of the current execution context.
.
Could you explain what you mean by this ? if the revert happens, all remaining gas is NOT consumed, but it goes back to the caller's account
Hi Alex,
I will try to explain my point of view on the gas costs of CALL
and hopefully, you can somehow make me see where I could be wrong.
So, before calling a function, EVM has to execute the following opcodes.
GAS
CALL
It's really easy to look into the source code and see what GAS
opcode does. It's constant gas is 2 and it's operation is opGas
quickly seen in the jump table.
opGas
function is super simple and it does the following:
callContext.stack.push(new(uint256.Int).SetUint64(callContext.contract.Gas))
So, after the GAS
opcode got executed, in the stack, we have the remaining gas stored. callContext.contract.Gas
is just a variable that decreases after each operation gets executed. So, first point here is that it's not going to store available_gas - 40
on the stack as you said. It's directly stores callContext.contract.Gas
. The reason it doesn't store available_gas - 40
is that it didn't yet move to the CALL
operation. So, long story, short, we have callContext.contract.Gas
stored on the stack. Let's say this number now is 4000...
Now, CALL
opcode comes into play. Here are what it has:
execute: opCall,
constantGas: params.CallGasFrontier,
dynamicGas: gasCall,
EVM first runs constantGas
which will make contract.Gas
=> contract.Gas - 40
because CallGasFrontier
is 40. So, it will become 4000-40 = 3960.
Then it runs dynamicGas
which has the corresponding function gasCall
..
gasCall
now creates a new variable called gas
and sums it up. (If the account is new, it adds some gas costs, if address doesn't exist, it adds some gas costs and so on) + it also adds up memory costs. After this, we got the final gas
counted and it calls:
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
// callGasTemp is the most important one, because this is exactly how much gas we pass to the callee.
// The above line calls the below code, where `contract.Gas` is `availableGas`(3960),
// `gas` is the `base` , and `stack.Back(0)` is what we put on the stack a while ago which is 4000.
availableGas = availableGas - base
gas := availableGas - availableGas/64
// If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150
// is smaller than the requested amount. Therefore we return the new gas instead
// of returning an error.
if !callCost.IsUint64() || gas < callCost.Uint64() {
return gas, nil
}
Now, if we calculate the gas
above, it will always be less than the requested gas from the GAS
opcode above which is 4000. Always and Always.
Question 1. So, I don't understand why we return the minimal from the requested gas and all_but_one_64th, because all_but_one_64
will always be less.
Question 2. Unfrotunatelly, I couldn't see where it reduces contract's gas by 700. It still does by 40. Shouldn't it be 700 ?
Line 15 in 2b745ab
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.