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
31lazy_static! {
32 pub static ref CONTRACT_ID_PREFIX: pallas::Base = pallas::Base::from(42);
39
40 pub static ref MONEY_CONTRACT_ID: ContractId =
44 ContractId::from(poseidon_hash([*CONTRACT_ID_PREFIX, pallas::Base::zero(), pallas::Base::from(0)]));
45
46 pub static ref DAO_CONTRACT_ID: ContractId =
50 ContractId::from(poseidon_hash([*CONTRACT_ID_PREFIX, pallas::Base::zero(), pallas::Base::from(1)]));
51
52 pub static ref DEPLOYOOOR_CONTRACT_ID: ContractId =
56 ContractId::from(poseidon_hash([*CONTRACT_ID_PREFIX, pallas::Base::zero(), pallas::Base::from(2)]));
57
58 pub static ref NATIVE_CONTRACT_IDS_BYTES: [[u8; 32]; 3] =
60 [MONEY_CONTRACT_ID.to_bytes(), DAO_CONTRACT_ID.to_bytes(), DEPLOYOOOR_CONTRACT_ID.to_bytes()];
61
62 pub static ref NATIVE_CONTRACT_ZKAS_DB_NAMES: [[u8; 32]; 3] = [
64 MONEY_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
65 DAO_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
66 DEPLOYOOOR_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
67 ];
68}
69
70#[derive(Copy, Clone, Debug, Eq, PartialEq, SerialEncodable, SerialDecodable)]
72pub struct ContractId(pallas::Base);
73
74impl ContractId {
75 pub fn derive(deploy_key: SecretKey) -> Self {
77 let public_key = PublicKey::from_secret(deploy_key);
78 let (x, y) = public_key.xy();
79 let hash = poseidon_hash([*CONTRACT_ID_PREFIX, x, y]);
80 Self(hash)
81 }
82
83 pub fn derive_public(public_key: PublicKey) -> Self {
85 let (x, y) = public_key.xy();
86 let hash = poseidon_hash([*CONTRACT_ID_PREFIX, x, y]);
87 Self(hash)
88 }
89
90 pub fn inner(&self) -> pallas::Base {
92 self.0
93 }
94
95 pub fn from_bytes(x: [u8; 32]) -> Result<Self, ContractError> {
97 match pallas::Base::from_repr(x).into() {
98 Some(v) => Ok(Self(v)),
99 None => Err(ContractError::IoError(
100 "Failed to instantiate ContractId from bytes".to_string(),
101 )),
102 }
103 }
104
105 pub fn to_bytes(&self) -> [u8; 32] {
107 self.0.to_repr()
108 }
109
110 pub fn hash_state_id(&self, tree_name: &str) -> [u8; 32] {
113 let mut hasher = blake3::Hasher::new();
114 hasher.update(&serialize(self));
115 hasher.update(tree_name.as_bytes());
116 let id = hasher.finalize();
117 *id.as_bytes()
118 }
119}
120
121use core::str::FromStr;
122crate::fp_from_bs58!(ContractId);
123crate::fp_to_bs58!(ContractId);
124crate::ty_from_fp!(ContractId);