To create your zkGraph project based on this template:
Option 1:
Click Use this template
, and Creating a new repository
.
Option 2:
Use gh
cli
gh repo create zkgraph-new --public --template="https://github.com/hyperoracle/zkgraph.git"
After clone your project, you need to create config.js
file at root folder based on config-example.js
// ./config.js
export const config = {
// Update your Etherum JSON RPC provider URL here.
// Please note that the provider must support debug_getRawReceipts RPC method.
// Recommended provider: ANKR.
JsonRpcProviderUrl: "https://{URL}",
UserPrivateKey: "0x{PRIVATE_KEY}",
// ...and other configs.
};
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 must follow: Develop
(code in /src) -> Compile
(get compiled wasm image) -> Execute
(get expected output) -> Prove
(generate input and pre-test for actual proving) -> Deploy
(deploy verification contract) -> Verify
(verify proof on-chain).
To upload and publish your zkGraph, you should Upload
(upload code to IPFS), and then Publish
(register zkGraph on onchain zkGraph Registry).
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 setup-local
npm run prove-local -- --inputgen <block_id> <expected_state>
npm run prove-local -- --pretest <block_id> <expected_state>
npm run prove-local -- --prove <block_id> <expected_state>
npm run deploy-local -- <network_name (goerli / sepolia)>
network_name
: loaddataDestinations.network
fromzkgraph.yaml
if not passed from command.
npm run upload-local
npm run compile
npm run setup
npm run prove -- --inputgen <block_id> <expected_state>
npm run prove -- --pretest <block_id> <expected_state>
npm run prove -- --prove <block_id> <expected_state>
npm run deploy -- [network_name (sepolia / goerli)]
network_name
: loaddataDestinations.network
fromzkgraph.yaml
if not passed from command.
npm run upload
npm run verify -- <verifier_deployed_network_name> <prove_task_id>
npm run publish -- <verifier_contract_address> <ipfs_hash> <bounty_reward_per_trigger>
See also: Verifier Contract Interface.
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);
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)
. - Try not to use template literals (
${}
), for example when throwing errors, because it will be compiled to too many WASM instructions (~1000 diff). - Try not to use
FC extensions
opcodes (<u32>parseInt(...)
,f64
, orMath
), because it will be compiled toUnknown opcode 252 (0xFC) in WASM
, and generates too many instructions.
References: WebAssembly Opcodes.
This repo has the following folders relevant to zkGraph development:
api
: APIs (the scripts inpackage.json
) for compile, execute, prove, and deploy zkGraph for testing locally, and fully with zkWASM node.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