Skip to main content

snarkvm_circuit_types_address/
lib.rs

1// Copyright (c) 2019-2026 Provable Inc.
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
16#![forbid(unsafe_code)]
17#![cfg_attr(test, allow(clippy::assertions_on_result_states))]
18
19extern crate snarkvm_console_types_address as console;
20
21mod helpers;
22
23mod compare;
24mod equal;
25mod ternary;
26
27#[cfg(test)]
28use console::{TestRng, Uniform};
29#[cfg(test)]
30use snarkvm_circuit_environment::{assert_count, assert_output_mode, assert_scope, count, output_mode};
31
32use snarkvm_circuit_environment::prelude::*;
33use snarkvm_circuit_types_boolean::Boolean;
34use snarkvm_circuit_types_field::Field;
35use snarkvm_circuit_types_group::Group;
36use snarkvm_circuit_types_scalar::Scalar;
37
38use core::str::FromStr;
39
40#[derive(Clone)]
41pub struct Address<E: Environment>(Group<E>);
42
43impl<E: Environment> AddressTrait for Address<E> {}
44
45impl<E: Environment> Address<E> {
46    /// Initializes the zero address.
47    #[inline]
48    pub fn zero() -> Self {
49        Self(Group::zero())
50    }
51}
52
53impl<E: Environment> Inject for Address<E> {
54    type Primitive = console::Address<E::Network>;
55
56    /// Initializes a new instance of an address.
57    fn new(mode: Mode, address: Self::Primitive) -> Self {
58        Self(Group::new(mode, *address))
59    }
60}
61
62impl<E: Environment> Eject for Address<E> {
63    type Primitive = console::Address<E::Network>;
64
65    /// Ejects the mode of the address.
66    fn eject_mode(&self) -> Mode {
67        self.0.eject_mode()
68    }
69
70    /// Ejects the address.
71    fn eject_value(&self) -> Self::Primitive {
72        Self::Primitive::new(self.0.eject_value())
73    }
74}
75
76impl<E: Environment> Parser for Address<E> {
77    /// Parses a string into an address circuit.
78    #[inline]
79    fn parse(string: &str) -> ParserResult<Self> {
80        // Parse the address from the string.
81        let (string, address) = console::Address::parse(string)?;
82        // Parse the mode from the string.
83        let (string, mode) = opt(pair(tag("."), Mode::parse))(string)?;
84
85        match mode {
86            Some((_, mode)) => Ok((string, Address::new(mode, address))),
87            None => Ok((string, Address::new(Mode::Constant, address))),
88        }
89    }
90}
91
92impl<E: Environment> FromStr for Address<E> {
93    type Err = Error;
94
95    /// Parses a string into a address.
96    #[inline]
97    fn from_str(string: &str) -> Result<Self> {
98        match Self::parse(string) {
99            Ok((remainder, object)) => {
100                // Ensure the remainder is empty.
101                ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
102                // Return the object.
103                Ok(object)
104            }
105            Err(error) => bail!("Failed to parse string. {error}"),
106        }
107    }
108}
109
110impl<E: Environment> TypeName for Address<E> {
111    /// Returns the type name of the circuit as a string.
112    #[inline]
113    fn type_name() -> &'static str {
114        console::Address::<E::Network>::type_name()
115    }
116}
117
118impl<E: Environment> Debug for Address<E> {
119    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120        Display::fmt(self, f)
121    }
122}
123
124impl<E: Environment> Display for Address<E> {
125    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126        write!(f, "{}.{}", self.eject_value(), self.eject_mode())
127    }
128}
129
130impl<E: Environment> From<Address<E>> for LinearCombination<E::BaseField> {
131    fn from(address: Address<E>) -> Self {
132        From::from(&address)
133    }
134}
135
136impl<E: Environment> From<&Address<E>> for LinearCombination<E::BaseField> {
137    fn from(address: &Address<E>) -> Self {
138        From::from(address.to_field())
139    }
140}
141
142#[cfg(test)]
143mod tests {
144    use super::*;
145    use snarkvm_circuit_environment::Circuit;
146
147    #[test]
148    fn test_address_parse() {
149        let expected = "aleo1d5hg2z3ma00382pngntdp68e74zv54jdxy249qhaujhks9c72yrs33ddah.public";
150        let address = Address::<Circuit>::parse(expected).unwrap().1;
151        assert_eq!(expected, &format!("{address}"));
152    }
153}