Ethereum Under The Hood Part 3 (RLP Decoding)
Tags: ethereum, blockchain, cryptocurrency
Published: 2021-03-10 13:36:30

---
title: Ethereum Under The Hood Part 3 (RLP Decoding)
published: true
date: 2021-03-09 05:15:05 UTC
tags: ethereum,blockchain,cryptocurrency
canonical_url: https://medium.com/coinmonks/ethereum-under-the-hood-part-3-rlp-decoding-df236dc13e58
---

![](https://cdn-images-1.medium.com/max/760/1*h6cTWRfIlxnSTjyPwPUGlA.png)

**_Update: Grammer fix_**

_Part-3 of the Recursive Link Prefix(RLP Decoding),_ **_if you have not gone through Part-1, Part-2, please do_** _. In this section, we address decoding Ethereum data using the_ **_RLP decoding specification_** _._

Let’s do a mini recap of what we learned so far:

> _Ethereum is world computer (global State +a virtual machine(VM) ). VM can add a new state to the global state machine. State is a collection blocks, blocks contains a set of transactions. Ethereum uses RLP to serialize/deserialize data. RLP specification only understands two data primitives(item, list of items). World state is stored as a_ [_Ethereum Patricia Merkel Trie_](https://github.com/ethereum/wiki/wiki/Patricia-Tree)_(note: if this does not sound familiar please read_ [_Part_](https://medium.com/@deepakraous/ethereum-under-the-hood-part-i-ver-0-1-4f2fb24b3d68)_1 again.)_

Now let’s jump right into it, **RLP decoding** is straightforward, “decoding” is a fancy word of saying that I am going convert this information to its original format.

**RLP decoding rules:**

1. Look at the first byte,The first byte should fall in one of the following ranges : _[[0x00 .. 0x7f] , [0x80.. 0xb7] , [0xb8 .. 0xbf] , [0xc0 .. 0xf7], [0xf8 .. 0xff]_ ] and Decipher Data type using the following rule if the byte falls within:

> _[0x00 .. 0x7f] : Data is of type_ **_String_** _and should be decoded as it is._

> _[0x80 .. 0xb7] :_ **_String_** _and its a_ **_short_** _ string_

> _[0xb8 .. 0xbf] :_ **_String_** _and its a_ **_long_** _ string_

> _[0xc0 .. 0xf7] :_ **_List_** _and_ **_short_** _ list_

> _[0xf8 .. 0xff] :_ **_List_** _and it’s a_ **_long_** _ list_

2. Get the **length** of the byte array :

_[First byte — First Byte from the Byte Range] = length of the data, e.g.:_ _0x83–0x80 = 3 , 3 is the length of the byte array_

3. Perform Step one and two all over until the end of the byte array.

Let’s take a simple example of a string **“dog”** encoded into RLP as:

```
"dog" = [**0x83** , 0x64, 0x6f, 0x67]
```

![](https://cdn-images-1.medium.com/max/1024/1*2JjSpUYDJqgV7UVUgPJynQ.png)<figcaption><a href="https://www.asciitable.com/">Ascii</a> Chart for handy reference</figcaption>

Let’s **decode** the input as per our rule, so given a byte array as an input

**0x83 '** _d' 'o' 'g'_

1. Retrieve the first byte:  **0x83**
2. Check If the range falls within the specified range set, in this case, it falls between **[0x80 .. 0xb7]** since the first byte is  **0x83.**
3. Calculate Length: First byte- **First byte** in Byte range, **0x83** – **0x80** = 3
4. Data is of type string, and its length is  **3**
5. With these facts, parse until end of string : **0x64, 0x6f, 0x67**

Let’s take another example which deals with **List’s; the** previous example was a simple data structure String “dog”. Decoding Lists is a little more involved; we need to figure the total length of the list and decipher the elements with the List. We also need to keep decoding the list until the end by using [recursion](https://en.wikipedia.org/wiki/Recursion#In_computer_science) techniques for repeatable tasks.

**_[“cat”, “dog”] -> C8 83_** _636174_ **_83_** _646F67 ,_ pause here for a second and let’s decipher by looking at the structure. I see a couple of items here, this is a List, and it has two elements in it, and the data type of those elements is a String, Decoding the List we get[**_C8 83_**](https://github.com/ethereum/wiki/wiki/RLP)[_63 61 74_](https://github.com/ethereum/wiki/wiki/RLP)[**_83_**](https://github.com/ethereum/wiki/wiki/RLP)[_64 6F 67_](https://github.com/ethereum/wiki/wiki/RLP) _(tip: refer to the ascii chart above)_

1. Retrieve the first byte :  **0xc8**
2. Find the closest Byte Range which the first byte falls within; In this case, the First byte falls within the range **[0xc0 .. 0xf7]** hence the data is a  **List.**
3. Create an empty List **[]** to accumulate
4. Length of the list, [0xc8 -0xc0] =  **8**
5. Start deciphering after c8 to get the encoded data from the List until end of List.
6. **_C8 83_** _63 61 74_ **_83_** _64 6F 67_
7. We know we have a list [and it has eight elements], now let’s look at what’s inside the List.
8. Figure out length which is: first byte-range, 0x83–0x80 = 3
9. The data type is **String,** and its length is 3
10. Parse and decipher the next **3** bytes _0x63, 0x61, 0x74_
11. Repeat Steps 8 through 11 until end of the list for the next set of bytes resulting in **0x83** , 0x64, 0x6f, 0x67
12. Calculate the Length and interpret the data, in this case, the data is **0x64,0x6f,0x67.**

Well, the steps involved are repeatable, and **_recursion_** would be a helpful pattern to decode the entire Byte Array. Have a look at the code skeleton which implements the RLP decoding spec. _Note the Byte Ranges in the code below converted to decimals._

![](https://cdn-images-1.medium.com/max/1024/1*kIpxG4jdDazlbBAEYHkhqg.png)<figcaption><em>RLP Decoding </em><a href="https://github.com/deepakraous/elixir_rlp"><em>Skeleton</em></a><em> Code in Elixir</em></figcaption>

![](https://cdn-images-1.medium.com/max/1024/1*yBIEfARx5fGByFdSh5Jt1g.png)<figcaption>Encoding/Decoding RLP for a Small String.</figcaption>

I choose Elixir due to various reasons, including its list manipulation and primitive data types. There are many examples covered in other languages which I would highly recommend to go through, in addition to this check out the references below.

Before we wrap this section up, there is one more encoding and decoding specification which we need to look into for a brief moment. We learned about RLP, which deals with **Values.** To retrieve the data, we need to have a **Key** which provides a path on where to find the Value. So let’s quickly dip into [Hex Prefix(Appendix C)](https://ethereum.github.io/yellowpaper/paper.pdf.)from the yellow paper.

**Hex Prefix:**

Think of Hex Prefix as an encoding/decoding mechanism of the “Path” to a given **value** in the Ethereum network, in Plain English; it means that _I know a way to get to this house and here is the way of storing the map to the house._ I think of this as the “Key” in {Key, Value} tuple and I envision the whole data structure as:

[{key1, value1}, {key2, value2}, {key2, value2} ]

[{hp1, rlp1}, {hp2, rlp2}, {hp3, rlp3} ]

That’s about it; I would highly recommend [Phan Sơn Tự](https://medium.com/u/2d1e5cc8c1db) [medium](https://medium.com/coinmonks/data-structure-in-ethereum-episode-1-compact-hex-prefix-encoding-12558ae02791) post about Hex Prefix for further reference. In [**Part-4**](https://medium.com/coinmonks/ethereum-under-the-hood-part-4-the-trie-a3f71f8dbef8), we connect some of the pieces while talking about Trie and relate to what we learned so far. See you around for [**Part-4**](https://medium.com/coinmonks/ethereum-under-the-hood-part-4-the-trie-a3f71f8dbef8)Patricia Merkle Trie, till then.

### References:

- [CodeChain Serialization](https://medium.com/codechain/test-4245f1fd1bb3)
- [Ethereum's Recursive Length Prefix encoding in Elixir](https://www.badykov.com/elixir/2018/05/06/rlp/)
- [Data structure in Ethereum | Episode 1+: Compact (Hex-prefix) encoding.](https://medium.com/coinmonks/data-structure-in-ethereum-episode-1-compact-hex-prefix-encoding-12558ae02791)
- [In the Ethereum Modified Merkle-Particia tree, what do the prefix, key and value signify?](https://ethereum.stackexchange.com/questions/12941/in-the-ethereum-modified-merkle-particia-tree-what-do-the-prefix-key-and-value/12942#12942)
- [ethereum/wiki](https://github.com/ethereum/wiki/wiki/Patricia-Tree)

* * *