contract/money: Token Freeze API

This commit is contained in:
parazyd
2023-02-23 13:20:20 +01:00
parent 41cdbbbe13
commit bafe4a4241
4 changed files with 102 additions and 4 deletions

View File

@@ -12,8 +12,9 @@ circuit "TokenFreeze_V1" {
mint_public = ec_mul_base(mint_authority, NULLIFIER_K);
mint_x = ec_get_x(mint_public);
mint_y = ec_get_y(mint_public);
constrain_instance(mint_x);
constrain_instance(mint_y);
# I don't think we need to enforce these two as public inputs
#constrain_instance(mint_x);
#constrain_instance(mint_y);
# Derive the token ID
token_id = poseidon_hash(mint_x, mint_y);

View File

@@ -0,0 +1,94 @@
/* This file is part of DarkFi (https://dark.fi)
*
* Copyright (C) 2020-2023 Dyne.org foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi::{
zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
zkas::ZkBinary,
Result,
};
use darkfi_sdk::{
crypto::{poseidon_hash, Keypair, TokenId},
pasta::pallas,
};
use log::{debug, info};
use rand::rngs::OsRng;
use crate::model::MoneyFreezeParamsV1;
pub struct FreezeCallDebris {
pub params: MoneyFreezeParamsV1,
pub proofs: Vec<Proof>,
}
pub struct TokenFreezeRevealed {
pub token_id: TokenId,
}
impl TokenFreezeRevealed {
pub fn to_vec(&self) -> Vec<pallas::Base> {
vec![self.token_id.inner()]
}
}
/// Struct holding necessary information to build a `Money::FreezeV1` contract call.
pub struct FreezeCallBuilder {
/// Mint authority keypair
pub mint_authority: Keypair,
/// `TokenFreeze_V1` zkas circuit ZkBinary
pub token_freeze_zkbin: ZkBinary,
/// Proving key for the `TokenFreeze_V1` zk circuit,
pub token_freeze_pk: ProvingKey,
}
impl FreezeCallBuilder {
pub fn build(&self) -> Result<FreezeCallDebris> {
debug!("Building Money::FreezeV1 contract call");
// For the Freeze call, we just need to produce a valid signature,
// and enforce the correct derivation inside ZK.
info!("Creating token freeze proof");
let (proof, _public_inputs) = create_token_freeze_proof(
&self.token_freeze_zkbin,
&self.token_freeze_pk,
&self.mint_authority,
)?;
let params = MoneyFreezeParamsV1 { signature_public: self.mint_authority.public };
let debris = FreezeCallDebris { params, proofs: vec![proof] };
Ok(debris)
}
}
pub(crate) fn create_token_freeze_proof(
zkbin: &ZkBinary,
pk: &ProvingKey,
mint_authority: &Keypair,
) -> Result<(Proof, TokenFreezeRevealed)> {
let (mint_x, mint_y) = mint_authority.public.xy();
let token_id = TokenId::from(poseidon_hash([mint_x, mint_y]));
let public_inputs = TokenFreezeRevealed { token_id };
let prover_witnesses = vec![Witness::Base(Value::known(mint_authority.secret.inner()))];
let circuit = ZkCircuit::new(prover_witnesses, zkbin.clone());
let proof = Proof::create(pk, &[circuit], &public_inputs.to_vec(), &mut OsRng)?;
Ok((proof, public_inputs))
}

View File

@@ -41,6 +41,9 @@ pub mod swap_v1;
/// `Money::MintV1` API
pub mod mint_v1;
/// `Money::FreezeV1` API
pub mod freeze_v1;
// Wallet SQL table constant names. These have to represent the `wallet.sql`
// SQL schema.
// TODO: They should also be prefixed with the contract ID to avoid collisions.

View File

@@ -49,8 +49,8 @@ pub(crate) fn money_freeze_get_metadata_v1(
let (mint_x, mint_y) = params.signature_public.xy();
let token_id = poseidon_hash([mint_x, mint_y]);
zk_public_inputs
.push((MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1.to_string(), vec![mint_x, mint_y, token_id]));
// In ZK we just verify that the token ID is properly derived from the authority.
zk_public_inputs.push((MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1.to_string(), vec![token_id]));
// Serialize everything gathered and return it
let mut metadata = vec![];