mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
Clean up makefiles and set the ground floor for upgradable zkas circuits.
This commit is contained in:
51
Makefile
51
Makefile
@@ -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
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
@@ -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"))
|
||||
};
|
||||
|
||||
|
||||
@@ -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"))
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ¶ms.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 ¶ms.inputs {
|
||||
if !db_contains_key(money_roots_db, &serialize(&input.merkle_root))? {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user