1

I am executing a dummy (smart) contract through the evm command line to understand how input is passed to the contract. I am using the following contract bytecode:

60003500
PUSH1 0x00
CALLDATALOAD
STOP

If I provide 0x101 as input I get the expected result:

>>> evm --code 60003500 --input 101 --debug run
0x
#### TRACE ####
PUSH1           pc=00000000 gas=10000000000 cost=3

CALLDATALOAD    pc=00000002 gas=9999999997 cost=3
Stack:
00000000  0x0

STOP            pc=00000003 gas=9999999994 cost=0
Stack:
00000000  0x101000000000000000000000000000000000000000000000000000000000000  # AS EXPECTED

Although, if I input 0x001, the heading zeros seem to be dropped by the evm (see stack state on last line).

>>> evm --code 60003500 --input 001 --debug run
0x
#### TRACE ####
PUSH1           pc=00000000 gas=10000000000 cost=3

CALLDATALOAD    pc=00000002 gas=9999999997 cost=3
Stack:
00000000  0x0

STOP            pc=00000003 gas=9999999994 cost=0
Stack:
00000000  0x1000000000000000000000000000000000000000000000000000000000000   # NOT AS EXPECTED

I am using evm version 1.10.17-stable-25c9b49f. Why does the evm drops the leading zeros?

Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
  • 1
    Leading zeros are irrelevant. That’s not different to elementary school’s math. – Holger Apr 19 '22 at 08:52
  • @Holger That is completely wrong. If I want the first 32-bytes word to be 0 and the second word to be say 42, I need to be able to add 126 heading hexadecimal zeros in to the input. – Olivier Melançon Apr 19 '22 at 12:53
  • You may write the obsolete leading zeros for the input if you have time to waste, the output obviously omits them. Even in the `0x101…` case, there’s a leading zero omitted, also when you do `PUSH1 0x00`, the printed result is `0x0`, without the obsolete second zero. – Holger Apr 19 '22 at 13:27
  • @Holger You seem to misunderstand my question. How do I use the evm command line interface such that the first word in the call message is a 0 and the second one is some other value? – Olivier Melançon Apr 19 '22 at 14:12

2 Answers2

0

See Holger's comment. Leading zeros do not change the value of a number.

Here's a decimal example to demonstrate:

12 = 1*10 + 2*1 = 10 + 2 = 12

012 = 0*100 + 1*10 + 2*1 = 0 + 10 + 2 = 12

The 0x in front of the hexadecimal number is simply to tell humans (and computers) that the number that follows is in hexadecimal format, instead of decimal.

EDIT: It appears that the question you are asking is how to pass 0x0100000000000000000000000000000. The reason that 0x01 translates to 0x100000000000000000000000000000 is because it first evaluates to 0x1, then it is right-shifted until all the remaining bits are filled with zeros. To represent 0x0100000000000000000000000000000, you must put 0x0100000000000000000000000000000.

Pandapip1
  • 730
  • 5
  • 15
  • See my response to Holger's comment. I know how to write numbers... my question is about the EVM representation of inputted 256-bit words. This does not answer my question. Putting `0x0100000000000000000000000000000` as input drops the leading zero as shown in my question. – Olivier Melançon Apr 19 '22 at 22:05
  • I admit I cannot seem to find an explanation for that. Perhaps it's a bug? – Pandapip1 Apr 20 '22 at 12:10
  • 1
    I ended posting an issue on github. The problem seems to be caused part by me not counting hex decimal digits correctly and half by the CLI weirdly accepting odd length input – Olivier Melançon Apr 20 '22 at 15:14
0

It turns out there is a tiny bug in the evm for odd length inputs. So none of the examples in the question actually gives the expected result despite me stating that the first one was as expected.

Here is a simplified example. Both of the following commands send the same call message to the smart contract:

evm --code 60003500 --input 1 -debug run

evm --code 60003500 --input 01 -debug run

The call message is 0x0100000000000000000000000000000000000000000000000000000000000000 in both cases. Thus the bug is not that the leading zero of the second command is dropped, but rather that a leading zero is added to the input when there is an odd-length input.

I eventually got confident enough that something was fishy to post an issue which was later fixed. For older versions the easy fix is to always provide even-length input as the call message is not simply filled bit by bit from left to right.

Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73