Merkle Trees in Aztec

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0101\)

Merkle Tree Basics

\(A\)

\(F\)

\(N\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(\text{root}\)

\(\text{nodes}\)

\(\text{leaves}\)

\(\text{hash path}\)

\(\text{depth} = 4\)

Storage of Merkle Tree

  • We store merkle trees using levelDB database
  • Use of the dictionary data structure 
  • For a depth \(d=3\) tree with all leaves non-empty:

\(i=0\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(i=1\)

\(i=2\)

\(\text{key}\)

\(\text{value}\)

\(r\)

\(h^2_0\)

\(h^2_1\)

\(h^2_1\)

\(h^1_2\)

\(h^1_3\)

\(h^1_0\)

\(h^0_0\)

\(h^0_1\)

\(h^1_1\)

\(h^0_2\)

\(h^0_3\)

\(h^1_2\)

\(h^0_4\)

\(h^0_5\)

\(h^1_3\)

\(h^0_6\)

\(h^0_7\)

\(h^2_0\)

\(h^1_0\)

\(h^1_1\)

Storage of Merkle Tree

  • Suppose we have depth \(d=3\) tree with only 5 filled leaves
  • Right subtree at \(i=2\) is called as a stump as only one leaf is filled in it!
  • For a stump, we only store the filled leaf value and its subtree index
  • Note that we use \(65\) bytes to store a stump, \(64\) bytes for a usual node
  • Provides optimised storage for sparse merkle trees

\(i=0\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(i=1\)

\(i=2\)

\(\text{key}\)

\(\text{value}\)

\(r\)

\(h^2_0\)

\(h^2_1\)

\(h^2_0\)

\(h^1_0\)

\(h^1_1\)

\(h^2_1\)

\(h^0_6\)

\(2\)

\(\texttt{true}\)

\(h^1_0\)

\(h^0_0\)

\(h^0_1\)

\(h^1_1\)

\(h^0_2\)

\(h^0_3\)

\(1101\)

\(1010\)

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(\text{key}\)

\(\text{value}\)

\(r\)

\(h^3_0\)

\(h^3_1\)

\(h^2_0\)

\(h^3_0\)

\(h^2_1\)

\(5\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(0\)

\(A\)

\(\texttt{true}\)

\(h^2_0\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

\(\text{Common Height} = 2\)

\(z[2]\)

\(h^2_3\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

\(z[2]\)

\(h^2_3\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

\(z[2]\)

\(h^2_3\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

\(z[2]\)

\(h^2_3\)

\(z[1]\)

\(z[1]\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

\(z[2]\)

\(h^2_3\)

\(z[1]\)

\(z[1]\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

\(z[2]\)

\(h^2_3\)

\(z[1]\)

\(z[1]\)

Hash Path

\(A\)

\(F\)

\(N\)

\(i=0\)

\(i=1\)

\(i=2\)

\(i=3\)

\(0\)

\(1\)

\(2\)

\(3\)

\(4\)

\(5\)

\(6\)

\(7\)

\(8\)

\(9\)

\(10\)

\(11\)

\(12\)

\(13\)

\(14\)

\(15\)

\(1101\)

\(1010\)

\(r\)

\(h^3_0\)

\(5\)

\(h^2_0\)

\(\text{key}\)

\(\text{value}\)

\(h^3_1\)

\(h^3_0\)

\(N\)

\(h^3_1\)

\(\texttt{true}\)

\(h^2_1\)

\(0\)

\(A\)

\(\texttt{true}\)

\(1\)

\(F\)

\(\texttt{true}\)

\(h^2_0\)

\(h^2_1\)

\(\vec{h}(10)\)

\(0\)

\(1\)

\(2\)

\(3\)

\(h^3_0\)

\(h^3_1\)

\(z[2]\)

\(h^2_3\)

\(z[1]\)

\(z[1]\)

\(-1\)

\(-1\)

Hash Path

Indexed Merkle Tree

\begin{aligned} \textsf{val} = \\ \textsf{nextIdx} = \\ \textsf{nextVal} = \end{aligned}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}

Indexed Merkle Tree

\begin{aligned} \textsf{val} = \\ \textsf{nextIdx} = \\ \textsf{nextVal} = \end{aligned}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 1 \\ 30 \end{bmatrix}
\begin{bmatrix} 30 \\ 0 \\ 0 \end{bmatrix}

Indexed Merkle Tree

\begin{aligned} \textsf{val} = \\ \textsf{nextIdx} = \\ \textsf{nextVal} = \end{aligned}
\begin{bmatrix} 10 \\ 1 \\ 30 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 2 \\ 20 \end{bmatrix}
\begin{bmatrix} 30 \\ 0 \\ 0 \end{bmatrix}

Indexed Merkle Tree

\begin{aligned} \textsf{val} = \\ \textsf{nextIdx} = \\ \textsf{nextVal} = \end{aligned}
\begin{bmatrix} 10 \\ 3 \\ 20 \end{bmatrix}
\begin{bmatrix} 20 \\ 1 \\ 30 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 2 \\ 20 \end{bmatrix}
\begin{bmatrix} 30 \\ 0 \\ 0 \end{bmatrix}

Indexed Merkle Tree

\begin{aligned} \textsf{val} = \\ \textsf{nextIdx} = \\ \textsf{nextVal} = \end{aligned}
\begin{bmatrix} 10 \\ 3 \\ 20 \end{bmatrix}
\begin{bmatrix} 20 \\ 1 \\ 30 \end{bmatrix}
\begin{bmatrix} 50 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}
\begin{bmatrix} 0 \\ 2 \\ 20 \end{bmatrix}
\begin{bmatrix} 30 \\ 4 \\ 50 \end{bmatrix}

Merkle Trees

By Suyash Bagad

Merkle Trees

How do Merkle trees work?

  • 225