To create your zkGraph project based on this template, click Use this template
, and Creating a new repository
.
After clone your project, you need to create config.js
file at root folder based on config-example.js
// ./config.js
export const config = {
// Etherum JSON RPC provider URL:
// (Please note the provider must support debug_getRawReceipts RPC method.)
JsonRpcProviderUrl: "https://{URL}",
};
Then run:
npm install
To test the whole flow of the library, run this after you have done the configuration:
sh test.sh
The workflow of local zkGraph development is: Develop
(code in /src) -> Compile
(to get compiled wasm image) -> Execute
(to get expected output) -> Prove
(to generate input and pre-test for actual proving) -> Deploy
.
If you encounter any problem, please refer to the test.sh for the example usage of the commands.
npm run compile-local
npm run exec-local -- {block_id}
npm run prove-local -- --inputgen {block_id} {expected_state}
npm run prove-local -- --pretest {block_id} {expected_state}
The configuration (such as blockchain json rpc provider url) for the local development API.
The configuration for the zkGraph.
It specifies information including:
- data source
- target blockchain network
- target smart contract address
- target event
- event handler
The logic of the event handler in AssemblyScript.
It specifies how to handle the event data and generate the output state.
export function handleEvents(events: Event[]): Bytes {
let state = new Bytes(0);
if (events.length > 0) {
state = events[0].address;
}
require(state.length == 20 ? 1 : 0);
return state;
}
More info and API reference can be found in Hyper Oracle zkGraph docs.
- Provable program needs to be compilable and runnable in normal execution runtime first.
- To running on zkwasm, do not use io syscalls like
console
etc. - You may need to use
BigEndian
version functions for Ethereum data structures. - For operators of
BigInt
(eg.+
,-
,*
,/
), use syntax likea.plus(b)
instead ofa + b
(this still works, but triggers compiler warning). require
is a cool Solidity-like language feature zkWasm provides, but will trigger warning when using in zkGraph'smapping.ts
. To ignore the error: when importing, add// @ts-ignore
after the import line; when using, write something likerequire(true ? 1 : 0)
to convert the boolean to number for the ts compiler.
- Look at (approximate) WASM cost for each operation! Complexer logic (eg. anything with lots of
if
orstring
) usally means more instructions, which means longer proof generation time. - Don't use template literals (
${}
), for example when throwing errors, because it will be compiled to too many WASM instructions (~1000 diff). - Try not to use keywords that may introduce extra global init code e.g.
new
,static
etc. (changetype
is fine).
- Don't use
I8.parseInt
because it will be compiled toi32.extend8_s (aka. Unknown opcode 192 (0xC0) in WASM)
. - Don't use template literals (
${}
), for example when throwing errors, because it will be compiled to too many WASM instructions (~1000 diff). - Don't use
FC extensions
opcodes, because it will be compiled toUnknown opcode 252 (0xFC) in WASM
.
References: WebAssembly Opcodes.
This repo has the following folders relevant to zkGraph development:
bundle-js
: APIs (the scripts inpackage.json
) for compile, execute, prove, and deploy zkGraph for testing locally.example
: Example zkGraphs.lib
: AssemblyScript library for zkGraph development, with data structure such as Bytes, ByteArray and BigInt.src
: Where your actual zkGraph should be in. Containsmapping.ts
andzkgraph.yaml
.
- zkWasm Project: DelphinusLab/zkWasm
- The Graph AssemblyScript API Specification: graphprotocol/graph-tooling
- Polywrap BigInt Implementation: polywrap/as-bigint
- Near Base58 Implementation: near/as-base58