In this part, we will walk through a simple Darkfi contract.
First, pull down the Darkmap repository, we'd use this example to understand how to write a simple yet powerful Darkfi contract!
Note: This book assumes basic familiarity with smart contracts and blockchain. It's good if you are familiar with Rust. You'd still be able to follow along even if you aren't by inferring from the context.
git clone https://github.com/darkrenaissance/darkmap
In Darkfi, a contract is deployed as a wasm module. Rust has one of the best wasm support, so Darkmap is implemented in Rust.
Take a look at Cargo.toml, the package's configurations.
There is macro defining 4 entrypoints the contract runtime calls. They are called in order:
apply
darkfi_sdk::define_contract!(
init: init_contract,
exec: process_instruction,
apply: process_update,
metadata: get_metadata
);
Init is responsible for 2 tasks:
initialize any number of databases (e.g. for the contract's business logic)
fn init_contract(cid: ContractId, ix: &[u8]) -> ContractResult {
// The way to load zkas binary as native contracts, it will probably be different regular contracts
let set_v1_bincode = include_bytes!("../proof/set_v1.zk.bin");
// Compute and store verifying key if it's not already stored
zkas_db_set(&set_v1_bincode[..])?;
// Check if a db is already initialized
if db_lookup(cid, MAP_CONTRACT_ENTRIES_TREE).is_err() {
// db for business logic
db_init(cid, MAP_CONTRACT_ENTRIES_TREE)?;
}
Ok(())
}
// https://github.com/darkrenaissance/darkfi/blob/85c53aa7b086652ed6d2428bf748f841485ee0e2/src/runtime/import/db.rs#L522
/// Only `deploy()` can call this. Given a zkas circuit, create a VerifyingKey and insert
/// them both into the db.
pub(crate) fn zkas_db_set(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i32 {