diff --git a/README.md b/README.md index 6c96b2b5..b18ed69c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ W3bstream is a key Layer-2 solution within the IoTeX ecosystem, designed to supp ## Workflow
- +
**Sequencer nodes** assemble received data messages with a “block header” that (among other things) references the previous block of data. Each block of data is mined using a proof-of-work mechanism and is then assigned as a Task to a Prover node that is available for data computation. Sequencer nodes receive rewards in IOTX for the mining activity. @@ -18,25 +18,24 @@ The chain of tasks and their ZK-proofs are recorded **on the IoTeX blockchain**, This architecture ensures secure, reliable, and scalable data processing, allowing DePIN dApps to act on verified real-world facts to trigger blockchain-based incentives. -## Architecture +## Get Started -[Detailed system architecture description →](./docs/ARCHITECTURE.md) +[Deploy a simple W3bstream prover →](./docs/QUICK_START.md) -## Docker images - -* [Sequencer](https://github.com/iotexproject/w3bstream/pkgs/container/w3bstream-sequencer) -* [Prover](https://github.com/iotexproject/w3bstream/pkgs/container/w3bstream-prover) +[Build custom provers →](./docs/DEVELOPER_GUIDE.md) -## Running +## Docker images -For users who just want to give it a try, please refer to [Quick Start →](./docs/QUICK_START.md), which will guide you through how to interact with existing projects deployed on testnet. +[Sequencer Node →](https://github.com/iotexproject/w3bstream/pkgs/container/w3bstream-sequencer) -Developers looking to build circuits and deploy W3bstream projects should consult the [DEVELOPER_GUIDE →](./docs/DEVELOPER_GUIDE.md) +[Prover Node →](https://github.com/iotexproject/w3bstream/pkgs/container/w3bstream-prover) ## Contract Deployments -Coming + [smartcontracts/README.md](./smartcontracts/README.md#deployment) ## Contributing -We welcome contributions! Please read our [contributing guidelines](./docs/CONTRIBUTING.md) and submit pull requests to our GitHub repository. +We welcome contributions! + +Please read our [contributing guidelines](./docs/CONTRIBUTING.md) and submit pull requests to our GitHub repository. diff --git a/docs/DEVELOPER_GUIDE.md b/docs/DEVELOPER_GUIDE.md index 5cf59f2e..19c216d5 100644 --- a/docs/DEVELOPER_GUIDE.md +++ b/docs/DEVELOPER_GUIDE.md @@ -1,50 +1,37 @@ # IoTeX W3bstream Project Developer Guide -W3bstream significantly enhances scalability and trust for dApps where the token economy depends on verifiable processing of real-world data. By providing a decentralized infrastructure to process raw data and generate custom Zero-Knowledge (ZK) Proofs, W3bstream ensures data authenticity and reliability in dApps' token economies. - -Dapps looking to utilize W3bstream capabilities should: - -1. [Create a W3bstream project](#create-a-w3bstream-project) -2. [Test the project](#test-your-w3bstream-project) -3. [Register it on the IoTeX blockchain](#registering-your-project) -4. [Verify proof on the IoTeX blockchain](#verify-proof-on-chain) - ## Prerequisites -- ioctl: The command-line interface for interacting with the IoTeX blockchain. +Ensure you have the following tools installed: -```bash -git clone https://github.com/iotexproject/iotex-core.git -cd iotex-core -make ioctl && mv bin/ioctl __YOUR_SYSTEM_PATH__ -``` +- [ioctl](https://docs.iotex.io/builders/reference-docs/ioctl-client#install-latest-release-build): For interacting with the IoTeX blockchain. -[More on the IoTeX ioctl client →](https://docs.iotex.io/the-iotex-stack/wallets/command-line-client) +## Create a W3bstream Prover Configuration -## Create a W3bstream Project +The W3bstream Prover Configuration consists primarily of the ZK Prover binary code and its revisions. To create a configuration file, first compile a ZK circuit into a prover using one of the supported ZK frameworks, then generate a W3bstream configuration file using the ioctl command-line client. -A W3bstream project primarily includes the binary code of the a ZK Prover and the destination contract for dispatching proofs. The steps involve first compiling a zk circuit into a prover using one of the supported ZK frameworks, and then generating a W3bstream project file using **ioctl** command line client. - -Start by cloning the W3bstream repository: +Begin by cloning the W3bstream repository: ```bash git clone https://github.com/iotexproject/w3bstream.git cd w3bstream ``` -### Create a W3bstream Project Using Halo2 - ->For more details on creating Halo2 circuits see the [Halo2 README](./examples/halo2-circuit/README.md). ++💡 NOTE: For circuit development with Halo2, refer to the halo2 development documentation. +-NOTE: If you want to develop your circuit, please refer [halo2 development documentation](https://zcash.github.io/halo2/user/simple-example.html) - -Install `wasm-pack` +#### Step 1: Install `wasm-pack` ```bash curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh ``` -build the wasm prover with: +#### Step 2: build the wasm prover ```bash cd examples/halo2-circuit/ @@ -53,24 +40,32 @@ wasm-pack build --target nodejs --out-dir pkg The `halo2_simple_bg.wasm` will be located under the `pkg` folder. -Generate the W3bstream project file: +#### Step 3: Generate the W3bstream config file + +Customize the output project file name: ```bash -# Customize the output project file name "$ID" with a unique number -ioctl ws project config -t 2 -i "halo2_wasm_bg.wasm" -c "path/$ID" +ioctl ws project config -t 2 -i "halo2_wasm_bg.wasm" -c "path/config_file_name.json" ``` -Create the blockchain verifier (Solidity) +#### Step 4: Create the blockchain verifier (Solidity) ``` shell target/release/halo2-simple-circuit solidity -f path/filename.sol ``` -### Create a W3bstream Project Using zkWASM +
+💡 NOTE: For zkWASM circuit development, refer to the zkWASM development documentation. -NOTE: If you want to develop your circuit, please refer [zkwasm project bootstrap](https://github.com/DelphinusLab/zkWasm?tab=readme-ov-file#project-bootstrap) ++ +#### Step 1: Install AssemblyScript Ensure you have AssemblyScript installed: @@ -78,211 +73,147 @@ Ensure you have AssemblyScript installed: npm install -g assemblyscript ``` -Build the circuit: +#### Step 2: Build the circuit ```bash cd examples/zkwasm-circuit/ asc src/add.ts -O --noAssert -o zkwasm_demo.wasm ``` -Create the verifier +#### Step 3: Create the verifier ```bash # Work in progress -`````` +``` -Generate the W3bstream project: +#### Step 4: Generate the W3bstream config file ```bash -# Customize the output project file name "$ID" with a unique number -ioctl ws project config -t 3 -i "zkwasm_demo.wasm" -o "path/ID" +ioctl ws project config -t 3 -i "zkwasm_demo.wasm" -o "path/config_file_name.json" ``` -### Create a W3bstream Project Using RISC0 - -More details and options for `Risc0 circuit` are given in [its README](./examples/risc0-circuit/README.md). +
+💡 NOTE: For Risc0 circuit development, refer to the Risc0 development documentation. - ```bash - cargo version - # Update with: rustup update - ``` - -Install the rustzero toolchain +- ```bash - cargo install cargo-risczero - cargo risczero install - ``` +#### Step 1: Install the Toolchain -Build the circuit +Make sure cargo version 1.72.0 or higher is installed: ```bash -cd examples/risc0-circuit/ -cargo build --release -``` +# Check with +cargo version -The path of `methods.rs` will be printed to the console, like in the output example below: +# Install with +curl https://sh.rustup.rs -sSf | sh -```bash -warning: methods_path is: "w3bstream/examples/risc0-circuits/target/release/build/risc0-circuits-5efc4ff59af940ab/out/methods.rs" +# Update with +rustup update ``` -Generate the W3bstream Project +Install the rustzero toolchain ```bash -ioctl ws project config -t 1 -i "methods.rs" -o "path/filename.json" -e "{\"image_id\":\"RANGE_ID\", \"elf\":\"RANGE_ELF\"}" +cargo install cargo-risczero +cargo risczero install ``` -The values of `image_id` and `elf` are variable names, and will be found in the `methods.rs` file. - -## Test Your W3bstream Project - -Once you have generated a W3bstream project file that includes a custom prover for your dApp, you might want to test it. - -Please refer to the [OPERATOR GUIDE](./OPERATOR_GUIDE.md) for instructions on how to: - -1. Run a W3bstream node locally. -2. Copy the W3bstream project file into the node's project directory (default location is ./test/project). -3. Run the node and send your test messages. - -## Registering Your Project - -To allow W3bstream node operators to download your project and compute ZK proofs for your dApp, you must register your W3bstream project on the IoTeX blockchain: - -### Acquire a Project ID +#### Step 2: Build the circuit ```bash -ioctl ioid register "your project name" +cd examples/risc0-circuit/ +cargo build --release ``` -### Register Project +The path of `methods.rs` will be printed in the output, as sown in the example below: ```bash -ioctl ws project register --id "your project id" +warning: methods_path is: "w3bstream/examples/risc0-circuits/target/release/build/risc0-circuits-5efc4ff59af940ab/out/methods.rs" ``` -### Use the Project File Generated above and Update Project Config +#### Step 3: Generate the W3bstream Config File ```bash -ioctl ws project update --id "your project id" --path "path/to/project_file" +ioctl ws project config -t 1 -i "methods.rs" -o "path/filename.json" -e "{\"image_id\":\"RANGE_ID\", \"elf\":\"RANGE_ELF\"}" ``` -### Start the Project +Customize the values for `image_id` and `elf` with the actual values found in your `methods.rs` file. -```bash -ioctl ws project resume --id "your project id" -``` +
{ - "output": { - "type": "ethereumContract", - "ethereum": { - "chainEndpoint": "https://babel-api.testnet.iotex.io", - "contractAddress": "0x3841A746F811c244292194825C5e528e61F890F8", - "contractMethod": "route", - "contractAbiJSON": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\", \"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"dapp\",\"type\":\"address\"}],\"name\":\"DappBound\",\"type\":\"event\"},{\"anonymous\":false, \"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}], \"name\":\"DappUnbound\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"indexed\":true, \"internalType\":\"uint256\",\"name\":\"router\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false, \"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"revertReason\",\"type\":\"string\"}],\"name\":\"DataProcessed\", \"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\": [{\"internalType\":\"uint256\",\"name\":\"_projectId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"}],\"name\":\"bindDapp\",\"outputs\":[], \"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"dapp\",\"outputs\":[{\"internalType\":\"address\", \"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fleetManagement\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\", \"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fleetManagement\",\"type\":\"address\"},{\"internalType\":\"address\", \"name\":\"_projectStore\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"projectStore\",\"outputs\": [{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_projectId\", \"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_proverId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_clientId\",\"type\":\"string\"},{\"internalType\":\"bytes\", \"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"route\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_projectId\", \"type\":\"uint256\"}],\"name\":\"unbindDapp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - } - } -} -``` -`chainEndpoint` is the target chain endpoint, -`contractAddress` is the router contract address, -`contractMethod` is the function that you want to call, -`contractAbiJSON` is the ABI of router contract. - -second, you should bind the Dapp of your project with the `Router`. - -## Bind Your Dapp Contract - -If you want to verify zk proof in your Dapp contract, you need to bind the project with the Dapp. - -``` bash -ioctl ws router bind --project-id "your project id" --dapp "your dapp contract address" -``` - -If you want to unbind the project with the Dapp. - -``` bash -ioctl ws router unbind --project-id "your project id" -``` - -## Dapp Contract -The Dapp Contract that bound with the project will implement the interface `process`, then invoke the verifcation contract, and verify proof. - -The example of Halo2Dapp - -``` bash -function process(uint256 _projectId, uint256 _proverId, string memory _clientId, bytes calldata _data) public { - require(halo2Verifier != address(0), "verifier address not set"); - - (uint256 publicInput, uint256 taskID, bytes memory _proof) = abi.decode(_data, (uint256, uint256, bytes)); - bytes32 _publicInput = uint256ToFr(publicInput); - bytes32 _taskID = uint256ToFr(taskID); - bytes32 _projectID = uint256ToFr(projectId); - bytes memory callData = abi.encodePacked(_publicInput, _projectID, _taskID, _proof); - - (bool success,) = halo2Verifier.staticcall(callData); - require(success, "Failed to verify proof"); - // TODO -} -``` + "defaultVersion": "0.1", + "versions": [ + { + "version": "v1.0.0", + "vmTypeID": 1, + "output": { + "type": "ethereumContract", + "ethereum": { + "chainEndpoint": "https://babel-api.testnet.iotex.io", + "contractAddress": "0x28E0A99A76a467E7418019cBBbF79E4599C73B5B", + "contractMethod": "route", + "contractAbiJSON": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"dapp\",\"type\":\"address\"}],\"name\":\"DappBound\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"DappUnbound\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"router\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"revertReason\",\"type\":\"string\"}],\"name\":\"DataProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_projectId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_dapp\",\"type\":\"address\"}],\"name\":\"bindDapp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"dapp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fleetManagement\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fleetManagement\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_projectStore\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"projectStore\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_projectId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_proverId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_clientId\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"route\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_projectId\",\"type\":\"uint256\"}],\"name\":\"unbindDapp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + } + }, + "codeExpParam": " ..." + ... ++