snarkvm_console_program/owner/
mod.rs

1// Copyright 2024-2025 Aleo Network Foundation
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16mod bytes;
17mod serialize;
18mod string;
19
20use snarkvm_console_account::{Address, PrivateKey, Signature};
21use snarkvm_console_network::Network;
22use snarkvm_console_types::prelude::*;
23
24#[derive(Copy, Clone, PartialEq, Eq, Hash)]
25pub struct ProgramOwner<N: Network> {
26    /// The address of the program owner.
27    address: Address<N>,
28    /// The signature of the program owner, over the deployment transaction ID.
29    signature: Signature<N>,
30}
31
32impl<N: Network> ProgramOwner<N> {
33    /// Initializes a new program owner.
34    pub fn new<R: Rng + CryptoRng>(private_key: &PrivateKey<N>, deployment_id: Field<N>, rng: &mut R) -> Result<Self> {
35        // Derive the address.
36        let address = Address::try_from(private_key)?;
37        // Sign the transaction ID.
38        let signature = private_key.sign(&[deployment_id], rng)?;
39        // Return the program owner.
40        Ok(Self { signature, address })
41    }
42
43    /// Initializes a new program owner from an address and signature.
44    pub fn from(address: Address<N>, signature: Signature<N>) -> Self {
45        Self { address, signature }
46    }
47
48    /// Returns the address of the program owner.
49    pub const fn address(&self) -> Address<N> {
50        self.address
51    }
52
53    /// Returns the signature of the program owner.
54    pub const fn signature(&self) -> &Signature<N> {
55        &self.signature
56    }
57
58    /// Verify that the signature is valid for the given deployment ID.
59    pub fn verify(&self, deployment_id: Field<N>) -> bool {
60        self.signature.verify(&self.address, &[deployment_id])
61    }
62}
63
64#[cfg(test)]
65pub(crate) mod test_helpers {
66    use super::*;
67    use snarkvm_console_network::MainnetV0;
68
69    use once_cell::sync::OnceCell;
70
71    type CurrentNetwork = MainnetV0;
72
73    pub(crate) fn sample_program_owner() -> ProgramOwner<CurrentNetwork> {
74        static INSTANCE: OnceCell<ProgramOwner<CurrentNetwork>> = OnceCell::new();
75        *INSTANCE.get_or_init(|| {
76            // Initialize the RNG.
77            let rng = &mut TestRng::default();
78
79            // Initialize a private key.
80            let private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
81
82            // Initialize a deployment ID.
83            let deployment_id: Field<CurrentNetwork> = rng.gen();
84
85            // Return the program owner.
86            ProgramOwner::new(&private_key, deployment_id, rng).unwrap()
87        })
88    }
89
90    #[test]
91    fn test_verify_program_owner() {
92        // Initialize the RNG.
93        let rng = &mut TestRng::default();
94
95        // Initialize a private key.
96        let private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
97
98        // Initialize a deployment ID.
99        let deployment_id: Field<CurrentNetwork> = rng.gen();
100
101        // Construct the program owner.
102        let owner = ProgramOwner::new(&private_key, deployment_id, rng).unwrap();
103        // Ensure that the program owner is verified for the given deployment ID.
104        assert!(owner.verify(deployment_id));
105
106        // Ensure that the program owner is not verified for a different deployment ID.
107        let incorrect_deployment_id: Field<CurrentNetwork> = rng.gen();
108        assert!(!owner.verify(incorrect_deployment_id));
109    }
110}