'EVM command line interface drops heading zeros in input
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?
Solution 1:[1]
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.
Solution 2:[2]
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
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Pandapip1 |