Clean up makefiles and set the ground floor for upgradable zkas circuits.

This commit is contained in:
parazyd
2022-12-15 20:43:24 +01:00
parent 40313cd6f5
commit 0c97a24b58
13 changed files with 153 additions and 145 deletions

View File

@@ -10,7 +10,19 @@ CARGO = cargo
#RUSTFLAGS = -C target-cpu=native
# Binaries to be built
BINS = drk darkfid tau taud ircd dnetview darkwikid darkwiki faucetd vanityaddr
BINS = drk darkfid ircd dnetview faucetd vanityaddr
# zkas dependencies
ZKASDEPS = \
Cargo.toml \
bin/zkas/Cargo.toml \
$(shell find src/zkas -type f) \
$(shell find src/serial -type f) \
$(shell find bin/zkas/src -type f)
# ZK proofs to compile with zkas
PROOFS_SRC = $(shell find proof -type f -name '*.zk')
PROOFS_BIN = $(PROOFS_SRC:=.bin)
# Common dependencies which should force the binaries to be rebuilt
BINDEPS = \
@@ -20,28 +32,19 @@ BINDEPS = \
$(shell find src -type f) \
$(shell find contrib/token -type f)
# ZK proofs to compile with zkas
PROOFS = \
$(shell find bin/dao/daod/proof -type f -name '*.zk') \
$(shell find example/dao/proof -type f -name '*.zk') \
$(shell find proof -type f -name '*.zk') \
example/simple.zk
all: $(BINS)
PROOFS_BIN = $(PROOFS:=.bin)
all: zkas $(PROOFS_BIN) $(BINS)
zkas: $(BINDEPS)
zkas: $(ZKASDEPS)
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --all-features --release --package $@
cp -f target/release/$@ $@
$(PROOFS_BIN): zkas $(PROOFS_SRC)
./zkas $(basename $@) -o $@
contracts: zkas
$(MAKE) -C src/contract/money
$(MAKE) -C src/contract/dao
$(PROOFS_BIN): $(PROOFS) zkas
./zkas $(basename $@) -o $@
token_lists:
$(MAKE) -C contrib/token all
@@ -49,25 +52,21 @@ $(BINS): token_lists contracts $(PROOFS_BIN) $(BINDEPS)
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --all-features --release --package $@
cp -f target/release/$@ $@
check: token_lists zkas $(PROOFS_BIN) contracts
check: token_lists contracts $(PROOFS_BIN)
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) hack check --release --feature-powerset --all
fix: token_lists zkas $(PROOFS_BIN)
fix: token_lists contracts $(PROOFS_BIN)
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clippy --release --all-features --fix --allow-dirty --all
clippy: token_lists zkas $(PROOFS_BIN)
clippy: token_lists contracts $(PROOFS_BIN)
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clippy --release --all-features --all
rustdoc: token_lists zkas
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) doc --release --workspace --all-features \
--no-deps --document-private-items
rustdoc: token_lists contracts $(PROOFS_BIN)
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) doc --release --all-features --workspace --no-deps --document-private-items
test: token_lists zkas $(PROOFS_BIN) contracts
test: token_lists $(PROOFS_BIN) contracts
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) test --release --all-features --all
test-dao: zkas
$(MAKE) -C example/dao
cleanbin:
rm -f $(BINS)
@@ -93,4 +92,4 @@ uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/$$i; \
done;
.PHONY: all contracts check fix clippy rustdoc test clean cleanbin install uninstall
.PHONY: all contracts token_lists check fix clippy rustdoc test cleanbin clean install uninstall

View File

