darkfi_sdk/crypto/
contract_id.rs1#[cfg(feature = "async")]
20use darkfi_serial::async_trait;
21use darkfi_serial::{serialize, SerialDecodable, SerialEncodable};
22use lazy_static::lazy_static;
23use pasta_curves::{group::ff::PrimeField, pallas};
24
25use super::{poseidon_hash, PublicKey, SecretKey};
26use crate::error::ContractError;
27
28pub const SMART_CONTRACT_ZKAS_DB_NAME: &str = "_zkas";
30
31pub const SMART_CONTRACT_MONOTREE_DB_NAME: &str = "_monotree";
33
34lazy_static! {
35 pub static ref CONTRACT_ID_PREFIX: pallas::Base = pallas::Base::from(42);
42
43 pub static ref MONEY_CONTRACT_ID: ContractId =
47 ContractId::from(poseidon_hash([*CONTRACT_ID_PREFIX, pallas::Base::zero(), pallas::Base::from(0)]));
48
49 pub static ref DAO_CONTRACT_ID: ContractId =
53 ContractId::from(poseidon_hash([*CONTRACT_ID_PREFIX, pallas::Base::zero(), pallas::Base::from(1)]));
54
55 pub static ref DEPLOYOOOR_CONTRACT_ID: ContractId =
59 ContractId::from(poseidon_hash([*CONTRACT_ID_PREFIX, pallas::Base::zero(), pallas::Base::from(2)]));
60
61 pub static ref NATIVE_CONTRACT_IDS_BYTES: [[u8; 32]; 3] =
63 [MONEY_CONTRACT_ID.to_bytes(), DAO_CONTRACT_ID.to_bytes(), DEPLOYOOOR_CONTRACT_ID.to_bytes()];
64
65 pub static ref NATIVE_CONTRACT_ZKAS_DB_NAMES: [[u8; 32]; 3] = [
67 MONEY_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
68 DAO_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
69 DEPLOYOOOR_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
70 ];
71}
72
73#[derive(Copy, Clone, Debug, Eq, PartialEq, SerialEncodable, SerialDecodable)]
75pub struct ContractId(pallas::Base);
76
77impl ContractId {
78 pub fn derive(deploy_key: SecretKey) -> Self {
80 let public_key = PublicKey::from_secret(deploy_key);
81 let (x, y) = public_key.xy();
82 let hash = poseidon_hash([*CONTRACT_ID_PREFIX, x, y]);
83 Self(hash)
84 }
85
86 pub fn derive_public(public_key: PublicKey) -> Self {
88 let (x, y) = public_key.xy();
89 let hash = poseidon_hash([*CONTRACT_ID_PREFIX, x, y]);
90 Self(hash)
91 }
92
93 pub fn inner(&self) -> pallas::Base {
95 self.0
96 }
97
98 pub fn from_bytes(x: [u8; 32]) -> Result<Self, ContractError> {
100 match pallas::Base::from_repr(x).into() {
101 Some(v) => Ok(Self(v)),
102 None => Err(ContractError::IoError(
103 "Failed to instantiate ContractId from bytes".to_string(),
104 )),
105 }
106 }
107
108 pub fn to_bytes(&self) -> [u8; 32] {
110 self.0.to_repr()
111 }
112
113 pub fn hash_state_id(&self, tree_name: &str) -> [u8; 32] {
116 let mut hasher = blake3::Hasher::new();
117 hasher.update(&serialize(self));
118 hasher.update(tree_name.as_bytes());
119 let id = hasher.finalize();
120 *id.as_bytes()
121 }
122}
123
124use core::str::FromStr;
125crate::fp_from_bs58!(ContractId);
126crate::fp_to_bs58!(ContractId);
127crate::ty_from_fp!(ContractId);