# Merkle-Patricia-tree
A Merkle Patricia Tree* is the combination of a:
* Patricia Trie: An efficient Radix Trie, a data structure in which "keys" represent the path one has to take to reach a node
* Merkle Tree: A hash tree in which each node's hash is computed from its child nodes hashes.
This is an implementation of the modified merkle patricia tree as specified in the Ethereum [Yellow Paper](https://drive.google.com/file/d/1CJWmxV9kq5iwaTiPxCrBYPq0ED_bwMu4/view?usp=drivesdk):
> The modified Merkle Patricia tree (trie) provides a persistent data structure to map between arbitrary-length binary data (byte arrays). It is defined in terms of a mutable data structure to map between 256-bit binary fragments and arbitrary-length binary data. The core of the trie, and its sole requirement in terms of the protocol specification is to provide a single 32-byte value that identifies a given set of key-value pairs.
#### Install
```
npm install merkle-patricia-tree
```
#### Usage
There are 3 variants of the tree implemented in this library, namely: `BaseTrie`, `CheckpointTrie`and`SecureTrie`.`CheckpointTrie` adds checkpointing functionality to the `BaseTrie` with the methods `checkpoint`,`commit` and `revert`.`SecureTrie` extends `CheckpointTrie` and is the most suitable variant for Ethereum applications. It stores values under the `keccsk256` hash of their keys.
###### Initialization and Basic Usage
```
import level from 'level'
import { BaseTrie as Trie } from 'merkle-patricia-tree'
const db = level('./testdb')
const trie = new Trie(db)
async function test() {
await trie.put(Buffer.from('test'), Buffer.from('one'))
const value = await trie.get(Buffer.from('test'))
console.log(value.toString()) // 'one'
}
test()
```
###### Merkle Proofs
```
const trie = new Trie()
async function test() {
await trie.put(Buffer.from('test'), Buffer.from('one'))
const proof = await Trie.createProof(trie, Buffer.from('test'))
const value = await Trie.verifyProof(trie.root, Buffer.from('test'), proof)
console.log(value.toString()) // 'one'
}
test()
```
###### Read stream on Geth DB
```
import level from 'level'
import { SecureTrie as Trie } from 'merkle-patricia-tree'
const db = level('YOUR_PATH_TO_THE_GETH_CHAIN_DB')
// Set stateRoot to block #222
const stateRoot = '0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544'
// Initialize trie
const trie = new Trie(db, stateRoot)
trie
.createReadStream()
.on('data', console.log)
.on('end', () => {
console.log('End.')
})
```
###### Read Account State including Storage from Geth DB
```
import level from 'level'
import rlp from 'rlp'
import { BN, bufferToHex } from 'ethereumjs-util'
import Account from 'ethereumjs-account'
import { SecureTrie as Trie } from 'merkle-patricia-tree'
const stateRoot = 'STATE_ROOT_OF_A_BLOCK'
const db = level('YOUR_PATH_TO_THE_GETH_CHAINDATA_FOLDER')
const trie = new Trie(db, stateRoot)
const address = 'AN_ETHEREUM_ACCOUNT_ADDRESS'
async function test() {
const data = await trie.get(address)
const acc = new Account(data)
console.log('-------State-------')
console.log(`nonce: ${new BN(acc.nonce)}`)
console.log(`balance in wei: ${new BN(acc.balance)}`)
console.log(`storageRoot: ${bufferToHex(acc.stateRoot)}`)
console.log(`codeHash: ${bufferToHex(acc.codeHash)}`)
let storageTrie = trie.copy()
storageTrie.root = acc.stateRoot
console.log('------Storage------')
const stream = storageTrie.createReadStream()
stream
.on('data', (data) => {
console.log(`key: ${bufferToHex(data.key)}`)
console.log(`Value: ${bufferToHex(rlp.decode(data.value))}`)
})
.on('end', () => {
console.log('Finished reading storage.')
})
}
test()
```
for more resources you can check [rockwaterweb blog](https://rockwaterweb.com/ethereum-merkle-patricia-trees-javascript-tutorial/)