3

I'm calculating the gas costs of the following contract: 0x6001600190016007026005016002900460049060016021900560150160030260059007600303600960110a60005260086000f3.

Disassembled versions:

contract Contract {
    function main() {
        var var0 = 0x04;
        var var1 = (0x05 + 0x07 * (0x01 + 0x01)) / 0x02;
        var var2 = 0x03 - (0x03 * 0x15) i% 0x05;
        memory[0x00:0x20] = 0x11 ** 0x09;
        return memory[0x00:0x08];
    }
}

label_0000:
    // Inputs[1] { @0032  memory[0x00:0x08] }
    0000    60  PUSH1 0x01
    0002    60  PUSH1 0x01
    0004    90  SWAP1
    0005    01  ADD
    0006    60  PUSH1 0x07
    0008    02  MUL
    0009    60  PUSH1 0x05
    000B    01  ADD
    000C    60  PUSH1 0x02
    000E    90  SWAP1
    000F    04  DIV
    0010    60  PUSH1 0x04
    0012    90  SWAP1
    0013    60  PUSH1 0x01
    0015    60  PUSH1 0x21
    0017    90  SWAP1
    0018    05  SDIV
    0019    60  PUSH1 0x15
    001B    01  ADD
    001C    60  PUSH1 0x03
    001E    02  MUL
    001F    60  PUSH1 0x05
    0021    90  SWAP1
    0022    07  SMOD
    0023    60  PUSH1 0x03
    0025    03  SUB
    0026    60  PUSH1 0x09
    0028    60  PUSH1 0x11
    002A    0A  EXP
    002B    60  PUSH1 0x00
    002D    52  MSTORE
    002E    60  PUSH1 0x08
    0030    60  PUSH1 0x00
    0032    F3  *RETURN

My estimation was (based on the recent fee schedule: https://docs.google.com/spreadsheets/d/1n6mRqkBz3iWcOlRem_mO09GtSKEKrAsfO7Frgx18pNU/edit#gid=0)

3 x ADD + 2 x MUL + SUB + DIV + SDIV + SMOD + EXP + MSTORE + 17 x PUSH + 5 x SWAP =
3 x 3   + 2 x 5   + 3   + 5   + 5    + 5    + 60  + 6      + 17 x 3    + 5 x 3    =
169

Unfortunately, the corresponding VM test in the official go-ethereum repository (https://github.com/ethereum/tests/blob/ad2184adca367c0b68c65b44519dba16e1d0b9e2/VMTests/vmArithmeticTest/arith1.json) estimates this as 129.

Where have I over-counted 40 gas in this execution?

(please note transaction and call costs are not applicable for VM tests)

  • 1
    I am not sure, but it could be due to G_expbyte. If you look at the yellow paper (294) there are two different cases for EXP. One with exponent = 0 and one with exponent > 0 where G_expbyte is involved. However, G_expbyte is 50, so it doesn't fit the gap of 15. – ivicaa Dec 9 '18 at 22:37
  • 1
    Do you have an idea how to explain the gap? Afaik G_expbyte is 50. – ivicaa Dec 10 '18 at 7:52
  • 1
    Hi, it is not the answer, but I think you added one PUSH in your calculation and you forgot one SMOD instruction. May I ask you which tool do you use for disassembling? – Briomkez Dec 10 '18 at 9:24
  • 1
    I'm using this tool: ethervm.io/decompile – Peteris Dec 10 '18 at 9:36
  • 1
    What does i% mean? Why is the function return-value type not declared? What does memory[...] mean? Your code does not compile. – goodvibration Dec 10 '18 at 9:51
3
+50

The formula for EXP (according to the yellow paper) is the following one:

G_exp + G_expbyte * (1 + floor(log256(exponent)))

In your case exponent is equals to 0x09. So if we use the current formula we will get:

10 + 50 * (1 + 0) = 60

As you said. However, apparently the test result were calculated with an old version in which EIP160 did not come into force. So the G_expbyte constant should be set to 10 (as stated here in this accademic paper):

10 + 10 * (1) = 20

Which explains the result of 129 gas.

The name of the fork as pointed out by @flygoing is "pre-Spurious Dragon fork".

  • 1
    Small correction, doesn't change the output, but EXP defines stack[0] as the base and stack[1] as the exponent, so the exponent is 0x09 – flygoing Dec 10 '18 at 17:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.