3

According to the docs here,

For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding

I ran the following using pyrlp (similar to the code in pyethereum here):

res = rlp.encode([1, 0])
print ':'.join(x.encode('hex') for x in res)

and got a result of c2:01:80. The c2 refers to the list identifier (c0 + 2 bytes for the following 2 elements). The 01 is obviously the first element in the array (1), encoded as itself. The 0 however is encoded to hex 80, which from my understanding of the documentation should not be the case.

I did notice in the examples on the RLP wiki that the null string encodes to hex 80, so is that factoring into this somehow?

2 Answers 2

4

It appears that encoding the integer 0 no longer equates to \x00 (as the documentation would imply). This can be seen both in your example, and in the fact that it can't be decoded:

>>> decode('\x00')
'\x00'
>>> decode('\x00', big_endian_int)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/rlp/codec.py", line 214, in decode
....

I think the typeless-ness of RLP encoding means that this shouldn't be an issue. Instead you can use \x80 and a sedes object to specify the type:

>>> decode('\x80')
''
>>> decode('\x80', big_endian_int)
0
2
  • The RLP specification says that an integer zero should equate to the empty array (zero bytes)
    – Sentinel
    Commented Nov 12, 2017 at 8:59
  • @Sentinel Can you please cite the exact quote Commented Mar 24, 2018 at 3:57
2

RLP is defined in Ethereum Yellow Paper (Appendix A, page 16).

There are few interesting quotes:

We define the RLP function as RLP through two sub-functions, the first handling the instance when the value is a byte array, the second when it is a sequence of further values

If the byte-array contains fewer than 56 bytes, then the output is equal to the input prefixed by the byte equal to the length of the byte array plus 128

If RLP is used to encode a scalar, defined only as a positive integer (P or any x for Px), it must be specified as the shortest byte array such that the big-endian interpretation of it is equal

The last one tells that leading zero bytes needs to be trimmed from big-endian representation of scalar values.

Scalar 0 is a special case - big-endian interpretation of 0 consists of zeros - so after trimming, we get empty byte array. Empty byte array has length < 56, so it's length is encoded as 0+128 which is 0x80 in hex.

@bozzle as you quoted from documentation, byte array consisting of single byte with value 0x00 should be encoded as 0x00. But scalar 0 is just a different case.

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.