Skip to main content

aztec_core/
constants.rs

1//! Well-known protocol contract addresses and domain separators.
2//!
3//! These addresses and constants are deterministic and identical across all Aztec networks.
4
5use crate::types::{AztecAddress, Fr};
6
7/// Well-known protocol contract addresses.
8pub mod protocol_contract_address {
9    use super::*;
10
11    /// The Fee Juice contract — manages fee token balances and claims.
12    pub fn fee_juice() -> AztecAddress {
13        AztecAddress(Fr::from(5u64))
14    }
15
16    /// The AuthRegistry protocol contract — manages public authorization witnesses.
17    pub fn auth_registry() -> AztecAddress {
18        AztecAddress(Fr::from(1u64))
19    }
20
21    /// The Contract Instance Deployer — registers contract instances on-chain.
22    pub fn contract_instance_deployer() -> AztecAddress {
23        AztecAddress(Fr::from(2u64))
24    }
25
26    /// The Contract Instance Registry — canonical public deployment registry.
27    pub fn contract_instance_registry() -> AztecAddress {
28        contract_instance_deployer()
29    }
30
31    /// The Contract Class Registerer — publishes contract classes on-chain.
32    pub fn contract_class_registerer() -> AztecAddress {
33        AztecAddress(Fr::from(3u64))
34    }
35
36    /// The Contract Class Registry — canonical class publication registry.
37    pub fn contract_class_registry() -> AztecAddress {
38        contract_class_registerer()
39    }
40
41    /// The Multi-Call Entrypoint — batches multiple calls in one tx.
42    pub fn multi_call_entrypoint() -> AztecAddress {
43        AztecAddress(Fr::from(4u64))
44    }
45}
46
47/// Domain separators used in Poseidon2 hashing throughout the protocol.
48///
49/// These must match the TS constants in `constants.gen.ts`.
50pub mod domain_separator {
51    /// Domain separator for authwit inner hash.
52    ///
53    /// TS: `DomainSeparator.AUTHWIT_INNER = 221354163`
54    pub const AUTHWIT_INNER: u32 = 221_354_163;
55
56    /// Domain separator for authwit outer hash.
57    ///
58    /// TS: `DomainSeparator.AUTHWIT_OUTER = 3283595782`
59    pub const AUTHWIT_OUTER: u32 = 3_283_595_782;
60
61    /// Domain separator for function args hashing.
62    ///
63    /// TS: `DomainSeparator.FUNCTION_ARGS = 3576554347`
64    pub const FUNCTION_ARGS: u32 = 3_576_554_347;
65
66    /// Domain separator for public function calldata hashing.
67    ///
68    /// TS: `DomainSeparator.PUBLIC_CALLDATA = 2760353947`
69    pub const PUBLIC_CALLDATA: u32 = 2_760_353_947;
70
71    /// Domain separator for public keys hash computation.
72    pub const PUBLIC_KEYS_HASH: u32 = 777_457_226;
73
74    /// Domain separator for partial address / salted initialization hash.
75    pub const PARTIAL_ADDRESS: u32 = 2_103_633_018;
76
77    /// Domain separator for contract class ID computation.
78    pub const CONTRACT_CLASS_ID: u32 = 3_923_495_515;
79
80    /// Domain separator for private function leaf hashing.
81    pub const PRIVATE_FUNCTION_LEAF: u32 = 1_389_398_688;
82
83    /// Domain separator for public bytecode commitment.
84    pub const PUBLIC_BYTECODE: u32 = 260_313_585;
85
86    /// Domain separator for initialization hash computation.
87    pub const INITIALIZER: u32 = 385_396_519;
88
89    /// Domain separator for contract address V1 derivation.
90    pub const CONTRACT_ADDRESS_V1: u32 = 1_788_365_517;
91
92    /// Master nullifier hiding key derivation.
93    ///
94    /// TS: `DomainSeparator.NHK_M = 242137788`
95    pub const NHK_M: u32 = 242_137_788;
96
97    /// Master incoming viewing secret key derivation.
98    ///
99    /// TS: `DomainSeparator.IVSK_M = 2747825907`
100    pub const IVSK_M: u32 = 2_747_825_907;
101
102    /// Master outgoing viewing secret key derivation.
103    ///
104    /// TS: `DomainSeparator.OVSK_M = 4272201051`
105    pub const OVSK_M: u32 = 4_272_201_051;
106
107    /// Master tagging secret key derivation.
108    ///
109    /// TS: `DomainSeparator.TSK_M = 1546190975`
110    pub const TSK_M: u32 = 1_546_190_975;
111
112    /// Secret hash (for L1-L2 messages and TransparentNote).
113    ///
114    /// TS: `DomainSeparator.SECRET_HASH = 4199652938`
115    pub const SECRET_HASH: u32 = 4_199_652_938;
116
117    /// Domain separator for signature payload hashing (entrypoint encoding).
118    ///
119    /// TS: `DomainSeparator.SIGNATURE_PAYLOAD = 2279843839`
120    pub const SIGNATURE_PAYLOAD: u32 = 2_279_843_839;
121}
122
123// Size constants for deployment computations.
124
125/// Height of the private functions Merkle tree.
126pub const FUNCTION_TREE_HEIGHT: usize = 7;
127
128/// Maximum number of field elements in packed public bytecode.
129pub const MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS: usize = 3000;
130
131/// Maximum height of the artifact function tree.
132pub const ARTIFACT_FUNCTION_TREE_MAX_HEIGHT: usize = 7;
133
134/// Maximum processable L2 gas for a transaction.
135pub const MAX_PROCESSABLE_L2_GAS: u64 = 6_540_000;
136
137/// Bytecode capsule slot used by the Contract Class Registry.
138pub fn contract_class_registry_bytecode_capsule_slot() -> Fr {
139    Fr::from_hex("0x1f61038721b052d5389449bf44f73c817146aedfab1ef13d37f16ce928df1fb7")
140        .expect("valid contract class registry capsule slot constant")
141}
142
143#[cfg(test)]
144#[allow(clippy::expect_used)]
145mod tests {
146    use super::*;
147
148    #[test]
149    fn fee_juice_address_is_5() {
150        let addr = protocol_contract_address::fee_juice();
151        assert_eq!(addr, AztecAddress(Fr::from(5u64)));
152    }
153
154    #[test]
155    fn auth_registry_address_is_1() {
156        let addr = protocol_contract_address::auth_registry();
157        assert_eq!(addr, AztecAddress(Fr::from(1u64)));
158    }
159
160    #[test]
161    fn domain_separator_values_match_ts() {
162        assert_eq!(domain_separator::AUTHWIT_INNER, 221_354_163);
163        assert_eq!(domain_separator::AUTHWIT_OUTER, 3_283_595_782);
164        assert_eq!(domain_separator::FUNCTION_ARGS, 3_576_554_347);
165        assert_eq!(domain_separator::PUBLIC_CALLDATA, 2_760_353_947);
166        assert_eq!(domain_separator::PUBLIC_KEYS_HASH, 777_457_226);
167        assert_eq!(domain_separator::PARTIAL_ADDRESS, 2_103_633_018);
168        assert_eq!(domain_separator::CONTRACT_CLASS_ID, 3_923_495_515);
169        assert_eq!(domain_separator::PRIVATE_FUNCTION_LEAF, 1_389_398_688);
170        assert_eq!(domain_separator::PUBLIC_BYTECODE, 260_313_585);
171        assert_eq!(domain_separator::INITIALIZER, 385_396_519);
172        assert_eq!(domain_separator::CONTRACT_ADDRESS_V1, 1_788_365_517);
173        // Key derivation separators
174        assert_eq!(domain_separator::NHK_M, 242_137_788);
175        assert_eq!(domain_separator::IVSK_M, 2_747_825_907);
176        assert_eq!(domain_separator::OVSK_M, 4_272_201_051);
177        assert_eq!(domain_separator::TSK_M, 1_546_190_975);
178        assert_eq!(domain_separator::SECRET_HASH, 4_199_652_938);
179    }
180
181    #[test]
182    fn protocol_contract_addresses() {
183        assert_eq!(
184            protocol_contract_address::contract_instance_deployer(),
185            AztecAddress(Fr::from(2u64))
186        );
187        assert_eq!(
188            protocol_contract_address::contract_class_registerer(),
189            AztecAddress(Fr::from(3u64))
190        );
191        assert_eq!(
192            protocol_contract_address::multi_call_entrypoint(),
193            AztecAddress(Fr::from(4u64))
194        );
195    }
196
197    #[test]
198    fn size_constants() {
199        assert_eq!(super::FUNCTION_TREE_HEIGHT, 7);
200        assert_eq!(super::MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, 3000);
201        assert_eq!(super::ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, 7);
202        assert_eq!(super::MAX_PROCESSABLE_L2_GAS, 6_540_000);
203    }
204
205    #[test]
206    fn capsule_slot_constant_matches_ts() {
207        assert_eq!(
208            contract_class_registry_bytecode_capsule_slot(),
209            Fr::from_hex("0x1f61038721b052d5389449bf44f73c817146aedfab1ef13d37f16ce928df1fb7")
210                .expect("valid slot")
211        );
212    }
213}