NOTE: For the latest version, please check out zkgraph-cli.
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.
// Recommended provider: ANKR.
JsonRpcProviderUrl: {
mainnet: "https://{URL}",
// ...or other networks.
},
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
Note: Only
full
image will be processed by zkOracle node.local
(generated by commands ending with-local
) means the zkGraph is compiled locally and only contains partial computation (so that proving and executing will be faster).
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 in zkOracle) -> 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 (eg. 69 / 0x45)>
Please save the ZKGRAPH_STATE_OUTPUT
string for following prove steps.
npm run setup-local
circuit-size
: Specify the circuit size of image instead of the default recommended. eg.npm run setup-local -- --circuit-size <size> (eg. 22)
.
npm run prove-local -- --inputgen <block_id (eg. 69 / 0x45)> <ZKGRAPH_STATE_OUTPUT>
npm run prove-local -- --test <block_id (eg. 69 / 0x45)> <ZKGRAPH_STATE_OUTPUT>
npm run prove-local -- --prove <block_id (eg. 69 / 0x45)> <ZKGRAPH_STATE_OUTPUT>
npm run deploy-local
Please save the verifer_contract_address
from the output dialog for following publish steps.
network_name
: Specify the network name of deployed verification smart contract, instead of loadingdataDestinations.network
fromzkgraph.yaml
. eg.npm run deploy-local -- --network-name <network (eg. goerli)>
.
npm run upload-local
npm run compile
npm run exec -- <block_id (eg. 69 / 0x45)>
npm run setup
circuit-size
: Specify the circuit size of image instead of the default recommended. eg.npm run setup -- --circuit-size <size (eg. 22)
.
npm run prove -- --inputgen <block_id (eg. 69 / 0x45)> <expected_state>
npm run prove -- --pretest <block_id (eg. 69 / 0x45)> <expected_state>
npm run prove -- --prove <block_id (eg. 69 / 0x45)> <expected_state>
After the prove task is completed, please save the proof task id from the output dialog for following verify step.
npm run deploy -- [network_name (sepolia / goerli)]
Please save the verifer_contract_address
from the output dialog for following publish steps.
network_name
: loaddataDestinations.network
fromzkgraph.yaml
if not passed from command.
npm run upload
Please save the ipfs_hash
from the output dialog for following publish steps.
npm run verify -- <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