Search code examples
command-line-interfaceethereumbytecodeevm

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

  • 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.