Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ethereumjs/merkle-patricia-tree
Project is in active development and has been moved to the EthereumJS VM monorepo.
https://github.com/ethereumjs/merkle-patricia-tree
data-structures ethereum merkle-patricia-tree merkle-proof merkle-tree proof trie
Last synced: 10 days ago
JSON representation
Project is in active development and has been moved to the EthereumJS VM monorepo.
- Host: GitHub
- URL: https://github.com/ethereumjs/merkle-patricia-tree
- Owner: ethereumjs
- Archived: true
- Created: 2014-05-14T17:41:00.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2021-01-19T10:04:32.000Z (almost 4 years ago)
- Last Synced: 2024-07-28T09:20:26.118Z (3 months ago)
- Topics: data-structures, ethereum, merkle-patricia-tree, merkle-proof, merkle-tree, proof, trie
- Language: TypeScript
- Homepage: https://github.com/ethereumjs/ethereumjs-monorepo
- Size: 1.27 MB
- Stars: 306
- Watchers: 30
- Forks: 89
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/contributing.md
Awesome Lists containing this project
- awesome-javascript-mathematics - `ethereumjs/merkle-patricia-tree`
- awesome-peer-to-peer - merkle-patricia-tree
- awesome-peer-to-peer - merkle-patricia-tree
README
# SYNOPSIS
[![NPM Status][npm-badge]][npm-link]
[![Actions Status][actions-badge]][actions-link]
[![Coverage Status][coverage-badge]][coverage-link]
[![Discord][discord-badge]][discord-link]This is an implementation of the modified merkle patricia tree as specified in the [Ethereum Yellow Paper](http://gavwood.com/Paper.pdf):
> 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.
The only backing store supported is LevelDB through the `levelup` module.
# 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 `keccak256` hash of their keys.
## Initialization and Basic Usage
```typescript
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
```typescript
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
```typescript
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
```typescript
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.stateRootconsole.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()
```Additional examples with detailed explanations are available [here](https://github.com/gabrocheleau/merkle-patricia-trees-examples).
# API
[Documentation](./docs/README.md)
# TESTING
`npm test`
# BENCHMARKS
There are two simple **benchmarks** in the `benchmarks` folder:
- `random.ts` runs random `PUT` operations on the tree.
- `checkpointing.ts` runs checkpoints and commits between `PUT` operations.A third benchmark using mainnet data to simulate real load is also under consideration.
Benchmarks can be run with:
```shell
npm run benchmarks
```To run a **profiler** on the `random.ts` benchmark and generate a flamegraph with [0x](https://github.com/davidmarkclements/0x) you can use:
```shell
npm run profiling
```0x processes the stacks and generates a profile folder (`.0x`) containing [`flamegraph.html`](https://github.com/davidmarkclements/0x/blob/master/docs/ui.md).
# REFERENCES
- Wiki
- [Ethereum Trie Specification](https://github.com/ethereum/wiki/wiki/Patricia-Tree)
- Blog posts
- [Ethereum's Merkle Patricia Trees - An Interactive JavaScript Tutorial](https://rockwaterweb.com/ethereum-merkle-patricia-trees-javascript-tutorial/)
- [Merkling in Ethereum](https://blog.ethereum.org/2015/11/15/merkling-in-ethereum/)
- [Understanding the Ethereum Trie](https://easythereentropy.wordpress.com/2014/06/04/understanding-the-ethereum-trie/). Worth a read, but the Python libraries are outdated.
- Videos
- [Trie and Patricia Trie Overview](https://www.youtube.com/watch?v=jXAHLqQthKw&t=26s)# EthereumJS
See our organizational [documentation](https://ethereumjs.readthedocs.io) for an introduction to `EthereumJS` as well as information on current standards and best practices.
If you want to join for work or do improvements on the libraries have a look at our [contribution guidelines](https://ethereumjs.readthedocs.io/en/latest/contributing.html).
# LICENSE
MPL-2.0
[npm-badge]: https://img.shields.io/npm/v/merkle-patricia-tree.svg
[npm-link]: https://www.npmjs.org/package/merkle-patricia-tree
[actions-badge]: https://github.com/ethereumjs/merkle-patricia-tree/workflows/Build/badge.svg
[actions-link]: https://github.com/ethereumjs/merkle-patricia-tree/actions
[coverage-badge]: https://codecov.io/gh/ethereumjs/merkle-patricia-tree/branch/master/graph/badge.svg
[coverage-link]: https://codecov.io/gh/ethereumjs/merkle-patricia-tree
[discord-badge]: https://img.shields.io/static/v1?logo=discord&label=discord&message=Join&color=blue
[discord-link]: https://discord.gg/TNwARpR