Example/Template DarkFi smart contract
|
|
4 nedēļas atpakaļ | |
|---|---|---|
| client | 2 mēneši atpakaļ | |
| proof | 8 mēneši atpakaļ | |
| src | 4 nedēļas atpakaļ | |
| .gitignore | 8 mēneši atpakaļ | |
| Cargo.lock | 4 nedēļas atpakaļ | |
| Cargo.toml | 4 nedēļas atpakaļ | |
| LICENSE.md | 8 mēneši atpakaļ | |
| Makefile | 8 mēneši atpakaļ | |
| README.md | 4 nedēļas atpakaļ | |
| flake.lock | 8 mēneši atpakaļ | |
| flake.nix | 8 mēneši atpakaļ |
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.
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.
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 .
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.
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