12

EVM has "256bit words". Some cases treat strings shorter than 32 bytes (256 bits) as left-justified ascii (packed into the most significant bytes of the word).

Does this mean that the word value of the string '*' is equivalent to: 42 << 148 ?

Note that the RLP encoding of the single ASCII character '*' is two bytes, whereas the RLP encoding of 42 << 148 is different. Are there important edge cases for security and correctness where the EVM word semantics and RLP encodings don't quite match up?

2 Answers 2

11

It will be easier to understand if we make these two definitions (note: this might not be fully correct, but is enough for the following explanation):

  • the EVM is the machine executing the instructions, which has inputs and outputs
  • the state manager as the one putting data in/out of the blockchain.

Many of the interactions with the blockchain (and state manager) happen via RLP encoded data. One notable exception is the ABI with the contracts (the data field in the transaction).

The EVM itself operates on 256 bit words, which means each stack and each storage space is 256 bit wide and usually you can address them that way (there are a few byte addressing methods). The EVM itself doesn't really care how the data is stored then. The arithmetic instructions will expect a certain format for the data, but that's really it.

The Contract ABI document defines how to interact with a contract and how they interact with each other. As far as I know Solidity as a language also stores data structures internally in a similar way.

The Contract ABI defines different data types each with their own layout. Numbers (int*/uint*) are stored left padded, whereas bytes/string is stored right padded.

9

The EVM is always 256 bits big-endian. From the Yellow Paper, Appendix H: "When interpreting 256-bit binary values as integers, the representation is big-endian."

RLP is different from the Contract ABI.

From above RLP wiki, encodings "must be represented in big endian binary form with no leading zeroes."

There are no (other) explicit rules about padding in the EVM and RLP.

Some cases treat strings shorter than 32 bytes (256 bits) as left-justified ascii (packed into the most significant bytes of the word).

As Axic's answer mentions: "The Contract ABI defines different data types each with their own layout. Numbers (int*/uint*) are stored left padded, whereas bytes/string is stored right padded."

Does this mean that the word value of the string '*' is equivalent to: 42 << 148 ?

No. The ASCII value of '*' is 42 (decimal). The word value is 42 (0x2a in hex) and the EVM would handle it as 42 (which is equivalent to left-padding the first 31 bytes with zeros, and the 32nd byte is 0x2a).

... the RLP encoding of the single ASCII character '*' is two bytes

False, the RLP encoding of '*' is 1 byte (0x2a).

Are there important edge cases for security and correctness where the EVM word semantics and RLP encodings don't quite match up?

The EVM is always 256 bits big-endian, so any RLP encodings smaller than 32 bytes that are provided to the EVM, will be treated by the EVM as having leading zeros. The ABI (separate from the EVM) is what has semantics about padding, which are important to match up for security and correctness.

1
  • Please can you assist with the following question ethereum.stackexchange.com/q/30518/7044 I am not sure if what is written above is entirely accurate. The RLP spec seems to suggest that all integers in Ethereum are always represented without leading zeroes, which would of course affect bitshift operations. The RLP doc says that RLP has no demands on the representation of integers but that 'Ethereum' does (whatever that is). Is that what you mean in the above answer?
    – Sentinel
    Commented Nov 12, 2017 at 9:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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