-
Notifications
You must be signed in to change notification settings - Fork 772
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* trie: update first module of examples * trie: update module 2 of mpt examples * trie: update module 3 of mpt examples * trie: simplify imports of mpt examples * trie: update module 4 of mpt examples * trie: remove redundant comments from code examples * Update packages/trie/examples/merkle_patricia_trees/README.md Co-authored-by: Scorbajio <[email protected]> * Update packages/trie/examples/merkle_patricia_trees/README.md Co-authored-by: Scorbajio <[email protected]> * Update packages/trie/examples/merkle_patricia_trees/README.md Co-authored-by: Scorbajio <[email protected]> * Update packages/trie/examples/merkle_patricia_trees/README.md Co-authored-by: Scorbajio <[email protected]> * trie: clarify sentence --------- Co-authored-by: Scorbajio <[email protected]>
- Loading branch information
1 parent
7a0a37b
commit 35dad1a
Showing
13 changed files
with
558 additions
and
422 deletions.
There are no files selected for viewing
650 changes: 354 additions & 296 deletions
650
packages/trie/examples/merkle_patricia_trees/README.md
Large diffs are not rendered by default.
Oops, something went wrong.
21 changes: 11 additions & 10 deletions
21
packages/trie/examples/merkle_patricia_trees/example1a.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,27 @@ | ||
/* Example 1a - Creating and Updating a Base Trie*/ | ||
|
||
const { Trie } = require('../../dist') // We import the library required to create a basic Merkle Patricia Tree | ||
const { Trie } = require('../../dist/cjs') // We import the library required to create a basic Merkle Patricia Tree | ||
const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') | ||
|
||
const trie = new Trie() // We create an empty Merkle Patricia Tree | ||
console.log('Empty trie root (Bytes): ', trie.root()) // The trie root (32 bytes) | ||
console.log('Empty trie root (Bytes): ', bytesToHex(trie.root())) // The trie root (32 bytes) | ||
|
||
async function test() { | ||
const key = Buffer.from('testKey') | ||
const value = Buffer.from('testValue') | ||
const key = utf8ToBytes('testKey') | ||
const value = utf8ToBytes('testValue') | ||
await trie.put(key, value) // We update (using "put") the trie with the key-value pair "testKey": "testValue" | ||
const retrievedValue = await trie.get(key) // We retrieve (using "get") the value at key "testKey" | ||
console.log('Value (Bytes): ', retrievedValue) | ||
console.log('Value (String): ', retrievedValue.toString()) | ||
console.log('Updated trie root:', trie.root()) // The new trie root (32 bytes) | ||
console.log('Value (Bytes): ', bytesToHex(retrievedValue)) | ||
console.log('Value (String): ', bytesToUtf8(retrievedValue)) | ||
console.log('Updated trie root:', bytesToHex(trie.root())) // The new trie root (32 bytes) | ||
} | ||
|
||
test() | ||
|
||
/* | ||
Results: | ||
Empty trie root (Bytes): <Buffer 56 e8 1f 17 1b cc 55 a6 ff 83 45 e6 92 c0 f8 6e 5b 48 e0 1b 99 6c ad c0 01 62 2f b5 e3 63 b4 21> | ||
Value (Bytes): <Buffer 74 65 73 74 56 61 6c 75 65> | ||
Empty trie root (Bytes): 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 | ||
Value (Bytes): 0x7465737456616c7565 | ||
Value (String): testValue | ||
Updated trie root: <Buffer 8e 81 43 67 21 33 dd 5a b0 0d fc 4b 01 14 60 ea 2a 7b 00 d9 10 dc 42 78 94 2a e9 10 5c b6 20 74> | ||
Updated trie root: 0x8e8143672133dd5ab00dfc4b011460ea2a7b00d910dc4278942ae9105cb62074 | ||
*/ |
23 changes: 12 additions & 11 deletions
23
packages/trie/examples/merkle_patricia_trees/example1b.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,26 @@ | ||
/* Example 1b - Manually Creating and Updating a Secure Trie*/ | ||
|
||
const { Trie } = require('../../dist') // We import the library required to create a basic Merkle Patricia Tree | ||
const { Trie } = require('../../dist/cjs') | ||
const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') | ||
const { keccak256 } = require('ethereum-cryptography/keccak') | ||
|
||
const trie = new Trie() // We create an empty Merkle Patricia Tree | ||
console.log('Empty trie root (Bytes): ', trie.root()) // The trie root (32 bytes) | ||
const trie = new Trie() | ||
console.log('Empty trie root (Bytes): ', bytesToHex(trie.root())) // The trie root (32 bytes) | ||
|
||
async function test() { | ||
await trie.put(keccak256(Buffer.from('testKey')), Buffer.from('testValue')) // We update (using "put") the trie with the key-value pair "testKey": "testValue" | ||
const value = await trie.get(keccak256(Buffer.from('testKey'))) // We retrieve (using "get") the value at key "testKey" | ||
console.log('Value (Bytes): ', value) | ||
console.log('Value (String): ', value.toString()) | ||
console.log('Updated trie root:', trie.root()) // The new trie root (32 bytes) | ||
await trie.put(keccak256(utf8ToBytes('testKey')), utf8ToBytes('testValue')) // We update (using "put") the trie with the key-value pair hash("testKey"): "testValue" | ||
const value = await trie.get(keccak256(utf8ToBytes('testKey'))) // We retrieve (using "get") the value at hash("testKey") | ||
console.log('Value (Bytes): ', bytesToHex(value)) | ||
console.log('Value (String): ', bytesToUtf8(value)) | ||
console.log('Updated trie root:', bytesToHex(trie.root())) // The new trie root (32 bytes) | ||
} | ||
|
||
test() | ||
|
||
/* | ||
Results: | ||
Empty trie root (Bytes): <Buffer 56 e8 1f 17 1b cc 55 a6 ff 83 45 e6 92 c0 f8 6e 5b 48 e0 1b 99 6c ad c0 01 62 2f b5 e3 63 b4 21> | ||
Value (Bytes): <Buffer 74 65 73 74 56 61 6c 75 65> | ||
Empty trie root (Bytes): 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 | ||
Value (Bytes): 0x7465737456616c7565 | ||
Value (String): testValue | ||
Updated trie root: <Buffer be ad e9 13 ab 37 dc a0 dc a2 e4 29 24 b9 18 c2 a1 ca c4 57 83 3b d8 2b 9e 32 45 de cb 87 d0 fb> | ||
Updated trie root: 0xbeade913ab37dca0dca2e42924b918c2a1cac457833bd82b9e3245decb87d0fb | ||
*/ |
23 changes: 12 additions & 11 deletions
23
packages/trie/examples/merkle_patricia_trees/example1c.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,25 @@ | ||
/* Example 1c - Creating an empty Merkle Patricia Tree and updating it with a single key-value pair */ | ||
|
||
const { Trie } = require('../../dist') // We import the library required to create a basic Merkle Patricia Tree | ||
const { Trie } = require('../../dist/cjs') | ||
const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') | ||
|
||
const trie = new Trie({ useKeyHashing: true }) // We create an empty Merkle Patricia Tree | ||
console.log('Empty trie root (Bytes): ', trie.root()) // The trie root (32 bytes) | ||
const trie = new Trie({ useKeyHashing: true }) // We create an empty Merkle Patricia Tree with key hashing enabled | ||
console.log('Empty trie root (Bytes): ', bytesToHex(trie.root())) // The trie root (32 bytes) | ||
|
||
async function test() { | ||
await trie.put(Buffer.from('testKey'), Buffer.from('testValue')) // We update (using "put") the trie with the key-value pair "testKey": "testValue" | ||
const value = await trie.get(Buffer.from('testKey')) // We retrieve (using "get") the value at key "testKey" | ||
console.log('Value (Bytes): ', value) | ||
console.log('Value (String): ', value.toString()) | ||
console.log('Updated trie root:', trie.root()) // The new trie root (32 bytes) | ||
await trie.put(utf8ToBytes('testKey'), utf8ToBytes('testValue')) // We update (using "put") the trie with the key-value pair "testKey": "testValue" | ||
const value = await trie.get(utf8ToBytes('testKey')) // We retrieve (using "get") the value at key "testKey" | ||
console.log('Value (Bytes): ', bytesToHex(value)) | ||
console.log('Value (String): ', bytesToUtf8(value)) | ||
console.log('Updated trie root:', bytesToHex(trie.root())) // The new trie root (32 bytes) | ||
} | ||
|
||
test() | ||
|
||
/* | ||
Results: | ||
Empty trie root (Bytes): <Buffer 56 e8 1f 17 1b cc 55 a6 ff 83 45 e6 92 c0 f8 6e 5b 48 e0 1b 99 6c ad c0 01 62 2f b5 e3 63 b4 21> | ||
Value (Bytes): <Buffer 74 65 73 74 56 61 6c 75 65> | ||
Empty trie root (Bytes): 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 | ||
Value (Bytes): 0x7465737456616c7565 | ||
Value (String): testValue | ||
Updated trie root: <Buffer be ad e9 13 ab 37 dc a0 dc a2 e4 29 24 b9 18 c2 a1 ca c4 57 83 3b d8 2b 9e 32 45 de cb 87 d0 fb> | ||
Updated trie root: 0xbeade913ab37dca0dca2e42924b918c2a1cac457833bd82b9e3245decb87d0fb | ||
*/ |
23 changes: 12 additions & 11 deletions
23
packages/trie/examples/merkle_patricia_trees/example1d.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,32 @@ | ||
/* Example 1d - Deleting a Key-Value Pair from a Trie*/ | ||
|
||
const { Trie } = require('../../dist') // We import the library required to create a basic Merkle Patricia Tree | ||
const { Trie } = require('../../dist/cjs') | ||
const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') | ||
|
||
const trie = new Trie() // We create an empty Merkle Patricia Tree | ||
console.log('Empty trie root: ', trie.root()) // The trie root | ||
const trie = new Trie() | ||
console.log('Empty trie root: ', bytesToHex(trie.root())) // The trie root | ||
|
||
async function test() { | ||
const key = Buffer.from('testKey') | ||
const value = Buffer.from('testValue') | ||
const key = utf8ToBytes('testKey') | ||
const value = utf8ToBytes('testValue') | ||
await trie.put(key, value) // We update (using "put") the trie with the key-value pair "testKey": "testValue" | ||
const valuePre = await trie.get(key) // We retrieve (using "get") the value at key "testKey" | ||
console.log('Value (String): ', valuePre.toString()) // We retrieve our value | ||
console.log('Updated trie root:', trie.root()) // The new trie root | ||
console.log('Value (String): ', bytesToUtf8(valuePre)) // We retrieve our value | ||
console.log('Updated trie root:', bytesToHex(trie.root())) // The new trie root | ||
|
||
await trie.del(key) | ||
const valuePost = await trie.get(key) // We try to retrieve the value at (deleted) key "testKey" | ||
console.log('Value at key "testKey": ', valuePost) // Key not found. Value is therefore null. | ||
console.log('Trie root after deletion:', trie.root()) // Our trie root is back to its initial value | ||
console.log('Trie root after deletion:', bytesToHex(trie.root())) // Our trie root is back to its initial value | ||
} | ||
|
||
test() | ||
|
||
/* | ||
Results: | ||
Empty trie root: <Buffer 56 e8 1f 17 1b cc 55 a6 ff 83 45 e6 92 c0 f8 6e 5b 48 e0 1b 99 6c ad c0 01 62 2f b5 e3 63 b4 21> | ||
Empty trie root: 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 | ||
Value (String): testValue | ||
Updated trie root: <Buffer 8e 81 43 67 21 33 dd 5a b0 0d fc 4b 01 14 60 ea 2a 7b 00 d9 10 dc 42 78 94 2a e9 10 5c b6 20 74> | ||
Updated trie root: 0x8e8143672133dd5ab00dfc4b011460ea2a7b00d910dc4278942ae9105cb62074 | ||
Value at key "testKey": null | ||
Trie root after deletion: <Buffer 56 e8 1f 17 1b cc 55 a6 ff 83 45 e6 92 c0 f8 6e 5b 48 e0 1b 99 6c ad c0 01 62 2f b5 e3 63 b4 21> | ||
Trie root after deletion: 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 33 additions & 14 deletions
47
packages/trie/examples/merkle_patricia_trees/example2b.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,17 @@ | ||
// Example 2c - Creating and looking up a leaf node | ||
|
||
const { Trie } = require('../../dist') // We import the library required to create a basic Merkle Patricia Tree | ||
const { Trie } = require('../../dist/cjs') | ||
const { bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') | ||
|
||
const trie = new Trie() // We create an empty Merkle Patricia Tree | ||
const trie = new Trie() | ||
|
||
async function test() { | ||
await trie.put(Buffer.from('testKey'), Buffer.from('testValue')) | ||
await trie.put(Buffer.from('testKey0'), Buffer.from('testValue0')) | ||
await trie.put(utf8ToBytes('testKey'), utf8ToBytes('testValue')) | ||
await trie.put(utf8ToBytes('testKey0'), utf8ToBytes('testValue0')) | ||
|
||
const node1 = await trie.findPath(Buffer.from('testKey0')) // We retrieve one of the leaf nodes | ||
console.log('Node 1: ', node1.node) // A leaf node! We can see that it contains 2 items: the encodedPath and the value | ||
console.log('Node 1 value: ', node1.node._value.toString()) // The leaf node's value | ||
const node1 = await trie.findPath(utf8ToBytes('testKey0')) // We retrieve one of the leaf nodes | ||
console.log('Node 1: ', node1.node) // A leaf node! We can see that it contains 2 items: the nibbles and the value | ||
console.log('Node 1 value: ', bytesToUtf8(node1.node._value)) // The leaf node's value | ||
} | ||
|
||
test() |
23 changes: 12 additions & 11 deletions
23
packages/trie/examples/merkle_patricia_trees/example2d.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,35 @@ | ||
// Example 3a - Generating a hash | ||
|
||
const { Trie } = require('../../dist') // We import the library required to create a basic Merkle Patricia Tree | ||
const { Trie } = require('../../dist/cjs') | ||
const rlp = require('@ethereumjs/rlp') | ||
const { bytesToHex, utf8ToBytes } = require('@ethereumjs/util') | ||
const { keccak256 } = require('ethereum-cryptography/keccak') | ||
const trie = new Trie() // We create an empty Merkle Patricia Tree | ||
const trie = new Trie() | ||
|
||
async function test() { | ||
// We populate the tree to create an extension node. | ||
await trie.put(Buffer.from('testKey'), Buffer.from('testValue')) | ||
await trie.put(Buffer.from('testKey0001'), Buffer.from('testValue1')) | ||
await trie.put(Buffer.from('testKey000A'), Buffer.from('testValueA')) | ||
await trie.put(utf8ToBytes('testKey'), utf8ToBytes('testValue')) | ||
await trie.put(utf8ToBytes('testKey0001'), utf8ToBytes('testValue1')) | ||
await trie.put(utf8ToBytes('testKey000A'), utf8ToBytes('testValueA')) | ||
|
||
const node1 = await trie.findPath(Buffer.from('testKey')) | ||
const node2 = await trie.lookupNode(Buffer.from(node1.node._branches[3])) | ||
const node1 = await trie.findPath(utf8ToBytes('testKey')) | ||
const node2 = await trie.lookupNode(node1.node._branches[3]) | ||
const node3 = await trie.lookupNode(node2._value) | ||
|
||
console.log('Our computed hash: ', Buffer.from(keccak256(rlp.encode(node2.raw())))) | ||
console.log('The extension node hash: ', node1.node._branches[3]) | ||
console.log('Extension node:', node2) | ||
console.log('Branch node:', node3._branches) | ||
console.log('Branch node hash:', bytesToHex(node2._value)) | ||
console.log( | ||
'Branch node branch 4:', | ||
'path: ', | ||
bytesToHex(node3._branches[4][0]), | ||
' | value: ', | ||
bytesToHex(node3._branches[4][1]) | ||
) | ||
|
||
console.log('Raw node:', bytesToHex(rlp.encode(node2.raw()))) | ||
console.log('Our computed hash: ', bytesToHex(keccak256(rlp.encode(node2.raw())))) | ||
console.log('The extension node hash: ', bytesToHex(node1.node._branches[3])) | ||
} | ||
|
||
test() |
34 changes: 17 additions & 17 deletions
34
packages/trie/examples/merkle_patricia_trees/example3b.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,30 @@ | ||
// Example 3b - Verification using a hash | ||
|
||
const { Trie } = require('../../dist') // We import the library required to create a basic Merkle Patricia Tree | ||
const { Trie } = require('../../dist/cjs') | ||
const { bytesToHex, utf8ToBytes } = require('@ethereumjs/util') | ||
const trie1 = new Trie() | ||
const trie2 = new Trie() | ||
|
||
async function test() { | ||
// We populate the tree to create an extension node. | ||
await trie1.put(utf8ToBytes('testKey'), utf8ToBytes('testValue')) | ||
await trie1.put(utf8ToBytes('testKey0001'), utf8ToBytes('testValue1')) | ||
await trie1.put(utf8ToBytes('testKey000A'), utf8ToBytes('testValueA')) | ||
|
||
await trie1.put(Buffer.from('testKey'), Buffer.from('testValue')) | ||
await trie1.put(Buffer.from('testKey0001'), Buffer.from('testValue1')) | ||
await trie1.put(Buffer.from('testKey000A'), Buffer.from('testValueA')) | ||
await trie2.put(utf8ToBytes('testKey'), utf8ToBytes('testValue')) | ||
await trie2.put(utf8ToBytes('testKey0001'), utf8ToBytes('testValue1')) | ||
await trie2.put(utf8ToBytes('testKey000z'), utf8ToBytes('testValuez')) | ||
|
||
await trie2.put(Buffer.from('testKey'), Buffer.from('testValue')) | ||
await trie2.put(Buffer.from('testKey0001'), Buffer.from('testValue1')) | ||
await trie2.put(Buffer.from('testKey000z'), Buffer.from('testValuez')) | ||
const temp1 = await trie1.findPath(utf8ToBytes('testKey')) | ||
const temp2 = await trie2.findPath(utf8ToBytes('testKey')) | ||
|
||
const temp1 = await trie1.findPath(Buffer.from('testKey')) | ||
const temp2 = await trie2.findPath(Buffer.from('testKey')) | ||
const node1 = await trie1.lookupNode(temp1.node._branches[3]) | ||
const node2 = await trie2.lookupNode(temp2.node._branches[3]) | ||
|
||
const node1 = await trie1.lookupNode(Buffer.from(temp1.node._branches[3])) | ||
const node2 = await trie2.lookupNode(Buffer.from(temp2.node._branches[3])) | ||
console.log('Branch node 1 hash: ', bytesToHex(node1._value)) | ||
console.log('Branch node 2 hash: ', bytesToHex(node2._value)) | ||
|
||
console.log('Branch node 1 hash: ', node1._value) | ||
console.log('Branch node 2 hash: ', node2._value) | ||
|
||
console.log('Root of trie 1: ', trie1.root()) | ||
console.log('Root of trie 2: ', trie2.root()) | ||
console.log('Root of trie 1: ', bytesToHex(trie1.root())) | ||
console.log('Root of trie 2: ', bytesToHex(trie2.root())) | ||
} | ||
|
||
test() |
Oops, something went wrong.