|
@@ -20,7 +20,6 @@
|
|
|
use crate::{
|
|
use crate::{
|
|
|
error::MapError, ContractFunction, MAP_CONTRACT_ENTRIES_TREE, MAP_CONTRACT_ZKAS_SET_NS,
|
|
error::MapError, ContractFunction, MAP_CONTRACT_ENTRIES_TREE, MAP_CONTRACT_ZKAS_SET_NS,
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
use darkfi_sdk::{
|
|
use darkfi_sdk::{
|
|
|
crypto::{poseidon_hash, ContractId, PublicKey},
|
|
crypto::{poseidon_hash, ContractId, PublicKey},
|
|
|
db::{db_get, db_init, db_lookup, db_set, zkas_db_set},
|
|
db::{db_get, db_init, db_lookup, db_set, zkas_db_set},
|
|
@@ -30,16 +29,15 @@ use darkfi_sdk::{
|
|
|
util::set_return_data,
|
|
util::set_return_data,
|
|
|
ContractCall,
|
|
ContractCall,
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
|
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
|
|
-
|
|
|
|
|
use crate::model::{SetParamsV1, SetUpdateV1};
|
|
use crate::model::{SetParamsV1, SetUpdateV1};
|
|
|
|
|
|
|
|
// A macro defining the 4 entrypoints
|
|
// A macro defining the 4 entrypoints
|
|
|
// init: called during (re)deployment
|
|
// init: called during (re)deployment
|
|
|
-// metadata: called during contract message call, first
|
|
|
|
|
-// exec: second
|
|
|
|
|
-// apply: last
|
|
|
|
|
|
|
+// The rest are called during a message call to the contract
|
|
|
|
|
+// metadata: called first
|
|
|
|
|
+// exec: called second
|
|
|
|
|
+// apply: called last
|
|
|
darkfi_sdk::define_contract!(
|
|
darkfi_sdk::define_contract!(
|
|
|
init: init_contract,
|
|
init: init_contract,
|
|
|
exec: process_instruction,
|
|
exec: process_instruction,
|
|
@@ -48,8 +46,8 @@ darkfi_sdk::define_contract!(
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
// init takes:
|
|
// init takes:
|
|
|
-// - the contract ID given by the runtime
|
|
|
|
|
-// - a payload in the form of a slice of bytes
|
|
|
|
|
|
|
+// - the contract ID given by the host
|
|
|
|
|
+// - deployment payload
|
|
|
// then:
|
|
// then:
|
|
|
// - initializes all the databases
|
|
// - initializes all the databases
|
|
|
// - and bundle zkas circuits that will gate this contract's functions
|
|
// - and bundle zkas circuits that will gate this contract's functions
|
|
@@ -60,8 +58,7 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
|
|
let set_v1_bincode = include_bytes!("../proof/set_v1.zk.bin");
|
|
let set_v1_bincode = include_bytes!("../proof/set_v1.zk.bin");
|
|
|
|
|
|
|
|
// When init is called, create a verifying key for this circuit.
|
|
// When init is called, create a verifying key for this circuit.
|
|
|
- // The verifying key will later be used to verify proofs that are
|
|
|
|
|
- // supposedly constrained by the `set` circuit.
|
|
|
|
|
|
|
+ // The verifying key will later be used to verify proofs generated by the `set` circuit.
|
|
|
zkas_db_set(&set_v1_bincode[..])?;
|
|
zkas_db_set(&set_v1_bincode[..])?;
|
|
|
|
|
|
|
|
// If this is a redeployment, skip the databsae initialization,
|
|
// If this is a redeployment, skip the databsae initialization,
|
|
@@ -70,7 +67,7 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
|
|
// name registries.
|
|
// name registries.
|
|
|
if db_lookup(cid, MAP_CONTRACT_ENTRIES_TREE).is_err() {
|
|
if db_lookup(cid, MAP_CONTRACT_ENTRIES_TREE).is_err() {
|
|
|
// "Under the hood" are comments for the studious ones about how
|
|
// "Under the hood" are comments for the studious ones about how
|
|
|
- // something works in its implementation.
|
|
|
|
|
|
|
+ // something works inside the host.
|
|
|
//
|
|
//
|
|
|
// Under the hood: db_init is only allowed callable inside init.
|
|
// Under the hood: db_init is only allowed callable inside init.
|
|
|
// https://github.com/darkrenaissance/darkfi/blob/35405831e366eaa74522ab14645a5a05ce5cfa1e/src/runtime/import/db.rs#L55-L58
|
|
// https://github.com/darkrenaissance/darkfi/blob/35405831e366eaa74522ab14645a5a05ce5cfa1e/src/runtime/import/db.rs#L55-L58
|
|
@@ -83,10 +80,9 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
|
|
Ok(())
|
|
Ok(())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// The `metadata` entrypoint takes 1) its contract ID and 2) payload,
|
|
|
|
|
-// but the payload is this call's index, and the calls themselves
|
|
|
|
|
|
|
+// The `metadata` entrypoint takes 1) contract ID and 2) (call's idx, calls),
|
|
|
// then it is supposed to return the public keys and public inputs, for
|
|
// then it is supposed to return the public keys and public inputs, for
|
|
|
-// verifying the signatures and zero knowledge proofs, respectively.
|
|
|
|
|
|
|
+// the host to verify the signatures and zero knowledge proofs, respectively.
|
|
|
fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
|
|
fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
|
|
|
// Parse the index and calls from the payload
|
|
// Parse the index and calls from the payload
|
|
|
let (call_idx, calls): (u32, Vec<ContractCall>) = deserialize(ix)?;
|
|
let (call_idx, calls): (u32, Vec<ContractCall>) = deserialize(ix)?;
|
|
@@ -153,8 +149,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
|
|
|
poseidon_hash([pallas::Base::zero(), params.key])
|
|
poseidon_hash([pallas::Base::zero(), params.key])
|
|
|
// else slot = poseidon_hash(account, key).
|
|
// else slot = poseidon_hash(account, key).
|
|
|
// That is, if you don't have the account's secret,
|
|
// That is, if you don't have the account's secret,
|
|
|
- // you cannot write to the same slot assuming second preimage
|
|
|
|
|
- // resistance.
|
|
|
|
|
|
|
+ // you cannot overwrite the names written by the account.
|
|
|
} else {
|
|
} else {
|
|
|
poseidon_hash([params.account, params.key])
|
|
poseidon_hash([params.account, params.key])
|
|
|
};
|
|
};
|