'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