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`: ```shell $ rustup target add wasm32-unknown-unknown ``` The `zkas` compiler can be compiled from the DarkFi repository: ```shell $ git clone https://git.dark.fi/darkrenaissance/darkfi && cd darkfi $ make zkas ``` In a new terminal grab this repository and enter its folder: ```shell $ git clone https://git.dark.fi/darkrenaissance/smart-contract && cd smart-contract ``` This project provides a convenient [`Makefile`](Makefile) that is able to compile everything. Just make sure to update the path to the `zkas` compiler or have it in your `$PATH`. ```shell $ 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`][1] 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. ```shell $ 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][2] `drk` before or haven't [initialized][3] a wallet refer to the corresponding sections of the [DarkFi Book][4]. 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: ```shell $ ./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: ```shell $ ./drk contract deploy {CONTRACT_ID} ../smart-contract/membership.wasm > deploy.tx $ ./drk broadcast < deploy.tx ``` Refer to the DarkFi Book [Contracts][5] 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: ```shell $ ./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: ```shell $ ./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. ```shell $ ./drk tx-from-calls < ../smart-contract/register.call > register.tx $ ./drk broadcast < register.tx ``` We can create a `deregister` call using the same steps: ```shell $ ./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](LICENSE.md) [1]: https://nixos.org/ [2]: https://dark.fi/book/testnet/node.html#compiling [3]: https://dark.fi/book/testnet/node.html#wallet-initialization [4]: https://dark.fi/book/ [5]: https://dark.fi/book/testnet/contract.html