zkjson 0.6.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +537 -0
- package/assets/collection.png +0 -0
- package/assets/db.png +0 -0
- package/assets/encode.png +0 -0
- package/assets/query.png +0 -0
- package/assets/rollup.png +0 -0
- package/assets/structure.png +0 -0
- package/assets/weavedb.png +0 -0
- package/assets/zkjson.png +0 -0
- package/benchmark/components/ui/avatar.jsx +49 -0
- package/benchmark/components/ui/checkbox.jsx +17 -0
- package/benchmark/components/ui/close-button.jsx +20 -0
- package/benchmark/components/ui/color-mode.jsx +89 -0
- package/benchmark/components/ui/dialog.jsx +54 -0
- package/benchmark/components/ui/drawer.jsx +44 -0
- package/benchmark/components/ui/field.jsx +22 -0
- package/benchmark/components/ui/input-group.jsx +39 -0
- package/benchmark/components/ui/popover.jsx +49 -0
- package/benchmark/components/ui/provider.jsx +12 -0
- package/benchmark/components/ui/radio.jsx +17 -0
- package/benchmark/components/ui/slider.jsx +107 -0
- package/benchmark/components/ui/tooltip.jsx +35 -0
- package/benchmark/jsconfig.json +7 -0
- package/benchmark/lib/cbor.js +387 -0
- package/benchmark/lib/msgpack.js +651 -0
- package/benchmark/next.config.mjs +6 -0
- package/benchmark/package.json +22 -0
- package/benchmark/pages/_app.js +9 -0
- package/benchmark/pages/_document.js +13 -0
- package/benchmark/pages/api/hello.js +5 -0
- package/benchmark/pages/index.js +438 -0
- package/benchmark/public/favicon.ico +0 -0
- package/benchmark/public/file.svg +1 -0
- package/benchmark/public/globe.svg +1 -0
- package/benchmark/public/next.svg +1 -0
- package/benchmark/public/vercel.svg +1 -0
- package/benchmark/public/window.svg +1 -0
- package/benchmark/yarn.lock +2448 -0
- package/circom/collection/collection.circom +32 -0
- package/circom/collection/compile.sh +10 -0
- package/circom/collection/gen.js +34 -0
- package/circom/collection/generateInput.js +10 -0
- package/circom/collection/index.circom +4 -0
- package/circom/collection/test.js +21 -0
- package/circom/collection/verifier.sol +247 -0
- package/circom/db/compile.sh +10 -0
- package/circom/db/db.circom +39 -0
- package/circom/db/gen.js +30 -0
- package/circom/db/generateInput.js +10 -0
- package/circom/db/index.circom +4 -0
- package/circom/db/test.js +21 -0
- package/circom/db/verifier.sol +261 -0
- package/circom/ipfs/calculate_total.circom +17 -0
- package/circom/ipfs/compile.sh +10 -0
- package/circom/ipfs/gen.js +18 -0
- package/circom/ipfs/generateInput.js +10 -0
- package/circom/ipfs/index.circom +4 -0
- package/circom/ipfs/ipfs.circom +62 -0
- package/circom/ipfs/parse.circom +289 -0
- package/circom/ipfs/sha256.circom +99 -0
- package/circom/ipfs/test.js +167 -0
- package/circom/ipfs/verifier.sol +261 -0
- package/circom/json/compile.sh +10 -0
- package/circom/json/gen.js +22 -0
- package/circom/json/gen2.js +21 -0
- package/circom/json/generateInput.js +20 -0
- package/circom/json/index.circom +4 -0
- package/circom/json/json.circom +81 -0
- package/circom/json/test.js +100 -0
- package/circom/json/verifier.sol +247 -0
- package/circom/query/compile.sh +10 -0
- package/circom/query/gen.js +28 -0
- package/circom/query/generateInput.js +11 -0
- package/circom/query/index.circom +4 -0
- package/circom/query/query.circom +58 -0
- package/circom/query/test.js +20 -0
- package/circom/query/verifier.sol +177 -0
- package/circom/rollup/compile.sh +10 -0
- package/circom/rollup/gen.js +36 -0
- package/circom/rollup/generateInput.js +11 -0
- package/circom/rollup/index.circom +4 -0
- package/circom/rollup/rollup.circom +43 -0
- package/circom/rollup/test.js +35 -0
- package/circom/rollup/verifier.sol +240 -0
- package/circom/scripts/ceremony.js +39 -0
- package/circom/scripts/ceremony.sh +6 -0
- package/circom/scripts/compile.js +113 -0
- package/circom/scripts/compile.sh +16 -0
- package/circom/utils/uint.circom +512 -0
- package/circom/utils/utils.circom +628 -0
- package/demos/arweave/jsconfig.json +7 -0
- package/demos/arweave/lib/ZKArweave.json +617 -0
- package/demos/arweave/lib/encoder.js +375 -0
- package/demos/arweave/next.config.js +6 -0
- package/demos/arweave/package.json +26 -0
- package/demos/arweave/pages/_app.js +9 -0
- package/demos/arweave/pages/_document.js +19 -0
- package/demos/arweave/pages/api/arweave.js +31 -0
- package/demos/arweave/pages/api/hello.js +5 -0
- package/demos/arweave/pages/index.js +869 -0
- package/demos/arweave/public/circuit.wasm +0 -0
- package/demos/arweave/public/circuit_final.zkey +0 -0
- package/demos/arweave/public/verification_key.json +149 -0
- package/demos/arweave/vercel.json +7 -0
- package/demos/arweave/yarn.lock +2510 -0
- package/demos/simple/jsconfig.json +7 -0
- package/demos/simple/lib/encoder.js +375 -0
- package/demos/simple/next.config.js +6 -0
- package/demos/simple/package.json +24 -0
- package/demos/simple/pages/_app.js +9 -0
- package/demos/simple/pages/_document.js +13 -0
- package/demos/simple/pages/api/hello.js +5 -0
- package/demos/simple/pages/index.js +342 -0
- package/demos/simple/public/circuit.wasm +0 -0
- package/demos/simple/public/circuit_final.zkey +0 -0
- package/demos/simple/public/verification_key.json +149 -0
- package/demos/simple/yarn.lock +2519 -0
- package/docs/README.md +17 -0
- package/docs/simple-zkjson.md +210 -0
- package/docs/solidity-contracts.md +216 -0
- package/docs/zk-circuits.md +125 -0
- package/docs/zkdb-rollup.md +218 -0
- package/docs/zkjson-sdk.md +254 -0
- package/docs/zkjson-v1_5.md +365 -0
- package/package.json +16 -7
- package/sdk/contracts/NORollup.sol +13 -0
- package/sdk/package.json +15 -0
- package/sdk/yarn.lock +881 -0
- package/solidity/README.md +13 -0
- package/solidity/arguments.js +4 -0
- package/solidity/contracts/NORollup.sol +13 -0
- package/solidity/contracts/OPRollup.sol +14 -0
- package/solidity/contracts/ZKIPFS.sol +95 -0
- package/solidity/contracts/ZKJson.sol +21 -0
- package/solidity/contracts/ZKQuery.sol +286 -0
- package/solidity/contracts/ZKRollup.sol +35 -0
- package/solidity/contracts/apps/NORU.sol +66 -0
- package/solidity/contracts/apps/SimpleJSON.sol +64 -0
- package/solidity/contracts/apps/SimpleOPRU.sol +67 -0
- package/solidity/contracts/apps/SimpleRU.sol +67 -0
- package/solidity/contracts/apps/Token.sol +12 -0
- package/solidity/contracts/apps/ZKArweave.sol +89 -0
- package/solidity/contracts/apps/ZKBridge.sol +74 -0
- package/solidity/contracts/apps/ZKNFT.sol +63 -0
- package/solidity/contracts/verifiers/verifier_db.sol +275 -0
- package/solidity/contracts/verifiers/verifier_ipfs.sol +464 -0
- package/solidity/contracts/verifiers/verifier_json.sol +261 -0
- package/solidity/contracts/verifiers/verifier_rollup.sol +240 -0
- package/solidity/package.json +27 -0
- package/solidity/scripts/deploy.js +33 -0
- package/solidity/test/NORU.js +66 -0
- package/solidity/test/ZKArweave.js +97 -0
- package/solidity/test/arweave.js +55 -0
- package/solidity/test/bridge.js +71 -0
- package/solidity/test/simple.js +76 -0
- package/solidity/test/simpleOPRU.js +98 -0
- package/solidity/test/simpleRU.js +94 -0
- package/solidity/test/zknft.js +98 -0
- package/solidity/yarn.lock +4152 -0
- package/test/test.js +304 -0
- /package/{circomlibjs.js → sdk/circomlibjs.js} +0 -0
- /package/{collection.js → sdk/collection.js} +0 -0
- /package/{contracts → sdk/contracts}/OPRollup.sol +0 -0
- /package/{contracts → sdk/contracts}/ZKIPFS.sol +0 -0
- /package/{contracts → sdk/contracts}/ZKJson.sol +0 -0
- /package/{contracts → sdk/contracts}/ZKQuery.sol +0 -0
- /package/{contracts → sdk/contracts}/ZKRollup.sol +0 -0
- /package/{contracts → sdk/contracts}/apps/SimpleJSON.sol +0 -0
- /package/{contracts → sdk/contracts}/apps/SimpleOPRU.sol +0 -0
- /package/{contracts → sdk/contracts}/apps/SimpleRU.sol +0 -0
- /package/{contracts → sdk/contracts}/apps/Token.sol +0 -0
- /package/{contracts → sdk/contracts}/apps/ZKArweave.sol +0 -0
- /package/{contracts → sdk/contracts}/apps/ZKBridge.sol +0 -0
- /package/{contracts → sdk/contracts}/apps/ZKNFT.sol +0 -0
- /package/{contracts → sdk/contracts}/verifiers/verifier_db.sol +0 -0
- /package/{contracts → sdk/contracts}/verifiers/verifier_ipfs.sol +0 -0
- /package/{contracts → sdk/contracts}/verifiers/verifier_json.sol +0 -0
- /package/{contracts → sdk/contracts}/verifiers/verifier_rollup.sol +0 -0
- /package/{db.js → sdk/db.js} +0 -0
- /package/{doc.js → sdk/doc.js} +0 -0
- /package/{encoder-v1_5.js → sdk/encoder-v1_5.js} +0 -0
- /package/{encoder.js → sdk/encoder.js} +0 -0
- /package/{index.js → sdk/index.js} +0 -0
- /package/{json.js → sdk/json.js} +0 -0
- /package/{nft.js → sdk/nft.js} +0 -0
- /package/{parse.js → sdk/parse.js} +0 -0
- /package/{uint.js → sdk/uint.js} +0 -0
package/docs/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
## zkJSON Docs
|
2
|
+
|
3
|
+
### About
|
4
|
+
|
5
|
+
- [Litepaper / Spec v1](../README.md)
|
6
|
+
- [Spec v1.5](./zkjson-v1_5.md)
|
7
|
+
|
8
|
+
### Tutorials
|
9
|
+
|
10
|
+
- [Tutorial: Simple zkJSON](./simple-zkjson.md)
|
11
|
+
- [Tutorial: zkDB Rollup](./zkdb-rollup.md)
|
12
|
+
|
13
|
+
### API Reference
|
14
|
+
|
15
|
+
- [ZK Circuits](./zk-circuits.md)
|
16
|
+
- [Solidity Contracts](./solidity-contracts.md)
|
17
|
+
- [zkJSON SDK](./zkjson-sdk.md)
|
@@ -0,0 +1,210 @@
|
|
1
|
+
## Simple zkJSON Tutorial
|
2
|
+
|
3
|
+
*zkJSON is still under active development, and neither the circuits nor the contracts have been audited. Please use it for only experimental purposes.*
|
4
|
+
|
5
|
+
### Install `zkjson` Package
|
6
|
+
|
7
|
+
Make sure you have [Circom](https://docs.circom.io/getting-started/installation/) and [Hardhat](https://hardhat.org/hardhat-runner/docs/getting-started#installation) installed globally.
|
8
|
+
|
9
|
+
```bash
|
10
|
+
git clone https://github.com/weavedb/zkjson.git
|
11
|
+
cd zkjson
|
12
|
+
yarn
|
13
|
+
```
|
14
|
+
|
15
|
+
### Generate Powers of Tau
|
16
|
+
|
17
|
+
```bash
|
18
|
+
yarn ceremony --power 14
|
19
|
+
```
|
20
|
+
|
21
|
+
### Compile Circuit
|
22
|
+
|
23
|
+
```bash
|
24
|
+
yarn compile --power 14 --circuit json
|
25
|
+
```
|
26
|
+
|
27
|
+
### Create Solidity Project with Hardhat
|
28
|
+
|
29
|
+
```bash
|
30
|
+
cd ..
|
31
|
+
mkdir myapp
|
32
|
+
cd myapp
|
33
|
+
npx hardhat init
|
34
|
+
yarn add zkjson
|
35
|
+
```
|
36
|
+
|
37
|
+
### Copy Verifier Contract
|
38
|
+
|
39
|
+
```bash
|
40
|
+
cp ../zkjson/circom/build/circuit/json/verifier.sol contracts/verifier_json.sol
|
41
|
+
```
|
42
|
+
|
43
|
+
Rename the contract name to `Groth16VerifierJSON` as we will have multiple verifiers with the same name.
|
44
|
+
|
45
|
+
Open `myapp/contracts/verifier_json.sol` and rename
|
46
|
+
|
47
|
+
```solidity
|
48
|
+
contract Groth16Verifier {
|
49
|
+
```
|
50
|
+
|
51
|
+
to
|
52
|
+
|
53
|
+
```solidity
|
54
|
+
contract Groth16VerifierJSON {
|
55
|
+
```
|
56
|
+
|
57
|
+
### Write Solidity Contract
|
58
|
+
|
59
|
+
`myapp/contracts/MyApp.sol`
|
60
|
+
|
61
|
+
```solidity
|
62
|
+
// SPDX-License-Identifier: UNLICENSED
|
63
|
+
|
64
|
+
pragma solidity >=0.7.0 <0.9.0;
|
65
|
+
|
66
|
+
import "../node_modules/zkjson/contracts/ZKJson.sol";
|
67
|
+
|
68
|
+
interface VerifierJSON {
|
69
|
+
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[12] calldata _pubSignals) view external returns (bool);
|
70
|
+
}
|
71
|
+
|
72
|
+
contract MyApp is ZKJSON {
|
73
|
+
uint constant SIZE_PATH = 5;
|
74
|
+
uint constant SIZE_VAL = 5;
|
75
|
+
|
76
|
+
constructor (address _verifierJSON){
|
77
|
+
verifierJSON = _verifierJSON;
|
78
|
+
}
|
79
|
+
|
80
|
+
function validateQuery(uint[] memory path, uint[] memory zkp) private view returns(uint[] memory){
|
81
|
+
verify(zkp, VerifierJSON.verifyProof.selector, verifierJSON);
|
82
|
+
return _validateQueryRU(path, zkp, SIZE_PATH, SIZE_VAL);
|
83
|
+
}
|
84
|
+
|
85
|
+
function qInt (uint[] memory path, uint[] memory zkp) public view returns (int) {
|
86
|
+
uint[] memory value = validateQuery(path, zkp);
|
87
|
+
return _qInt(value);
|
88
|
+
}
|
89
|
+
|
90
|
+
function qFloat (uint[] memory path, uint[] memory zkp) public view returns (uint[3] memory) {
|
91
|
+
uint[] memory value = validateQuery(path, zkp);
|
92
|
+
return _qFloat(value);
|
93
|
+
}
|
94
|
+
|
95
|
+
function qRaw (uint[] memory path, uint[] memory zkp) public view returns (uint[] memory) {
|
96
|
+
uint[] memory value = validateQuery(path, zkp);
|
97
|
+
return _qRaw(value);
|
98
|
+
}
|
99
|
+
|
100
|
+
function qString (uint[] memory path, uint[] memory zkp) public view returns (string memory) {
|
101
|
+
uint[] memory value = validateQuery(path, zkp);
|
102
|
+
return _qString(value);
|
103
|
+
}
|
104
|
+
|
105
|
+
function qBool (uint[] memory path, uint[] memory zkp) public view returns (bool) {
|
106
|
+
uint[] memory value = validateQuery(path, zkp);
|
107
|
+
return _qBool(value);
|
108
|
+
}
|
109
|
+
|
110
|
+
function qNull (uint[] memory path, uint[] memory zkp) public view returns (bool) {
|
111
|
+
uint[] memory value = validateQuery(path, zkp);
|
112
|
+
return _qNull(value);
|
113
|
+
}
|
114
|
+
|
115
|
+
function qCustom (uint[] memory path, uint[] memory path2, uint[] memory zkp) public view returns (int) {
|
116
|
+
uint[] memory value = validateQuery(path, zkp);
|
117
|
+
return getInt(path2, value);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
```
|
121
|
+
|
122
|
+
### Write Tests
|
123
|
+
|
124
|
+
`myapp/test/MyApp.js`
|
125
|
+
|
126
|
+
```javascript
|
127
|
+
const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers")
|
128
|
+
const { path, Doc } = require("../../sdk")
|
129
|
+
const { resolve } = require("path")
|
130
|
+
const { expect } = require("chai")
|
131
|
+
|
132
|
+
async function deploy() {
|
133
|
+
const Verifier = await ethers.getContractFactory("Groth16VerifierJSON")
|
134
|
+
const verifier = await Verifier.deploy()
|
135
|
+
const MyApp = await ethers.getContractFactory("SimpleJSON")
|
136
|
+
const myapp = await MyApp.deploy(verifier.address)
|
137
|
+
return { myapp }
|
138
|
+
}
|
139
|
+
|
140
|
+
describe("MyApp", function () {
|
141
|
+
let myapp
|
142
|
+
this.timeout(0)
|
143
|
+
|
144
|
+
beforeEach(async () => {
|
145
|
+
const dep = await loadFixture(deploy)
|
146
|
+
myapp = dep.myapp
|
147
|
+
})
|
148
|
+
|
149
|
+
it("should verify JSON", async function () {
|
150
|
+
const doc = new Doc({
|
151
|
+
wasm: resolve(
|
152
|
+
__dirname,
|
153
|
+
"../../zkjson/circom/build/circuits/json/index_js/index.wasm"
|
154
|
+
),
|
155
|
+
zkey: resolve(
|
156
|
+
__dirname,
|
157
|
+
"../../zkjson/circom/build/circuits/json/index_0001.zkey"
|
158
|
+
),
|
159
|
+
})
|
160
|
+
const json = {
|
161
|
+
num: 1,
|
162
|
+
float: 1.23,
|
163
|
+
str: "string",
|
164
|
+
bool: true,
|
165
|
+
null: null,
|
166
|
+
array: [1, 2, 3],
|
167
|
+
}
|
168
|
+
|
169
|
+
// query number
|
170
|
+
const zkp = await doc.genProof({ json, path: "num" })
|
171
|
+
expect((await myapp.qInt(path("num"), zkp)).toNumber()).to.eql(1)
|
172
|
+
|
173
|
+
// query string
|
174
|
+
const zkp2 = await doc.genProof({ json, path: "str" })
|
175
|
+
expect(await myapp.qString(path("str"), zkp2)).to.eql("string")
|
176
|
+
|
177
|
+
// query bool
|
178
|
+
const zkp3 = await doc.genProof({ json, path: "bool" })
|
179
|
+
expect(await myapp.qBool(path("bool"), zkp3)).to.eql(true)
|
180
|
+
|
181
|
+
// query null
|
182
|
+
const zkp4 = await doc.genProof({ json, path: "null" })
|
183
|
+
expect(await myapp.qNull(path("null"), zkp4)).to.eql(true)
|
184
|
+
|
185
|
+
// query float
|
186
|
+
const zkp5 = await doc.genProof({ json, path: "float" })
|
187
|
+
expect(
|
188
|
+
(await myapp.qFloat(path("float"), zkp5)).map(f => f.toNumber())
|
189
|
+
).to.eql([1, 2, 123])
|
190
|
+
|
191
|
+
// query array and get number
|
192
|
+
const zkp6 = await doc.genProof({ json, path: "array" })
|
193
|
+
expect(
|
194
|
+
(await myapp.qCustom(path("array"), path("[1]"), zkp6)).toNumber()
|
195
|
+
).to.eql(2)
|
196
|
+
|
197
|
+
// conditional operator
|
198
|
+
const zkp7 = await doc.genProof({ json, path: "num", query: ["$gt", 0] })
|
199
|
+
expect(await myapp.qCond(path("num"), zkp7.slice(15, 21), zkp7)).to.eql(
|
200
|
+
true
|
201
|
+
)
|
202
|
+
})
|
203
|
+
})
|
204
|
+
```
|
205
|
+
|
206
|
+
Then run the tests.
|
207
|
+
|
208
|
+
```bash
|
209
|
+
yarn hardhat test test/MyApp.js
|
210
|
+
```
|
@@ -0,0 +1,216 @@
|
|
1
|
+
## Solidity Contracts
|
2
|
+
|
3
|
+
### ZKQuery.sol
|
4
|
+
|
5
|
+
```solidity
|
6
|
+
interface ZKQuery {
|
7
|
+
function toArr(uint[] memory json) internal pure returns (uint[] memory);
|
8
|
+
|
9
|
+
function _qNull (uint[] memory path, uint[] memory zkp) internal pure returns (bool);
|
10
|
+
function _qBool (uint[] memory path, uint[] memory zkp) internal pure returns (bool);
|
11
|
+
function _qInt (uint[] memory path, uint[] memory zkp) internal pure returns (int);
|
12
|
+
function _qFloat (uint[] memory path, uint[] memory zkp) internal pure returns (uint[3] memory);
|
13
|
+
function _qString (uint[] memory path, uint[] memory zkp) internal pure returns (string memory);
|
14
|
+
function _qRaw (uint[] memory path, uint[] memory zkp) internal pure returns (uint[] memory);
|
15
|
+
|
16
|
+
function getNull (uint[] memory path, uint[] memory raw) internal pure returns (bool);
|
17
|
+
function getBool (uint[] memory path, uint[] memory raw) internal pure returns (bool);
|
18
|
+
function getInt (uint[] memory path, uint[] memory raw) internal pure returns (int);
|
19
|
+
function getFloat (uint[] memory path, uint[] memory raw) internal pure returns (uint[3] memory);
|
20
|
+
function getString (uint[] memory path, uint[] memory raw) internal pure returns (string memory);
|
21
|
+
}
|
22
|
+
```
|
23
|
+
|
24
|
+
### ZKJson.sol
|
25
|
+
|
26
|
+
```solidity
|
27
|
+
interface ZKJSON {
|
28
|
+
function _validateQueryJSON(
|
29
|
+
uint[] memory path,
|
30
|
+
uint[] memory zkp,
|
31
|
+
uint size_path,
|
32
|
+
uint size_val
|
33
|
+
) internal pure returns (uint[] memory);
|
34
|
+
}
|
35
|
+
```
|
36
|
+
|
37
|
+
### ZKRollup.sol
|
38
|
+
|
39
|
+
```solidity
|
40
|
+
interface ZKRollup {
|
41
|
+
function _validateQueryRU(
|
42
|
+
uint[] memory path,
|
43
|
+
uint[] memory zkp,
|
44
|
+
uint size_path,
|
45
|
+
uint size_val
|
46
|
+
) internal view returns (uint[] memory);
|
47
|
+
|
48
|
+
function commit (uint[] memory zkp) public returns (uint);
|
49
|
+
}
|
50
|
+
```
|
51
|
+
|
52
|
+
### Examples
|
53
|
+
|
54
|
+
`ZKJson` and `ZKRollup` inherit `ZKQuery`. You need to either inherit `ZKJson` or `ZKRollup` to build your own ZKDB-enabled contract. You can install `zkjson` node package and use the contract located at `node_modules/zkjson/contracts` in your Solidity contract. To install the package,
|
55
|
+
|
56
|
+
```bash
|
57
|
+
yarn add zkjson
|
58
|
+
```
|
59
|
+
|
60
|
+
#### Simple zkJSON
|
61
|
+
|
62
|
+
```solidity
|
63
|
+
// SPDX-License-Identifier: MIT
|
64
|
+
pragma solidity >=0.7.0 <0.9.0;
|
65
|
+
import "ZKJson.sol";
|
66
|
+
|
67
|
+
interface VerifierJSON {
|
68
|
+
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[12] calldata _pubSignals) view external returns (bool);
|
69
|
+
}
|
70
|
+
|
71
|
+
contract SimpleJSON is ZKJson {
|
72
|
+
uint constant SIZE_PATH = 5;
|
73
|
+
uint constant SIZE_VAL = 5;
|
74
|
+
|
75
|
+
constructor (address _verifierJSON){
|
76
|
+
verifierJSON = _verifierJSON;
|
77
|
+
}
|
78
|
+
|
79
|
+
function verify(uint[] memory zkp) private view returns (bool) {
|
80
|
+
uint[SIZE_PATH + SIZE_VAL + 2] memory sigs;
|
81
|
+
(
|
82
|
+
uint[2] memory _pA,
|
83
|
+
uint[2][2] memory _pB,
|
84
|
+
uint[2] memory _pC,
|
85
|
+
uint[] memory _sigs
|
86
|
+
) = _parseZKP(zkp);
|
87
|
+
for(uint i = 0; i < sigs.length; i++) sigs[i] = _sigs[i];
|
88
|
+
|
89
|
+
require(VerifierJSON(verifierJSON).verifyProof(_pA, _pB, _pC, sigs), "invalid proof");
|
90
|
+
return true;
|
91
|
+
}
|
92
|
+
|
93
|
+
function validateQuery(uint[] memory path, uint[] memory zkp) private view returns(uint[] memory){
|
94
|
+
verify(zkp);
|
95
|
+
return _validateQueryJSON(path, zkp, SIZE_PATH, SIZE_VAL);
|
96
|
+
}
|
97
|
+
|
98
|
+
function qInt (uint[] memory path, uint[] memory zkp) public view returns (int) {
|
99
|
+
uint[] memory value = validateQuery(path, zkp);
|
100
|
+
return _qInt(value);
|
101
|
+
}
|
102
|
+
|
103
|
+
function qFloat (uint[] memory path, uint[] memory zkp) public view returns (uint[3] memory) {
|
104
|
+
uint[] memory value = validateQuery(path, zkp);
|
105
|
+
return _qFloat(value);
|
106
|
+
}
|
107
|
+
|
108
|
+
function qRaw (uint[] memory path, uint[] memory zkp) public view returns (uint[] memory) {
|
109
|
+
uint[] memory value = validateQuery(path, zkp);
|
110
|
+
return _qRaw(value);
|
111
|
+
}
|
112
|
+
|
113
|
+
function qString (uint[] memory path, uint[] memory zkp) public view returns (string memory) {
|
114
|
+
uint[] memory value = validateQuery(path, zkp);
|
115
|
+
return _qString(value);
|
116
|
+
}
|
117
|
+
|
118
|
+
function qBool (uint[] memory path, uint[] memory zkp) public view returns (bool) {
|
119
|
+
uint[] memory value = validateQuery(path, zkp);
|
120
|
+
return _qBool(value);
|
121
|
+
}
|
122
|
+
|
123
|
+
function qNull (uint[] memory path, uint[] memory zkp) public view returns (bool) {
|
124
|
+
uint[] memory value = validateQuery(path, zkp);
|
125
|
+
return _qNull(value);
|
126
|
+
}
|
127
|
+
|
128
|
+
function qCond (uint[] memory path, uint[] memory cond, uint[] memory zkp) public view returns (bool) {
|
129
|
+
uint[] memory value = validateQuery(path, zkp);
|
130
|
+
return _qCond(value, cond);
|
131
|
+
}
|
132
|
+
|
133
|
+
function qCustom (uint[] memory path, uint[] memory path2, uint[] memory zkp) public view returns (int) {
|
134
|
+
uint[] memory value = validateQuery(path, zkp);
|
135
|
+
return getInt(path2, value);
|
136
|
+
}
|
137
|
+
|
138
|
+
}
|
139
|
+
```
|
140
|
+
|
141
|
+
#### Simple zkRollup
|
142
|
+
|
143
|
+
```solidity
|
144
|
+
// SPDX-License-Identifier: MIT
|
145
|
+
pragma solidity >=0.7.0 <0.9.0;
|
146
|
+
import "ZKRollup.sol";
|
147
|
+
|
148
|
+
interface VerifierDB {
|
149
|
+
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[14] calldata _pubSignals) view external returns (bool);
|
150
|
+
}
|
151
|
+
|
152
|
+
contract SimpleRU is ZKRollup {
|
153
|
+
uint constant SIZE_PATH = 5;
|
154
|
+
uint constant SIZE_VAL = 5;
|
155
|
+
address public verifierDB;
|
156
|
+
|
157
|
+
constructor (address _verifierRU, address _verifierDB, address _committer){
|
158
|
+
verifierRU = _verifierRU;
|
159
|
+
verifierDB = _verifierDB;
|
160
|
+
committer = _committer;
|
161
|
+
}
|
162
|
+
|
163
|
+
function verify(uint[] memory zkp) private view returns (bool) {
|
164
|
+
uint[SIZE_PATH + SIZE_VAL + 4] memory sigs;
|
165
|
+
(
|
166
|
+
uint[2] memory _pA,
|
167
|
+
uint[2][2] memory _pB,
|
168
|
+
uint[2] memory _pC,
|
169
|
+
uint[] memory _sigs
|
170
|
+
) = _parseZKP(zkp);
|
171
|
+
for(uint i = 0; i < sigs.length; i++) sigs[i] = _sigs[i];
|
172
|
+
require(VerifierDB(verifierDB).verifyProof(_pA, _pB, _pC, sigs), "invalid proof");
|
173
|
+
return true;
|
174
|
+
}
|
175
|
+
|
176
|
+
function validateQuery(uint[] memory path, uint[] memory zkp) private view returns(uint[] memory){
|
177
|
+
verify(zkp);
|
178
|
+
return _validateQueryRU(path, zkp, SIZE_PATH, SIZE_VAL);
|
179
|
+
}
|
180
|
+
|
181
|
+
function qInt (uint[] memory path, uint[] memory zkp) public view returns (int) {
|
182
|
+
uint[] memory value = validateQuery(path, zkp);
|
183
|
+
return _qInt(value);
|
184
|
+
}
|
185
|
+
|
186
|
+
function qFloat (uint[] memory path, uint[] memory zkp) public view returns (uint[3] memory) {
|
187
|
+
uint[] memory value = validateQuery(path, zkp);
|
188
|
+
return _qFloat(value);
|
189
|
+
}
|
190
|
+
|
191
|
+
function qRaw (uint[] memory path, uint[] memory zkp) public view returns (uint[] memory) {
|
192
|
+
uint[] memory value = validateQuery(path, zkp);
|
193
|
+
return _qRaw(value);
|
194
|
+
}
|
195
|
+
|
196
|
+
function qString (uint[] memory path, uint[] memory zkp) public view returns (string memory) {
|
197
|
+
uint[] memory value = validateQuery(path, zkp);
|
198
|
+
return _qString(value);
|
199
|
+
}
|
200
|
+
|
201
|
+
function qBool (uint[] memory path, uint[] memory zkp) public view returns (bool) {
|
202
|
+
uint[] memory value = validateQuery(path, zkp);
|
203
|
+
return _qBool(value);
|
204
|
+
}
|
205
|
+
|
206
|
+
function qCond (uint[] memory path, uint[] memory cond, uint[] memory zkp) public view returns (bool) {
|
207
|
+
uint[] memory value = validateQuery(path, zkp);
|
208
|
+
return _qCond(value, cond);
|
209
|
+
}
|
210
|
+
|
211
|
+
function qNull (uint[] memory path, uint[] memory zkp) public view returns (bool) {
|
212
|
+
uint[] memory value = validateQuery(path, zkp);
|
213
|
+
return _qNull(value);
|
214
|
+
}
|
215
|
+
}
|
216
|
+
```
|
@@ -0,0 +1,125 @@
|
|
1
|
+
## ZK Circuits
|
2
|
+
|
3
|
+
There are 5 main circuits, and each circuit is built on top of the preceding one.
|
4
|
+
|
5
|
+
### Circuits
|
6
|
+
|
7
|
+
#### JSON.circom
|
8
|
+
|
9
|
+
The base building block to prove JSON with an efficient encoding.
|
10
|
+
|
11
|
+
- `size_json` : JSON size : default `256`
|
12
|
+
- `size_path` : path size : default `4`
|
13
|
+
- `size_val` : value size : default `8`
|
14
|
+
|
15
|
+
#### Collection.circom
|
16
|
+
|
17
|
+
A collection proven by a sparse merkle tree (SMT) can contain many JSON documents (2 ** 168 by default).
|
18
|
+
|
19
|
+
- `level` : collection SMT level : default `168`
|
20
|
+
- `size_json` : JSON size : default `256`
|
21
|
+
- `size_path` : path size : default `4`
|
22
|
+
- `size_val` : value size : default `8`
|
23
|
+
|
24
|
+
#### DB.circom
|
25
|
+
|
26
|
+
A database proven by a sparse merkle tree (SMT) can contain many collections (2 ** 8 by default).
|
27
|
+
|
28
|
+
- `level_col` : DB SMT level : default `8`
|
29
|
+
- `level` : collection SMT level : default `168`
|
30
|
+
- `size_json` : JSON size : default `256`
|
31
|
+
- `size_path` : path size : default `4`
|
32
|
+
- `size_val` : value size : default `8`
|
33
|
+
|
34
|
+
#### Query.circom
|
35
|
+
|
36
|
+
Query proves a JSON data insert or update by a single write query.
|
37
|
+
|
38
|
+
- `level_col` : DB SMT level : default `8`
|
39
|
+
- `level` : collection SMT level : default `168`
|
40
|
+
- `size_json` : JSON size : default `256`
|
41
|
+
|
42
|
+
#### Rollup.circom
|
43
|
+
|
44
|
+
Rollup proves batch data transitions.
|
45
|
+
|
46
|
+
- `tx_size` : max number of queries in a batch : default `10`
|
47
|
+
- `level_col` : DB SMT level : default `8`
|
48
|
+
- `level` : collection SMT level : default `168`
|
49
|
+
- `size_json` : JSON size : default `256`
|
50
|
+
|
51
|
+
### Powers of Tau
|
52
|
+
|
53
|
+
The first thing you need to do is to set up a powers of tau by a ceremony. As the power goes up the generation time and the wasm file size increases exponentially, and what power required for each circuit depends on the parameters above. So you need to find the right balance with the parameters of each circuit for your application. For instance, `power 20` required for the default `Rollup` circuit settings takes hours with a normal consumer computer.
|
54
|
+
|
55
|
+
To run a ceremony,
|
56
|
+
|
57
|
+
```bash
|
58
|
+
yarn ceremony --power 14
|
59
|
+
```
|
60
|
+
|
61
|
+
Generated files are located at `build/pot`.
|
62
|
+
|
63
|
+
You can also specify `entropy` and `name` for the ceremony. Refer to [the Circom docs](https://docs.circom.io/getting-started/proving-circuits/) for what they mean.
|
64
|
+
|
65
|
+
```bash
|
66
|
+
yarn ceremony --power 14 --name "first contribution" --entropy "some random value"
|
67
|
+
```
|
68
|
+
|
69
|
+
The same goes with the compiling process below.
|
70
|
+
|
71
|
+
### Compile Circuit
|
72
|
+
|
73
|
+
You can specify the parameters when compiling a circuit. Unspecified parameters will use the default values.
|
74
|
+
|
75
|
+
For instance, to compile the `JSON` circuit,
|
76
|
+
|
77
|
+
```bash
|
78
|
+
yarn compile --power 14 --circuit json --size_json 256 --size_path 4 --size_val 8
|
79
|
+
```
|
80
|
+
|
81
|
+
To compile the `Rollup` circuit, you might need to increase `--max-old-space-size` of NodeJS.
|
82
|
+
|
83
|
+
```bash
|
84
|
+
yarn compile --power 20 --circuit rollup --tx_size 10 --level_col 8 --level 168 --size_json 256
|
85
|
+
```
|
86
|
+
|
87
|
+
All the generated files are stored at `build/circuits` including a Solidity verifier contract.
|
88
|
+
|
89
|
+
### Concept of Some Parameters
|
90
|
+
|
91
|
+
[The litepaper](../) explains in detail, but here are brief explanations on `size` and `level`.
|
92
|
+
|
93
|
+
#### size
|
94
|
+
|
95
|
+
The base unit of `size` is `uint`. Circom by default uses the module of `21888242871839275222246405745257275088548364400416034343698204186575808495617` (77 digits) and Solidity's base storage block is `uint256` and allows 78 digits. So zkJSON efficiently encodes JSON and packs it into blocks of 76 digits, which is one `uint`.
|
96
|
+
|
97
|
+
`path_size=5` means, 5 * 76 digits are allowed for the query path when encoded, and it will be represented within `uint[5]` in Solidity. on the Solidity side, however, zkJSON uses dynamic arrays `uint[]`, so it will be more space-efficient than the max set size. But the zk-circuits cannot prove data sizes more than the set size.
|
98
|
+
|
99
|
+
The default `json_size` is set `256`, which is 256 * 76 digits and should be sufficient for most JSON data.
|
100
|
+
|
101
|
+
#### level
|
102
|
+
|
103
|
+
`level` is the level of the sparse merkle tree (SMT). As the litepaper describes, the level of SMT for Collection determines how many alphanumeric characters each document ID can contain. It's determined by
|
104
|
+
|
105
|
+
```math
|
106
|
+
Number of Characters = \frac{\log_{10}(2^{\text{Level}})}{2}
|
107
|
+
```
|
108
|
+
|
109
|
+
`level=168` can allow 28 characters in document ID. This is significant because document IDs are often used in access control rules of NoSQL databases (with WeaveDB, for instance).
|
110
|
+
|
111
|
+
28 characters can fit compressed Ethereum addresses (20 bytes) in Bse64 format.
|
112
|
+
|
113
|
+
For DB, `level_col` determines how many collections the DB can contain. The collection IDs use the direct index numbers and are not converted to an alphanumeric representation, so `level_col=8` (2 ** 8 = 256) collections should be sufficient for most applications. But you are free to set a different value.
|
114
|
+
|
115
|
+
### Default Parameters and Required POT
|
116
|
+
|
117
|
+
| Circuit | POT | size_json | size_path | size_val | level | level_col | tx_size |
|
118
|
+
|---|---|---|---|---|---|---|---|
|
119
|
+
| **JSON** | 14 | 256 | 4 | 8 | | | |
|
120
|
+
| **Collection** | 16 | 256 | 4 | 8 | 168 | | |
|
121
|
+
| **DB** | 16 | 256 | 4 | 8 | 168 | 8 | |
|
122
|
+
| **Query** | 17 | 256 | | | 168 | 8 | |
|
123
|
+
| **Rollup** | 20 | 256 | | | 168 | 8 | 10 |
|
124
|
+
|
125
|
+
**Currently the SDK only works with `size_json=256` due to some hash logic. Keep it 256 for now please.**
|