@@ -18,7 +18,7 @@
use darkfi_sdk::{
crypto::{ContractId, MerkleNode},
db::ZKAS_DB_NAME,
db::SMART_CONTRACT_ZKAS_DB_NAME,
};
use darkfi_serial::{deserialize, serialize};
use log::{debug, error};
@@ -150,7 +150,7 @@ impl Darkfid {
let blockchain = { self.validator_state.read().await.blockchain.clone() };
let Ok(zkas_db) = blockchain.contracts.lookup(&blockchain.sled_db, &contract_id, ZKAS_DB_NAME) else {
let Ok(zkas_db) = blockchain.contracts.lookup(&blockchain.sled_db, &contract_id, SMART_CONTRACT_ZKAS_DB_NAME) else {
error!("[RPC] blockchain.lookup_zkas: Did not find zkas db for ContractId: {}", contract_id);
return server_error(RpcError::ContractZkasDbNotFound, id, None)
};

View File

@@ -26,7 +26,7 @@ use darkfi::{
use darkfi_money_contract::{
client::{build_half_swap_tx, EncryptedNote, Note},
state::MoneyTransferParams,
MoneyFunction, ZKAS_BURN_NS, ZKAS_MINT_NS,
MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
};
use darkfi_sdk::{
crypto::{
@@ -91,11 +91,11 @@ impl Drk {
// We also do this through the RPC.
let zkas_bins = self.lookup_zkas(&contract_id).await?;
let Some(mint_zkbin) = zkas_bins.iter().find(|x| x.0 == ZKAS_MINT_NS) else {
let Some(mint_zkbin) = zkas_bins.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_MINT_NS_V1) else {
return Err(anyhow!("Mint circuit not found"))
};
let Some(burn_zkbin) = zkas_bins.iter().find(|x| x.0 == ZKAS_BURN_NS) else {
let Some(burn_zkbin) = zkas_bins.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_BURN_NS_V1) else {
return Err(anyhow!("Burn circuit not found"))
};
@@ -178,11 +178,11 @@ impl Drk {
// We also do this through the RPC.
let zkas_bins = self.lookup_zkas(&contract_id).await?;
let Some(mint_zkbin) = zkas_bins.iter().find(|x| x.0 == ZKAS_MINT_NS) else {
let Some(mint_zkbin) = zkas_bins.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_MINT_NS_V1) else {
return Err(anyhow!("Mint circuit not found"))
};
let Some(burn_zkbin) = zkas_bins.iter().find(|x| x.0 == ZKAS_BURN_NS) else {
let Some(burn_zkbin) = zkas_bins.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_BURN_NS_V1) else {
return Err(anyhow!("Burn circuit not found"))
};

View File

@@ -25,7 +25,7 @@ use darkfi::{
};
use darkfi_money_contract::{
client::{build_transfer_tx, OwnCoin},
MoneyFunction, ZKAS_BURN_NS, ZKAS_MINT_NS,
MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
};
use darkfi_sdk::{
crypto::{ContractId, Keypair, PublicKey, TokenId},
@@ -34,7 +34,6 @@ use darkfi_sdk::{
};
use darkfi_serial::Encodable;
use rand::rngs::OsRng;
//use serde_json::json;
use super::Drk;
@@ -86,11 +85,11 @@ impl Drk {
// We also do this through the RPC.
let zkas_bins = self.lookup_zkas(&contract_id).await?;
let Some(mint_zkbin) = zkas_bins.iter().find(|x| x.0 == ZKAS_MINT_NS) else {
let Some(mint_zkbin) = zkas_bins.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_MINT_NS_V1) else {
return Err(anyhow!("Mint circuit not found"))
};
let Some(burn_zkbin) = zkas_bins.iter().find(|x| x.0 == ZKAS_BURN_NS) else {
let Some(burn_zkbin) = zkas_bins.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_BURN_NS_V1) else {
return Err(anyhow!("Burn circuit not found"))
};

View File

@@ -31,11 +31,11 @@ use darkfi_money_contract::{
build_transfer_tx, MONEY_KEYS_COL_IS_DEFAULT, MONEY_KEYS_COL_PUBLIC, MONEY_KEYS_COL_SECRET,
MONEY_KEYS_TABLE, MONEY_TREE_COL_TREE, MONEY_TREE_TABLE,
},
MoneyFunction, ZKAS_BURN_NS, ZKAS_MINT_NS,
MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
};
use darkfi_sdk::{
crypto::{constants::MERKLE_DEPTH, ContractId, Keypair, MerkleNode, PublicKey, TokenId},
db::ZKAS_DB_NAME,
db::SMART_CONTRACT_ZKAS_DB_NAME,
incrementalmerkletree::bridgetree::BridgeTree,
pasta::{group::ff::PrimeField, pallas},
tx::ContractCall,
@@ -213,14 +213,15 @@ impl Faucetd {
// Do a lookup for the money contract's zkas database and fetch the circuits.
let blockchain = { validator_state.read().await.blockchain.clone() };
let db_handle = blockchain.contracts.lookup(&blockchain.sled_db, &cid, ZKAS_DB_NAME)?;
let db_handle =
blockchain.contracts.lookup(&blockchain.sled_db, &cid, SMART_CONTRACT_ZKAS_DB_NAME)?;
let Some(mint_zkbin) = db_handle.get(&serialize(&ZKAS_MINT_NS))? else {
error!("{} zkas bincode not found in sled database", ZKAS_MINT_NS);
let Some(mint_zkbin) = db_handle.get(&serialize(&MONEY_CONTRACT_ZKAS_MINT_NS_V1))? else {
error!("{} zkas bincode not found in sled database", MONEY_CONTRACT_ZKAS_MINT_NS_V1);
return Err(Error::ZkasBincodeNotFound);
};
let Some(burn_zkbin) = db_handle.get(&serialize(&ZKAS_BURN_NS))? else {
error!("{} zkas bincode not found in sled database", ZKAS_BURN_NS);
let Some(burn_zkbin) = db_handle.get(&serialize(&MONEY_CONTRACT_ZKAS_BURN_NS_V1))? else {
error!("{} zkas bincode not found in sled database", MONEY_CONTRACT_ZKAS_BURN_NS_V1);
return Err(Error::ZkasBincodeNotFound);
};
@@ -238,8 +239,8 @@ impl Faucetd {
{
let provingkeys = vec![
(ZKAS_MINT_NS.to_string(), mint_provingkey, mint_zkbin),
(ZKAS_BURN_NS.to_string(), burn_provingkey, burn_zkbin),
(MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string(), mint_provingkey, mint_zkbin),
(MONEY_CONTRACT_ZKAS_BURN_NS_V1.to_string(), burn_provingkey, burn_zkbin),
];
let mut proving_keys_w = proving_keys.write().await;
@@ -414,13 +415,13 @@ impl Faucetd {
return server_error(RpcError::InternalError, id)
};
let Some(mint_data) = arr.iter().find(|x| x.0 == ZKAS_MINT_NS) else {
error!("{} proof data not found in vector", ZKAS_MINT_NS);
let Some(mint_data) = arr.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_MINT_NS_V1) else {
error!("{} proof data not found in vector", MONEY_CONTRACT_ZKAS_MINT_NS_V1);
return server_error(RpcError::InternalError, id)
};
let Some(burn_data) = arr.iter().find(|x| x.0 == ZKAS_BURN_NS) else {
error!("{} prof data not found in vector", ZKAS_BURN_NS);
let Some(burn_data) = arr.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_BURN_NS_V1) else {
error!("{} prof data not found in vector", MONEY_CONTRACT_ZKAS_BURN_NS_V1);
return server_error(RpcError::InternalError, id)
};

View File

@@ -25,7 +25,7 @@ use darkfi_sdk::{
schnorr::{SchnorrPublic, SchnorrSecret},
ContractId, MerkleNode, PublicKey,
},
db::ZKAS_DB_NAME,
db::SMART_CONTRACT_ZKAS_DB_NAME,
incrementalmerkletree::{bridgetree::BridgeTree, Tree},
pasta::{group::ff::PrimeField, pallas},
};
@@ -177,7 +177,11 @@ impl ValidatorState {
// initialize verifying keys for them.
info!("Creating ZK verifying keys for {} zkas circuits", nc.0);
info!("Looking up zkas db for {} (ContractID: {})", nc.0, nc.1);
let zkas_db = blockchain.contracts.lookup(&blockchain.sled_db, &nc.1, ZKAS_DB_NAME)?;
let zkas_db = blockchain.contracts.lookup(
&blockchain.sled_db,
&nc.1,
SMART_CONTRACT_ZKAS_DB_NAME,
)?;
let mut vks = vec![];
for i in zkas_db.iter() {

View File

@@ -1,11 +1,14 @@
.POSIX:
# Cargo binary
CARGO ?= cargo
CARGO = cargo
# Zkas binary
ZKAS ?= ../../../zkas
# zkas compiler binary
ZKAS = ../../../zkas
# zkas circuit source files
ZKAS_SRC = $(shell find proof -type f -name '*.zk')
# zkas circuits
PROOFS_SRC = $(shell find proof -type f -name '*.zk')
PROOFS_BIN = $(PROOFS_SRC:=.bin)
# wasm source files
WASM_SRC = \
@@ -13,25 +16,22 @@ WASM_SRC = \
$(shell find ../../sdk -type f) \
$(shell find ../../serial -type f)
# zkas circuit bin files
ZKAS_BIN = $(ZKAS_SRC:=.bin)
# Contract WASM binaries
# wasm contract binary
WASM_BIN = dao_contract.wasm
all: $(WASM_BIN)
$(ZKAS_BIN): $(ZKAS_SRC)
$(ZKAS) $(basename $@) -o $@
dao_contract.wasm: $(ZKAS_BIN) $(WASM_SRC)
$(WASM_BIN): $(WASM_SRC) $(PROOFS_BIN)
$(CARGO) build --release --package darkfi-dao-contract --target wasm32-unknown-unknown
cp -f ../../../target/wasm32-unknown-unknown/release/darkfi_dao_contract.wasm $@
$(PROOFS_BIN): $(ZKAS) $(PROOFS_SRC)
$(ZKAS) $(basename $@) -o $@
test: all
$(CARGO) test --release --features=no-entrypoint,client --package darkfi-dao-contract
clean:
rm -f $(ZKAS_BIN) $(WASM_BIN)
rm -f $(PROOFS_BIN) $(WASM_BIN)
.PHONY: all test clean

View File

@@ -18,7 +18,7 @@
use darkfi_sdk::{
crypto::{ContractId, MerkleNode, MerkleTree, PublicKey},
db::{db_contains_key, db_get, db_init, db_lookup, db_set, ZKAS_DB_NAME},
db::{db_contains_key, db_get, db_init, db_lookup, db_set, SMART_CONTRACT_ZKAS_DB_NAME},
error::{ContractError, ContractResult},
merkle::merkle_add,
msg,
@@ -33,7 +33,8 @@ use darkfi_sdk::{
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
use darkfi_money_contract::{
state::MoneyTransferParams, MoneyFunction, COIN_ROOTS_TREE, NULLIFIERS_TREE,
state::MoneyTransferParams, MoneyFunction, MONEY_CONTRACT_COIN_ROOTS_TREE,
MONEY_CONTRACT_NULLIFIERS_TREE,
};
use crate::{
@@ -74,9 +75,9 @@ fn init_contract(cid: ContractId, ix: &[u8]) -> ContractResult {
// The zkas circuits can simply be embedded in the wasm and set up by
// the initialization. Note that the tree should then be called "zkas".
// The lookups can then be done by `contract_id+_zkas+namespace`.
let zkas_db = match db_lookup(cid, ZKAS_DB_NAME) {
let zkas_db = match db_lookup(cid, SMART_CONTRACT_ZKAS_DB_NAME) {
Ok(v) => v,
Err(_) => db_init(cid, ZKAS_DB_NAME)?,
Err(_) => db_init(cid, SMART_CONTRACT_ZKAS_DB_NAME)?,
};
let dao_exec_bin = include_bytes!("../proof/dao-exec.zk.bin");
let dao_mint_bin = include_bytes!("../proof/dao-mint.zk.bin");
@@ -85,12 +86,12 @@ fn init_contract(cid: ContractId, ix: &[u8]) -> ContractResult {
let dao_propose_burn_bin = include_bytes!("../proof/dao-propose-burn.zk.bin");
let dao_propose_main_bin = include_bytes!("../proof/dao-propose-main.zk.bin");
db_set(zkas_db, &serialize(&ZKAS_DAO_EXEC_NS.to_string()), &dao_exec_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_MINT_NS.to_string()), &dao_mint_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_VOTE_BURN_NS.to_string()), &dao_vote_burn_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_VOTE_MAIN_NS.to_string()), &dao_vote_main_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_PROPOSE_BURN_NS.to_string()), &dao_propose_burn_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_PROPOSE_MAIN_NS.to_string()), &dao_propose_main_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_EXEC_NS), &dao_exec_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_MINT_NS), &dao_mint_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_VOTE_BURN_NS), &dao_vote_burn_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_VOTE_MAIN_NS), &dao_vote_main_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_PROPOSE_BURN_NS), &dao_propose_burn_bin[..])?;
db_set(zkas_db, &serialize(&ZKAS_DAO_PROPOSE_MAIN_NS), &dao_propose_main_bin[..])?;
// Set up a database tree to hold the Merkle tree for DAO bullas
let dao_bulla_db = match db_lookup(cid, DAO_BULLA_TREE) {
@@ -177,7 +178,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
// Check the Merkle roots for the input coins are valid
let money_cid = ContractId::from(pallas::Base::from(u64::MAX - 420));
let coin_roots_db = db_lookup(money_cid, COIN_ROOTS_TREE)?;
let coin_roots_db = db_lookup(money_cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
for input in &params.inputs {
if !db_contains_key(coin_roots_db, &serialize(&input.merkle_root))? {
msg!("Invalid input Merkle root: {}", input.merkle_root);
@@ -221,8 +222,8 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
// Check the Merkle roots and nullifiers for the input coins are valid
let mut vote_nullifiers = vec![];
let mut all_vote_commit = pallas::Point::identity();
let money_roots_db = db_lookup(money_cid, COIN_ROOTS_TREE)?;
let money_nullifier_db = db_lookup(money_cid, NULLIFIERS_TREE)?;
let money_roots_db = db_lookup(money_cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
let money_nullifier_db = db_lookup(money_cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
for input in &params.inputs {
if !db_contains_key(money_roots_db, &serialize(&input.merkle_root))? {

View File

@@ -1,11 +1,14 @@
.POSIX:
# Cargo binary
CARGO ?= cargo
CARGO = cargo
# Zkas binary
ZKAS ?= ../../../zkas
# zkas compiler binary
ZKAS = ../../../zkas
# zkas circuit source files
ZKAS_SRC = $(shell find proof -type f -name '*.zk')
# zkas circuits
PROOFS_SRC = $(shell find proof -type f -name '*.zk')
PROOFS_BIN = $(PROOFS_SRC:=.bin)
# wasm source files
WASM_SRC = \
@@ -13,35 +16,31 @@ WASM_SRC = \
$(shell find ../../sdk -type f) \
$(shell find ../../serial -type f)
# zkas circuit bin files
ZKAS_BIN = $(ZKAS_SRC:=.bin)
# Contract WASM binaries
# wasm contract binary
WASM_BIN = money_contract.wasm
# Filter test to run
FILTER = ''
all: $(WASM_BIN)
all: $(ZKAS_BIN) $(WASM_BIN)
$(ZKAS_BIN): $(ZKAS_SRC)
$(ZKAS) $(basename $@) -o $@
money_contract.wasm: $(ZKAS_BIN) $(WASM_SRC)
$(WASM_BIN): $(WASM_SRC) $(PROOFS_BIN)
$(CARGO) build --release --package darkfi-money-contract --target wasm32-unknown-unknown
cp -f ../../../target/wasm32-unknown-unknown/release/darkfi_money_contract.wasm $@
test-drop-pay-swap: all
$(CARGO) test --release --features=no-entrypoint,client --package darkfi-money-contract --test drop_pay_swap
$(PROOFS_BIN): $(ZKAS) $(PROOFS_SRC)
$(ZKAS) $(basename $@) -o $@
test: test-drop-pay-swap
test-drop-pay-swap: all
$(CARGO) test --release --features=no-entrypoint,client \
--package darkfi-money-contract \
--test drop_pay_swap
bench:
$(CARGO) test --release --features=no-entrypoint,client \
--package darkfi-money-contract \
--test verification_bench $(FILTER)
clean:
rm -f $(ZKAS_BIN) $(WASM_BIN)
test: test-drop-pay-swap
.PHONY: all test clean
clean:
rm -f $(PROOFS_BIN) $(WASM_BIN)
.PHONY: all test-drop-pay-swap bench test clean

View File

@@ -1,10 +1,10 @@
constant "Burn" {
constant "Burn_V1" {
EcFixedPointShort VALUE_COMMIT_VALUE,
EcFixedPoint VALUE_COMMIT_RANDOM,
EcFixedPointBase NULLIFIER_K,
}
contract "Burn" {
contract "Burn_V1" {
# The value of this coin
Base value,
# The token ID
@@ -33,7 +33,7 @@ contract "Burn" {
Base signature_secret,
}
circuit "Burn" {
circuit "Burn_V1" {
# Poseidon hash of the nullifier
nullifier = poseidon_hash(secret, serial);
constrain_instance(nullifier);

View File

@@ -1,10 +1,10 @@
constant "Mint" {
constant "Mint_V1" {
EcFixedPointShort VALUE_COMMIT_VALUE,
EcFixedPoint VALUE_COMMIT_RANDOM,
EcFixedPointBase NULLIFIER_K,
}
contract "Mint" {
contract "Mint_V1" {
# X coordinate for public key
Base pub_x,
# Y coordinate for public key
@@ -27,7 +27,7 @@ contract "Mint" {
Scalar token_blind,
}
circuit "Mint" {
circuit "Mint_V1" {
# Poseidon hash of the coin
C = poseidon_hash(
pub_x,

View File

@@ -22,7 +22,7 @@ use darkfi_sdk::{
pedersen::{pedersen_commitment_base, pedersen_commitment_u64},
Coin, ContractId, MerkleNode, MerkleTree, PublicKey,
},
db::{db_contains_key, db_get, db_init, db_lookup, db_set, ZKAS_DB_NAME},
db::{db_contains_key, db_get, db_init, db_lookup, db_set, SMART_CONTRACT_ZKAS_DB_NAME},
error::ContractResult,
merkle::merkle_add,
msg,
@@ -82,18 +82,18 @@ darkfi_sdk::define_contract!(
);
// These are the different sled trees that will be created
pub const COIN_ROOTS_TREE: &str = "coin_roots";
pub const NULLIFIERS_TREE: &str = "nullifiers";
pub const INFO_TREE: &str = "info";
pub const MONEY_CONTRACT_COIN_ROOTS_TREE: &str = "coin_roots";
pub const MONEY_CONTRACT_NULLIFIERS_TREE: &str = "nullifiers";
pub const MONEY_CONTRACT_INFO_TREE: &str = "info";
// This is a key inside the info tree
pub const COIN_MERKLE_TREE: &str = "coin_tree";
pub const FAUCET_PUBKEYS: &str = "faucet_pubkeys";
pub const MONEY_CONTRACT_COIN_MERKLE_TREE: &str = "coin_tree";
pub const MONEY_CONTRACT_FAUCET_PUBKEYS: &str = "faucet_pubkeys";
/// zkas mint contract namespace
pub const ZKAS_MINT_NS: &str = "Mint";
pub const MONEY_CONTRACT_ZKAS_MINT_NS_V1: &str = "Mint_V1";
/// zkas burn contract namespace
pub const ZKAS_BURN_NS: &str = "Burn";
pub const MONEY_CONTRACT_ZKAS_BURN_NS_V1: &str = "Burn_V1";
/// This function runs when the contract is (re)deployed and initialized.
#[cfg(not(feature = "no-entrypoint"))]
@@ -105,12 +105,12 @@ fn init_contract(cid: ContractId, ix: &[u8]) -> ContractResult {
// The zkas circuits can simply be embedded in the wasm and set up by
// the initialization. Note that the tree should then be called "zkas".
// The lookups can then be done by `contract_id+_zkas+namespace`.
let zkas_db = match db_lookup(cid, ZKAS_DB_NAME) {
let zkas_db = match db_lookup(cid, SMART_CONTRACT_ZKAS_DB_NAME) {
Ok(v) => v,
Err(_) => db_init(cid, ZKAS_DB_NAME)?,
Err(_) => db_init(cid, SMART_CONTRACT_ZKAS_DB_NAME)?,
};
let mint_bincode = include_bytes!("../proof/mint.zk.bin");
let burn_bincode = include_bytes!("../proof/burn.zk.bin");
let mint_v1_bincode = include_bytes!("../proof/mint_v1.zk.bin");
let burn_v1_bincode = include_bytes!("../proof/burn_v1.zk.bin");
/* TODO: Do I really want to make zkas a dependency? Yeah, in the future.
For now we take anything.
@@ -123,26 +123,26 @@ fn init_contract(cid: ContractId, ix: &[u8]) -> ContractResult {
db_set(zkas_db, &serialize(&mint_namespace), &mint_bincode[..])?;
db_set(zkas_db, &serialize(&burn_namespace), &burn_bincode[..])?;
*/
db_set(zkas_db, &serialize(&ZKAS_MINT_NS.to_string()), &mint_bincode[..])?;
db_set(zkas_db, &serialize(&ZKAS_BURN_NS.to_string()), &burn_bincode[..])?;
db_set(zkas_db, &serialize(&MONEY_CONTRACT_ZKAS_MINT_NS_V1), &mint_v1_bincode[..])?;
db_set(zkas_db, &serialize(&MONEY_CONTRACT_ZKAS_BURN_NS_V1), &burn_v1_bincode[..])?;
// Set up a database tree to hold Merkle roots
let _ = match db_lookup(cid, COIN_ROOTS_TREE) {
let _ = match db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE) {
Ok(v) => v,
Err(_) => db_init(cid, COIN_ROOTS_TREE)?,
Err(_) => db_init(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?,
};
// Set up a database tree to hold nullifiers
let _ = match db_lookup(cid, NULLIFIERS_TREE) {
let _ = match db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE) {
Ok(v) => v,
Err(_) => db_init(cid, NULLIFIERS_TREE)?,
Err(_) => db_init(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?,
};
// Set up a database tree for arbitrary data
let info_db = match db_lookup(cid, INFO_TREE) {
let info_db = match db_lookup(cid, MONEY_CONTRACT_INFO_TREE) {
Ok(v) => v,
Err(_) => {
let info_db = db_init(cid, INFO_TREE)?;
let info_db = db_init(cid, MONEY_CONTRACT_INFO_TREE)?;
// Add a Merkle tree to the info db:
let coin_tree = MerkleTree::new(100);
let mut coin_tree_data = vec![];
@@ -150,13 +150,13 @@ fn init_contract(cid: ContractId, ix: &[u8]) -> ContractResult {
coin_tree_data.write_u32(0)?;
coin_tree.encode(&mut coin_tree_data)?;
db_set(info_db, &serialize(&COIN_MERKLE_TREE.to_string()), &coin_tree_data)?;
db_set(info_db, &serialize(&MONEY_CONTRACT_COIN_MERKLE_TREE), &coin_tree_data)?;
info_db
}
};
// Whitelisted faucets
db_set(info_db, &serialize(&FAUCET_PUBKEYS.to_string()), &serialize(&faucet_pubkeys))?;
db_set(info_db, &serialize(&MONEY_CONTRACT_FAUCET_PUBKEYS), &serialize(&faucet_pubkeys))?;
Ok(())
}
@@ -187,7 +187,7 @@ fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
let (sig_x, sig_y) = input.signature_public.xy();
zk_public_values.push((
ZKAS_BURN_NS.to_string(),
MONEY_CONTRACT_ZKAS_BURN_NS_V1.to_string(),
vec![
input.nullifier.inner(),
*value_coords.x(),
@@ -209,7 +209,7 @@ fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
let token_coords = output.token_commit.to_affine().coordinates().unwrap();
zk_public_values.push((
ZKAS_MINT_NS.to_string(),
MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string(),
vec![
//output.coin.inner(),
output.coin,
@@ -253,11 +253,11 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
assert!(params.clear_inputs.len() + params.inputs.len() > 0);
assert!(!params.outputs.is_empty());
let info_db = db_lookup(cid, INFO_TREE)?;
let nullifier_db = db_lookup(cid, NULLIFIERS_TREE)?;
let coin_roots_db = db_lookup(cid, COIN_ROOTS_TREE)?;
let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
let Some(faucet_pubkeys) = db_get(info_db, &serialize(&FAUCET_PUBKEYS.to_string()))? else {
let Some(faucet_pubkeys) = db_get(info_db, &serialize(&MONEY_CONTRACT_FAUCET_PUBKEYS))? else {
msg!("[Transfer] Error: Missing faucet pubkeys from info db");
return Err(ContractError::Internal);
};
@@ -292,7 +292,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
// The nullifiers should not already exist. It is the double-spend protection.
if new_nullifiers.contains(&input.nullifier) ||
db_contains_key(nullifier_db, &serialize(&input.nullifier))?
db_contains_key(nullifiers_db, &serialize(&input.nullifier))?
{
msg!("[Transfer] Error: Duplicate nullifier found in input {}", i);
return Err(ContractError::Custom(22))
@@ -354,8 +354,8 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
msg!("[OtcSwap] Entered match arm");
let params: MoneyTransferParams = deserialize(&self_.data[1..])?;
let nullifier_db = db_lookup(cid, NULLIFIERS_TREE)?;
let coin_roots_db = db_lookup(cid, COIN_ROOTS_TREE)?;
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
// State transition for OTC swaps
// For now we enforce 2 inputs and 2 outputs, which means the coins
@@ -401,7 +401,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
// The nullifiers should not already exist. It is the double-spend protection.
if new_nullifiers.contains(&input.nullifier) ||
db_contains_key(nullifier_db, &serialize(&input.nullifier))?
db_contains_key(nullifiers_db, &serialize(&input.nullifier))?
{
msg!("[OtcSwap] Error: Duplicate nullifier found in input {}", i);
return Err(ContractError::Custom(22))
@@ -453,9 +453,9 @@ fn process_update(cid: ContractId, update_data: &[u8]) -> ContractResult {
MoneyFunction::Transfer | MoneyFunction::OtcSwap => {
let update: MoneyTransferUpdate = deserialize(&update_data[1..])?;
let info_db = db_lookup(cid, INFO_TREE)?;
let nullifiers_db = db_lookup(cid, NULLIFIERS_TREE)?;
let coin_roots_db = db_lookup(cid, COIN_ROOTS_TREE)?;
let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
for nullifier in update.nullifiers {
db_set(nullifiers_db, &serialize(&nullifier), &[])?;
@@ -463,7 +463,12 @@ fn process_update(cid: ContractId, update_data: &[u8]) -> ContractResult {
msg!("Adding coins {:?} to Merkle tree", update.coins);
let coins: Vec<_> = update.coins.iter().map(|x| MerkleNode::from(x.inner())).collect();
merkle_add(info_db, coin_roots_db, &serialize(&COIN_MERKLE_TREE.to_string()), &coins)?;
merkle_add(
info_db,
coin_roots_db,
&serialize(&MONEY_CONTRACT_COIN_MERKLE_TREE),
&coins,
)?;
Ok(())
}

View File

@@ -25,7 +25,7 @@ use super::{
};
// This might not be the right place for this constant...
pub const ZKAS_DB_NAME: &str = "_zkas";
pub const SMART_CONTRACT_ZKAS_DB_NAME: &str = "_zkas";
pub type DbHandle = u32;