zkjson 0.6.1 → 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/{contracts → sdk/contracts}/NORollup.sol +0 -2
- 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
@@ -0,0 +1,869 @@
|
|
1
|
+
import Head from "next/head"
|
2
|
+
import Link from "next/link"
|
3
|
+
import { Contract, providers } from "ethers"
|
4
|
+
import { useToast, Select, Box, Flex, Input, Textarea } from "@chakra-ui/react"
|
5
|
+
import { useState, useEffect } from "react"
|
6
|
+
import { map, append, concat } from "ramda"
|
7
|
+
const snarkjs = require("snarkjs")
|
8
|
+
import { Doc } from "zkjson"
|
9
|
+
const abi = require("../lib/ZKArweave.json").abi
|
10
|
+
const contractAddr = process.env.NEXT_PUBLIC_CONTRACT_ADDR
|
11
|
+
import { CopyToClipboard } from "react-copy-to-clipboard"
|
12
|
+
|
13
|
+
export default function Home() {
|
14
|
+
const [signals, setSignals] = useState(null)
|
15
|
+
const [proof, setProof] = useState(null)
|
16
|
+
const [result, setResult] = useState(null)
|
17
|
+
const [type, setType] = useState("number")
|
18
|
+
const [json, setJSON] = useState("")
|
19
|
+
const [path, setPath] = useState("")
|
20
|
+
const [paths, setPaths] = useState([])
|
21
|
+
const [num, setNum] = useState("")
|
22
|
+
const [bool, setBool] = useState(true)
|
23
|
+
const [str, setStr] = useState("")
|
24
|
+
const [txid, setTxid] = useState("")
|
25
|
+
const [params, setParams] = useState(null)
|
26
|
+
const [signature, setSignature] = useState("")
|
27
|
+
const [generating, setGenerating] = useState(false)
|
28
|
+
const toast = useToast()
|
29
|
+
let valid = false
|
30
|
+
try {
|
31
|
+
let _j = null
|
32
|
+
eval("_j = " + json)
|
33
|
+
valid = true
|
34
|
+
} catch (e) {}
|
35
|
+
let tx_valid = !/^\s*$/.test(txid)
|
36
|
+
return (
|
37
|
+
<>
|
38
|
+
<Head>
|
39
|
+
<title>zkJSON Demo - Arweave | Ethereum</title>
|
40
|
+
<meta name="description" content="Zero Knowledge Provable JSON" />
|
41
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
42
|
+
<link rel="icon" href="/favicon.ico" />
|
43
|
+
</Head>
|
44
|
+
<Flex w="100%" h="100%" justify="center" p={4} fontSize="14px">
|
45
|
+
<Box>
|
46
|
+
<Flex align="center" justify="center" w="750px">
|
47
|
+
<Box fontSize="30px" fontWeight="bold" color="#5037C6">
|
48
|
+
zkJSON
|
49
|
+
</Box>
|
50
|
+
<Box ml={4}>Arweave | Ethereum Demo</Box>
|
51
|
+
</Flex>
|
52
|
+
<Box
|
53
|
+
w="750px"
|
54
|
+
bg="#eee"
|
55
|
+
py={2}
|
56
|
+
px={8}
|
57
|
+
mt={4}
|
58
|
+
sx={{ borderRadius: "10px" }}
|
59
|
+
>
|
60
|
+
<Box align="center" mt={4} color="#5037C6">
|
61
|
+
You can directly query any Arweave stored JSON from Ethereum smart
|
62
|
+
contracts with a zkJSON proof.
|
63
|
+
</Box>
|
64
|
+
<Box mt={4}>
|
65
|
+
<Flex>
|
66
|
+
<Flex w="100%">
|
67
|
+
<Box as="label" mb={1}>
|
68
|
+
Arweave TxID
|
69
|
+
</Box>
|
70
|
+
<Box flex={1} />
|
71
|
+
<Box
|
72
|
+
mr={2}
|
73
|
+
as="a"
|
74
|
+
href="https://viewblock.io/arweave"
|
75
|
+
target="_blank"
|
76
|
+
sx={{
|
77
|
+
textDecoration: "underline",
|
78
|
+
color: "#5037C6",
|
79
|
+
cursor: "pointer",
|
80
|
+
":hover": { opacity: 0.75 },
|
81
|
+
}}
|
82
|
+
>
|
83
|
+
Find One on Explorer
|
84
|
+
</Box>
|
85
|
+
</Flex>
|
86
|
+
<Box flex={1} />
|
87
|
+
{json === "" ? null : (
|
88
|
+
<Box
|
89
|
+
w="80px"
|
90
|
+
mx={2}
|
91
|
+
sx={{
|
92
|
+
textDecoration: "underline",
|
93
|
+
color: "#5037C6",
|
94
|
+
cursor: tx_valid ? "pointer" : "default",
|
95
|
+
":hover": { opacity: 0.75 },
|
96
|
+
}}
|
97
|
+
onClick={() => {
|
98
|
+
setJSON("")
|
99
|
+
setSignature("")
|
100
|
+
setParams(null)
|
101
|
+
}}
|
102
|
+
>
|
103
|
+
Another Tx
|
104
|
+
</Box>
|
105
|
+
)}
|
106
|
+
</Flex>
|
107
|
+
{json === "" ? (
|
108
|
+
<Input
|
109
|
+
disabled={json !== ""}
|
110
|
+
bg="white"
|
111
|
+
placeholder="Arweave TxID"
|
112
|
+
value={txid}
|
113
|
+
onChange={e => setTxid(e.target.value)}
|
114
|
+
/>
|
115
|
+
) : (
|
116
|
+
<Box
|
117
|
+
bg="white"
|
118
|
+
fontSize="12px"
|
119
|
+
p={2}
|
120
|
+
sx={{
|
121
|
+
border: "1px solid #5037C6",
|
122
|
+
borderRadius: "3px",
|
123
|
+
}}
|
124
|
+
>
|
125
|
+
{txid}
|
126
|
+
</Box>
|
127
|
+
)}
|
128
|
+
</Box>
|
129
|
+
{json !== "" ? null : (
|
130
|
+
<Flex justify="center" my={4}>
|
131
|
+
<Flex
|
132
|
+
py={3}
|
133
|
+
bg={tx_valid ? "#5037C6" : "#aaa"}
|
134
|
+
w="100%"
|
135
|
+
justify="center"
|
136
|
+
color="white"
|
137
|
+
fontSize="16px"
|
138
|
+
sx={{
|
139
|
+
borderRadius: "5px",
|
140
|
+
cursor: tx_valid ? "pointer" : "default",
|
141
|
+
":hover": { opacity: 0.75 },
|
142
|
+
}}
|
143
|
+
onClick={async () => {
|
144
|
+
if (/^\s*$/.test(txid)) {
|
145
|
+
alert("Enter Arweave transaction ID")
|
146
|
+
} else {
|
147
|
+
const getPath = (json, prefix = [], paths = []) => {
|
148
|
+
if (typeof json !== "object") return [prefix.join(".")]
|
149
|
+
|
150
|
+
for (let k in json) {
|
151
|
+
if (Array.isArray(json[k])) {
|
152
|
+
let i = 0
|
153
|
+
for (let v of json[k]) {
|
154
|
+
const _paths = getPath(
|
155
|
+
v,
|
156
|
+
append(`${k}[${i}]`, prefix)
|
157
|
+
)
|
158
|
+
paths = concat(paths, _paths)
|
159
|
+
i++
|
160
|
+
}
|
161
|
+
} else if (typeof json[k] === "object") {
|
162
|
+
for (let k2 in json[k]) {
|
163
|
+
const _paths = getPath(
|
164
|
+
json[k][k2],
|
165
|
+
append(`${k}.${k2}`, prefix)
|
166
|
+
)
|
167
|
+
paths = concat(paths, _paths)
|
168
|
+
}
|
169
|
+
} else {
|
170
|
+
paths.push(append(k, prefix).join("."))
|
171
|
+
}
|
172
|
+
}
|
173
|
+
return paths
|
174
|
+
}
|
175
|
+
try {
|
176
|
+
const json = await fetch(
|
177
|
+
`https://arweave.net/${txid}`
|
178
|
+
).then(v => v.json())
|
179
|
+
setJSON(JSON.stringify(json))
|
180
|
+
const paths = getPath(json)
|
181
|
+
setPaths(paths)
|
182
|
+
setPath(paths[0])
|
183
|
+
const getVal = (j, p) => {
|
184
|
+
return p.length === 0
|
185
|
+
? j
|
186
|
+
: getVal(j[p[0]], p.slice(1))
|
187
|
+
}
|
188
|
+
const _paths = paths[0].split(".")
|
189
|
+
const val = getVal(json, _paths)
|
190
|
+
const type = val === null ? "null" : typeof val
|
191
|
+
setType(type)
|
192
|
+
if (type === "number") {
|
193
|
+
setNum(val)
|
194
|
+
} else if (type === "boolean") {
|
195
|
+
setBool(val)
|
196
|
+
} else if (type === "string") {
|
197
|
+
setStr(val)
|
198
|
+
}
|
199
|
+
const { hash, signature } = await fetch(
|
200
|
+
"/api/arweave",
|
201
|
+
{
|
202
|
+
method: "POST",
|
203
|
+
headers: {
|
204
|
+
"Content-Type": "application/json",
|
205
|
+
},
|
206
|
+
body: JSON.stringify({ txid }),
|
207
|
+
}
|
208
|
+
).then(v => v.json())
|
209
|
+
setSignature(signature)
|
210
|
+
} catch (e) {
|
211
|
+
alert("JSON fetch failed")
|
212
|
+
setJSON("")
|
213
|
+
}
|
214
|
+
}
|
215
|
+
}}
|
216
|
+
>
|
217
|
+
Get Arweave Tx & JSON
|
218
|
+
</Flex>
|
219
|
+
</Flex>
|
220
|
+
)}
|
221
|
+
{!valid ? null : (
|
222
|
+
<>
|
223
|
+
<Box mt={4}>
|
224
|
+
<Flex>
|
225
|
+
<Box as="label" color={valid ? "" : "crimson"} mb={1}>
|
226
|
+
JSON (private, this data won't be revealed){" "}
|
227
|
+
{valid ? "" : "Invalid JSON"}
|
228
|
+
</Box>
|
229
|
+
<Box flex={1} />
|
230
|
+
</Flex>
|
231
|
+
<Box
|
232
|
+
bg="white"
|
233
|
+
fontSize="12px"
|
234
|
+
p={2}
|
235
|
+
sx={{
|
236
|
+
border: "1px solid #5037C6",
|
237
|
+
borderRadius: "3px",
|
238
|
+
}}
|
239
|
+
>
|
240
|
+
{json}
|
241
|
+
</Box>
|
242
|
+
</Box>
|
243
|
+
{signature === "" ? (
|
244
|
+
<Box mt={4}>
|
245
|
+
<Flex mt={1} mb={2} justify="center" align="center">
|
246
|
+
<Box
|
247
|
+
as="label"
|
248
|
+
color={signature !== "" ? "" : "#5037C6"}
|
249
|
+
textAlign="center"
|
250
|
+
>
|
251
|
+
<Box
|
252
|
+
as="i"
|
253
|
+
className="fas fa-spin fa-circle-notch"
|
254
|
+
mr={2}
|
255
|
+
/>
|
256
|
+
Validating Arweave Tx...
|
257
|
+
</Box>
|
258
|
+
</Flex>
|
259
|
+
</Box>
|
260
|
+
) : (
|
261
|
+
<>
|
262
|
+
<Box mt={4}>
|
263
|
+
<Flex mt={1} mb={1}>
|
264
|
+
<Box
|
265
|
+
as="label"
|
266
|
+
color={signature !== "" ? "" : "crimson"}
|
267
|
+
>
|
268
|
+
Validator Signature (veridating the existence of the
|
269
|
+
Arweave Tx)
|
270
|
+
</Box>
|
271
|
+
<Box flex={1} />
|
272
|
+
</Flex>
|
273
|
+
<Box
|
274
|
+
bg="white"
|
275
|
+
fontSize="12px"
|
276
|
+
p={2}
|
277
|
+
sx={{
|
278
|
+
border: "1px solid #5037C6",
|
279
|
+
borderRadius: "3px",
|
280
|
+
}}
|
281
|
+
>
|
282
|
+
{signature}
|
283
|
+
</Box>
|
284
|
+
</Box>
|
285
|
+
<Box p={4} bg="white" my={4} sx={{ borderRadius: "3px" }}>
|
286
|
+
<Box mx={2}>
|
287
|
+
<Flex mb={1}>
|
288
|
+
<Box as="label">Path (public)</Box> <Box flex={1} />
|
289
|
+
</Flex>
|
290
|
+
<Select
|
291
|
+
bg="white"
|
292
|
+
value={path}
|
293
|
+
onChange={e => {
|
294
|
+
const getVal = (j, p) => {
|
295
|
+
if (p.length === 0) {
|
296
|
+
return j
|
297
|
+
} else {
|
298
|
+
const sp = p[0].split("[")
|
299
|
+
for (let v of sp) {
|
300
|
+
if (/]$/.test(v)) {
|
301
|
+
j = j[v.replace(/]$/, "") * 1]
|
302
|
+
} else {
|
303
|
+
j = j[v]
|
304
|
+
}
|
305
|
+
}
|
306
|
+
return getVal(j, p.slice(1))
|
307
|
+
}
|
308
|
+
}
|
309
|
+
const _json = JSON.parse(json)
|
310
|
+
const paths = e.target.value.split(".")
|
311
|
+
const val = getVal(_json, paths)
|
312
|
+
const type = val === null ? "null" : typeof val
|
313
|
+
setType(type)
|
314
|
+
if (type === "number") {
|
315
|
+
setNum(val)
|
316
|
+
} else if (type === "boolean") {
|
317
|
+
setBool(val)
|
318
|
+
} else if (type === "string") {
|
319
|
+
setStr(val)
|
320
|
+
}
|
321
|
+
setPath(e.target.value)
|
322
|
+
}}
|
323
|
+
>
|
324
|
+
{map(v => <option value={v}>{v}</option>)(paths)}
|
325
|
+
</Select>
|
326
|
+
</Box>
|
327
|
+
<Box mt={4}>
|
328
|
+
<Flex>
|
329
|
+
<Box width="150px" pr={2}>
|
330
|
+
<Box mx={2} as="label">
|
331
|
+
Data Type (public)
|
332
|
+
</Box>
|
333
|
+
<Box
|
334
|
+
mt={1}
|
335
|
+
fontSize="12px"
|
336
|
+
mx={2}
|
337
|
+
p={2}
|
338
|
+
sx={{
|
339
|
+
border: "1px solid #5037C6",
|
340
|
+
borderRadius: "3px",
|
341
|
+
}}
|
342
|
+
>
|
343
|
+
{type}
|
344
|
+
</Box>
|
345
|
+
</Box>
|
346
|
+
<Box flex={1} pl={2}>
|
347
|
+
<Box mx={2} as="label">
|
348
|
+
Value (public)
|
349
|
+
</Box>
|
350
|
+
<Box
|
351
|
+
mt={1}
|
352
|
+
fontSize="12px"
|
353
|
+
mx={2}
|
354
|
+
p={2}
|
355
|
+
sx={{
|
356
|
+
border: "1px solid #5037C6",
|
357
|
+
borderRadius: "3px",
|
358
|
+
wordBreak: "break-all",
|
359
|
+
}}
|
360
|
+
>
|
361
|
+
{type === "string"
|
362
|
+
? str
|
363
|
+
: type === "number"
|
364
|
+
? num
|
365
|
+
: type === "null"
|
366
|
+
? "null"
|
367
|
+
: bool}
|
368
|
+
</Box>
|
369
|
+
</Box>
|
370
|
+
</Flex>
|
371
|
+
</Box>
|
372
|
+
<Flex justify="center" mt={4}>
|
373
|
+
<Flex
|
374
|
+
mx={2}
|
375
|
+
py={3}
|
376
|
+
bg={valid ? "#5037C6" : "#aaa"}
|
377
|
+
w="100%"
|
378
|
+
justify="center"
|
379
|
+
color="white"
|
380
|
+
fontSize="16px"
|
381
|
+
sx={{
|
382
|
+
borderRadius: "5px",
|
383
|
+
cursor: valid ? "pointer" : "default",
|
384
|
+
":hover": { opacity: 0.75 },
|
385
|
+
}}
|
386
|
+
onClick={async () => {
|
387
|
+
if (generating === false) {
|
388
|
+
setGenerating(true)
|
389
|
+
setParams(null)
|
390
|
+
try {
|
391
|
+
if (valid) {
|
392
|
+
let _json = null
|
393
|
+
try {
|
394
|
+
eval("_json = " + json)
|
395
|
+
} catch (e) {}
|
396
|
+
let _val =
|
397
|
+
type === "number"
|
398
|
+
? num * 1
|
399
|
+
: type === "string"
|
400
|
+
? str
|
401
|
+
: type === "boolean"
|
402
|
+
? bool
|
403
|
+
: null
|
404
|
+
|
405
|
+
const doc = new Doc({
|
406
|
+
size: 5,
|
407
|
+
size_json: 256,
|
408
|
+
})
|
409
|
+
const inputs = await doc.getInputs({
|
410
|
+
json: _json,
|
411
|
+
path,
|
412
|
+
val: _val,
|
413
|
+
})
|
414
|
+
const { proof, publicSignals } =
|
415
|
+
await snarkjs.groth16.fullProve(
|
416
|
+
inputs,
|
417
|
+
"circuit.wasm",
|
418
|
+
"circuit_final.zkey"
|
419
|
+
)
|
420
|
+
setSignals(publicSignals)
|
421
|
+
setProof(proof)
|
422
|
+
setResult(null)
|
423
|
+
|
424
|
+
const vkey = await fetch(
|
425
|
+
"verification_key.json"
|
426
|
+
).then(function (res) {
|
427
|
+
return res.json()
|
428
|
+
})
|
429
|
+
const res = await snarkjs.groth16.verify(
|
430
|
+
vkey,
|
431
|
+
publicSignals,
|
432
|
+
proof
|
433
|
+
)
|
434
|
+
setResult(res)
|
435
|
+
const inputs2 = [
|
436
|
+
...proof.pi_a.slice(0, 2),
|
437
|
+
...proof.pi_b[0].slice(0, 2).reverse(),
|
438
|
+
...proof.pi_b[1].slice(0, 2).reverse(),
|
439
|
+
...proof.pi_c.slice(0, 2),
|
440
|
+
...publicSignals,
|
441
|
+
]
|
442
|
+
const sigs = inputs2.slice(8)
|
443
|
+
const params = [
|
444
|
+
txid,
|
445
|
+
sigs.slice(2, 7),
|
446
|
+
inputs2,
|
447
|
+
signature,
|
448
|
+
]
|
449
|
+
const getVal = (j, p) => {
|
450
|
+
if (p.length === 0) {
|
451
|
+
return j
|
452
|
+
} else {
|
453
|
+
const sp = p[0].split("[")
|
454
|
+
for (let v of sp) {
|
455
|
+
if (/]$/.test(v)) {
|
456
|
+
console.log(v.replace(/]$/, "") * 1)
|
457
|
+
j = j[v.replace(/]$/, "") * 1]
|
458
|
+
} else {
|
459
|
+
j = j[v]
|
460
|
+
}
|
461
|
+
}
|
462
|
+
return getVal(j, p.slice(1))
|
463
|
+
}
|
464
|
+
}
|
465
|
+
const paths = path.split(".")
|
466
|
+
const val = getVal(_json, paths)
|
467
|
+
let type2 =
|
468
|
+
val === null
|
469
|
+
? 0
|
470
|
+
: typeof val === "string"
|
471
|
+
? 3
|
472
|
+
: typeof val === "boolean"
|
473
|
+
? 1
|
474
|
+
: typeof val === "number"
|
475
|
+
? Number.isInteger(val)
|
476
|
+
? 2
|
477
|
+
: 2.5
|
478
|
+
: 4
|
479
|
+
|
480
|
+
let op = null
|
481
|
+
switch (type2) {
|
482
|
+
case 0:
|
483
|
+
op = "qNull"
|
484
|
+
break
|
485
|
+
case 1:
|
486
|
+
op = "qBool"
|
487
|
+
break
|
488
|
+
case 2:
|
489
|
+
op = "qInt"
|
490
|
+
break
|
491
|
+
case 2.5:
|
492
|
+
op = "qFloat"
|
493
|
+
break
|
494
|
+
case 3:
|
495
|
+
op = "qString"
|
496
|
+
break
|
497
|
+
case 4:
|
498
|
+
op = "qRaw"
|
499
|
+
break
|
500
|
+
}
|
501
|
+
setParams({ op, params })
|
502
|
+
/*
|
503
|
+
const provider = new providers.Web3Provider(
|
504
|
+
window.ethereum,
|
505
|
+
"any"
|
506
|
+
)
|
507
|
+
const zkar = await new Contract(
|
508
|
+
contractAddr,
|
509
|
+
abi,
|
510
|
+
provider
|
511
|
+
)
|
512
|
+
switch (type2) {
|
513
|
+
case 0:
|
514
|
+
console.log(await zkar.qNull(...params))
|
515
|
+
break
|
516
|
+
case 1:
|
517
|
+
console.log(await zkar.qBool(...params))
|
518
|
+
op = "qBool"
|
519
|
+
break
|
520
|
+
case 2:
|
521
|
+
console.log(await zkar.qInt(...params))
|
522
|
+
op = "qInt"
|
523
|
+
break
|
524
|
+
case 2.5:
|
525
|
+
console.log(await zkar.qFloat(...params))
|
526
|
+
op = "qFloat"
|
527
|
+
break
|
528
|
+
case 3:
|
529
|
+
console.log(await zkar.qString(...params))
|
530
|
+
op = "qString"
|
531
|
+
break
|
532
|
+
case 4:
|
533
|
+
console.log(await zkar.qRaw(...params))
|
534
|
+
op = "qRaw"
|
535
|
+
break
|
536
|
+
}
|
537
|
+
*/
|
538
|
+
}
|
539
|
+
} catch (e) {
|
540
|
+
console.log(e)
|
541
|
+
alert("something went wrong, please try again.")
|
542
|
+
}
|
543
|
+
setGenerating(false)
|
544
|
+
}
|
545
|
+
}}
|
546
|
+
>
|
547
|
+
{generating ? (
|
548
|
+
<Box
|
549
|
+
as="i"
|
550
|
+
className="fas fa-spin fa-circle-notch"
|
551
|
+
/>
|
552
|
+
) : (
|
553
|
+
"Generate Proof"
|
554
|
+
)}
|
555
|
+
</Flex>
|
556
|
+
</Flex>
|
557
|
+
</Box>
|
558
|
+
</>
|
559
|
+
)}
|
560
|
+
</>
|
561
|
+
)}
|
562
|
+
{!params ? null : (
|
563
|
+
<Box mt={6}>
|
564
|
+
<Box
|
565
|
+
bg="white"
|
566
|
+
w="100%"
|
567
|
+
fontSize="14px"
|
568
|
+
mb={4}
|
569
|
+
color="#5037C6"
|
570
|
+
p={4}
|
571
|
+
sx={{ borderRadius: "5px" }}
|
572
|
+
>
|
573
|
+
<Box>
|
574
|
+
<Box align="center">
|
575
|
+
Copy & Paste the input values to
|
576
|
+
<Box as="b" mx={1}>
|
577
|
+
{params.op}
|
578
|
+
</Box>
|
579
|
+
function on PolygonScan
|
580
|
+
</Box>
|
581
|
+
<Box mt={2}>
|
582
|
+
<Flex>
|
583
|
+
<Box mx={2} mb={1}>
|
584
|
+
txid (string) - Arweave TxId
|
585
|
+
</Box>
|
586
|
+
<Box flex={1} />
|
587
|
+
<CopyToClipboard
|
588
|
+
text={params.params[0]}
|
589
|
+
onCopy={() => {
|
590
|
+
toast({
|
591
|
+
duration: 1000,
|
592
|
+
position: "top-right",
|
593
|
+
render: () => (
|
594
|
+
<Flex
|
595
|
+
justify="center"
|
596
|
+
bg="#5037C6"
|
597
|
+
color="white"
|
598
|
+
p={2}
|
599
|
+
m={1}
|
600
|
+
sx={{ borderRadius: "3px" }}
|
601
|
+
>
|
602
|
+
txid copied!
|
603
|
+
</Flex>
|
604
|
+
),
|
605
|
+
})
|
606
|
+
}}
|
607
|
+
>
|
608
|
+
<Box
|
609
|
+
mr={4}
|
610
|
+
sx={{
|
611
|
+
textDecoration: "underline",
|
612
|
+
cursor: "pointer",
|
613
|
+
":hover": { opacity: 0.75 },
|
614
|
+
}}
|
615
|
+
>
|
616
|
+
Copy
|
617
|
+
</Box>
|
618
|
+
</CopyToClipboard>
|
619
|
+
</Flex>
|
620
|
+
<Box
|
621
|
+
mx={2}
|
622
|
+
p={2}
|
623
|
+
sx={{
|
624
|
+
border: "1px solid #5037C6",
|
625
|
+
borderRadius: "3px",
|
626
|
+
}}
|
627
|
+
>
|
628
|
+
{params.params[0]}
|
629
|
+
</Box>
|
630
|
+
</Box>
|
631
|
+
<Box mt={2}>
|
632
|
+
<Flex>
|
633
|
+
<Box mx={2} mb={1}>
|
634
|
+
path (uint256[5]) - encoded path to value
|
635
|
+
</Box>
|
636
|
+
<Box flex={1} />
|
637
|
+
<CopyToClipboard
|
638
|
+
text={`[${params.params[1].join(",")}]`}
|
639
|
+
onCopy={() => {
|
640
|
+
toast({
|
641
|
+
duration: 1000,
|
642
|
+
position: "top-right",
|
643
|
+
render: () => (
|
644
|
+
<Flex
|
645
|
+
justify="center"
|
646
|
+
bg="#5037C6"
|
647
|
+
color="white"
|
648
|
+
p={2}
|
649
|
+
m={1}
|
650
|
+
sx={{ borderRadius: "3px" }}
|
651
|
+
>
|
652
|
+
path copied!
|
653
|
+
</Flex>
|
654
|
+
),
|
655
|
+
})
|
656
|
+
}}
|
657
|
+
>
|
658
|
+
<Box
|
659
|
+
mr={4}
|
660
|
+
sx={{
|
661
|
+
textDecoration: "underline",
|
662
|
+
cursor: "pointer",
|
663
|
+
":hover": { opacity: 0.75 },
|
664
|
+
}}
|
665
|
+
>
|
666
|
+
Copy
|
667
|
+
</Box>
|
668
|
+
</CopyToClipboard>
|
669
|
+
</Flex>
|
670
|
+
<Box
|
671
|
+
mx={2}
|
672
|
+
p={2}
|
673
|
+
sx={{
|
674
|
+
border: "1px solid #5037C6",
|
675
|
+
borderRadius: "3px",
|
676
|
+
}}
|
677
|
+
>
|
678
|
+
[{params.params[1].join(",")}]
|
679
|
+
</Box>
|
680
|
+
</Box>
|
681
|
+
<Box mt={2}>
|
682
|
+
<Flex>
|
683
|
+
<Box mx={2} mb={1}>
|
684
|
+
zkp (uint256[20]) - zk proof and public signals
|
685
|
+
</Box>
|
686
|
+
<Box flex={1} />
|
687
|
+
<CopyToClipboard
|
688
|
+
text={`[${params.params[2]
|
689
|
+
.map(v => `${v}`)
|
690
|
+
.join(",")}]`}
|
691
|
+
onCopy={() => {
|
692
|
+
toast({
|
693
|
+
duration: 1000,
|
694
|
+
position: "top-right",
|
695
|
+
render: () => (
|
696
|
+
<Flex
|
697
|
+
justify="center"
|
698
|
+
bg="#5037C6"
|
699
|
+
color="white"
|
700
|
+
p={2}
|
701
|
+
m={1}
|
702
|
+
sx={{ borderRadius: "3px" }}
|
703
|
+
>
|
704
|
+
zkp copied!
|
705
|
+
</Flex>
|
706
|
+
),
|
707
|
+
})
|
708
|
+
}}
|
709
|
+
>
|
710
|
+
<Box
|
711
|
+
mr={4}
|
712
|
+
sx={{
|
713
|
+
textDecoration: "underline",
|
714
|
+
cursor: "pointer",
|
715
|
+
":hover": { opacity: 0.75 },
|
716
|
+
}}
|
717
|
+
>
|
718
|
+
Copy
|
719
|
+
</Box>
|
720
|
+
</CopyToClipboard>
|
721
|
+
</Flex>
|
722
|
+
<Box
|
723
|
+
mx={2}
|
724
|
+
p={2}
|
725
|
+
sx={{
|
726
|
+
border: "1px solid #5037C6",
|
727
|
+
borderRadius: "3px",
|
728
|
+
}}
|
729
|
+
>
|
730
|
+
[{params.params[2].map(v => `${v}`).join(",")}]
|
731
|
+
</Box>
|
732
|
+
</Box>
|
733
|
+
<Box mt={2}>
|
734
|
+
<Flex>
|
735
|
+
<Box mx={2} mb={1}>
|
736
|
+
sig (bytes) - validator signature
|
737
|
+
</Box>
|
738
|
+
<Box flex={1} />
|
739
|
+
<CopyToClipboard
|
740
|
+
text={params.params[3]}
|
741
|
+
onCopy={() => {
|
742
|
+
toast({
|
743
|
+
duration: 1000,
|
744
|
+
position: "top-right",
|
745
|
+
render: () => (
|
746
|
+
<Flex
|
747
|
+
justify="center"
|
748
|
+
bg="#5037C6"
|
749
|
+
color="white"
|
750
|
+
p={2}
|
751
|
+
m={1}
|
752
|
+
sx={{ borderRadius: "3px" }}
|
753
|
+
>
|
754
|
+
sig copied!
|
755
|
+
</Flex>
|
756
|
+
),
|
757
|
+
})
|
758
|
+
}}
|
759
|
+
>
|
760
|
+
<Box
|
761
|
+
mr={4}
|
762
|
+
sx={{
|
763
|
+
textDecoration: "underline",
|
764
|
+
cursor: "pointer",
|
765
|
+
":hover": { opacity: 0.75 },
|
766
|
+
}}
|
767
|
+
>
|
768
|
+
Copy
|
769
|
+
</Box>
|
770
|
+
</CopyToClipboard>
|
771
|
+
</Flex>
|
772
|
+
<Box
|
773
|
+
mx={2}
|
774
|
+
p={2}
|
775
|
+
sx={{
|
776
|
+
border: "1px solid #5037C6",
|
777
|
+
borderRadius: "3px",
|
778
|
+
}}
|
779
|
+
>
|
780
|
+
{params.params[3]}
|
781
|
+
</Box>
|
782
|
+
</Box>
|
783
|
+
<Flex justify="center" mt={4} mx={1}>
|
784
|
+
<Flex
|
785
|
+
fontSize="16px"
|
786
|
+
justify="center"
|
787
|
+
mx={1}
|
788
|
+
color="white"
|
789
|
+
py={3}
|
790
|
+
w="100%"
|
791
|
+
bg="#5037C6"
|
792
|
+
sx={{
|
793
|
+
borderRadius: "5px",
|
794
|
+
cursor: proof ? "pointer" : "default",
|
795
|
+
":hover": { opacity: 0.75 },
|
796
|
+
}}
|
797
|
+
as="a"
|
798
|
+
target="_blank"
|
799
|
+
href={`https://mumbai.polygonscan.com/address/${contractAddr}#readContract`}
|
800
|
+
>
|
801
|
+
Go To PolygonScan
|
802
|
+
</Flex>
|
803
|
+
</Flex>
|
804
|
+
</Box>
|
805
|
+
</Box>
|
806
|
+
</Box>
|
807
|
+
)}
|
808
|
+
<Box mt={6}>
|
809
|
+
<Box
|
810
|
+
bg="white"
|
811
|
+
w="100%"
|
812
|
+
mb={4}
|
813
|
+
color="#5037C6"
|
814
|
+
p={4}
|
815
|
+
sx={{ borderRadius: "5px" }}
|
816
|
+
fontSize="12px"
|
817
|
+
>
|
818
|
+
<Box mb={2} fontWeight="bold" fontSize="14px">
|
819
|
+
How it works?
|
820
|
+
</Box>
|
821
|
+
<Box>
|
822
|
+
We could simply prove an arbitrary JSON with zkJSON on
|
823
|
+
Ethereum, but there needs to be logic to validate existence of
|
824
|
+
Arweave transactions. For this demo, we use a simple
|
825
|
+
centralized validator to check an Arweave gateway and sign the
|
826
|
+
poseidon hash of the encoded JSON. Once you have the
|
827
|
+
signature, you can query any data field in that JSON with the
|
828
|
+
Ethereum smart contract. The ethereum contract (Polygon
|
829
|
+
Mumbai) checks the zkJSON proof and the validator's signature.
|
830
|
+
</Box>
|
831
|
+
<Box mt={2}>
|
832
|
+
However, for real use cases, we can use a decentralized
|
833
|
+
validator such as Lit protocol's PKP and Lit Action to do the
|
834
|
+
same. WeaveDB also has a zkDB and zkRollup mechanisms to build
|
835
|
+
hyper-scalable decentralized databases.
|
836
|
+
</Box>
|
837
|
+
<Box mt={2}>
|
838
|
+
We could also remove the validator signature check from the
|
839
|
+
smart contract and zk-proof the signature with another
|
840
|
+
circuit. This will make the onchain computation lighter and
|
841
|
+
simpler, but the offchain circuit computation heaviour and
|
842
|
+
more complex.
|
843
|
+
</Box>
|
844
|
+
<Box mt={2}>
|
845
|
+
These optimizations are out of scope for this simple demo.
|
846
|
+
</Box>
|
847
|
+
<Flex mt={2} justify="center">
|
848
|
+
<Box
|
849
|
+
as="a"
|
850
|
+
sx={{ textDecoration: "underline" }}
|
851
|
+
target="_blank"
|
852
|
+
href="https://github.com/weavedb/zkjson"
|
853
|
+
>
|
854
|
+
Go Check the Litepaper
|
855
|
+
</Box>
|
856
|
+
</Flex>
|
857
|
+
</Box>
|
858
|
+
</Box>
|
859
|
+
</Box>
|
860
|
+
<Flex justify="center" mt={4} color="#5037C6">
|
861
|
+
<Link href="https://github.com/weavedb/zkjson" target="_blank">
|
862
|
+
Built by WeaveDB
|
863
|
+
</Link>
|
864
|
+
</Flex>
|
865
|
+
</Box>
|
866
|
+
</Flex>
|
867
|
+
</>
|
868
|
+
)
|
869
|
+
}
|