Example/Template DarkFi smart contract

x 4b2b317006 Cargo.toml: updated repository url 4 minggu lalu
client acec629364 chore: updated to latest versions 2 bulan lalu
proof fc3e08388d README: updated tx-from-calls usage example 8 bulan lalu
src 4b2b317006 Cargo.toml: updated repository url 4 minggu lalu
.gitignore fc3e08388d README: updated tx-from-calls usage example 8 bulan lalu
Cargo.lock 4b2b317006 Cargo.toml: updated repository url 4 minggu lalu
Cargo.toml 4b2b317006 Cargo.toml: updated repository url 4 minggu lalu
LICENSE.md b52f11d6ce Add project 8 bulan lalu
Makefile b52f11d6ce Add project 8 bulan lalu
README.md 4b2b317006 Cargo.toml: updated repository url 4 minggu lalu
flake.lock b52f11d6ce Add project 8 bulan lalu
flake.nix b52f11d6ce Add project 8 bulan lalu

README.md

DarkFi template smart contract

This repository is an example smart contract on DarkFi.

It shows how to write a Rust WASM contract that contains a ZK proof of knowing a secret key and shows how to create signatures.

The source code is entirely documented, so it's best recommended to read through it all to understand the structure.

lib.rs and entrypoint.rs define the actual smart contract, while client/main.rs shows a simple tool that acts as the "client-side" of the smart contract and explains how to create the contract calls that become part of the transaction on DarkFi that will use this smart contract.

The smart contract implements a simple membership proof and provides two functions: Register and Deregister. These two functions simply add or remove a public key commitment from a database on-chain, provided that the functions' executions are valid and they pass.

Compiling

The project requires the Rust WASM toolchain to compile the smart contract, stable Rust to compile the helper client binary, and the zkas compiler provided by DarkFi.

We can obtain the wasm32-unknown-unknown toolchain with rustup:

$ rustup target add wasm32-unknown-unknown

The zkas compiler can be compiled from the DarkFi repository:

$ git clone https://git.dark.fi/darkrenaissance/darkfi && cd darkfi
$ make zkas

In a new terminal grab this repository and enter its folder:

$ git clone https://git.dark.fi/darkrenaissance/smart-contract && cd smart-contract

This project provides a convenient Makefile that is able to compile everything. Just make sure to update the path to the zkas compiler or have it in your $PATH.

$ make

Running make should result in having both membership and membership.wasm in the git project root directory.

Deterministic WASM build

We can also use nix to produce a deterministic build of the WASM module. This is useful when we want to prove this source code matches the deployed binary on the DarkFi blockchain.

The provided flake.nix contains the code necessary to produce such a build.

$ nix build && cp -f result/membership.wasm .

Deploying on DarkFi

To deploy smart contracts on DarkFi we need a wallet to control the contract deployment authority secret key. We are going to use the native drk wallet tool in the DarkFi repository, so return to the terminal where you got it open. If you have not compiled drk before or haven't initialized a wallet refer to the corresponding sections of the DarkFi Book. The wallet must also have balance in order to deploy contracts.

Generate a contract authority keypair and note the generated contract ID, since that will be used to reference our contract:

$ ./drk contract generate-deploy

Generating a new keypair
Created new contract deploy authority
Contract ID: {CONTRACT_ID}

Now we can deploy our contract on chain:

$ ./drk contract deploy {CONTRACT_ID} ../smart-contract/membership.wasm > deploy.tx
$ ./drk broadcast < deploy.tx

Refer to the DarkFi Book Contracts for further handling of the deployed contract.

Creating a transaction using this smart contract

Once deployed, we can use the generated contract ID to refer to our deployed contract. Return to the terminal in our contract repo and use the membership tool to generate an identity:

$ ./membership generate
Secret key: {IDENTITY_SECRET_KEY}
Public key: {IDENTITY_PUBLIC_KEY}

And then we can create a register call with our new secret key:

$ ./membership register {CONTRACT_ID} {IDENTITY_SECRET_KEY} > register.call

Once we have this call, we can use the drk wallet tool again to create the actual transaction and attach the fee call to pay any necessary execution fees on-chain.

$ ./drk tx-from-calls < ../smart-contract/register.call > register.tx
$ ./drk broadcast < register.tx

We can create a deregister call using the same steps:

$ ./membership deregister {CONTRACT_ID} {IDENTITY_SECRET_KEY} > deregister.call
$ ./drk tx-from-calls < ../smart-contract/deregister.call > deregister.tx
$ ./drk broadcast < deregister.tx

License

GNU AGPL-3