refactor: update incremental merkle tree sol pkg

This commit is contained in:
cedoor
2022-07-04 15:54:15 +02:00
parent c239638cd9
commit 4064e92f46
13 changed files with 262 additions and 218 deletions

View File

@@ -17,7 +17,8 @@
"benchmarks": "rimraf benchmarks/results && ts-node benchmarks/index.ts",
"docs": "yarn workspaces foreach run docs",
"commit": "cz",
"precommit": "lint-staged"
"precommit": "lint-staged",
"postinstall": "yarn build"
},
"keywords": [
"javascript",

View File

@@ -1,168 +0,0 @@
<p align="center">
<h1 align="center">
Incremental Merkle Trees (Solidity)
</h1>
<p align="center">Incremental Merkle tree Solidity libraries.</p>
</p>
<p align="center">
<a href="https://github.com/privacy-scaling-explorations/zk-kit">
<img src="https://img.shields.io/badge/project-zk--kit-blue.svg?style=flat-square">
</a>
<a href="https://github.com/privacy-scaling-explorations/zk-kit/blob/main/LICENSE">
<img alt="Github license" src="https://img.shields.io/github/license/privacy-scaling-explorations/zk-kit.svg?style=flat-square">
</a>
<a href="https://www.npmjs.com/package/@zk-kit/incremental-merkle-tree.sol">
<img alt="NPM version" src="https://img.shields.io/npm/v/@zk-kit/incremental-merkle-tree.sol?style=flat-square" />
</a>
<a href="https://npmjs.org/package/@zk-kit/incremental-merkle-tree.sol">
<img alt="Downloads" src="https://img.shields.io/npm/dm/@zk-kit/incremental-merkle-tree.sol.svg?style=flat-square" />
</a>
<a href="https://eslint.org/">
<img alt="Linter eslint" src="https://img.shields.io/badge/linter-eslint-8080f2?style=flat-square&logo=eslint" />
</a>
<a href="https://prettier.io/">
<img alt="Code style prettier" src="https://img.shields.io/badge/code%20style-prettier-f8bc45?style=flat-square&logo=prettier" />
</a>
</p>
<div align="center">
<h4>
<a href="https://discord.gg/9B9WgGP6YM">
🗣️ Chat &amp; Support
</a>
</h4>
</div>
## Libraries:
✔️ [IncrementalBinaryTree](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/incremental-merkle-tree.sol/contracts/IncrementalBinaryTree.sol) (Poseidon)\
✔️ [IncrementalQuinTree](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/incremental-merkle-tree.sol/contracts/IncrementalQuinTree.sol) (Poseidon)
> The methods of each library are always the same (i.e `insert`, `remove`, `verify`).
---
## 🛠 Install
### npm or yarn
Install the `@zk-kit/incremental-merkle-tree.sol` package with npm:
```bash
npm i @zk-kit/incremental-merkle-tree.sol --save
```
or yarn:
```bash
yarn add @zk-kit/incremental-merkle-tree.sol
```
## 📜 Usage
### Importing and using the library
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@zk-kit/incremental-merkle-tree.sol/contracts/IncrementalBinaryTree.sol";
contract Example {
using IncrementalBinaryTree for IncrementalTreeData;
event TreeCreated(bytes32 id, uint8 depth);
event LeafInserted(bytes32 indexed treeId, uint256 leaf, uint256 root);
event LeafRemoved(bytes32 indexed treeId, uint256 leaf, uint256 root);
mapping(bytes32 => IncrementalTreeData) public trees;
function createTree(bytes32 _id, uint8 _depth) external {
require(trees[_id].depth == 0, "Example: tree already exists");
trees[_id].init(_depth, 0);
emit TreeCreated(_id, _depth);
}
function insertLeaf(bytes32 _treeId, uint256 _leaf) external {
require(trees[_treeId].depth != 0, "Example: tree does not exist");
trees[_treeId].insert(_leaf);
emit LeafInserted(_treeId, _leaf, trees[_treeId].root);
}
function removeLeaf(
bytes32 _treeId,
uint256 _leaf,
uint256[] calldata _proofSiblings,
uint8[] calldata _proofPathIndices
) external {
require(trees[_treeId].depth != 0, "Example: tree does not exist");
trees[_treeId].remove(_leaf, _proofSiblings, _proofPathIndices);
emit LeafRemoved(_treeId, _leaf, trees[_treeId].root);
}
}
```
### Creating an Hardhat task to deploy the contract
```typescript
import { poseidon_gencontract as poseidonContract } from "circomlibjs"
import { Contract } from "ethers"
import { task, types } from "hardhat/config"
task("deploy:example", "Deploy an Example contract")
.addOptionalParam<boolean>("logs", "Print the logs", true, types.boolean)
.setAction(async ({ logs }, { ethers }): Promise<Contract> => {
const poseidonT3ABI = poseidonContract.generateABI(2)
const poseidonT3Bytecode = poseidonContract.createCode(2)
const [signer] = await ethers.getSigners()
const PoseidonLibT3Factory = new ethers.ContractFactory(poseidonT3ABI, poseidonT3Bytecode, signer)
const poseidonT3Lib = await PoseidonLibT3Factory.deploy()
await poseidonT3Lib.deployed()
logs && console.log(`PoseidonT3 library has been deployed to: ${poseidonT3Lib.address}`)
const IncrementalBinaryTreeLibFactory = await ethers.getContractFactory("IncrementalBinaryTree", {
libraries: {
PoseidonT3: poseidonT3Lib.address
}
})
const incrementalBinaryTreeLib = await IncrementalBinaryTreeLibFactory.deploy()
await incrementalBinaryTreeLib.deployed()
logs && console.log(`IncrementalBinaryTree library has been deployed to: ${incrementalBinaryTreeLib.address}`)
const ContractFactory = await ethers.getContractFactory("Example", {
libraries: {
IncrementalBinaryTree: incrementalBinaryTreeLib.address
}
})
const contract = await ContractFactory.deploy()
await contract.deployed()
logs && console.log(`Example contract has been deployed to: ${contract.address}`)
return contract
})
```
## Contacts
### Developers
- e-mail : me@cedoor.dev
- github : [@cedoor](https://github.com/cedoor)
- website : https://cedoor.dev

View File

@@ -0,0 +1 @@
contracts/README.md

View File

@@ -0,0 +1,160 @@
<p align="center">
<h1 align="center">
Incremental Merkle Trees (Solidity)
</h1>
<p align="center">Incremental Merkle tree Solidity libraries.</p>
</p>
<p align="center">
<a href="https://github.com/privacy-scaling-explorations/zk-kit">
<img src="https://img.shields.io/badge/project-zk--kit-blue.svg?style=flat-square">
</a>
<a href="https://github.com/privacy-scaling-explorations/zk-kit/blob/main/LICENSE">
<img alt="Github license" src="https://img.shields.io/github/license/privacy-scaling-explorations/zk-kit.svg?style=flat-square">
</a>
<a href="https://www.npmjs.com/package/@zk-kit/incremental-merkle-tree.sol">
<img alt="NPM version" src="https://img.shields.io/npm/v/@zk-kit/incremental-merkle-tree.sol?style=flat-square" />
</a>
<a href="https://npmjs.org/package/@zk-kit/incremental-merkle-tree.sol">
<img alt="Downloads" src="https://img.shields.io/npm/dm/@zk-kit/incremental-merkle-tree.sol.svg?style=flat-square" />
</a>
<a href="https://eslint.org/">
<img alt="Linter eslint" src="https://img.shields.io/badge/linter-eslint-8080f2?style=flat-square&logo=eslint" />
</a>
<a href="https://prettier.io/">
<img alt="Code style prettier" src="https://img.shields.io/badge/code%20style-prettier-f8bc45?style=flat-square&logo=prettier" />
</a>
</p>
<div align="center">
<h4>
<a href="https://discord.gg/9B9WgGP6YM">
🗣️ Chat &amp; Support
</a>
</h4>
</div>
## Libraries:
✔️ [IncrementalBinaryTree](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/incremental-merkle-tree.sol/contracts/IncrementalBinaryTree.sol) (Poseidon)\
✔️ [IncrementalQuinTree](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/incremental-merkle-tree.sol/contracts/IncrementalQuinTree.sol) (Poseidon)
> The methods of each library are always the same (i.e `insert`, `remove`, `verify`).
---
## 🛠 Install
### npm or yarn
Install the `@zk-kit/incremental-merkle-tree.sol` package with npm:
```bash
npm i @zk-kit/incremental-merkle-tree.sol --save
```
or yarn:
```bash
yarn add @zk-kit/incremental-merkle-tree.sol
```
## 📜 Usage
### Importing and using the library
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@zk-kit/incremental-merkle-tree.sol/contracts/IncrementalBinaryTree.sol";
contract Example {
using IncrementalBinaryTree for IncrementalTreeData;
event TreeCreated(bytes32 id, uint8 depth);
event LeafInserted(bytes32 indexed treeId, uint256 leaf, uint256 root);
event LeafRemoved(bytes32 indexed treeId, uint256 leaf, uint256 root);
mapping(bytes32 => IncrementalTreeData) public trees;
function createTree(bytes32 _id, uint8 _depth) external {
require(trees[_id].depth == 0, "Example: tree already exists");
trees[_id].init(_depth, 0);
emit TreeCreated(_id, _depth);
}
function insertLeaf(bytes32 _treeId, uint256 _leaf) external {
require(trees[_treeId].depth != 0, "Example: tree does not exist");
trees[_treeId].insert(_leaf);
emit LeafInserted(_treeId, _leaf, trees[_treeId].root);
}
function removeLeaf(
bytes32 _treeId,
uint256 _leaf,
uint256[] calldata _proofSiblings,
uint8[] calldata _proofPathIndices
) external {
require(trees[_treeId].depth != 0, "Example: tree does not exist");
trees[_treeId].remove(_leaf, _proofSiblings, _proofPathIndices);
emit LeafRemoved(_treeId, _leaf, trees[_treeId].root);
}
}
```
### Creating an Hardhat task to deploy the contract
```typescript
import { poseidon_gencontract as poseidonContract } from "circomlibjs"
import { Contract } from "ethers"
import { task, types } from "hardhat/config"
task("deploy:example", "Deploy an Example contract")
.addOptionalParam<boolean>("logs", "Print the logs", true, types.boolean)
.setAction(async ({ logs }, { ethers }): Promise<Contract> => {
const poseidonT3ABI = poseidonContract.generateABI(2)
const poseidonT3Bytecode = poseidonContract.createCode(2)
const [signer] = await ethers.getSigners()
const PoseidonLibT3Factory = new ethers.ContractFactory(poseidonT3ABI, poseidonT3Bytecode, signer)
const poseidonT3Lib = await PoseidonLibT3Factory.deploy()
await poseidonT3Lib.deployed()
logs && console.log(`PoseidonT3 library has been deployed to: ${poseidonT3Lib.address}`)
const IncrementalBinaryTreeLibFactory = await ethers.getContractFactory("IncrementalBinaryTree", {
libraries: {
PoseidonT3: poseidonT3Lib.address
}
})
const incrementalBinaryTreeLib = await IncrementalBinaryTreeLibFactory.deploy()
await incrementalBinaryTreeLib.deployed()
logs && console.log(`IncrementalBinaryTree library has been deployed to: ${incrementalBinaryTreeLib.address}`)
const ContractFactory = await ethers.getContractFactory("Example", {
libraries: {
IncrementalBinaryTree: incrementalBinaryTreeLib.address
}
})
const contract = await ContractFactory.deploy()
await contract.deployed()
logs && console.log(`Example contract has been deployed to: ${contract.address}`)
return contract
})
```

View File

@@ -0,0 +1,31 @@
{
"name": "@zk-kit/incremental-merkle-tree.sol",
"version": "1.0.0",
"description": "Incremental Merkle tree Solidity libraries.",
"license": "MIT",
"files": [
"**/*.sol",
"!test/",
"README.md"
],
"keywords": [
"blockchain",
"ethereum",
"hardhat",
"smart-contracts",
"solidity",
"libraries",
"merkle-tree",
"incremental-merkle-tree"
],
"repository": "git@github.com:privacy-scaling-explorations/zk-kit.git",
"homepage": "https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/incremental-merkle-tree.sol",
"author": {
"name": "Omar Desogus",
"email": "me@cedoor.dev",
"url": "https://cedoor.dev"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -2,9 +2,9 @@
pragma solidity ^0.8.4;
import "./IncrementalBinaryTree.sol";
import "../IncrementalBinaryTree.sol";
contract BinaryTreeTest {
contract IncrementalBinaryTreeTest {
using IncrementalBinaryTree for IncrementalTreeData;
event TreeCreated(bytes32 id, uint8 depth);

View File

@@ -2,9 +2,9 @@
pragma solidity ^0.8.4;
import "./IncrementalQuinTree.sol";
import "../IncrementalQuinTree.sol";
contract QuinTreeTest {
contract IncrementalQuinTreeTest {
using IncrementalQuinTree for IncrementalTreeData;
event TreeCreated(bytes32 id, uint8 depth);

View File

@@ -6,8 +6,8 @@ import { HardhatUserConfig } from "hardhat/config"
import { resolve } from "path"
import "solidity-coverage"
import { config } from "./package.json"
import "./tasks/deploy-binary-tree-test"
import "./tasks/deploy-quin-tree-test"
import "./tasks/deploy-ibt-test"
import "./tasks/deploy-iqt-test"
dotenvConfig({ path: resolve(__dirname, "./.env") })

View File

@@ -1,46 +1,16 @@
{
"name": "@zk-kit/incremental-merkle-tree.sol",
"version": "0.3.1",
"description": "Incremental Merkle tree Solidity libraries.",
"license": "MIT",
"files": [
"contracts/",
"!contracts/Test.sol",
"build/",
"!build/contracts/Test.sol",
"README.md"
],
"keywords": [
"blockchain",
"ethereum",
"hardhat",
"smart-contracts",
"solidity",
"libraries",
"merkle-tree",
"incremental-merkle-tree"
],
"repository": "git@github.com:privacy-scaling-explorations/zk-kit.git",
"homepage": "https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/incremental-merkle-tree.sol",
"author": {
"name": "Omar Desogus",
"email": "me@cedoor.dev",
"url": "https://cedoor.dev"
},
"private": true,
"scripts": {
"start": "hardhat node",
"build": "hardhat compile",
"deploy:binary-tree-test": "hardhat deploy:binary-tree-test",
"deploy:quin-tree-test": "hardhat deploy:quin-tree-test",
"compile": "hardhat compile",
"deploy:test-contracts": "hardhat deploy:tree-contracts",
"test": "hardhat test",
"test:report-gas": "REPORT_GAS=true hardhat test",
"test:coverage": "hardhat coverage",
"test:prod": "yarn lint && yarn coverage",
"lint": "solhint 'contracts/**/*.sol'",
"prepublishOnly": "yarn build"
},
"publishConfig": {
"access": "public"
"lint": "solhint 'contracts/**/*.sol'"
},
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.4",

View File

@@ -0,0 +1,50 @@
import { poseidon_gencontract as poseidonContract } from "circomlibjs"
import { Contract } from "ethers"
import { task, types } from "hardhat/config"
task("deploy:ibt-test", "Deploy an IncrementalBinaryTreeTest contract")
.addOptionalParam<boolean>("logs", "Print the logs", true, types.boolean)
.setAction(async ({ logs }, { ethers }): Promise<Contract> => {
const poseidonT3ABI = poseidonContract.generateABI(2)
const poseidonT3Bytecode = poseidonContract.createCode(2)
const [signer] = await ethers.getSigners()
const PoseidonLibT3Factory = new ethers.ContractFactory(poseidonT3ABI, poseidonT3Bytecode, signer)
const poseidonT3Lib = await PoseidonLibT3Factory.deploy()
await poseidonT3Lib.deployed()
if (logs) {
console.info(`PoseidonT3 library has been deployed to: ${poseidonT3Lib.address}`)
}
const IncrementalBinaryTreeLibFactory = await ethers.getContractFactory("IncrementalBinaryTree", {
libraries: {
PoseidonT3: poseidonT3Lib.address
}
})
const incrementalBinaryTreeLib = await IncrementalBinaryTreeLibFactory.deploy()
await incrementalBinaryTreeLib.deployed()
if (logs) {
console.info(`IncrementalBinaryTree library has been deployed to: ${incrementalBinaryTreeLib.address}`)
}
const ContractFactory = await ethers.getContractFactory("IncrementalBinaryTreeTest", {
libraries: {
IncrementalBinaryTree: incrementalBinaryTreeLib.address
}
})
const contract = await ContractFactory.deploy()
await contract.deployed()
if (logs) {
console.info(`Test contract has been deployed to: ${contract.address}`)
}
return contract
})

View File

@@ -2,7 +2,7 @@ import { poseidon_gencontract as poseidonContract } from "circomlibjs"
import { Contract } from "ethers"
import { task, types } from "hardhat/config"
task("deploy:binary-tree-test", "Deploy a BinaryTreeTest contract")
task("deploy:incremental-binary-tree-test", "Deploy an IncrementalBinaryTreeTest contract")
.addOptionalParam<boolean>("logs", "Print the logs", true, types.boolean)
.setAction(async ({ logs }, { ethers }): Promise<Contract> => {
const poseidonT3ABI = poseidonContract.generateABI(2)

View File

@@ -2,7 +2,7 @@ import { poseidon_gencontract as poseidonContract } from "circomlibjs"
import { Contract } from "ethers"
import { task, types } from "hardhat/config"
task("deploy:quin-tree-test", "Deploy a QuinTreeTest contract")
task("deploy:iqt-test", "Deploy an IncrementalQuinTreeTest contract")
.addOptionalParam<boolean>("logs", "Print the logs", true, types.boolean)
.setAction(async ({ logs }, { ethers }): Promise<Contract> => {
const poseidonT6ABI = poseidonContract.generateABI(5)
@@ -32,7 +32,7 @@ task("deploy:quin-tree-test", "Deploy a QuinTreeTest contract")
console.info(`IncrementalQuinTree library has been deployed to: ${incrementalQuinTreeLib.address}`)
}
const ContractFactory = await ethers.getContractFactory("QuinTreeTest", {
const ContractFactory = await ethers.getContractFactory("IncrementalQuinTreeTest", {
libraries: {
IncrementalQuinTree: incrementalQuinTreeLib.address
}

View File

@@ -3,8 +3,7 @@ import { Contract } from "ethers"
import { ethers, run } from "hardhat"
import { createTree } from "./utils"
/* eslint-disable jest/valid-expect */
describe("BinaryTreeTest", () => {
describe("IncrementalBinaryTreeTest", () => {
let contract: Contract
const treeId = ethers.utils.formatBytes32String("treeId")
@@ -12,7 +11,7 @@ describe("BinaryTreeTest", () => {
const depth = 16
before(async () => {
contract = await run("deploy:binary-tree-test", { logs: false })
contract = await run("deploy:ibt-test", { logs: false })
})
it("Should not create a tree with a depth > 32", async () => {

View File

@@ -4,15 +4,15 @@ import { ethers, run } from "hardhat"
import { createTree } from "./utils"
/* eslint-disable jest/valid-expect */
describe("QuinTreeTest", () => {
describe("IncrementalQuinTreeTest", () => {
let contract: Contract
const treeId = ethers.utils.formatBytes32String("treeId")
const leaf = BigInt(1)
const depth = 16
const depth = 8
before(async () => {
contract = await run("deploy:quin-tree-test", { logs: false })
contract = await run("deploy:iqt-test", { logs: false })
})
it("Should not create a tree with a depth > 32", async () => {