diff --git a/basics/aptos/aptos-sdk-account/Readme.md b/aptos/aptos-sdk-account/Readme.md similarity index 100% rename from basics/aptos/aptos-sdk-account/Readme.md rename to aptos/aptos-sdk-account/Readme.md diff --git a/basics/aptos/aptos-sdk-account/package.json b/aptos/aptos-sdk-account/package.json similarity index 100% rename from basics/aptos/aptos-sdk-account/package.json rename to aptos/aptos-sdk-account/package.json diff --git a/basics/aptos/aptos-sdk-account/test/account.test.ts b/aptos/aptos-sdk-account/test/account.test.ts similarity index 100% rename from basics/aptos/aptos-sdk-account/test/account.test.ts rename to aptos/aptos-sdk-account/test/account.test.ts diff --git a/basics/aptos/aptos-sdk-multi-agent-transaction/Readme.md b/aptos/aptos-sdk-multi-agent-transaction/Readme.md similarity index 100% rename from basics/aptos/aptos-sdk-multi-agent-transaction/Readme.md rename to aptos/aptos-sdk-multi-agent-transaction/Readme.md diff --git a/basics/aptos/aptos-sdk-multi-agent-transaction/package.json b/aptos/aptos-sdk-multi-agent-transaction/package.json similarity index 100% rename from basics/aptos/aptos-sdk-multi-agent-transaction/package.json rename to aptos/aptos-sdk-multi-agent-transaction/package.json diff --git a/basics/aptos/aptos-sdk-multi-agent-transaction/sources/multi-signer-counter.move b/aptos/aptos-sdk-multi-agent-transaction/sources/multi-signer-counter.move similarity index 100% rename from basics/aptos/aptos-sdk-multi-agent-transaction/sources/multi-signer-counter.move rename to aptos/aptos-sdk-multi-agent-transaction/sources/multi-signer-counter.move diff --git a/basics/aptos/aptos-sdk-multi-agent-transaction/test/multi-agent-transaction.test.anwser.ts b/aptos/aptos-sdk-multi-agent-transaction/test/multi-agent-transaction.test.anwser.ts similarity index 100% rename from basics/aptos/aptos-sdk-multi-agent-transaction/test/multi-agent-transaction.test.anwser.ts rename to aptos/aptos-sdk-multi-agent-transaction/test/multi-agent-transaction.test.anwser.ts diff --git a/basics/aptos/aptos-sdk-multi-agent-transaction/test/multi-agent-transaction.test.ts b/aptos/aptos-sdk-multi-agent-transaction/test/multi-agent-transaction.test.ts similarity index 100% rename from basics/aptos/aptos-sdk-multi-agent-transaction/test/multi-agent-transaction.test.ts rename to aptos/aptos-sdk-multi-agent-transaction/test/multi-agent-transaction.test.ts diff --git a/basics/aptos/aptos-sdk-sponsoring-transactions/Readme.md b/aptos/aptos-sdk-sponsoring-transactions/Readme.md similarity index 100% rename from basics/aptos/aptos-sdk-sponsoring-transactions/Readme.md rename to aptos/aptos-sdk-sponsoring-transactions/Readme.md diff --git a/basics/aptos/aptos-sdk-sponsoring-transactions/package.json b/aptos/aptos-sdk-sponsoring-transactions/package.json similarity index 100% rename from basics/aptos/aptos-sdk-sponsoring-transactions/package.json rename to aptos/aptos-sdk-sponsoring-transactions/package.json diff --git a/basics/aptos/aptos-sdk-sponsoring-transactions/test/sponsoring-transaction.test.ts b/aptos/aptos-sdk-sponsoring-transactions/test/sponsoring-transaction.test.ts similarity index 100% rename from basics/aptos/aptos-sdk-sponsoring-transactions/test/sponsoring-transaction.test.ts rename to aptos/aptos-sdk-sponsoring-transactions/test/sponsoring-transaction.test.ts diff --git a/basics/aptos/aptos-sdk-transaction/Readme.md b/aptos/aptos-sdk-transaction/Readme.md similarity index 100% rename from basics/aptos/aptos-sdk-transaction/Readme.md rename to aptos/aptos-sdk-transaction/Readme.md diff --git a/basics/aptos/aptos-sdk-transaction/module/storage.move b/aptos/aptos-sdk-transaction/module/storage.move similarity index 100% rename from basics/aptos/aptos-sdk-transaction/module/storage.move rename to aptos/aptos-sdk-transaction/module/storage.move diff --git a/basics/aptos/aptos-sdk-transaction/package.json b/aptos/aptos-sdk-transaction/package.json similarity index 100% rename from basics/aptos/aptos-sdk-transaction/package.json rename to aptos/aptos-sdk-transaction/package.json diff --git a/basics/aptos/aptos-sdk-transaction/test/transaction.anwser.ts b/aptos/aptos-sdk-transaction/test/transaction.anwser.ts similarity index 100% rename from basics/aptos/aptos-sdk-transaction/test/transaction.anwser.ts rename to aptos/aptos-sdk-transaction/test/transaction.anwser.ts diff --git a/basics/aptos/aptos-sdk-transaction/test/transaction.test.ts b/aptos/aptos-sdk-transaction/test/transaction.test.ts similarity index 100% rename from basics/aptos/aptos-sdk-transaction/test/transaction.test.ts rename to aptos/aptos-sdk-transaction/test/transaction.test.ts diff --git a/basics/aptos/move-basic/Move.toml b/aptos/move-basic/Move.toml similarity index 100% rename from basics/aptos/move-basic/Move.toml rename to aptos/move-basic/Move.toml diff --git a/basics/aptos/move-basic/Readme.md b/aptos/move-basic/Readme.md similarity index 100% rename from basics/aptos/move-basic/Readme.md rename to aptos/move-basic/Readme.md diff --git a/basics/aptos/move-basic/sources/basic.move b/aptos/move-basic/sources/basic.move similarity index 100% rename from basics/aptos/move-basic/sources/basic.move rename to aptos/move-basic/sources/basic.move diff --git a/basics/aptos/move-basic/tests/basic.test.move b/aptos/move-basic/tests/basic.test.move similarity index 100% rename from basics/aptos/move-basic/tests/basic.test.move rename to aptos/move-basic/tests/basic.test.move diff --git a/basics/aptos/move-basic2/Move.toml b/aptos/move-basic2/Move.toml similarity index 100% rename from basics/aptos/move-basic2/Move.toml rename to aptos/move-basic2/Move.toml diff --git a/basics/aptos/move-basic2/Readme.md b/aptos/move-basic2/Readme.md similarity index 100% rename from basics/aptos/move-basic2/Readme.md rename to aptos/move-basic2/Readme.md diff --git a/basics/aptos/move-basic2/sources/basic2.move b/aptos/move-basic2/sources/basic2.move similarity index 100% rename from basics/aptos/move-basic2/sources/basic2.move rename to aptos/move-basic2/sources/basic2.move diff --git a/basics/aptos/move-basic2/tests/basic2.test.move b/aptos/move-basic2/tests/basic2.test.move similarity index 100% rename from basics/aptos/move-basic2/tests/basic2.test.move rename to aptos/move-basic2/tests/basic2.test.move diff --git a/basics/aptos/move-pow/Move.toml b/aptos/move-pow/Move.toml similarity index 100% rename from basics/aptos/move-pow/Move.toml rename to aptos/move-pow/Move.toml diff --git a/basics/aptos/move-pow/Readme.md b/aptos/move-pow/Readme.md similarity index 100% rename from basics/aptos/move-pow/Readme.md rename to aptos/move-pow/Readme.md diff --git a/basics/aptos/move-pow/sources/pow.move b/aptos/move-pow/sources/pow.move similarity index 100% rename from basics/aptos/move-pow/sources/pow.move rename to aptos/move-pow/sources/pow.move diff --git a/basics/aptos/move-struct/Move.toml b/aptos/move-struct/Move.toml similarity index 100% rename from basics/aptos/move-struct/Move.toml rename to aptos/move-struct/Move.toml diff --git a/basics/aptos/move-struct/Readme.md b/aptos/move-struct/Readme.md similarity index 100% rename from basics/aptos/move-struct/Readme.md rename to aptos/move-struct/Readme.md diff --git a/basics/aptos/move-struct/sources/resource.move b/aptos/move-struct/sources/resource.move similarity index 100% rename from basics/aptos/move-struct/sources/resource.move rename to aptos/move-struct/sources/resource.move diff --git a/basics/aptos/move-struct/sources/structability.move b/aptos/move-struct/sources/structability.move similarity index 100% rename from basics/aptos/move-struct/sources/structability.move rename to aptos/move-struct/sources/structability.move diff --git a/basics/aptos/move-struct/tests/resouece.test.move b/aptos/move-struct/tests/resouece.test.move similarity index 100% rename from basics/aptos/move-struct/tests/resouece.test.move rename to aptos/move-struct/tests/resouece.test.move diff --git a/basics/aptos/move-struct/tests/structability.test.move b/aptos/move-struct/tests/structability.test.move similarity index 100% rename from basics/aptos/move-struct/tests/structability.test.move rename to aptos/move-struct/tests/structability.test.move diff --git a/basics/ethereum/vrf/lib/chainlink b/basics/ethereum/vrf/lib/chainlink deleted file mode 160000 index 0382a7f..0000000 --- a/basics/ethereum/vrf/lib/chainlink +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0382a7f4cab4cd8bb080fe0c9b7b5c30383205b8 diff --git a/basics/ethereum/vrf/lib/chainlink-brownie-contracts b/basics/ethereum/vrf/lib/chainlink-brownie-contracts deleted file mode 160000 index f06ed4c..0000000 --- a/basics/ethereum/vrf/lib/chainlink-brownie-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f06ed4c7e43de0359e0e337ce56e55cab90b0178 diff --git a/basics/ethereum/vrf/lib/forge-std b/basics/ethereum/vrf/lib/forge-std deleted file mode 160000 index 3353993..0000000 --- a/basics/ethereum/vrf/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3353993420c6e488a2914ce02d88174e80ad80f8 diff --git a/basics/ethereum/vrf/lib/foundry-chainlink-toolkit b/basics/ethereum/vrf/lib/foundry-chainlink-toolkit deleted file mode 160000 index d610ec9..0000000 --- a/basics/ethereum/vrf/lib/foundry-chainlink-toolkit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d610ec9ef54c325de7de1a5622c19933b2ae26cf diff --git a/basics/ethereum/vrf/lib/openzeppelin-contracts b/basics/ethereum/vrf/lib/openzeppelin-contracts deleted file mode 160000 index acd4ff7..0000000 --- a/basics/ethereum/vrf/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit acd4ff74de833399287ed6b31b4debf6b2b35527 diff --git a/advanced/bitcoinscript/README.md b/bitcoin/bitcoinscript/README.md similarity index 100% rename from advanced/bitcoinscript/README.md rename to bitcoin/bitcoinscript/README.md diff --git a/advanced/bitcoinscript/package-lock.json b/bitcoin/bitcoinscript/package-lock.json similarity index 100% rename from advanced/bitcoinscript/package-lock.json rename to bitcoin/bitcoinscript/package-lock.json diff --git a/advanced/bitcoinscript/package.json b/bitcoin/bitcoinscript/package.json similarity index 100% rename from advanced/bitcoinscript/package.json rename to bitcoin/bitcoinscript/package.json diff --git a/advanced/bitcoinscript/src/bitcoinscript-interpreter.ts b/bitcoin/bitcoinscript/src/bitcoinscript-interpreter.ts similarity index 100% rename from advanced/bitcoinscript/src/bitcoinscript-interpreter.ts rename to bitcoin/bitcoinscript/src/bitcoinscript-interpreter.ts diff --git a/advanced/bitcoinscript/test/bitcoinscript-interpreter.test.ts b/bitcoin/bitcoinscript/test/bitcoinscript-interpreter.test.ts similarity index 100% rename from advanced/bitcoinscript/test/bitcoinscript-interpreter.test.ts rename to bitcoin/bitcoinscript/test/bitcoinscript-interpreter.test.ts diff --git a/basics/bitcoin/ordinals/README.MD b/bitcoin/ordinals/README.MD similarity index 100% rename from basics/bitcoin/ordinals/README.MD rename to bitcoin/ordinals/README.MD diff --git a/basics/bitcoin/ordinals/package-lock.json b/bitcoin/ordinals/package-lock.json similarity index 100% rename from basics/bitcoin/ordinals/package-lock.json rename to bitcoin/ordinals/package-lock.json diff --git a/basics/bitcoin/ordinals/package.json b/bitcoin/ordinals/package.json similarity index 100% rename from basics/bitcoin/ordinals/package.json rename to bitcoin/ordinals/package.json diff --git a/basics/bitcoin/ordinals/src/bitcoin.ts b/bitcoin/ordinals/src/bitcoin.ts similarity index 100% rename from basics/bitcoin/ordinals/src/bitcoin.ts rename to bitcoin/ordinals/src/bitcoin.ts diff --git a/basics/bitcoin/ordinals/src/ordinals.ts b/bitcoin/ordinals/src/ordinals.ts similarity index 100% rename from basics/bitcoin/ordinals/src/ordinals.ts rename to bitcoin/ordinals/src/ordinals.ts diff --git a/basics/bitcoin/ordinals/src/ordinals.txbuilder.ts b/bitcoin/ordinals/src/ordinals.txbuilder.ts similarity index 100% rename from basics/bitcoin/ordinals/src/ordinals.txbuilder.ts rename to bitcoin/ordinals/src/ordinals.txbuilder.ts diff --git a/basics/bitcoin/ordinals/test/ordinals.test.ts b/bitcoin/ordinals/test/ordinals.test.ts similarity index 100% rename from basics/bitcoin/ordinals/test/ordinals.test.ts rename to bitcoin/ordinals/test/ordinals.test.ts diff --git a/basics/bitcoin/ordinals/test/ordinals.txbuilder.test.ts b/bitcoin/ordinals/test/ordinals.txbuilder.test.ts similarity index 100% rename from basics/bitcoin/ordinals/test/ordinals.txbuilder.test.ts rename to bitcoin/ordinals/test/ordinals.txbuilder.test.ts diff --git a/basics/bitcoin/taproot/README.md b/bitcoin/taproot/README.md similarity index 100% rename from basics/bitcoin/taproot/README.md rename to bitcoin/taproot/README.md diff --git a/basics/bitcoin/taproot/package-lock.json b/bitcoin/taproot/package-lock.json similarity index 100% rename from basics/bitcoin/taproot/package-lock.json rename to bitcoin/taproot/package-lock.json diff --git a/basics/bitcoin/taproot/package.json b/bitcoin/taproot/package.json similarity index 100% rename from basics/bitcoin/taproot/package.json rename to bitcoin/taproot/package.json diff --git a/basics/bitcoin/taproot/src/p2tr.ts b/bitcoin/taproot/src/p2tr.ts similarity index 100% rename from basics/bitcoin/taproot/src/p2tr.ts rename to bitcoin/taproot/src/p2tr.ts diff --git a/basics/bitcoin/taproot/test/p2tr.test.ts b/bitcoin/taproot/test/p2tr.test.ts similarity index 100% rename from basics/bitcoin/taproot/test/p2tr.test.ts rename to bitcoin/taproot/test/p2tr.test.ts diff --git a/basics/bitcoin/utxo/README.md b/bitcoin/utxo/README.md similarity index 100% rename from basics/bitcoin/utxo/README.md rename to bitcoin/utxo/README.md diff --git a/basics/bitcoin/utxo/package.json b/bitcoin/utxo/package.json similarity index 100% rename from basics/bitcoin/utxo/package.json rename to bitcoin/utxo/package.json diff --git a/basics/bitcoin/utxo/src/utxo.ts b/bitcoin/utxo/src/utxo.ts similarity index 100% rename from basics/bitcoin/utxo/src/utxo.ts rename to bitcoin/utxo/src/utxo.ts diff --git a/basics/bitcoin/utxo/test/utxo.scenario.test.ts b/bitcoin/utxo/test/utxo.scenario.test.ts similarity index 100% rename from basics/bitcoin/utxo/test/utxo.scenario.test.ts rename to bitcoin/utxo/test/utxo.scenario.test.ts diff --git a/basics/bitcoin/utxo/test/utxo.test.ts b/bitcoin/utxo/test/utxo.test.ts similarity index 100% rename from basics/bitcoin/utxo/test/utxo.test.ts rename to bitcoin/utxo/test/utxo.test.ts diff --git a/basics/ethereum/ethers-account/README.md b/ethereum/ethers-account/README.md similarity index 100% rename from basics/ethereum/ethers-account/README.md rename to ethereum/ethers-account/README.md diff --git a/basics/ethereum/ethers-account/package.json b/ethereum/ethers-account/package.json similarity index 100% rename from basics/ethereum/ethers-account/package.json rename to ethereum/ethers-account/package.json diff --git a/basics/ethereum/ethers-account/test/account.test.ts b/ethereum/ethers-account/test/account.test.ts similarity index 100% rename from basics/ethereum/ethers-account/test/account.test.ts rename to ethereum/ethers-account/test/account.test.ts diff --git a/basics/ethereum/ethers-transaction/README.md b/ethereum/ethers-transaction/README.md similarity index 100% rename from basics/ethereum/ethers-transaction/README.md rename to ethereum/ethers-transaction/README.md diff --git a/basics/ethereum/ethers-transaction/contracts/SimpleStorage.sol b/ethereum/ethers-transaction/contracts/SimpleStorage.sol similarity index 100% rename from basics/ethereum/ethers-transaction/contracts/SimpleStorage.sol rename to ethereum/ethers-transaction/contracts/SimpleStorage.sol diff --git a/basics/ethereum/ethers-transaction/hardhat.config.ts b/ethereum/ethers-transaction/hardhat.config.ts similarity index 100% rename from basics/ethereum/ethers-transaction/hardhat.config.ts rename to ethereum/ethers-transaction/hardhat.config.ts diff --git a/basics/ethereum/ethers-transaction/package.json b/ethereum/ethers-transaction/package.json similarity index 100% rename from basics/ethereum/ethers-transaction/package.json rename to ethereum/ethers-transaction/package.json diff --git a/basics/ethereum/ethers-transaction/test/transaction.test.ts b/ethereum/ethers-transaction/test/transaction.test.ts similarity index 100% rename from basics/ethereum/ethers-transaction/test/transaction.test.ts rename to ethereum/ethers-transaction/test/transaction.test.ts diff --git a/basics/ethereum/proxy-upgrade/.gitignore b/ethereum/proxy-upgrade/.gitignore similarity index 100% rename from basics/ethereum/proxy-upgrade/.gitignore rename to ethereum/proxy-upgrade/.gitignore diff --git a/basics/ethereum/proxy-upgrade/README.md b/ethereum/proxy-upgrade/README.md similarity index 100% rename from basics/ethereum/proxy-upgrade/README.md rename to ethereum/proxy-upgrade/README.md diff --git a/basics/ethereum/proxy-upgrade/foundry.toml b/ethereum/proxy-upgrade/foundry.toml similarity index 100% rename from basics/ethereum/proxy-upgrade/foundry.toml rename to ethereum/proxy-upgrade/foundry.toml diff --git a/basics/ethereum/proxy-upgrade/src/Proxy.sol b/ethereum/proxy-upgrade/src/Proxy.sol similarity index 100% rename from basics/ethereum/proxy-upgrade/src/Proxy.sol rename to ethereum/proxy-upgrade/src/Proxy.sol diff --git a/basics/ethereum/proxy-upgrade/src/v1/ConflictedStorage.sol b/ethereum/proxy-upgrade/src/v1/ConflictedStorage.sol similarity index 100% rename from basics/ethereum/proxy-upgrade/src/v1/ConflictedStorage.sol rename to ethereum/proxy-upgrade/src/v1/ConflictedStorage.sol diff --git a/basics/ethereum/proxy-upgrade/src/v1/GuardianStorage.sol b/ethereum/proxy-upgrade/src/v1/GuardianStorage.sol similarity index 100% rename from basics/ethereum/proxy-upgrade/src/v1/GuardianStorage.sol rename to ethereum/proxy-upgrade/src/v1/GuardianStorage.sol diff --git a/basics/ethereum/proxy-upgrade/src/v2/EIP1967Storage.sol b/ethereum/proxy-upgrade/src/v2/EIP1967Storage.sol similarity index 100% rename from basics/ethereum/proxy-upgrade/src/v2/EIP1967Storage.sol rename to ethereum/proxy-upgrade/src/v2/EIP1967Storage.sol diff --git a/basics/ethereum/proxy-upgrade/test/Proxy.t.sol b/ethereum/proxy-upgrade/test/Proxy.t.sol similarity index 100% rename from basics/ethereum/proxy-upgrade/test/Proxy.t.sol rename to ethereum/proxy-upgrade/test/Proxy.t.sol diff --git a/basics/ethereum/proxy-upgrade/test/SlotConflicted.t.sol b/ethereum/proxy-upgrade/test/SlotConflicted.t.sol similarity index 100% rename from basics/ethereum/proxy-upgrade/test/SlotConflicted.t.sol rename to ethereum/proxy-upgrade/test/SlotConflicted.t.sol diff --git a/basics/ethereum/state/README.md b/ethereum/state/README.md similarity index 100% rename from basics/ethereum/state/README.md rename to ethereum/state/README.md diff --git a/basics/ethereum/state/package.json b/ethereum/state/package.json similarity index 100% rename from basics/ethereum/state/package.json rename to ethereum/state/package.json diff --git a/basics/ethereum/state/src/state.ts b/ethereum/state/src/state.ts similarity index 100% rename from basics/ethereum/state/src/state.ts rename to ethereum/state/src/state.ts diff --git a/basics/ethereum/state/test/state.test.ts b/ethereum/state/test/state.test.ts similarity index 100% rename from basics/ethereum/state/test/state.test.ts rename to ethereum/state/test/state.test.ts diff --git a/ethereum/statetrie/README.md b/ethereum/statetrie/README.md new file mode 100644 index 0000000..b94364b --- /dev/null +++ b/ethereum/statetrie/README.md @@ -0,0 +1,375 @@ +# State Trie Implementation in TypeScript + +This Learning Module implements a simplified hexary Merkle Patricia Trie (MPT) for storing Ethereum state data. This is a streamlined version of the full MPT specification - it doesn't include extension nodes or other optimizations found in production implementations. + +> **Prerequisites**: To better understand this module, it is recommended to have: +> +> - Basic understanding of hash functions and trees +> - Familiarity with key-value databases +> - Knowledge of Ethereum state storage concepts + +
+ +## 1. Overview + +Imagine you need to store and verify account balances in a blockchain system. You want to: + +- Efficiently store millions of account balances +- Quickly prove a specific account has a certain balance +- Generate a single hash that represents the entire state +- Update individual balances without recalculating everything +- **Maintain historical versions of the state for rollbacks** + +This simplified Merkle Patricia Trie (MPT) solves these challenges by organizing data in a tree structure where: + +- Each node's location is determined by its key's hash +- The tree has 16 branches at each level (hexary) +- The root hash uniquely identifies the entire state +- Updates only affect nodes along a single path + +**Note**: This implementation is simplified compared to Ethereum's full MPT specification. It uses only leaf and branch nodes, without extension nodes or other optimizations. + +## 2. Learning Objectives + +- Understand how simplified MPTs store and organize key-value data +- Learn the detailed mechanics of insert and get operations +- Explore how cryptographic hashing ensures data integrity +- Grasp the relationship between nodes, paths, and state roots +- **Understand immutable state management and version control** +- **Learn how MPTs enable time-travel debugging and rollbacks** + +## 3. Core Components + +### 3.1 Node Types + +The trie uses two types of nodes: + +**Leaf Node** + +- Stores actual key-value data +- Contains: + - Full key (address) + - Value (balance) + - Hash of the node + +**Branch Node** + +- Internal routing node with 16 children (0-F in hex) +- Contains: + - Up to 16 child pointers (hashes) + - Hash of the node + +### 3.2 Detailed Operation Mechanics + +#### 3.2.1 Insert Operation (`set`) + +The insert operation follows these detailed steps: + +1. **Key Preprocessing** + + - Take the input key (e.g., Ethereum address) + - Hash it using SHA-256 to get a deterministic path + - Convert the hash to hexadecimal nibbles (each hex digit = 4 bits) + - Each nibble (0-15) determines which branch to follow at each level + +2. **Tree Traversal** + + - Start from the root (or null for empty tree) + - For each level, use the corresponding nibble as the branch index + - Follow existing branches or prepare to create new ones + +3. **Node Creation/Update** + + - When reaching the insertion point: + - Create a new leaf node with the key-value pair + - Store the leaf node in the database + - Work backwards up the tree: + - Create/update branch nodes to point to the new leaf + - Each branch node gets stored in the database + - Update parent pointers along the entire path + +4. **Root Hash Update** + - Return the hash of the new root node + - This hash represents the entire updated state + +**Visual Example - Insert Operation**: + +Let's trace through inserting address `0x0001` with value `100`: + +1. **Hash the key**: `0x0001` → SHA-256 → `4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a` +2. **Extract path**: First few nibbles: `4`, `b`, `f`, `5`, `1`, `2`, `2`, `f`, `3`... +3. **Tree construction**: + ``` + Root (Branch) + └── [4] → Leaf(key: 0x0001, value: 100) + ``` +4. **Database storage**: Each node (leaf and branch node) gets stored with their hash as the key +5. **Return**: Hash of the root branch node + +**Adding a second address** `0x0002` with value `200`: + +- Hash: `0x0002` → SHA-256 → `dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986` +- Path starts with: `d`, `b`, `c`, `1`... +- Since the first nibble `d` is different from `4`, we can directly place the leaf: + ``` + Root (Branch) + ├── [4] → Leaf(key: 0x0001, value: 100) + └── [d] → Leaf(key: 0x0002, value: 200) + ``` + +**Adding a third address with similar path** `0x0003` with value `300`: + +- Hash: `0x0003` → SHA-256 → `4bf5122f3a4554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459b` +- Path starts with: `4`, `b`, `f`, `5`, `1`, `2`, `2`, `f`, `3`, `a`... +- Notice the path is identical to `0x0001` until `4bf5122f3` (9 nibbles), then diverges at the 10th nibble (`4` vs `a`) +- This creates a deeper tree structure: + ``` + Root (Branch) + ├── [4] → Branch + │ └── [b] → Branch + │ └── [f] → Branch + │ └── [5] → Branch + │ └── [1] → Branch + │ └── [2] → Branch + │ └── [2] → Branch + │ └── [f] → Branch + │ └── [3] → Branch + │ ├── [4] → Leaf(key: 0x0001, value: 100) + │ └── [a] → Leaf(key: 0x0003, value: 300) + └── [d] → Leaf(key: 0x0002, value: 200) + ``` +- The algorithm creates intermediate branch nodes for each shared nibble in the path (`4bf5122f3`) +- Only at the point where paths diverge (10th nibble: `4` vs `a`) do we place the actual leaf nodes + +**Parent Branch Update Process**: + +When inserting or updating a node, all parent branch nodes must be updated because their hash changes. Here's how the update propagates: + +1. **Bottom-up Hash Update**: + + - After creating/updating the leaf node, work backwards up the tree + - Each branch node's hash depends on its children's hashes + - When a child changes, the parent's hash must be recalculated + +2. **Step-by-step Update Process**: + + ``` + // Example: Updating 0x0001 from value 100 to 150 + + Before: + Root(hash: ABC123) → [4] → Branch(hash: DEF456) → ... → Leaf(0x0001, 100) + + After leaf update: + 1. Create new Leaf(0x0001, 150) with new hash GHI789 + 2. Update deepest branch: children[4] = GHI789, recalculate hash → JKL012 + 3. Update next branch up: children[b] = JKL012, recalculate hash → MNO345 + 4. Continue up the tree until reaching root + 5. Root gets new hash PQR678 + ``` + +3. **Database Operations**: + + - Each updated branch node is stored in the database with its new hash + - Old nodes remain in the database (for historical states) + - Only the new root hash is returned, representing the updated state + +4. **Immutability Preservation**: + - Original tree structure remains intact in the database + - New tree shares unchanged branches with the old tree + - Only the path from root to the modified leaf gets new nodes + - This enables efficient state history and rollbacks + +#### 3.2.2 Get Operation (`get`) + +The `get` operation retrieves a value from the trie by traversing the tree structure using the key's hash path. + +### Algorithm Overview + +1. **Path Generation**: Convert the key to a hexadecimal path using SHA-256 hash +2. **Tree Traversal**: Navigate through branch nodes following the path nibbles +3. **Value Retrieval**: Return the value when reaching the correct leaf node + +### Step-by-Step Process + +1. **Input Validation**: + + ```typescript + // Handle empty tree case + if (parent === this.EMPTY_TREE_ROOT) { + return null; + } + ``` + +2. **Path Generation**: + + ```typescript + // Convert key to hex path using SHA-256 + const path = this.getHexPath(key); + // Example: "0x0001" → SHA-256 → "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a" + // → [4, b, f, 5, 1, 2, 2, f, 3, 4, 4, 5, 5, 4, c, 5, 3, b, d, e, 2, e, b, b, 8, c, d, 2, b, 7, e, 3, d, 1, 6, 0, 0, a, d, 6, 3, 1, c, 3, 8, 5, a, 5, d, 7, c, c, e, 2, 3, c, 7, 7, 8, 5, 4, 5, 9, a] + ``` + +3. **Tree Traversal Process**: + + ``` + Looking for key: "0x0001" (path: [4, b, f, 5, 1, 2, 2, f, ...]) + + Step 1: Start at Root + ┌─────────────────┐ + │ Root Branch │ + │ [0][1][2][3][4] │ ← Check index [4] (first nibble) + │ [ ][ ][ ][ ][●] │ + └─────────────────┘ + │ + ▼ + + Step 2: Follow path[0] = 4 + ┌─────────────────┐ + │ Branch Node │ + │ [a][b][c][d][e] │ ← Check index [b] (second nibble) + │ [ ][●][ ][ ][ ] │ + └─────────────────┘ + │ + ▼ + + Step 3: Follow path[1] = b + ┌─────────────────┐ + │ Branch Node │ + │ [0][1][2][f][4] │ ← Check index [f] (third nibble) + │ [ ][ ][ ][●][ ] │ + └─────────────────┘ + │ + ▼ + + Step 4: Continue until reaching leaf... + ┌─────────────────┐ + │ Leaf Node │ + │ key: "0x0001" │ ← Compare with search key + │ value: 100 │ ← Return this value if match + └─────────────────┘ + ``` + +4. **Decision Points During Traversal**: + + ``` + At each branch node: + + ┌─────────────────┐ + │ Branch Node │ + │ [0][1][2][3][4] │ + │ [ ][ ][●][ ][ ] │ ← nibble = path[depth] + └─────────────────┘ + │ + ▼ + + Decision Tree: + ├─ If children[nibble] is null → Return null (key not found) + ├─ If children[nibble] exists → Continue to child node + └─ If reached leaf → Check if leaf.key === search_key + ``` + +5. **Complete Example - Finding "0x0001"**: + + ``` + Search: get(rootHash, "0x0001") + Path: [4, b, f, 5, 1, 2, 2, f, ...] + + Traversal: + Root → children[4] → Branch_A + Branch_A → children[b] → Branch_B + Branch_B → children[f] → Branch_C + Branch_C → children[5] → Branch_D + ... + Branch_X → children[a] → Leaf("0x0001", 100) + + Final Check: + ✓ Leaf.key ("0x0001") === search_key ("0x0001") + ✓ Return Leaf.value (100) + ``` + +6. **Failure Cases**: + + ``` + Case 1: Missing Branch + Root → children[4] → null + Result: Return null + + Case 2: Wrong Leaf Key + ...→ Leaf("0x0002", 200) + Search key: "0x0001" + Result: Return null (key mismatch) + + Case 3: Path Exhausted + Depth >= path.length but still at branch node + Result: Return null + ``` + +## 4. Implementation Details + +### 4.1 Core Components + +1. **StateTrie Class** + + - Main trie structure implementation + - Handles node creation, insertion, and retrieval + - Manages root hash calculation and updates + +2. **Node Types** + + - **Branch Node**: Contains 16 children array for hex nibbles + - **Leaf Node**: Stores key-value pairs at tree endpoints + - **Extension Node**: Optimizes paths with common prefixes + +3. **Key Processing** + - Converts hex keys to nibble arrays for traversal + - Handles path compression and decompression + - Manages key encoding/decoding for storage + +### 4.2 Storage and Hashing + +1. **Merkle Patricia Structure** + + ```typescript + // Example node structure + interface BranchNode { + children: (Node | null)[]; // 16 children for hex nibbles + value?: any; // Optional value at this node + } + + interface LeafNode { + key: string; // Remaining key path + value: any; // Stored value + } + ``` + +2. **Hash Calculation** + - Each node's hash is calculated from its contents + - Root hash represents entire trie state + - Changes propagate up to update root hash + +### 4.3 Operations + +1. **Insert Operation** + + - Traverses trie following key path + - Creates new nodes as needed + - Updates parent hashes up to root + +2. **Get Operation** + - Follows nibble path through branch nodes + - Verifies leaf key matches search key + - Returns value or null if not found + +## 5. Running Tests + +1. Install dependencies: + +```bash +npm install +``` + +2. Run tests: + +```bash +npm run test +``` diff --git a/ethereum/statetrie/package.json b/ethereum/statetrie/package.json new file mode 100644 index 0000000..2afcb6a --- /dev/null +++ b/ethereum/statetrie/package.json @@ -0,0 +1,12 @@ +{ + "name": "statetrie", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "mocha test/**/*.test.ts" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "" +} diff --git a/ethereum/statetrie/src/db.ts b/ethereum/statetrie/src/db.ts new file mode 100644 index 0000000..01748f8 --- /dev/null +++ b/ethereum/statetrie/src/db.ts @@ -0,0 +1,23 @@ +import { Hash, TrieNode } from "./hexatree"; + +export interface KVDB { + get(hash: Hash): Promise; + put(node: TrieNode): Promise; +} + +export class MemoryKVDB implements KVDB { + private db: Map; + + constructor() { + this.db = new Map(); + } + + async get(hash: Hash): Promise { + return this.db.get(hash); + } + async put(node: TrieNode): Promise { + const h = node.hash(); + this.db.set(h, node); + return h; + } +} diff --git a/ethereum/statetrie/src/hexatree.ts b/ethereum/statetrie/src/hexatree.ts new file mode 100644 index 0000000..ef5d691 --- /dev/null +++ b/ethereum/statetrie/src/hexatree.ts @@ -0,0 +1,190 @@ +import { createHash } from "crypto"; +import { KVDB } from "./db"; + +export type Hash = string; + +export enum NodeType { + LEAF = "leaf", + BRANCH = "branch", +} + +export abstract class TrieNode { + abstract type: NodeType; + abstract hash(): Hash; + abstract serialize(): Buffer; +} + +export class LeafNode extends TrieNode { + type: NodeType = NodeType.LEAF; + + constructor( + public key: string, + public value: number + ) { + super(); + } + + serialize(): Buffer { + const valueBuf = Buffer.alloc(8); + valueBuf.writeBigInt64BE(BigInt(this.value)); + + return Buffer.concat([Buffer.from([0]), Buffer.from(this.key), valueBuf]); + } + + hash(): Hash { + return createHash("sha256").update(this.serialize()).digest("hex"); + } +} + +export class BranchNode extends TrieNode { + type: NodeType = NodeType.BRANCH; + + constructor(public children: (Hash | null)[]) { + super(); + } + + serialize(): Buffer { + return Buffer.concat([ + Buffer.from([1]), + ...this.children.map((h) => + h ? Buffer.from(h.replace(/^0x/, ""), "hex") : Buffer.alloc(32, 0) + ), + ]); + } + + hash(): Hash { + return createHash("sha256").update(this.serialize()).digest("hex"); + } +} + +export class HexaTree { + EMPTY_TREE_ROOT: Hash = "56e81f171bcc55a6ff8345e69d5c7dbb273d1a4217b5e31eecfb5a6b9554d0e7"; + + constructor(private db: KVDB) {} + + async set(parent: Hash | null, key: string, value: number, depth: number = 0): Promise { + if (parent === this.EMPTY_TREE_ROOT) { + parent = null; + } + + const path = this.getHexPath(key); + if (!parent) { + const leaf = new LeafNode(key, value); + await this.db.put(leaf); + return leaf.hash(); + } + + const node = await this.db.get(parent); + if (!node) { + const leaf = new LeafNode(key, value); + await this.db.put(leaf); + return leaf.hash(); + } + + if (node.type === NodeType.BRANCH) { + const branchNode = node as BranchNode; + const children = [...branchNode.children]; + const nibble = path[depth]; + + const childHash = children[nibble]; + const newChildHash = await this.set(childHash, key, value, depth + 1); + + children[nibble] = newChildHash; + + const newBranch = new BranchNode(children); + await this.db.put(newBranch); + return newBranch.hash(); + } + + const leafNode = node as LeafNode; + if (leafNode.key === key) { + const newLeaf = new LeafNode(key, value); + await this.db.put(newLeaf); + return newLeaf.hash(); + } + + const oldPath = this.getHexPath(leafNode.key); + let i = depth; + while (i < path.length && i < oldPath.length && path[i] === oldPath[i]) { + i++; + } + + const currentBranchChildren = Array(16).fill(null); + const existingLeaf = new LeafNode(leafNode.key, leafNode.value); + await this.db.put(existingLeaf); + currentBranchChildren[oldPath[i]] = existingLeaf.hash(); + + const newLeaf = new LeafNode(key, value); + await this.db.put(newLeaf); + currentBranchChildren[path[i]] = newLeaf.hash(); + + let branch = new BranchNode(currentBranchChildren); + await this.db.put(branch); + while (i > depth) { + i--; + const tempChildren = Array(16).fill(null); + tempChildren[path[i]] = branch.hash(); + branch = new BranchNode(tempChildren); + await this.db.put(branch); + } + + return branch.hash(); + } + + async get(parent: Hash, key: string, depth: number = 0): Promise { + if (parent === this.EMPTY_TREE_ROOT) { + return null; + } + + const path = this.getHexPath(key); + const node = await this.db.get(parent); + if (!node) return null; + if (node.type === NodeType.LEAF) { + return (node as LeafNode).key === key ? (node as LeafNode).value : null; + } + if (depth >= path.length) return null; + const nibble = path[depth]; + const childHash = (node as BranchNode).children[nibble]; + if (!childHash) return null; + return this.get(childHash, key, depth + 1); + } + + getHexPath(key: string): number[] { + const hex = createHash("sha256").update(key).digest("hex"); + return hex.split("").map((c) => parseInt(c, 16)); + } + + /** + * Debug utility function to visualize the tree structure + * @param root Root hash of the tree to print + * @param depth Current depth in the tree (for indentation) + */ + async printTree(root: Hash | null, depth: number = 0) { + if (!root || root === this.EMPTY_TREE_ROOT) { + console.debug("Empty tree"); + return; + } + + const indent = " ".repeat(depth); + const node = await this.db.get(root); + + if (!node) { + console.debug(`${indent}Node not found: ${root}`); + return; + } + + if (node.type === NodeType.LEAF) { + const leaf = node as LeafNode; + console.debug(`${indent}Leaf: key=${leaf.key}, value=${leaf.value}`); + } else { + const branch = node as BranchNode; + console.debug(`${indent}Branch:`); + for (let i = 0; i < branch.children.length; i++) { + if (branch.children[i]) { + console.debug(`${indent}[${i}]:`); + await this.printTree(branch.children[i], depth + 1); + } + } + } + } +} diff --git a/ethereum/statetrie/src/state.ts b/ethereum/statetrie/src/state.ts new file mode 100644 index 0000000..02dcd0e --- /dev/null +++ b/ethereum/statetrie/src/state.ts @@ -0,0 +1,62 @@ +import { HexaTree, Hash } from "./hexatree"; +import { Address, Transaction, TransactionReceipt } from "./types"; + +export class State { + private trie: HexaTree; + private root: Hash; + private journal: Map; + + constructor(root: Hash, trie: HexaTree) { + this.root = root; + this.trie = trie; + this.journal = new Map(); + } + + getRoot(): Hash { + return this.root; + } + + async getBalance(address: Address): Promise { + const key = address.toString(); + if (this.journal.has(key)) { + return this.journal.get(key)!; + } + return (await this.trie.get(this.root, key)) ?? 0; + } + + async apply(transactions: Transaction[]): Promise { + const receipts: TransactionReceipt[] = []; + for (const tx of transactions) { + const fromBal = await this.getBalance(tx.from); + const toBal = await this.getBalance(tx.to); + + if (fromBal < tx.value) { + receipts.push({ + status: 0, + reason: "insufficient balance", + }); + continue; + } + + this.journal.set(tx.from, fromBal - tx.value); + this.journal.set(tx.to, toBal + tx.value); + receipts.push({ status: 1 }); + } + + return receipts; + } + + async commit(): Promise { + let newRoot = this.root; + for (const [key, value] of this.journal) { + newRoot = await this.trie.set(newRoot, key, value); + } + this.root = newRoot; + this.journal.clear(); + return this.root; + } + + revert() { + this.journal.clear(); + } +} diff --git a/ethereum/statetrie/src/types.ts b/ethereum/statetrie/src/types.ts new file mode 100644 index 0000000..4bbd271 --- /dev/null +++ b/ethereum/statetrie/src/types.ts @@ -0,0 +1,12 @@ +export type Address = string; + +export interface Transaction { + from: Address; + to: Address; + value: number; +} + +export type TransactionReceipt = { + status: number; + reason?: string; +}; diff --git a/ethereum/statetrie/test/db.test.ts b/ethereum/statetrie/test/db.test.ts new file mode 100644 index 0000000..ee388f8 --- /dev/null +++ b/ethereum/statetrie/test/db.test.ts @@ -0,0 +1,88 @@ +import { describe, it } from "mocha"; +import { expect } from "chai"; +import { MemoryKVDB } from "../src/db"; +import { LeafNode, BranchNode } from "../src/hexatree"; + +describe("MemoryKVDB", () => { + let db: MemoryKVDB; + + beforeEach(() => { + db = new MemoryKVDB(); + }); + + describe("#put()", () => { + it("should store leaf node and return hash", async () => { + const node = new LeafNode("0x1234", 100); + const hash = await db.put(node); + expect(hash).to.be.a("string"); + expect(hash).to.equal(node.hash()); + }); + + it("should store branch node and return hash", async () => { + const node = new BranchNode([null, null, "0x1234", null]); + const hash = await db.put(node); + expect(hash).to.be.a("string"); + expect(hash).to.equal(node.hash()); + }); + + it("should return same hash for identical nodes", async () => { + const leaf1 = new LeafNode("0x1234", 100); + const leaf2 = new LeafNode("0x1234", 100); + const hash1 = await db.put(leaf1); + const hash2 = await db.put(leaf2); + expect(hash1).to.equal(hash2); + }); + }); + + describe("#get()", () => { + it("should return undefined for non-existent hash", async () => { + const result = await db.get("0x1234"); + expect(result).to.be.undefined; + }); + + it("should retrieve stored leaf node", async () => { + const node = new LeafNode("0x1234", 100); + const hash = await db.put(node); + const retrieved = await db.get(hash); + expect(retrieved).to.deep.equal(node); + }); + + it("should retrieve stored branch node", async () => { + const node = new BranchNode([null, "0x5678", null]); + const hash = await db.put(node); + const retrieved = await db.get(hash); + expect(retrieved).to.deep.equal(node); + }); + }); + + describe("@Scenario: Multiple node operations", () => { + it("should handle multiple nodes of different types", async () => { + const leafNode = new LeafNode("0x1234", 100); + const branchNode = new BranchNode([null, "0x5678", null, null]); + + const leafHash = await db.put(leafNode); + const branchHash = await db.put(branchNode); + + const retrievedLeaf = await db.get(leafHash); + const retrievedBranch = await db.get(branchHash); + + expect(retrievedLeaf).to.deep.equal(leafNode); + expect(retrievedBranch).to.deep.equal(branchNode); + expect(leafHash).to.not.equal(branchHash); + }); + + it("should maintain consistency with identical nodes", async () => { + const branch1 = new BranchNode([null, "0x5678", null]); + const branch2 = new BranchNode([null, "0x5678", null]); + + const hash1 = await db.put(branch1); + const hash2 = await db.put(branch2); + + const retrieved1 = await db.get(hash1); + const retrieved2 = await db.get(hash2); + + expect(hash1).to.equal(hash2); + expect(retrieved1).to.deep.equal(retrieved2); + }); + }); +}); diff --git a/ethereum/statetrie/test/hexatree.test.ts b/ethereum/statetrie/test/hexatree.test.ts new file mode 100644 index 0000000..5c8af6d --- /dev/null +++ b/ethereum/statetrie/test/hexatree.test.ts @@ -0,0 +1,222 @@ +import { describe, it } from "mocha"; +import { HexaTree, LeafNode, BranchNode } from "../src/hexatree"; +import { expect } from "chai"; +import { MemoryKVDB } from "../src/db"; +import { createHash } from "crypto"; + +describe("HexaTree", () => { + let trie: HexaTree; + const ZERO_ROOT_HASH = "0x0000000000000000000000000000000000000000"; + + beforeEach(() => { + trie = new HexaTree(new MemoryKVDB()); + }); + + describe("#set()", () => { + it("should set value and return new root", async () => { + const address = "0x0000000000000000000000000000000000000001"; + const root = await trie.set(null, address, 100); + expect(root).to.be.a("string"); + + const value = await trie.get(root, address); + expect(value).to.equal(100); + }); + + it("should update existing value", async () => { + const address = "0x0000000000000000000000000000000000000001"; + let root = await trie.set(null, address, 100); + root = await trie.set(root, address, 200); + + const value = await trie.get(root, address); + expect(value).to.equal(200); + }); + + it("should handle multiple addresses", async () => { + const addr1 = "0x0000000000000000000000000000000000000001"; + const addr2 = "0x0000000000000000000000000000000000000002"; + + let root = await trie.set(null, addr1, 100); + root = await trie.set(root, addr2, 200); + + expect(await trie.get(root, addr1)).to.equal(100); + expect(await trie.get(root, addr2)).to.equal(200); + }); + + it("should handle addresses with similar hex paths", async () => { + const findSimilarAddresses = () => { + const addresses = []; + let i = 1; + while (addresses.length < 3) { + const addr = `0x${i.toString(16).padStart(40, "0")}`; + const hex = createHash("sha256").update(addr).digest("hex"); + if (addresses.length === 0) { + addresses.push(addr); + } else { + const firstAddr = addresses[0]; + const firstHex = createHash("sha256").update(firstAddr).digest("hex"); + if (hex.substring(0, 3) === firstHex.substring(0, 3)) { + addresses.push(addr); + } + } + i++; + } + return addresses; + }; + + const [addr1, addr2, addr3] = findSimilarAddresses(); + + let root = await trie.set(null, addr1, 100); + root = await trie.set(root, addr2, 200); + root = await trie.set(root, addr3, 300); + + expect(await trie.get(root, addr1)).to.equal(100); + expect(await trie.get(root, addr2)).to.equal(200); + expect(await trie.get(root, addr3)).to.equal(300); + }); + }); + + describe("#get()", () => { + it("should return null for new address", async () => { + const address = "0x0000000000000000000000000000000000000001"; + const value = await trie.get(ZERO_ROOT_HASH, address); + expect(value).to.be.null; + }); + + it("should return correct value after setting", async () => { + const address = "0x0000000000000000000000000000000000000001"; + const root = await trie.set(null, address, 100); + const value = await trie.get(root, address); + expect(value).to.equal(100); + }); + }); + + describe("@Scenario: Bulk operations", () => { + it("should handle bulk insertions and updates", async () => { + const addresses = Array.from( + { length: 100 }, + (_, i) => `0x${i.toString(16).padStart(40, "0")}` + ); + + let root = ZERO_ROOT_HASH; + for (let i = 0; i < addresses.length; i++) { + root = await trie.set(root, addresses[i], i * 100); + } + + for (let i = 0; i < addresses.length; i++) { + const value = await trie.get(root, addresses[i]); + expect(value).to.equal(i * 100); + } + + for (let i = 0; i < addresses.length; i += 2) { + root = await trie.set(root, addresses[i], i * 200); + } + + for (let i = 0; i < addresses.length; i++) { + const value = await trie.get(root, addresses[i]); + expect(value).to.equal(i % 2 === 0 ? i * 200 : i * 100); + } + }); + }); + + describe("@Scenario: Consistency after multiple operations", () => { + it("should maintain consistency after updates", async () => { + const operations = []; + let root = ZERO_ROOT_HASH; + + const addresses = Array.from( + { length: 20 }, + (_, i) => `0x${(i * 123).toString(16).padStart(40, "0")}` + ); + + for (let i = 0; i < addresses.length; i++) { + const value = Math.floor(Math.random() * 1000); + root = await trie.set(root, addresses[i], value); + operations.push({ addr: addresses[i], value }); + } + + for (let i = 0; i < 10; i++) { + const idx = Math.floor(Math.random() * addresses.length); + const newValue = Math.floor(Math.random() * 1000); + root = await trie.set(root, addresses[idx], newValue); + operations[idx].value = newValue; + } + + for (const op of operations) { + const value = await trie.get(root, op.addr); + expect(value).to.equal(op.value); + } + }); + }); +}); + +describe("LeafNode", () => { + describe("#constructor", () => { + it("should create a leaf node with key and value", () => { + const node = new LeafNode("0x1234", 100); + expect(node.key).to.equal("0x1234"); + expect(node.value).to.equal(100); + }); + }); + + describe("#serialize", () => { + it("should serialize node data correctly", () => { + const node = new LeafNode("0x1234", 100); + const serialized = node.serialize(); + expect(serialized).to.be.instanceof(Buffer); + expect(serialized[0]).to.equal(0); // Type identifier for leaf + }); + }); + + describe("#hash", () => { + it("should generate consistent hash for same data", () => { + const node1 = new LeafNode("0x1234", 100); + const node2 = new LeafNode("0x1234", 100); + expect(node1.hash()).to.equal(node2.hash()); + }); + + it("should generate different hash for different data", () => { + const node1 = new LeafNode("0x1234", 100); + const node2 = new LeafNode("0x1234", 200); + const node3 = new LeafNode("0x5678", 100); + expect(node1.hash()).to.not.equal(node2.hash()); + expect(node1.hash()).to.not.equal(node3.hash()); + }); + }); +}); + +describe("BranchNode", () => { + describe("#constructor", () => { + it("should create a branch node with children", () => { + const children = [null, "0x1234", null, "0x5678"]; + const node = new BranchNode(children); + expect(node.children).to.deep.equal(children); + }); + }); + + describe("#serialize", () => { + it("should serialize node data correctly", () => { + const node = new BranchNode([null, "0x1234", null]); + const serialized = node.serialize(); + expect(serialized).to.be.instanceof(Buffer); + expect(serialized[0]).to.equal(1); // Type identifier for branch + }); + }); + + describe("#hash", () => { + it("should generate consistent hash for same data", () => { + const children1 = [null, "0x1234", null]; + const children2 = [null, "0x1234", null]; + const node1 = new BranchNode(children1); + const node2 = new BranchNode(children2); + expect(node1.hash()).to.equal(node2.hash()); + }); + + it("should generate different hash for different data", () => { + const node1 = new BranchNode([null, "0x1234", null]); + const node2 = new BranchNode([null, "0x5678", null]); + const node3 = new BranchNode(["0x1234", null, null]); + expect(node1.hash()).to.not.equal(node2.hash()); + expect(node1.hash()).to.not.equal(node3.hash()); + }); + }); +}); diff --git a/ethereum/statetrie/test/state.test.ts b/ethereum/statetrie/test/state.test.ts new file mode 100644 index 0000000..f2b7db2 --- /dev/null +++ b/ethereum/statetrie/test/state.test.ts @@ -0,0 +1,118 @@ +import { describe, it } from "mocha"; +import { State } from "../src/state"; +import { expect } from "chai"; +import { HexaTree } from "../src/hexatree"; +import { MemoryKVDB } from "../src/db"; + +describe("State", () => { + let trie: HexaTree; + const ZERO_ROOT_HASH = "0x0000000000000000000000000000000000000000"; + + beforeEach(() => { + trie = new HexaTree(new MemoryKVDB()); + }); + + describe("#getRoot()", () => { + it("should return the current root hash", () => { + const state = new State(ZERO_ROOT_HASH, trie); + expect(state.getRoot()).to.equal(ZERO_ROOT_HASH); + }); + }); + + describe("#getBalance()", () => { + it("should return zero for new address", async () => { + const state = new State(ZERO_ROOT_HASH, trie); + const address = "0x0000000000000000000000000000000000000001"; + const balance = await state.getBalance(address); + expect(balance).to.equal(0); + }); + + it("should return correct balance after setting", async () => { + const address = "0x0000000000000000000000000000000000000001"; + const root = await trie.set(null, address, 100); + const state = new State(root, trie); + const balance = await state.getBalance(address); + expect(balance).to.equal(100); + }); + }); + + describe("#apply()", () => { + it("should process valid transaction", async () => { + const from = "0x0000000000000000000000000000000000000000"; + const to = "0x0000000000000000000000000000000000000001"; + const root = await trie.set(null, from, 200); + const transactions = [ + { + from: from, + to: to, + value: 100, + }, + ]; + + const state = new State(root, trie); + const receipts = await state.apply(transactions); + expect(receipts).to.be.an("array"); + expect(receipts.length).to.equal(1); + expect(receipts[0].status).to.equal(1); + expect(receipts[0].reason).to.be.undefined; + + const toBalance = await state.getBalance(to); + expect(toBalance).to.equal(100); + + const fromBalance = await state.getBalance(from); + expect(fromBalance).to.equal(100); + }); + + it("should fail with insufficient balance", async () => { + const from = "0x0000000000000000000000000000000000000000"; + const to = "0x0000000000000000000000000000000000000001"; + const root = await trie.set(null, from, 50); + const transactions = [ + { + from: from, + to: to, + value: 100, + }, + ]; + + const state = new State(root, trie); + const receipts = await state.apply(transactions); + expect(receipts[0].status).to.equal(0); + expect(receipts[0].reason).to.equal("insufficient balance"); + }); + }); + + describe("#commit()", () => { + it("should persist changes to trie", async () => { + const from = "0x0000000000000000000000000000000000000001"; + const to = "0x0000000000000000000000000000000000000002"; + const root = await trie.set(null, from, 200); + const state = new State(root, trie); + + const fromBalance = await state.getBalance(from); + expect(fromBalance).to.equal(200); + + await state.apply([{ from, to, value: 100 }]); + const newRoot = await state.commit(); + const newState = new State(newRoot, trie); + + expect(await newState.getBalance(from)).to.equal(100); + expect(await newState.getBalance(to)).to.equal(100); + }); + }); + + describe("#revert()", () => { + it("should discard uncommitted changes", async () => { + const from = "0x0000000000000000000000000000000000000000"; + const to = "0x0000000000000000000000000000000000000001"; + const root = await trie.set(null, from, 200); + const state = new State(root, trie); + + await state.apply([{ from, to, value: 100 }]); + state.revert(); + + expect(await state.getBalance(from)).to.equal(200); + expect(await state.getBalance(to)).to.equal(0); + }); + }); +}); diff --git a/basics/ethereum/vrf/.env.example b/ethereum/vrf/.env.example similarity index 100% rename from basics/ethereum/vrf/.env.example rename to ethereum/vrf/.env.example diff --git a/basics/ethereum/vrf/.gitignore b/ethereum/vrf/.gitignore similarity index 100% rename from basics/ethereum/vrf/.gitignore rename to ethereum/vrf/.gitignore diff --git a/basics/ethereum/vrf/README.md b/ethereum/vrf/README.md similarity index 100% rename from basics/ethereum/vrf/README.md rename to ethereum/vrf/README.md diff --git a/basics/ethereum/vrf/foundry.toml b/ethereum/vrf/foundry.toml similarity index 100% rename from basics/ethereum/vrf/foundry.toml rename to ethereum/vrf/foundry.toml diff --git a/basics/ethereum/vrf/package.json b/ethereum/vrf/package.json similarity index 100% rename from basics/ethereum/vrf/package.json rename to ethereum/vrf/package.json diff --git a/basics/ethereum/vrf/remappings.txt b/ethereum/vrf/remappings.txt similarity index 100% rename from basics/ethereum/vrf/remappings.txt rename to ethereum/vrf/remappings.txt diff --git a/basics/ethereum/vrf/script/DeployLottery.s.sol b/ethereum/vrf/script/DeployLottery.s.sol similarity index 100% rename from basics/ethereum/vrf/script/DeployLottery.s.sol rename to ethereum/vrf/script/DeployLottery.s.sol diff --git a/basics/ethereum/vrf/script/JoinLottery.s.sol b/ethereum/vrf/script/JoinLottery.s.sol similarity index 100% rename from basics/ethereum/vrf/script/JoinLottery.s.sol rename to ethereum/vrf/script/JoinLottery.s.sol diff --git a/basics/ethereum/vrf/src/Lottery.sol b/ethereum/vrf/src/Lottery.sol similarity index 100% rename from basics/ethereum/vrf/src/Lottery.sol rename to ethereum/vrf/src/Lottery.sol diff --git a/basics/ethereum/vrf/test/Lottery.t.sol b/ethereum/vrf/test/Lottery.t.sol similarity index 100% rename from basics/ethereum/vrf/test/Lottery.t.sol rename to ethereum/vrf/test/Lottery.t.sol diff --git a/basics/ethereum/vrf/test/mocks/VRFV2PlusWrapperMock.sol b/ethereum/vrf/test/mocks/VRFV2PlusWrapperMock.sol similarity index 100% rename from basics/ethereum/vrf/test/mocks/VRFV2PlusWrapperMock.sol rename to ethereum/vrf/test/mocks/VRFV2PlusWrapperMock.sol diff --git a/advanced/mev/.dockerignore b/mev/.dockerignore similarity index 100% rename from advanced/mev/.dockerignore rename to mev/.dockerignore diff --git a/advanced/mev/.env.example b/mev/.env.example similarity index 100% rename from advanced/mev/.env.example rename to mev/.env.example diff --git a/advanced/mev/.gitignore b/mev/.gitignore similarity index 100% rename from advanced/mev/.gitignore rename to mev/.gitignore diff --git a/advanced/mev/.nvmrc b/mev/.nvmrc similarity index 100% rename from advanced/mev/.nvmrc rename to mev/.nvmrc diff --git a/advanced/mev/README.md b/mev/README.md similarity index 100% rename from advanced/mev/README.md rename to mev/README.md diff --git a/advanced/mev/docker-compose.yml b/mev/docker-compose.yml similarity index 100% rename from advanced/mev/docker-compose.yml rename to mev/docker-compose.yml diff --git a/advanced/mev/docker/caller-bot.Dockerfile b/mev/docker/caller-bot.Dockerfile similarity index 100% rename from advanced/mev/docker/caller-bot.Dockerfile rename to mev/docker/caller-bot.Dockerfile diff --git a/advanced/mev/docker/caller.Dockerfile b/mev/docker/caller.Dockerfile similarity index 100% rename from advanced/mev/docker/caller.Dockerfile rename to mev/docker/caller.Dockerfile diff --git a/advanced/mev/docker/deployer.Dockerfile b/mev/docker/deployer.Dockerfile similarity index 100% rename from advanced/mev/docker/deployer.Dockerfile rename to mev/docker/deployer.Dockerfile diff --git a/advanced/mev/docker/game-manager.Dockerfile b/mev/docker/game-manager.Dockerfile similarity index 100% rename from advanced/mev/docker/game-manager.Dockerfile rename to mev/docker/game-manager.Dockerfile diff --git a/advanced/mev/foundry/Deploy.s.sol b/mev/foundry/Deploy.s.sol similarity index 100% rename from advanced/mev/foundry/Deploy.s.sol rename to mev/foundry/Deploy.s.sol diff --git a/advanced/mev/foundry/NthCallerGame.sol b/mev/foundry/NthCallerGame.sol similarity index 100% rename from advanced/mev/foundry/NthCallerGame.sol rename to mev/foundry/NthCallerGame.sol diff --git a/advanced/mev/foundry/foundry.toml b/mev/foundry/foundry.toml similarity index 100% rename from advanced/mev/foundry/foundry.toml rename to mev/foundry/foundry.toml diff --git a/advanced/mev/index.ts b/mev/index.ts similarity index 100% rename from advanced/mev/index.ts rename to mev/index.ts diff --git a/advanced/mev/package-lock.json b/mev/package-lock.json similarity index 100% rename from advanced/mev/package-lock.json rename to mev/package-lock.json diff --git a/advanced/mev/package.json b/mev/package.json similarity index 100% rename from advanced/mev/package.json rename to mev/package.json diff --git a/advanced/mev/setup.sh b/mev/setup.sh similarity index 100% rename from advanced/mev/setup.sh rename to mev/setup.sh diff --git a/advanced/mev/src/caller-bot.ts b/mev/src/caller-bot.ts similarity index 100% rename from advanced/mev/src/caller-bot.ts rename to mev/src/caller-bot.ts diff --git a/advanced/mev/src/config.ts b/mev/src/config.ts similarity index 100% rename from advanced/mev/src/config.ts rename to mev/src/config.ts diff --git a/advanced/mev/src/game-manager.ts b/mev/src/game-manager.ts similarity index 100% rename from advanced/mev/src/game-manager.ts rename to mev/src/game-manager.ts diff --git a/advanced/mev/src/utils.ts b/mev/src/utils.ts similarity index 100% rename from advanced/mev/src/utils.ts rename to mev/src/utils.ts diff --git a/advanced/mev/tsconfig.json b/mev/tsconfig.json similarity index 100% rename from advanced/mev/tsconfig.json rename to mev/tsconfig.json diff --git a/basics/core/ecdsa/README.md b/primitives/ecdsa/README.md similarity index 100% rename from basics/core/ecdsa/README.md rename to primitives/ecdsa/README.md diff --git a/basics/core/ecdsa/package.json b/primitives/ecdsa/package.json similarity index 100% rename from basics/core/ecdsa/package.json rename to primitives/ecdsa/package.json diff --git a/basics/core/ecdsa/src/ecdsa.ts b/primitives/ecdsa/src/ecdsa.ts similarity index 100% rename from basics/core/ecdsa/src/ecdsa.ts rename to primitives/ecdsa/src/ecdsa.ts diff --git a/basics/core/ecdsa/test/ecdsa.test.ts b/primitives/ecdsa/test/ecdsa.test.ts similarity index 100% rename from basics/core/ecdsa/test/ecdsa.test.ts rename to primitives/ecdsa/test/ecdsa.test.ts diff --git a/basics/core/merkletree/README.md b/primitives/merkletree/README.md similarity index 100% rename from basics/core/merkletree/README.md rename to primitives/merkletree/README.md diff --git a/basics/core/merkletree/package.json b/primitives/merkletree/package.json similarity index 100% rename from basics/core/merkletree/package.json rename to primitives/merkletree/package.json diff --git a/basics/core/merkletree/src/merkletree.ts b/primitives/merkletree/src/merkletree.ts similarity index 100% rename from basics/core/merkletree/src/merkletree.ts rename to primitives/merkletree/src/merkletree.ts diff --git a/basics/core/merkletree/test/merkletres.test.ts b/primitives/merkletree/test/merkletres.test.ts similarity index 100% rename from basics/core/merkletree/test/merkletres.test.ts rename to primitives/merkletree/test/merkletres.test.ts diff --git a/basics/core/pow/README.md b/primitives/pow/README.md similarity index 100% rename from basics/core/pow/README.md rename to primitives/pow/README.md diff --git a/basics/core/pow/package.json b/primitives/pow/package.json similarity index 100% rename from basics/core/pow/package.json rename to primitives/pow/package.json diff --git a/basics/core/pow/src/pow.ts b/primitives/pow/src/pow.ts similarity index 100% rename from basics/core/pow/src/pow.ts rename to primitives/pow/src/pow.ts diff --git a/basics/core/pow/test/pow.test.ts b/primitives/pow/test/pow.test.ts similarity index 100% rename from basics/core/pow/test/pow.test.ts rename to primitives/pow/test/pow.test.ts diff --git a/advanced/bitvm/README.md b/scaling/bitvm/README.md similarity index 100% rename from advanced/bitvm/README.md rename to scaling/bitvm/README.md diff --git a/advanced/bitvm/package.json b/scaling/bitvm/package.json similarity index 100% rename from advanced/bitvm/package.json rename to scaling/bitvm/package.json diff --git a/advanced/bitvm/src/bit4/bit4.ts b/scaling/bitvm/src/bit4/bit4.ts similarity index 100% rename from advanced/bitvm/src/bit4/bit4.ts rename to scaling/bitvm/src/bit4/bit4.ts diff --git a/advanced/bitvm/src/bitcoinscript.ts b/scaling/bitvm/src/bitcoinscript.ts similarity index 100% rename from advanced/bitvm/src/bitcoinscript.ts rename to scaling/bitvm/src/bitcoinscript.ts diff --git a/advanced/bitvm/src/bitvm.ts b/scaling/bitvm/src/bitvm.ts similarity index 100% rename from advanced/bitvm/src/bitvm.ts rename to scaling/bitvm/src/bitvm.ts diff --git a/advanced/bitvm/src/gate/index.ts b/scaling/bitvm/src/gate/index.ts similarity index 100% rename from advanced/bitvm/src/gate/index.ts rename to scaling/bitvm/src/gate/index.ts diff --git a/advanced/bitvm/src/gate/logic.ts b/scaling/bitvm/src/gate/logic.ts similarity index 100% rename from advanced/bitvm/src/gate/logic.ts rename to scaling/bitvm/src/gate/logic.ts diff --git a/advanced/bitvm/src/gate/nand.ts b/scaling/bitvm/src/gate/nand.ts similarity index 100% rename from advanced/bitvm/src/gate/nand.ts rename to scaling/bitvm/src/gate/nand.ts diff --git a/advanced/bitvm/src/proof.ts b/scaling/bitvm/src/proof.ts similarity index 100% rename from advanced/bitvm/src/proof.ts rename to scaling/bitvm/src/proof.ts diff --git a/advanced/bitvm/src/taproot.ts b/scaling/bitvm/src/taproot.ts similarity index 100% rename from advanced/bitvm/src/taproot.ts rename to scaling/bitvm/src/taproot.ts diff --git a/advanced/bitvm/src/u4/index.ts b/scaling/bitvm/src/u4/index.ts similarity index 100% rename from advanced/bitvm/src/u4/index.ts rename to scaling/bitvm/src/u4/index.ts diff --git a/advanced/bitvm/src/u4/u4-add.ts b/scaling/bitvm/src/u4/u4-add.ts similarity index 100% rename from advanced/bitvm/src/u4/u4-add.ts rename to scaling/bitvm/src/u4/u4-add.ts diff --git a/advanced/bitvm/src/u4/u4-gt.ts b/scaling/bitvm/src/u4/u4-gt.ts similarity index 100% rename from advanced/bitvm/src/u4/u4-gt.ts rename to scaling/bitvm/src/u4/u4-gt.ts diff --git a/advanced/bitvm/src/u4/u4-iszero.ts b/scaling/bitvm/src/u4/u4-iszero.ts similarity index 100% rename from advanced/bitvm/src/u4/u4-iszero.ts rename to scaling/bitvm/src/u4/u4-iszero.ts diff --git a/advanced/bitvm/src/u4/u4-mux.ts b/scaling/bitvm/src/u4/u4-mux.ts similarity index 100% rename from advanced/bitvm/src/u4/u4-mux.ts rename to scaling/bitvm/src/u4/u4-mux.ts diff --git a/advanced/bitvm/src/u4/u4-sub.ts b/scaling/bitvm/src/u4/u4-sub.ts similarity index 100% rename from advanced/bitvm/src/u4/u4-sub.ts rename to scaling/bitvm/src/u4/u4-sub.ts diff --git a/advanced/bitvm/src/u4/u4.ts b/scaling/bitvm/src/u4/u4.ts similarity index 100% rename from advanced/bitvm/src/u4/u4.ts rename to scaling/bitvm/src/u4/u4.ts diff --git a/advanced/bitvm/src/util/index.ts b/scaling/bitvm/src/util/index.ts similarity index 100% rename from advanced/bitvm/src/util/index.ts rename to scaling/bitvm/src/util/index.ts diff --git a/advanced/bitvm/test/bitvm.test.ts b/scaling/bitvm/test/bitvm.test.ts similarity index 100% rename from advanced/bitvm/test/bitvm.test.ts rename to scaling/bitvm/test/bitvm.test.ts diff --git a/advanced/bitvm/test/gate/logic.test.ts b/scaling/bitvm/test/gate/logic.test.ts similarity index 100% rename from advanced/bitvm/test/gate/logic.test.ts rename to scaling/bitvm/test/gate/logic.test.ts diff --git a/advanced/bitvm/test/gate/nand.test.ts b/scaling/bitvm/test/gate/nand.test.ts similarity index 100% rename from advanced/bitvm/test/gate/nand.test.ts rename to scaling/bitvm/test/gate/nand.test.ts diff --git a/advanced/bitvm/test/proof.test.ts b/scaling/bitvm/test/proof.test.ts similarity index 100% rename from advanced/bitvm/test/proof.test.ts rename to scaling/bitvm/test/proof.test.ts diff --git a/advanced/bitvm/test/taproot.test.ts b/scaling/bitvm/test/taproot.test.ts similarity index 100% rename from advanced/bitvm/test/taproot.test.ts rename to scaling/bitvm/test/taproot.test.ts diff --git a/advanced/bitvm/test/u4/u4-add.test.ts b/scaling/bitvm/test/u4/u4-add.test.ts similarity index 100% rename from advanced/bitvm/test/u4/u4-add.test.ts rename to scaling/bitvm/test/u4/u4-add.test.ts diff --git a/advanced/bitvm/test/u4/u4-gt.test.ts b/scaling/bitvm/test/u4/u4-gt.test.ts similarity index 100% rename from advanced/bitvm/test/u4/u4-gt.test.ts rename to scaling/bitvm/test/u4/u4-gt.test.ts diff --git a/advanced/bitvm/test/u4/u4-mux.test.ts b/scaling/bitvm/test/u4/u4-mux.test.ts similarity index 100% rename from advanced/bitvm/test/u4/u4-mux.test.ts rename to scaling/bitvm/test/u4/u4-mux.test.ts diff --git a/advanced/bitvm/test/u4/u4-sub.test.ts b/scaling/bitvm/test/u4/u4-sub.test.ts similarity index 100% rename from advanced/bitvm/test/u4/u4-sub.test.ts rename to scaling/bitvm/test/u4/u4-sub.test.ts diff --git a/advanced/bitvm/test/u4/u4.test.ts b/scaling/bitvm/test/u4/u4.test.ts similarity index 100% rename from advanced/bitvm/test/u4/u4.test.ts rename to scaling/bitvm/test/u4/u4.test.ts diff --git a/advanced/optimistic-rollup/README.md b/scaling/optimistic-rollup/README.md similarity index 100% rename from advanced/optimistic-rollup/README.md rename to scaling/optimistic-rollup/README.md diff --git a/advanced/optimistic-rollup/contracts/Rollup.sol b/scaling/optimistic-rollup/contracts/Rollup.sol similarity index 100% rename from advanced/optimistic-rollup/contracts/Rollup.sol rename to scaling/optimistic-rollup/contracts/Rollup.sol diff --git a/advanced/optimistic-rollup/hardhat.config.ts b/scaling/optimistic-rollup/hardhat.config.ts similarity index 100% rename from advanced/optimistic-rollup/hardhat.config.ts rename to scaling/optimistic-rollup/hardhat.config.ts diff --git a/advanced/optimistic-rollup/package-lock.json b/scaling/optimistic-rollup/package-lock.json similarity index 100% rename from advanced/optimistic-rollup/package-lock.json rename to scaling/optimistic-rollup/package-lock.json diff --git a/advanced/optimistic-rollup/package.json b/scaling/optimistic-rollup/package.json similarity index 100% rename from advanced/optimistic-rollup/package.json rename to scaling/optimistic-rollup/package.json diff --git a/advanced/optimistic-rollup/test/helper.ts b/scaling/optimistic-rollup/test/helper.ts similarity index 100% rename from advanced/optimistic-rollup/test/helper.ts rename to scaling/optimistic-rollup/test/helper.ts diff --git a/advanced/optimistic-rollup/test/rollup.test.ts b/scaling/optimistic-rollup/test/rollup.test.ts similarity index 100% rename from advanced/optimistic-rollup/test/rollup.test.ts rename to scaling/optimistic-rollup/test/rollup.test.ts diff --git a/tsconfig.json b/tsconfig.json index e8c9db3..6e006de 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,19 +10,14 @@ "rootDir": "./" }, "include": [ - "hand-on-sessions/**/*", - "assignments/**/*", "hardhat.config.ts", - "basics/ethereum/04-eth-account", - "basics/ethereum/05-eth-transaction", - "basics/ethereum/06-eth-state", - "basics/core/03-pow", - "basics/core/02-merkletree", - "basics/core/01-ecdsa", - "basics/aptos/14-aptos-multi-agent-transaction", - "basics/aptos/aptos-sdk-sponsoring-transactions", - "basics/aptos/aptos-sdk-account/aptos-sdk-transaction", - "basics/aptos/aptos-sdk-account" + "aptos/**/*", + "bitcoin/**/*", + "ethereum/**/*", + "mev/**/*", + "primitives/**/*", + "scaling/**/*", + "zk/**/*" ], "exclude": ["node_modules"] -} \ No newline at end of file +} diff --git a/basics/core/izkp/README.md b/zk/izkp/README.md similarity index 100% rename from basics/core/izkp/README.md rename to zk/izkp/README.md diff --git a/basics/core/izkp/package-lock.json b/zk/izkp/package-lock.json similarity index 100% rename from basics/core/izkp/package-lock.json rename to zk/izkp/package-lock.json diff --git a/basics/core/izkp/package.json b/zk/izkp/package.json similarity index 100% rename from basics/core/izkp/package.json rename to zk/izkp/package.json diff --git a/basics/core/izkp/src/fetch.ts b/zk/izkp/src/fetch.ts similarity index 100% rename from basics/core/izkp/src/fetch.ts rename to zk/izkp/src/fetch.ts diff --git a/basics/core/izkp/src/prover.ts b/zk/izkp/src/prover.ts similarity index 100% rename from basics/core/izkp/src/prover.ts rename to zk/izkp/src/prover.ts diff --git a/basics/core/izkp/src/verifier.ts b/zk/izkp/src/verifier.ts similarity index 100% rename from basics/core/izkp/src/verifier.ts rename to zk/izkp/src/verifier.ts diff --git a/basics/core/izkp/test/prover.test.ts b/zk/izkp/test/prover.test.ts similarity index 100% rename from basics/core/izkp/test/prover.test.ts rename to zk/izkp/test/prover.test.ts diff --git a/basics/core/izkp/test/verifier.test.ts b/zk/izkp/test/verifier.test.ts similarity index 100% rename from basics/core/izkp/test/verifier.test.ts rename to zk/izkp/test/verifier.test.ts diff --git a/advanced/zksnark/Readme.md b/zk/zksnark/Readme.md similarity index 100% rename from advanced/zksnark/Readme.md rename to zk/zksnark/Readme.md diff --git a/advanced/zksnark/package.json b/zk/zksnark/package.json similarity index 100% rename from advanced/zksnark/package.json rename to zk/zksnark/package.json diff --git a/advanced/zksnark/src/crs.ts b/zk/zksnark/src/crs.ts similarity index 100% rename from advanced/zksnark/src/crs.ts rename to zk/zksnark/src/crs.ts diff --git a/advanced/zksnark/src/prover.ts b/zk/zksnark/src/prover.ts similarity index 100% rename from advanced/zksnark/src/prover.ts rename to zk/zksnark/src/prover.ts diff --git a/advanced/zksnark/src/qap.ts b/zk/zksnark/src/qap.ts similarity index 100% rename from advanced/zksnark/src/qap.ts rename to zk/zksnark/src/qap.ts diff --git a/advanced/zksnark/src/r1cs.ts b/zk/zksnark/src/r1cs.ts similarity index 100% rename from advanced/zksnark/src/r1cs.ts rename to zk/zksnark/src/r1cs.ts diff --git a/advanced/zksnark/src/verifier.ts b/zk/zksnark/src/verifier.ts similarity index 100% rename from advanced/zksnark/src/verifier.ts rename to zk/zksnark/src/verifier.ts diff --git a/advanced/zksnark/test/crs.test.ts b/zk/zksnark/test/crs.test.ts similarity index 100% rename from advanced/zksnark/test/crs.test.ts rename to zk/zksnark/test/crs.test.ts diff --git a/advanced/zksnark/test/prover.test.ts b/zk/zksnark/test/prover.test.ts similarity index 100% rename from advanced/zksnark/test/prover.test.ts rename to zk/zksnark/test/prover.test.ts diff --git a/advanced/zksnark/test/qap.test.ts b/zk/zksnark/test/qap.test.ts similarity index 100% rename from advanced/zksnark/test/qap.test.ts rename to zk/zksnark/test/qap.test.ts diff --git a/advanced/zksnark/test/r1cs.test.ts b/zk/zksnark/test/r1cs.test.ts similarity index 100% rename from advanced/zksnark/test/r1cs.test.ts rename to zk/zksnark/test/r1cs.test.ts diff --git a/advanced/zksnark/test/zksnark.test.ts b/zk/zksnark/test/zksnark.test.ts similarity index 100% rename from advanced/zksnark/test/zksnark.test.ts rename to zk/zksnark/test/zksnark.test.ts