From 82ae0dd32c57b1d76ebf40b8984a84e71db2682c Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Mon, 20 Nov 2023 14:13:19 +0300 Subject: [PATCH 1/8] review code --- sdk/src/account/address.rs | 5 ----- sdk/src/account/mod.rs | 2 +- sdk/src/account/private_key.rs | 8 +------- sdk/src/account/record.rs | 19 +++---------------- sdk/src/account/signature.rs | 7 +------ sdk/src/account/view_key.rs | 5 ----- sdk/src/coinbase/verifying_key.rs | 2 +- 7 files changed, 7 insertions(+), 41 deletions(-) diff --git a/sdk/src/account/address.rs b/sdk/src/account/address.rs index a64666c..93b77c9 100644 --- a/sdk/src/account/address.rs +++ b/sdk/src/account/address.rs @@ -39,11 +39,6 @@ impl Address { } /// Returns the address as a base58 string. - #[allow(clippy::inherent_to_string)] - fn to_string(&self) -> String { - self.0.to_string() - } - fn __str__(&self) -> String { self.0.to_string() } diff --git a/sdk/src/account/mod.rs b/sdk/src/account/mod.rs index 26b989b..b3fcb8c 100644 --- a/sdk/src/account/mod.rs +++ b/sdk/src/account/mod.rs @@ -123,4 +123,4 @@ impl From for Account { fn from(private_key: PrivateKey) -> Self { Self::from_private_key(private_key) } -} \ No newline at end of file +} diff --git a/sdk/src/account/private_key.rs b/sdk/src/account/private_key.rs index e92e977..2ca81bb 100644 --- a/sdk/src/account/private_key.rs +++ b/sdk/src/account/private_key.rs @@ -79,19 +79,13 @@ impl PrivateKey { self.0.r_sig().to_string() } - /// Returns the private key as a base58 string. - #[allow(clippy::inherent_to_string)] - #[allow(clippy::wrong_self_convention)] - fn to_string(&self) -> String { - self.0.to_string() - } - /// Initializes a new account view key from an account private key. pub fn view_key(&self) -> ViewKey { let view_key = ViewKeyNative::try_from(&self.0).unwrap(); ViewKey::from(view_key) } + /// Returns the private key as a base58 string. fn __str__(&self) -> String { self.0.to_string() } diff --git a/sdk/src/account/record.rs b/sdk/src/account/record.rs index 37515d1..d7c5383 100644 --- a/sdk/src/account/record.rs +++ b/sdk/src/account/record.rs @@ -16,10 +16,7 @@ use crate::{ account::{PrivateKey, ViewKey}, - types::{ - IdentifierNative, ProgramIDNative, RecordCiphertextNative, - RecordPlaintextNative, - }, + types::{IdentifierNative, ProgramIDNative, RecordCiphertextNative, RecordPlaintextNative}, }; use std::ops::Deref; @@ -38,12 +35,6 @@ impl RecordCiphertext { Ok(Self::from(RecordCiphertextNative::from_str(s)?)) } - /// Returns the record ciphertext as a string. - #[allow(clippy::inherent_to_string)] - fn to_string(&self) -> String { - self.0.to_string() - } - /// Decrypts self into plaintext using the given view key and checks that the owner matches the view key. pub fn decrypt(&self, view_key: &ViewKey) -> anyhow::Result { let plaintext = self.0.decrypt(view_key)?; @@ -55,6 +46,7 @@ impl RecordCiphertext { self.0.is_owner(view_key) } + /// Returns the record ciphertext as a string. fn __str__(&self) -> String { self.0.to_string() } @@ -110,18 +102,13 @@ impl RecordPlaintext { } /// Returns the plaintext as a string. - #[allow(clippy::inherent_to_string)] - fn to_string(&self) -> String { + fn __str__(&self) -> String { self.0.to_string() } fn __eq__(&self, other: &Self) -> bool { self.0 == other.0 } - - fn __str__(&self) -> String { - self.0.to_string() - } } impl Deref for RecordPlaintext { diff --git a/sdk/src/account/signature.rs b/sdk/src/account/signature.rs index 928f8c2..65814c3 100644 --- a/sdk/src/account/signature.rs +++ b/sdk/src/account/signature.rs @@ -63,18 +63,13 @@ impl Signature { Ok(Self(signature)) } - /// Returns a string representation of the signature. - #[allow(clippy::inherent_to_string)] - fn to_string(&self) -> String { - self.0.to_string() - } - /// Verifies (challenge == challenge') && (address == address') where: /// challenge' := HashToScalar(G^response pk_sig^challenge, pk_sig, pr_sig, address, message) pub fn verify(&self, address: &Address, message: &[u8]) -> bool { self.0.verify_bytes(address, message) } + /// Returns a string representation of the signature. fn __str__(&self) -> String { self.0.to_string() } diff --git a/sdk/src/account/view_key.rs b/sdk/src/account/view_key.rs index 3369e9f..c4c1c81 100644 --- a/sdk/src/account/view_key.rs +++ b/sdk/src/account/view_key.rs @@ -57,11 +57,6 @@ impl ViewKey { } /// Returns the view key as a base58 string. - #[allow(clippy::inherent_to_string)] - fn to_string(&self) -> String { - self.0.to_string() - } - fn __str__(&self) -> String { self.0.to_string() } diff --git a/sdk/src/coinbase/verifying_key.rs b/sdk/src/coinbase/verifying_key.rs index 8160b93..1eeb4dd 100644 --- a/sdk/src/coinbase/verifying_key.rs +++ b/sdk/src/coinbase/verifying_key.rs @@ -38,4 +38,4 @@ impl Deref for CoinbaseVerifyingKey { fn deref(&self) -> &Self::Target { &self.0 } -} \ No newline at end of file +} From 1e01926a6613b0e4bb2e73ddf20938a9ac979f51 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Mon, 20 Nov 2023 20:10:50 +0300 Subject: [PATCH 2/8] Add program and algebra classes --- sdk/src/algebra/boolean.rs | 61 +++++++++ sdk/src/algebra/field.rs | 87 +++++++++++++ sdk/src/algebra/group.rs | 81 ++++++++++++ sdk/src/algebra/integer.rs | 86 +++++++++++++ sdk/src/algebra/mod.rs | 30 +++++ sdk/src/algebra/scalar.rs | 81 ++++++++++++ sdk/src/credits/mod.rs | 79 ++++++++++++ sdk/src/lib.rs | 39 ++++++ sdk/src/programs/authorization.rs | 38 ++++++ sdk/src/programs/execution.rs | 53 ++++++++ sdk/src/programs/fee.rs | 80 ++++++++++++ sdk/src/programs/identifier.rs | 75 +++++++++++ sdk/src/programs/literal.rs | 147 +++++++++++++++++++++ sdk/src/programs/locator.rs | 103 +++++++++++++++ sdk/src/programs/mod.rs | 66 ++++++++++ sdk/src/programs/process.rs | 207 ++++++++++++++++++++++++++++++ sdk/src/programs/program.rs | 97 ++++++++++++++ sdk/src/programs/program_id.rs | 90 +++++++++++++ sdk/src/programs/proving_key.rs | 72 +++++++++++ sdk/src/programs/query.rs | 47 +++++++ sdk/src/programs/response.rs | 36 ++++++ sdk/src/programs/trace.rs | 80 ++++++++++++ sdk/src/programs/transaction.rs | 64 +++++++++ sdk/src/programs/transition.rs | 74 +++++++++++ sdk/src/programs/value.rs | 75 +++++++++++ sdk/src/programs/verifying_key.rs | 72 +++++++++++ sdk/src/types.rs | 45 ++++++- 27 files changed, 2063 insertions(+), 2 deletions(-) create mode 100644 sdk/src/algebra/boolean.rs create mode 100644 sdk/src/algebra/field.rs create mode 100644 sdk/src/algebra/group.rs create mode 100644 sdk/src/algebra/integer.rs create mode 100644 sdk/src/algebra/mod.rs create mode 100644 sdk/src/algebra/scalar.rs create mode 100644 sdk/src/credits/mod.rs create mode 100644 sdk/src/programs/authorization.rs create mode 100644 sdk/src/programs/execution.rs create mode 100644 sdk/src/programs/fee.rs create mode 100644 sdk/src/programs/identifier.rs create mode 100644 sdk/src/programs/literal.rs create mode 100644 sdk/src/programs/locator.rs create mode 100644 sdk/src/programs/mod.rs create mode 100644 sdk/src/programs/process.rs create mode 100644 sdk/src/programs/program.rs create mode 100644 sdk/src/programs/program_id.rs create mode 100644 sdk/src/programs/proving_key.rs create mode 100644 sdk/src/programs/query.rs create mode 100644 sdk/src/programs/response.rs create mode 100644 sdk/src/programs/trace.rs create mode 100644 sdk/src/programs/transaction.rs create mode 100644 sdk/src/programs/transition.rs create mode 100644 sdk/src/programs/value.rs create mode 100644 sdk/src/programs/verifying_key.rs diff --git a/sdk/src/algebra/boolean.rs b/sdk/src/algebra/boolean.rs new file mode 100644 index 0000000..a08df8e --- /dev/null +++ b/sdk/src/algebra/boolean.rs @@ -0,0 +1,61 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::BooleanNative; + +use pyo3::prelude::*; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, +}; + +#[pyclass(frozen)] +#[derive(Copy, Clone)] +pub struct Boolean(BooleanNative); + +#[pymethods] +impl Boolean { + #[new] + fn new(value: bool) -> Self { + Self(BooleanNative::new(value)) + } + + /// Returns the boolean as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __bool__(&self) -> bool { + *self.0 + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} + +impl From for BooleanNative { + fn from(value: Boolean) -> Self { + value.0 + } +} diff --git a/sdk/src/algebra/field.rs b/sdk/src/algebra/field.rs new file mode 100644 index 0000000..81f4aa5 --- /dev/null +++ b/sdk/src/algebra/field.rs @@ -0,0 +1,87 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::FieldNative; + +use pyo3::prelude::*; +use snarkvm::prelude::Zero; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + ops::Deref, + str::FromStr, +}; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Field(FieldNative); + +#[pymethods] +impl Field { + /// Parses a field from a string. + #[staticmethod] + fn from_string(s: &str) -> anyhow::Result { + FieldNative::from_str(s).map(Self) + } + + /// Initializes a new field from a `u128`. + #[staticmethod] + fn from_u128(value: u128) -> Self { + FieldNative::from_u128(value).into() + } + + /// Returns the `0` element of the field. + #[staticmethod] + fn zero() -> Self { + FieldNative::zero().into() + } + + /// Returns the Field as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} + +impl Deref for Field { + type Target = FieldNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Field { + fn from(value: FieldNative) -> Self { + Self(value) + } +} + +impl From for FieldNative { + fn from(value: Field) -> Self { + value.0 + } +} diff --git a/sdk/src/algebra/group.rs b/sdk/src/algebra/group.rs new file mode 100644 index 0000000..111e9a5 --- /dev/null +++ b/sdk/src/algebra/group.rs @@ -0,0 +1,81 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::GroupNative; + +use pyo3::prelude::*; +use snarkvm::prelude::Zero; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + ops::Deref, + str::FromStr, +}; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Group(GroupNative); + +#[pymethods] +impl Group { + /// Parses a group from a string. + #[staticmethod] + fn from_string(s: &str) -> anyhow::Result { + GroupNative::from_str(s).map(Self) + } + + /// Returns the `0` element of the group. + #[staticmethod] + fn zero() -> Self { + GroupNative::zero().into() + } + + /// Returns the Group as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} + +impl Deref for Group { + type Target = GroupNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Group { + fn from(value: GroupNative) -> Self { + Self(value) + } +} + +impl From for GroupNative { + fn from(value: Group) -> Self { + value.0 + } +} diff --git a/sdk/src/algebra/integer.rs b/sdk/src/algebra/integer.rs new file mode 100644 index 0000000..eab2122 --- /dev/null +++ b/sdk/src/algebra/integer.rs @@ -0,0 +1,86 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::{ + I128Native, I16Native, I32Native, I64Native, I8Native, U128Native, U16Native, U32Native, + U64Native, U8Native, +}; + +use pyo3::prelude::*; +use snarkvm::prelude::Zero; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, +}; + +macro_rules! integer { + ($export_ty:ident, $native:ident, $machine:ident) => { + #[pyclass(frozen)] + #[derive(Copy, Clone)] + pub struct $export_ty($native); + #[pymethods] + impl $export_ty { + #[new] + fn new(value: $machine) -> Self { + Self($native::new(value)) + } + + /// Returns the `0` element of the integer. + #[staticmethod] + fn zero() -> Self { + Self($native::zero()) + } + + /// Returns the integer as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __int__(&self) -> $machine { + *self.0 + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } + } + + impl From<$export_ty> for $native { + fn from(value: $export_ty) -> Self { + value.0 + } + } + }; +} + +integer!(I8, I8Native, i8); +integer!(I16, I16Native, i16); +integer!(I32, I32Native, i32); +integer!(I64, I64Native, i64); +integer!(I128, I128Native, i128); + +integer!(U8, U8Native, u8); +integer!(U16, U16Native, u16); +integer!(U32, U32Native, u32); +integer!(U64, U64Native, u64); +integer!(U128, U128Native, u128); diff --git a/sdk/src/algebra/mod.rs b/sdk/src/algebra/mod.rs new file mode 100644 index 0000000..2e0a310 --- /dev/null +++ b/sdk/src/algebra/mod.rs @@ -0,0 +1,30 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +mod boolean; +pub use boolean::Boolean; + +mod field; +pub use field::Field; + +mod group; +pub use group::Group; + +mod scalar; +pub use scalar::Scalar; + +mod integer; +pub use integer::*; diff --git a/sdk/src/algebra/scalar.rs b/sdk/src/algebra/scalar.rs new file mode 100644 index 0000000..36d8cca --- /dev/null +++ b/sdk/src/algebra/scalar.rs @@ -0,0 +1,81 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::ScalarNative; + +use pyo3::prelude::*; +use snarkvm::prelude::Zero; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + ops::Deref, + str::FromStr, +}; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Scalar(ScalarNative); + +#[pymethods] +impl Scalar { + /// Parses a scalar from a string. + #[staticmethod] + fn from_string(s: &str) -> anyhow::Result { + ScalarNative::from_str(s).map(Self) + } + + /// Returns the `0` element of the scalar. + #[staticmethod] + fn zero() -> Self { + ScalarNative::zero().into() + } + + /// Returns the Scalar as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} + +impl Deref for Scalar { + type Target = ScalarNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Scalar { + fn from(value: ScalarNative) -> Self { + Self(value) + } +} + +impl From for ScalarNative { + fn from(value: Scalar) -> Self { + value.0 + } +} diff --git a/sdk/src/credits/mod.rs b/sdk/src/credits/mod.rs new file mode 100644 index 0000000..150f411 --- /dev/null +++ b/sdk/src/credits/mod.rs @@ -0,0 +1,79 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use pyo3::prelude::*; + +#[pyclass(frozen)] +#[derive(Clone, Copy)] +pub struct Credits(f64); + +#[pymethods] +impl Credits { + #[new] + fn new(value: f64) -> Self { + Self(value) + } + + fn micro(&self) -> MicroCredits { + MicroCredits((self.0 * 1_000_000.0) as u64) + } + + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __float__(&self) -> f64 { + self.0 + } + + #[classattr] + const __hash__: Option = None; +} + +#[pyclass(frozen)] +#[derive(Clone, Copy)] +pub struct MicroCredits(u64); + +#[pymethods] +impl MicroCredits { + #[new] + fn new(value: u64) -> Self { + Self(value) + } + + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __int__(&self) -> u64 { + self.0 + } + + #[classattr] + const __hash__: Option = None; +} + +impl From for MicroCredits { + fn from(value: u64) -> Self { + Self(value) + } +} + +impl From for u64 { + fn from(value: MicroCredits) -> Self { + value.0 + } +} diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index cb96cc4..9169cce 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -17,26 +17,65 @@ use pyo3::prelude::*; mod account; +mod algebra; mod coinbase; +mod credits; +mod programs; mod types; use account::*; +use algebra::*; use coinbase::*; +use credits::*; +use programs::*; #[pymodule] #[pyo3(name = "aleo")] fn register_module(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_class::
()?; + m.add_class::()?; + m.add_class::()?; m.add_class::()?; m.add_class::()?; m.add_class::()?; + m.add_class::()?; m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; m.add_class::()?; + m.add_class::()?; + m.add_class::()?; m.add_class::()?; m.add_class::()?; + m.add_class::()?; + m.add_class::()?; m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; m.add_class::()?; Ok(()) } diff --git a/sdk/src/programs/authorization.rs b/sdk/src/programs/authorization.rs new file mode 100644 index 0000000..049bfa2 --- /dev/null +++ b/sdk/src/programs/authorization.rs @@ -0,0 +1,38 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::AuthorizationNative; + +use pyo3::prelude::*; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Authorization(AuthorizationNative); + +#[pymethods] +impl Authorization {} + +impl From for Authorization { + fn from(value: AuthorizationNative) -> Self { + Self(value) + } +} + +impl From for AuthorizationNative { + fn from(value: Authorization) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/execution.rs b/sdk/src/programs/execution.rs new file mode 100644 index 0000000..f7936ff --- /dev/null +++ b/sdk/src/programs/execution.rs @@ -0,0 +1,53 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{types::ExecutionNative, Field}; + +use pyo3::prelude::*; + +use std::ops::Deref; + +#[pyclass] +#[derive(Clone)] +pub struct Execution(ExecutionNative); + +#[pymethods] +impl Execution { + /// Returns the execution ID. + fn execution_id(&self) -> anyhow::Result { + self.0.to_execution_id().map(Into::into) + } +} + +impl Deref for Execution { + type Target = ExecutionNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Execution { + fn from(value: ExecutionNative) -> Self { + Self(value) + } +} + +impl From for ExecutionNative { + fn from(value: Execution) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/fee.rs b/sdk/src/programs/fee.rs new file mode 100644 index 0000000..6e5e4f5 --- /dev/null +++ b/sdk/src/programs/fee.rs @@ -0,0 +1,80 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{types::FeeNative, Address, Transition}; + +use pyo3::prelude::*; + +use std::ops::Deref; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Fee(FeeNative); + +#[pymethods] +impl Fee { + /// Returns true if this is a fee_private transition. + fn is_fee_private(&self) -> bool { + self.0.is_fee_private() + } + + /// Returns true if this is a fee_public transition. + fn is_fee_public(&self) -> bool { + self.0.is_fee_public() + } + + /// Returns the payer, if the fee is public. + fn payer(&self) -> Option
{ + self.0.payer().map(Into::into) + } + + /// Returns the transition. + fn transition(&self) -> Transition { + self.0.transition().clone().into() + } + + /// Returns the Fee as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + #[classattr] + const __hash__: Option = None; +} + +impl Deref for Fee { + type Target = FeeNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Fee { + fn from(value: FeeNative) -> Self { + Self(value) + } +} + +impl From for FeeNative { + fn from(value: Fee) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/identifier.rs b/sdk/src/programs/identifier.rs new file mode 100644 index 0000000..6aae216 --- /dev/null +++ b/sdk/src/programs/identifier.rs @@ -0,0 +1,75 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::IdentifierNative; + +use pyo3::prelude::*; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + ops::Deref, + str::FromStr, +}; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Identifier(IdentifierNative); + +#[pymethods] +impl Identifier { + /// Parses an identifier from a string. + #[staticmethod] + fn from_string(s: &str) -> anyhow::Result { + let identifier = FromStr::from_str(s)?; + Ok(Self(identifier)) + } + + /// Returns the identifier as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} + +impl Deref for Identifier { + type Target = IdentifierNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Identifier { + fn from(value: IdentifierNative) -> Self { + Self(value) + } +} + +impl From for IdentifierNative { + fn from(value: Identifier) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/literal.rs b/sdk/src/programs/literal.rs new file mode 100644 index 0000000..0373475 --- /dev/null +++ b/sdk/src/programs/literal.rs @@ -0,0 +1,147 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + types::LiteralNative, Address, Boolean, Field, Group, Scalar, Signature, I128, I16, I32, I64, + I8, U128, U16, U32, U64, U8, +}; + +use pyo3::prelude::*; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + str::FromStr, +}; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Literal(LiteralNative); + +#[pymethods] +impl Literal { + /// Parses a literal from a string. + #[staticmethod] + fn parse(s: &str) -> anyhow::Result { + LiteralNative::from_str(s).map(Self) + } + + #[staticmethod] + fn from_address(address: Address) -> Self { + Self(LiteralNative::Address(*address)) + } + + #[staticmethod] + fn from_field(field: Field) -> Self { + Self(LiteralNative::Field(*field)) + } + + #[staticmethod] + fn from_group(group: Group) -> Self { + Self(LiteralNative::Group(*group)) + } + + #[staticmethod] + fn from_scalar(scalar: Scalar) -> Self { + Self(LiteralNative::Scalar(*scalar)) + } + + #[staticmethod] + fn from_signature(signature: Signature) -> Self { + Self(LiteralNative::Signature(Box::new(*signature))) + } + + #[staticmethod] + fn from_boolean(b: Boolean) -> Self { + Self(LiteralNative::Boolean(b.into())) + } + + #[staticmethod] + fn from_i8(value: I8) -> Self { + Self(LiteralNative::I8(value.into())) + } + + #[staticmethod] + fn from_i16(value: I16) -> Self { + Self(LiteralNative::I16(value.into())) + } + + #[staticmethod] + fn from_i32(value: I32) -> Self { + Self(LiteralNative::I32(value.into())) + } + + #[staticmethod] + fn from_i64(value: I64) -> Self { + Self(LiteralNative::I64(value.into())) + } + + #[staticmethod] + fn from_i128(value: I128) -> Self { + Self(LiteralNative::I128(value.into())) + } + + #[staticmethod] + fn from_u8(value: U8) -> Self { + Self(LiteralNative::U8(value.into())) + } + + #[staticmethod] + fn from_u16(value: U16) -> Self { + Self(LiteralNative::U16(value.into())) + } + + #[staticmethod] + fn from_u32(value: U32) -> Self { + Self(LiteralNative::U32(value.into())) + } + + #[staticmethod] + fn from_u64(value: U64) -> Self { + Self(LiteralNative::U64(value.into())) + } + + #[staticmethod] + fn from_u128(value: U128) -> Self { + Self(LiteralNative::U128(value.into())) + } + + /// Returns the type of the literal. + fn type_name(&self) -> String { + self.0.to_type().type_name().to_string() + } + + /// Returns the literal as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} + +impl From for LiteralNative { + fn from(value: Literal) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/locator.rs b/sdk/src/programs/locator.rs new file mode 100644 index 0000000..8ed9d30 --- /dev/null +++ b/sdk/src/programs/locator.rs @@ -0,0 +1,103 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + programs::{Identifier, ProgramID}, + types::LocatorNative, +}; + +use pyo3::prelude::*; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + ops::Deref, + str::FromStr, +}; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Locator(LocatorNative); + +#[pymethods] +impl Locator { + /// Initializes a locator from a program ID and resource. + #[new] + fn new(program_id: ProgramID, resource: Identifier) -> Self { + LocatorNative::new(program_id.into(), resource.into()).into() + } + + /// Parses a Locator from a string. + #[staticmethod] + fn from_string(s: &str) -> anyhow::Result { + LocatorNative::from_str(s).map(Self) + } + + /// Returns the program ID. + fn program_id(&self) -> ProgramID { + (*self.0.program_id()).into() + } + + /// Returns the program name. + fn name(&self) -> Identifier { + (*self.0.name()).into() + } + + /// Returns the network-level domain (NLD). + fn network(&self) -> Identifier { + (*self.0.network()).into() + } + + /// Returns the resource name. + fn resource(&self) -> Identifier { + (*self.0.resource()).into() + } + + /// Returns the Locator as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} + +impl Deref for Locator { + type Target = LocatorNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Locator { + fn from(value: LocatorNative) -> Self { + Self(value) + } +} + +impl From for LocatorNative { + fn from(value: Locator) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/mod.rs b/sdk/src/programs/mod.rs new file mode 100644 index 0000000..e180c28 --- /dev/null +++ b/sdk/src/programs/mod.rs @@ -0,0 +1,66 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +mod authorization; +pub use authorization::Authorization; + +mod execution; +pub use execution::Execution; + +mod fee; +pub use fee::Fee; + +mod identifier; +pub use identifier::Identifier; + +mod literal; +pub use literal::Literal; + +mod locator; +pub use locator::Locator; + +mod process; +pub use process::Process; + +mod program_id; +pub use program_id::ProgramID; + +mod program; +pub use program::Program; + +mod proving_key; +pub use proving_key::ProvingKey; + +mod response; +pub use response::Response; + +mod query; +pub use query::Query; + +mod trace; +pub use trace::Trace; + +mod transaction; +pub use transaction::Transaction; + +mod transition; +pub use transition::Transition; + +mod value; +pub use value::Value; + +mod verifying_key; +pub use verifying_key::VerifyingKey; diff --git a/sdk/src/programs/process.rs b/sdk/src/programs/process.rs new file mode 100644 index 0000000..05f8490 --- /dev/null +++ b/sdk/src/programs/process.rs @@ -0,0 +1,207 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + types::{CurrentAleo, ProcessNative}, + Authorization, Execution, Fee, Field, Identifier, MicroCredits, PrivateKey, Program, ProgramID, + ProvingKey, RecordPlaintext, Response, Trace, Value, VerifyingKey, +}; + +use pyo3::prelude::*; +use rand::{rngs::StdRng, SeedableRng}; +use snarkvm::prelude::cost_in_microcredits; + +#[pyclass] +pub struct Process(ProcessNative); + +#[pymethods] +impl Process { + /// Initializes a new process. + #[staticmethod] + fn load() -> anyhow::Result { + ProcessNative::load().map(Self) + } + + /// Adds a new program to the process + fn add_program(&mut self, program: &Program) -> anyhow::Result<()> { + self.0.add_program(program) + } + + /// Returns true if the process contains the program with the given ID. + fn contains_program(&self, program_id: &ProgramID) -> bool { + self.0.contains_program(program_id) + } + + /// Returns the proving key for the given program ID and function name. + fn get_proving_key( + &self, + program_id: ProgramID, + function_name: Identifier, + ) -> anyhow::Result { + self.0 + .get_proving_key(program_id, function_name) + .map(ProvingKey::from) + } + + /// Inserts the given proving key, for the given program ID and function name. + fn insert_proving_key( + &mut self, + program_id: &ProgramID, + function_name: &Identifier, + proving_key: ProvingKey, + ) -> anyhow::Result<()> { + self.0 + .insert_proving_key(program_id, function_name, proving_key.into()) + } + + /// Returns the verifying key for the given program ID and function name. + fn get_verifying_key( + &self, + program_id: ProgramID, + function_name: Identifier, + ) -> anyhow::Result { + self.0 + .get_verifying_key(program_id, function_name) + .map(Into::into) + } + + /// Inserts the given verifying key, for the given program ID and function name. + fn insert_verifying_key( + &mut self, + program_id: &ProgramID, + function_name: &Identifier, + verifying_key: VerifyingKey, + ) -> anyhow::Result<()> { + self.0 + .insert_verifying_key(program_id, function_name, verifying_key.into()) + } + + /// Authorizes a call to the program function for the given inputs. + fn authorize( + &self, + private_key: &PrivateKey, + program_id: ProgramID, + function_name: Identifier, + inputs: Vec, + ) -> anyhow::Result { + self.0 + .authorize::( + private_key, + program_id, + function_name, + inputs.into_iter(), + &mut StdRng::from_entropy(), + ) + .map(Into::into) + } + + /// Authorizes the fee given the credits record, the fee amount (in microcredits), and the deployment or execution ID. + fn authorize_fee_private( + &self, + private_key: &PrivateKey, + credits: RecordPlaintext, + base_fee: MicroCredits, + deployment_or_execution_id: Field, + priority_fee: Option, + ) -> anyhow::Result { + self.0 + .authorize_fee_private::( + private_key, + credits.into(), + base_fee.into(), + priority_fee.map(Into::into).unwrap_or(0), + deployment_or_execution_id.into(), + &mut StdRng::from_entropy(), + ) + .map(Into::into) + } + + /// Authorizes the fee given the the fee amount (in microcredits) and the deployment or execution ID. + fn authorize_fee_public( + &self, + private_key: &PrivateKey, + base_fee: MicroCredits, + deployment_or_execution_id: Field, + priority_fee: Option, + ) -> anyhow::Result { + self.0 + .authorize_fee_public::( + private_key, + base_fee.into(), + priority_fee.map(Into::into).unwrap_or(0), + deployment_or_execution_id.into(), + &mut StdRng::from_entropy(), + ) + .map(Into::into) + } + + /// Executes the given authorization. + fn execute(&self, authorization: Authorization) -> anyhow::Result<(Response, Trace)> { + self.0 + .execute::(authorization.into()) + .map(|(r, t)| (Response::from(r), Trace::from(t))) + } + + /// Verifies the given execution is valid. Note: This does not check that the global state root exists in the ledger. + fn verify_execution(&self, execution: &Execution) -> anyhow::Result<()> { + self.0.verify_execution(execution) + } + + /// Verifies the given fee is valid. Note: This does not check that the global state root exists in the ledger. + fn verify_fee(&self, fee: &Fee, deployment_or_execution_id: Field) -> anyhow::Result<()> { + self.0.verify_fee(fee, deployment_or_execution_id.into()) + } + + /// Returns the *minimum* cost in microcredits to publish the given execution (total cost, (storage cost, finalize cost)). + fn execution_cost( + &self, + execution: &Execution, + ) -> anyhow::Result<(MicroCredits, (MicroCredits, MicroCredits))> { + // Compute the storage cost in microcredits. + let storage_cost = execution.size_in_bytes()?; + + // Compute the finalize cost in microcredits. + let mut finalize_cost = 0u64; + + for transition in execution.transitions() { + let program = self.0.get_program(transition.program_id())?; + let function = program.get_function(transition.function_name())?; + let cost = match function.finalize_logic() { + Some(finalize) => cost_in_microcredits(finalize)?, + None => continue, + }; + // Accumulate the finalize cost. + finalize_cost = finalize_cost.checked_add(cost).ok_or(anyhow::anyhow!( + "The finalize cost computation overflowed for an execution" + ))?; + } + + // Compute the total cost in microcredits. + let total_cost = storage_cost + .checked_add(finalize_cost) + .ok_or(anyhow::anyhow!( + "The total cost computation overflowed for an execution" + ))?; + + Ok(( + MicroCredits::from(total_cost), + ( + MicroCredits::from(storage_cost), + MicroCredits::from(finalize_cost), + ), + )) + } +} diff --git a/sdk/src/programs/program.rs b/sdk/src/programs/program.rs new file mode 100644 index 0000000..664a031 --- /dev/null +++ b/sdk/src/programs/program.rs @@ -0,0 +1,97 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + programs::{Identifier, ProgramID}, + types::ProgramNative, +}; + +use pyo3::prelude::*; + +use std::{ops::Deref, str::FromStr}; + +#[pyclass(frozen)] +pub struct Program(ProgramNative); + +#[pymethods] +impl Program { + /// Creates a program from source code. + #[staticmethod] + fn from_source(s: &str) -> anyhow::Result { + let program = FromStr::from_str(s)?; + Ok(Self(program)) + } + + /// Returns the credits.aleo program + #[staticmethod] + fn credits() -> Self { + Program::from(ProgramNative::credits().unwrap()) + } + + /// Returns the id of the program + fn id(&self) -> ProgramID { + ProgramID::from(*self.0.id()) + } + + /// Returns all function names present in the program + fn functions(&self) -> Vec { + self.0 + .functions() + .iter() + .map(|(id, _func)| Identifier::from(*id)) + .collect() + } + + /// Returns the imports of the program + fn imports(&self) -> Vec { + self.0 + .imports() + .iter() + .map(|(id, _import)| ProgramID::from(*id)) + .collect() + } + + /// Returns the source code of the program + fn source(&self) -> String { + self.0.to_string() + } + + /// Returns the program ID as a string + fn __str__(&self) -> String { + self.0.id().to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + #[classattr] + const __hash__: Option = None; +} + +impl Deref for Program { + type Target = ProgramNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Program { + fn from(program: ProgramNative) -> Self { + Self(program) + } +} diff --git a/sdk/src/programs/program_id.rs b/sdk/src/programs/program_id.rs new file mode 100644 index 0000000..d3de301 --- /dev/null +++ b/sdk/src/programs/program_id.rs @@ -0,0 +1,90 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{programs::Identifier, types::ProgramIDNative}; + +use pyo3::prelude::*; + +use std::{ + collections::hash_map::DefaultHasher, + hash::{Hash, Hasher}, + ops::Deref, + str::FromStr, +}; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct ProgramID(ProgramIDNative); + +#[pymethods] +impl ProgramID { + /// Parses a string into a program ID. + #[staticmethod] + fn from_string(s: &str) -> anyhow::Result { + let program_id = FromStr::from_str(s)?; + Ok(Self(program_id)) + } + + /// Returns the program name. + fn name(&self) -> Identifier { + Identifier::from(*self.0.name()) + } + + /// Returns the network-level domain (NLD). + fn network(&self) -> Identifier { + Identifier::from(*self.0.network()) + } + + /// Returns `true` if the network-level domain is `aleo`. + fn is_aleo(&self) -> bool { + self.0.is_aleo() + } + + /// Returns the program ID as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.0.hash(&mut hasher); + hasher.finish() + } +} + +impl Deref for ProgramID { + type Target = ProgramIDNative; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ProgramID { + fn from(value: ProgramIDNative) -> Self { + Self(value) + } +} + +impl From for ProgramIDNative { + fn from(value: ProgramID) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/proving_key.rs b/sdk/src/programs/proving_key.rs new file mode 100644 index 0000000..bb16a68 --- /dev/null +++ b/sdk/src/programs/proving_key.rs @@ -0,0 +1,72 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::ProvingKeyNative; + +use pyo3::prelude::*; +use snarkvm::prelude::{FromBytes, ToBytes}; + +use std::str::FromStr; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct ProvingKey(ProvingKeyNative); + +#[pymethods] +impl ProvingKey { + /// Parses a proving key from string. + #[staticmethod] + fn from_string(s: &str) -> anyhow::Result { + let proving_key = FromStr::from_str(s)?; + Ok(Self(proving_key)) + } + + /// Constructs a proving key from a byte array + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + let proving_key = ProvingKeyNative::from_bytes_le(bytes)?; + Ok(Self(proving_key)) + } + + /// Returns the byte representation of a proving key + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + + /// Returns the proving key as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + *self.0 == *other.0 + } + + #[classattr] + const __hash__: Option = None; +} + +impl From for ProvingKey { + fn from(value: ProvingKeyNative) -> Self { + Self(value) + } +} + +impl From for ProvingKeyNative { + fn from(value: ProvingKey) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/query.rs b/sdk/src/programs/query.rs new file mode 100644 index 0000000..f8e0b6e --- /dev/null +++ b/sdk/src/programs/query.rs @@ -0,0 +1,47 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::QueryNative; + +use pyo3::prelude::*; + +#[pyclass] +#[derive(Clone)] +pub struct Query(QueryNative); + +#[pymethods] +impl Query { + /// The base URL of the node. + #[staticmethod] + fn rest(url: String) -> Self { + QueryNative::REST(url).into() + } + + #[classattr] + const __hash__: Option = None; +} + +impl From for Query { + fn from(value: QueryNative) -> Self { + Self(value) + } +} + +impl From for QueryNative { + fn from(value: Query) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/response.rs b/sdk/src/programs/response.rs new file mode 100644 index 0000000..65d39aa --- /dev/null +++ b/sdk/src/programs/response.rs @@ -0,0 +1,36 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{programs::Value, types::ResponseNative}; + +use pyo3::prelude::*; + +#[pyclass(frozen)] +pub struct Response(ResponseNative); + +#[pymethods] +impl Response { + /// Returns the function outputs. + fn outputs(&self) -> Vec { + self.0.outputs().iter().cloned().map(Into::into).collect() + } +} + +impl From for Response { + fn from(value: ResponseNative) -> Self { + Self(value) + } +} diff --git a/sdk/src/programs/trace.rs b/sdk/src/programs/trace.rs new file mode 100644 index 0000000..8bb22ce --- /dev/null +++ b/sdk/src/programs/trace.rs @@ -0,0 +1,80 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + types::{CurrentAleo, LocatorNative, QueryNative, TraceNative}, + Execution, Fee, Locator, Query, Transition, +}; + +use pyo3::prelude::*; +use rand::{rngs::StdRng, SeedableRng}; + +#[pyclass] +pub struct Trace(TraceNative); + +#[pymethods] +impl Trace { + /// Returns true if the trace is for a fee transition. + fn is_fee(&self) -> bool { + self.0.is_fee() + } + + /// Returns true if the trace is for a private fee transition. + fn is_fee_private(&self) -> bool { + self.0.is_fee_private() + } + + /// Returns true if the trace is for a public fee transition. + fn is_fee_public(&self) -> bool { + self.0.is_fee_public() + } + + /// Returns the list of transitions. + fn transitions(&self) -> Vec { + self.0 + .transitions() + .iter() + .cloned() + .map(Into::into) + .collect() + } + + /// Returns a new execution with a proof, for the current inclusion assignments and global state root. + fn prove_execution(&self, locator: Locator) -> anyhow::Result { + let locator: LocatorNative = locator.into(); + let locator_s = locator.to_string(); + self.0 + .prove_execution::(&locator_s, &mut StdRng::from_entropy()) + .map(Into::into) + } + + /// Returns a new fee with a proof, for the current inclusion assignment and global state root. + fn prove_fee(&self) -> anyhow::Result { + self.0 + .prove_fee::(&mut StdRng::from_entropy()) + .map(Into::into) + } + + fn prepare(&mut self, query: Query) -> anyhow::Result<()> { + self.0.prepare(QueryNative::from(query)) + } +} + +impl From for Trace { + fn from(value: TraceNative) -> Self { + Self(value) + } +} diff --git a/sdk/src/programs/transaction.rs b/sdk/src/programs/transaction.rs new file mode 100644 index 0000000..28f228d --- /dev/null +++ b/sdk/src/programs/transaction.rs @@ -0,0 +1,64 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + programs::{Execution, Fee}, + types::TransactionNative, +}; + +use pyo3::prelude::*; + +use std::str::FromStr; + +#[pyclass(frozen)] +pub struct Transaction(TransactionNative); + +#[pymethods] +impl Transaction { + #[staticmethod] + fn from_execution(execution: Execution, fee: Option) -> anyhow::Result { + TransactionNative::from_execution(execution.into(), fee.map(Into::into)).map(Self) + } + + /// Parses a Transaction from a JSON string. + #[staticmethod] + fn from_json(json: &str) -> anyhow::Result { + TransactionNative::from_str(json).map(Self) + } + + /// Serialize the given Transaction as a JSON string. + fn to_json(&self) -> String { + self.0.to_string() + } + + /// Returns the Transaction as a string. + fn __str__(&self) -> String { + self.to_json() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + #[classattr] + const __hash__: Option = None; +} + +impl From for Transaction { + fn from(value: TransactionNative) -> Self { + Self(value) + } +} diff --git a/sdk/src/programs/transition.rs b/sdk/src/programs/transition.rs new file mode 100644 index 0000000..9e0030d --- /dev/null +++ b/sdk/src/programs/transition.rs @@ -0,0 +1,74 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + programs::{Identifier, ProgramID}, + types::TransitionNative, +}; + +use pyo3::prelude::*; + +#[pyclass(frozen)] +pub struct Transition(TransitionNative); + +#[pymethods] +impl Transition { + /// Returns the transition ID. + fn id(&self) -> String { + self.0.id().to_string() + } + + /// Returns the program ID. + fn program_id(&self) -> ProgramID { + (*self.0.program_id()).into() + } + + /// Returns the function name. + fn function_name(&self) -> Identifier { + (*self.0.function_name()).into() + } + + /// Returns true if this is a bond transition. + fn is_bond(&self) -> bool { + self.0.is_bond() + } + + /// Returns true if this is an unbond transition. + fn is_unbond(&self) -> bool { + self.0.is_unbond() + } + + /// Returns true if this is a fee_private transition. + fn is_fee_private(&self) -> bool { + self.0.is_fee_private() + } + + /// Returns true if this is a fee_public transition. + fn is_fee_public(&self) -> bool { + self.0.is_fee_public() + } + + /// Returns true if this is a split transition. + fn is_split(&self) -> bool { + self.0.is_split() + } +} + +impl From for Transition { + fn from(value: TransitionNative) -> Self { + Self(value) + } +} diff --git a/sdk/src/programs/value.rs b/sdk/src/programs/value.rs new file mode 100644 index 0000000..2e2c241 --- /dev/null +++ b/sdk/src/programs/value.rs @@ -0,0 +1,75 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::{ + types::{LiteralNative, RecordPlaintextNative, ValueNative}, + Literal, RecordPlaintext, +}; + +use pyo3::prelude::*; + +use std::str::FromStr; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct Value(ValueNative); + +#[pymethods] +impl Value { + /// Parses a string (Future, Plaintext, Record) into a value. + #[staticmethod] + fn parse(s: &str) -> anyhow::Result { + ValueNative::from_str(s).map(Self) + } + + /// Initializes the value from a literal. + #[staticmethod] + fn from_literal(literal: Literal) -> Self { + Self(ValueNative::from(LiteralNative::from(literal))) + } + + /// Initializes the value from a record. + #[staticmethod] + fn from_record_plaintext(record_plaintext: RecordPlaintext) -> Self { + Self(ValueNative::from(Into::::into( + record_plaintext, + ))) + } + + /// Returns the value as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + self.0 == other.0 + } + + #[classattr] + const __hash__: Option = None; +} + +impl From for Value { + fn from(value: ValueNative) -> Self { + Self(value) + } +} + +impl From for ValueNative { + fn from(value: Value) -> Self { + value.0 + } +} diff --git a/sdk/src/programs/verifying_key.rs b/sdk/src/programs/verifying_key.rs new file mode 100644 index 0000000..e8555c5 --- /dev/null +++ b/sdk/src/programs/verifying_key.rs @@ -0,0 +1,72 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Aleo SDK library. + +// The Aleo SDK library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Aleo SDK library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Aleo SDK library. If not, see . + +use crate::types::VerifyingKeyNative; + +use pyo3::prelude::*; +use snarkvm::prelude::{FromBytes, ToBytes}; + +use std::str::FromStr; + +#[pyclass(frozen)] +#[derive(Clone)] +pub struct VerifyingKey(VerifyingKeyNative); + +#[pymethods] +impl VerifyingKey { + /// Parses a veryifying key from string. + #[staticmethod] + fn from_string(s: &str) -> anyhow::Result { + let verifying_key = FromStr::from_str(s)?; + Ok(Self(verifying_key)) + } + + /// Constructs a proving key from a byte array + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + let veryfying_key = VerifyingKeyNative::from_bytes_le(bytes)?; + Ok(Self(veryfying_key)) + } + + /// Returns the byte representation of a veryfying key + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + + /// Returns the verifying key as a string. + fn __str__(&self) -> String { + self.0.to_string() + } + + fn __eq__(&self, other: &Self) -> bool { + *self.0 == *other.0 + } + + #[classattr] + const __hash__: Option = None; +} + +impl From for VerifyingKey { + fn from(value: VerifyingKeyNative) -> Self { + Self(value) + } +} + +impl From for VerifyingKeyNative { + fn from(value: VerifyingKey) -> Self { + value.0 + } +} diff --git a/sdk/src/types.rs b/sdk/src/types.rs index ccdcf3b..20e8432 100644 --- a/sdk/src/types.rs +++ b/sdk/src/types.rs @@ -14,13 +14,19 @@ // You should have received a copy of the GNU General Public License // along with the Aleo SDK library. If not, see . +use snarkvm::circuit::network::AleoV0; use snarkvm::console::network::Testnet3; use snarkvm::prelude::coinbase::{ CoinbasePuzzle, CoinbaseVerifyingKey, EpochChallenge, ProverSolution, }; +use snarkvm::prelude::query::Query; +use snarkvm::prelude::store::helpers::memory::BlockMemory; +use snarkvm::prelude::transaction::Transaction; use snarkvm::prelude::{ - Address, Ciphertext, ComputeKey, Identifier, Plaintext, PrivateKey, ProgramID, Record, - Signature, ViewKey, + Address, Authorization, Boolean, Ciphertext, ComputeKey, Execution, Fee, Field, Group, + Identifier, Literal, Locator, Plaintext, PrivateKey, Process, Program, ProgramID, ProvingKey, + Record, Response, Scalar, Signature, Trace, Transition, Value, VerifyingKey, ViewKey, I128, + I16, I32, I64, I8, U128, U16, U32, U64, U8, }; // Account types @@ -30,12 +36,47 @@ pub type PrivateKeyNative = PrivateKey; pub type SignatureNative = Signature; pub type ViewKeyNative = ViewKey; +// Algebraic types +pub type FieldNative = Field; +pub type GroupNative = Group; +pub type ScalarNative = Scalar; + +// Integer types +pub type BooleanNative = Boolean; +pub type I8Native = I8; +pub type I16Native = I16; +pub type I32Native = I32; +pub type I64Native = I64; +pub type I128Native = I128; +pub type U8Native = U8; +pub type U16Native = U16; +pub type U32Native = U32; +pub type U64Native = U64; +pub type U128Native = U128; + // Network types pub type CurrentNetwork = Testnet3; +pub type CurrentAleo = AleoV0; // Program Types +type CurrentBlockMemory = BlockMemory; +pub type AuthorizationNative = Authorization; +pub type ExecutionNative = Execution; +pub type FeeNative = Fee; pub type IdentifierNative = Identifier; +pub type LiteralNative = Literal; +pub type LocatorNative = Locator; +pub type ProcessNative = Process; pub type ProgramIDNative = ProgramID; +pub type ProgramNative = Program; +pub type ProvingKeyNative = ProvingKey; +pub type QueryNative = Query; +pub type ResponseNative = Response; +pub type TraceNative = Trace; +pub type TransactionNative = Transaction; +pub type TransitionNative = Transition; +pub type ValueNative = Value; +pub type VerifyingKeyNative = VerifyingKey; // Record types pub type CiphertextNative = Ciphertext; From 57f9111a637bfe32f30831ac9354b5cfd2f65282 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Fri, 24 Nov 2023 20:01:48 +0300 Subject: [PATCH 3/8] Refactor account and coinbase classes (return types and style) --- sdk/src/account/address.rs | 7 ++--- sdk/src/account/compute_key.rs | 20 ++++++------ sdk/src/account/private_key.rs | 34 +++++++++++---------- sdk/src/account/record.rs | 47 +++++++++++++++-------------- sdk/src/account/signature.rs | 28 ++++++++--------- sdk/src/account/view_key.rs | 9 ++---- sdk/src/coinbase/epoch_challenge.rs | 2 +- sdk/src/coinbase/verifying_key.rs | 4 +-- 8 files changed, 75 insertions(+), 76 deletions(-) diff --git a/sdk/src/account/address.rs b/sdk/src/account/address.rs index 93b77c9..d047033 100644 --- a/sdk/src/account/address.rs +++ b/sdk/src/account/address.rs @@ -34,8 +34,7 @@ impl Address { /// Reads in an account address string. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - let address = FromStr::from_str(s)?; - Ok(Self(address)) + AddressNative::from_str(s).map(Self) } /// Returns the address as a base58 string. @@ -63,7 +62,7 @@ impl Deref for Address { } impl From for Address { - fn from(address: AddressNative) -> Self { - Self(address) + fn from(value: AddressNative) -> Self { + Self(value) } } diff --git a/sdk/src/account/compute_key.rs b/sdk/src/account/compute_key.rs index 0068f7b..844a0a3 100644 --- a/sdk/src/account/compute_key.rs +++ b/sdk/src/account/compute_key.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Aleo SDK library. If not, see . -use crate::{types::ComputeKeyNative, Address}; +use crate::{types::ComputeKeyNative, Address, Group, Scalar}; use pyo3::prelude::*; @@ -27,22 +27,22 @@ pub struct ComputeKey(ComputeKeyNative); impl ComputeKey { /// Returns the address from the compute key. fn address(&self) -> Address { - Address::from(self.0.to_address()) + self.0.to_address().into() } /// Returns the signature public key. - fn pk_sig(&self) -> String { - self.0.pk_sig().to_string() + fn pk_sig(&self) -> Group { + self.0.pk_sig().into() } /// Returns the signature public randomizer. - fn pr_sig(&self) -> String { - self.0.pr_sig().to_string() + fn pr_sig(&self) -> Group { + self.0.pr_sig().into() } /// Returns a reference to the PRF secret key. - fn sk_prf(&self) -> String { - self.0.sk_prf().to_string() + fn sk_prf(&self) -> Scalar { + self.0.sk_prf().into() } } @@ -55,7 +55,7 @@ impl Deref for ComputeKey { } impl From for ComputeKey { - fn from(compute_key: ComputeKeyNative) -> Self { - Self(compute_key) + fn from(value: ComputeKeyNative) -> Self { + Self(value) } } diff --git a/sdk/src/account/private_key.rs b/sdk/src/account/private_key.rs index 2ca81bb..7d4ec6c 100644 --- a/sdk/src/account/private_key.rs +++ b/sdk/src/account/private_key.rs @@ -15,8 +15,8 @@ // along with the Aleo SDK library. If not, see . use crate::{ - account::{Address, ComputeKey, Signature, ViewKey}, types::{AddressNative, ComputeKeyNative, PrivateKeyNative, ViewKeyNative}, + Address, ComputeKey, Field, Scalar, Signature, ViewKey, }; use pyo3::prelude::*; @@ -39,29 +39,31 @@ impl PrivateKey { #[allow(clippy::new_without_default)] #[new] pub fn new() -> Self { - Self(PrivateKeyNative::new(&mut StdRng::from_entropy()).unwrap()) + PrivateKeyNative::new(&mut StdRng::from_entropy()) + .unwrap() + .into() } /// Derives the account address from an account private key. pub fn address(&self) -> anyhow::Result
{ - Ok(Address::from(AddressNative::try_from(&self.0)?)) + AddressNative::try_from(&self.0).map(Into::into) } /// Derives the account compute key from an account private key. fn compute_key(&self) -> ComputeKey { let compute_key = ComputeKeyNative::try_from(&self.0).unwrap(); - ComputeKey::from(compute_key) + compute_key.into() } /// Reads in an account private key from a base58 string. #[staticmethod] fn from_string(private_key: &str) -> anyhow::Result { - Ok(Self(PrivateKeyNative::from_str(private_key)?)) + PrivateKeyNative::from_str(private_key).map(Self) } /// Returns the account seed. - fn seed(&self) -> String { - self.0.seed().to_string() + fn seed(&self) -> Field { + self.0.seed().into() } /// Returns a signature for the given message (as bytes) using the private key. @@ -70,19 +72,19 @@ impl PrivateKey { } /// Returns the signature secret key. - fn sk_sig(&self) -> String { - self.0.sk_sig().to_string() + fn sk_sig(&self) -> Scalar { + self.0.sk_sig().into() } /// Returns the signature randomizer. - fn r_sig(&self) -> String { - self.0.r_sig().to_string() + fn r_sig(&self) -> Scalar { + self.0.r_sig().into() } /// Initializes a new account view key from an account private key. pub fn view_key(&self) -> ViewKey { let view_key = ViewKeyNative::try_from(&self.0).unwrap(); - ViewKey::from(view_key) + view_key.into() } /// Returns the private key as a base58 string. @@ -110,13 +112,13 @@ impl Deref for PrivateKey { } impl From for PrivateKeyNative { - fn from(private_key: PrivateKey) -> Self { - private_key.0 + fn from(value: PrivateKey) -> Self { + value.0 } } impl From for PrivateKey { - fn from(private_key: PrivateKeyNative) -> Self { - Self(private_key) + fn from(value: PrivateKeyNative) -> Self { + Self(value) } } diff --git a/sdk/src/account/record.rs b/sdk/src/account/record.rs index d7c5383..e27abc3 100644 --- a/sdk/src/account/record.rs +++ b/sdk/src/account/record.rs @@ -15,8 +15,8 @@ // along with the Aleo SDK library. If not, see . use crate::{ - account::{PrivateKey, ViewKey}, - types::{IdentifierNative, ProgramIDNative, RecordCiphertextNative, RecordPlaintextNative}, + types::{RecordCiphertextNative, RecordPlaintextNative}, + Field, Group, Identifier, PrivateKey, ProgramID, ViewKey, }; use std::ops::Deref; @@ -32,13 +32,12 @@ impl RecordCiphertext { /// Creates a record ciphertext from string #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - Ok(Self::from(RecordCiphertextNative::from_str(s)?)) + RecordCiphertextNative::from_str(s).map(Self) } /// Decrypts self into plaintext using the given view key and checks that the owner matches the view key. pub fn decrypt(&self, view_key: &ViewKey) -> anyhow::Result { - let plaintext = self.0.decrypt(view_key)?; - Ok(RecordPlaintext(plaintext)) + self.0.decrypt(view_key).map(Into::into) } /// Determines whether the record belongs to the view key associated with an account. @@ -61,12 +60,13 @@ impl Deref for RecordCiphertext { } impl From for RecordCiphertext { - fn from(record_ciphertext: RecordCiphertextNative) -> Self { - Self(record_ciphertext) + fn from(value: RecordCiphertextNative) -> Self { + Self(value) } } #[pyclass(frozen)] +#[derive(Clone)] pub struct RecordPlaintext(RecordPlaintextNative); #[pymethods] @@ -74,7 +74,7 @@ impl RecordPlaintext { /// Reads in the plaintext string. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - Ok(Self::from(RecordPlaintextNative::from_str(s)?)) + RecordPlaintextNative::from_str(s).map(Self) } /// Returns the owner of the record as a string @@ -82,23 +82,20 @@ impl RecordPlaintext { self.0.owner().to_string() } - /// Returns the nonce of the record as a string - fn nonce(&self) -> String { - self.0.nonce().to_string() + /// Returns the nonce of the program record. + fn nonce(&self) -> Group { + (*self.0.nonce()).into() } /// Attempt to get the serial number of a record to determine whether or not is has been spent - pub fn serial_number_string( + pub fn serial_number( &self, private_key: &PrivateKey, - program_id: &str, - record_name: &str, - ) -> anyhow::Result { - let parsed_program_id = ProgramIDNative::from_str(program_id)?; - let record_identifier = IdentifierNative::from_str(record_name)?; - let commitment = self.to_commitment(&parsed_program_id, &record_identifier)?; - let serial_number = RecordPlaintextNative::serial_number(**private_key, commitment)?; - Ok(serial_number.to_string()) + program_id: &ProgramID, + record_identifier: &Identifier, + ) -> anyhow::Result { + let commitment = self.to_commitment(program_id, record_identifier)?; + RecordPlaintextNative::serial_number(**private_key, commitment).map(Into::into) } /// Returns the plaintext as a string. @@ -120,7 +117,13 @@ impl Deref for RecordPlaintext { } impl From for RecordPlaintext { - fn from(record_plaintext: RecordPlaintextNative) -> Self { - Self(record_plaintext) + fn from(value: RecordPlaintextNative) -> Self { + Self(value) + } +} + +impl From for RecordPlaintextNative { + fn from(value: RecordPlaintext) -> Self { + value.0 } } diff --git a/sdk/src/account/signature.rs b/sdk/src/account/signature.rs index 65814c3..26d29c1 100644 --- a/sdk/src/account/signature.rs +++ b/sdk/src/account/signature.rs @@ -14,10 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Aleo SDK library. If not, see . -use crate::{ - account::{Address, ComputeKey, PrivateKey}, - types::SignatureNative, -}; +use crate::{types::SignatureNative, Address, ComputeKey, PrivateKey, Scalar}; use pyo3::prelude::*; use rand::{rngs::StdRng, SeedableRng}; @@ -30,37 +27,38 @@ use std::{ }; #[pyclass(frozen)] +#[derive(Clone)] pub struct Signature(SignatureNative); #[pymethods] impl Signature { /// Returns the verifier challenge. - fn challenge(&self) -> String { - self.0.challenge().to_string() + fn challenge(&self) -> Scalar { + self.0.challenge().into() } /// Returns the signer compute key. fn compute_key(&self) -> ComputeKey { - ComputeKey::from(self.0.compute_key()) + self.0.compute_key().into() } /// Creates a signature from a string representation. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - let signature = FromStr::from_str(s)?; - Ok(Self(signature)) + FromStr::from_str(s).map(Self) } /// Returns the prover response. - fn response(&self) -> String { - self.0.response().to_string() + fn response(&self) -> Scalar { + self.0.response().into() } /// Returns a signature for the given message (as bytes) using the private key. #[staticmethod] pub fn sign(private_key: &PrivateKey, message: &[u8]) -> anyhow::Result { - let signature = private_key.sign_bytes(message, &mut StdRng::from_entropy())?; - Ok(Self(signature)) + private_key + .sign_bytes(message, &mut StdRng::from_entropy()) + .map(Self) } /// Verifies (challenge == challenge') && (address == address') where: @@ -94,7 +92,7 @@ impl Deref for Signature { } impl From for Signature { - fn from(signature: SignatureNative) -> Self { - Self(signature) + fn from(value: SignatureNative) -> Self { + Self(value) } } diff --git a/sdk/src/account/view_key.rs b/sdk/src/account/view_key.rs index c4c1c81..ac204d4 100644 --- a/sdk/src/account/view_key.rs +++ b/sdk/src/account/view_key.rs @@ -14,10 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the Aleo SDK library. If not, see . -use crate::{ - account::{Address, RecordCiphertext, RecordPlaintext}, - types::ViewKeyNative, -}; +use crate::{types::ViewKeyNative, Address, RecordCiphertext, RecordPlaintext}; use pyo3::prelude::*; @@ -81,7 +78,7 @@ impl Deref for ViewKey { } impl From for ViewKey { - fn from(view_key: ViewKeyNative) -> Self { - Self(view_key) + fn from(value: ViewKeyNative) -> Self { + Self(value) } } diff --git a/sdk/src/coinbase/epoch_challenge.rs b/sdk/src/coinbase/epoch_challenge.rs index 9e8496b..23c9ff5 100644 --- a/sdk/src/coinbase/epoch_challenge.rs +++ b/sdk/src/coinbase/epoch_challenge.rs @@ -79,7 +79,7 @@ impl Deref for EpochChallenge { #[pymethods] impl EpochChallenge { - /// Reads in an epoch challenge from a json string. + /// Parses an epoch challenge from a JSON string. #[staticmethod] fn from_json(json: String) -> anyhow::Result { Ok(serde_json::from_str(&json)?) diff --git a/sdk/src/coinbase/verifying_key.rs b/sdk/src/coinbase/verifying_key.rs index 1eeb4dd..aa572e4 100644 --- a/sdk/src/coinbase/verifying_key.rs +++ b/sdk/src/coinbase/verifying_key.rs @@ -27,8 +27,8 @@ pub struct CoinbaseVerifyingKey(CoinbaseVerifyingKeyNative); impl CoinbaseVerifyingKey {} impl From for CoinbaseVerifyingKey { - fn from(key: CoinbaseVerifyingKeyNative) -> Self { - Self(key) + fn from(value: CoinbaseVerifyingKeyNative) -> Self { + Self(value) } } From efd1155a9f0358b8715a4e012c186337cbbd7a31 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Fri, 24 Nov 2023 20:02:21 +0300 Subject: [PATCH 4/8] Add test for public_transfer --- sdk/test.py | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/sdk/test.py b/sdk/test.py index da6e096..a71be26 100644 --- a/sdk/test.py +++ b/sdk/test.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import aleo import unittest -import json + class TestAleo(unittest.TestCase): @@ -11,7 +11,7 @@ def test_sanity(self): c_address = "aleo184vuwr5u7u0ha5f5k44067dd2uaqewxx6pe5ltha5pv99wvhfqxqv339h4" private_key = aleo.PrivateKey.from_string(c_private_key) - + self.assertEqual(str(private_key), c_private_key) self.assertEqual(str(private_key.view_key()), c_view_key) self.assertEqual(str(private_key.address()), c_address) @@ -40,7 +40,8 @@ def test_decrypt_success(self): self.assertEqual(str(plaintext), c_plaintext) def test_signature_verify(self): - address = aleo.Address.from_string("aleo16u4ecz4yqq0udtnmsy8qzvj8emnua24n27c264f2t3unekdlpy8sh4hat2") + address = aleo.Address.from_string( + "aleo16u4ecz4yqq0udtnmsy8qzvj8emnua24n27c264f2t3unekdlpy8sh4hat2") c_signature = "sign1q366eqppwqvmsq0epddmkpqr7ul5rkkltewatf4wdwd82l5yhypdwfnrng6tkj3ryx36wz2dptfq4aev8pwl85u9u6fk48mwmqe35q7h3ptmdtcfxxlcc6ardzayk5ykn2xzp5mhv3spwl3ajgc3y8mfqdmqs7fq3w4wc6j65e3z9ttthqwfy570yef6l9f8klnskzsu9adquzsjwhw" signature = aleo.Signature.from_string(c_signature) message = bytes("asd", "utf-8") @@ -50,7 +51,8 @@ def test_signature_verify(self): self.assertEqual(signature, aleo.Signature.from_string(c_signature)) def test_account_sanity(self): - private_key = aleo.PrivateKey.from_string("APrivateKey1zkp3dQx4WASWYQVWKkq14v3RoQDfY2kbLssUj7iifi1VUQ6") + private_key = aleo.PrivateKey.from_string( + "APrivateKey1zkp3dQx4WASWYQVWKkq14v3RoQDfY2kbLssUj7iifi1VUQ6") account = aleo.Account.from_private_key(private_key) self.assertEqual(account.private_key(), private_key) @@ -65,7 +67,8 @@ def test_account_sanity(self): self.assertTrue(signature.verify(account.address(), message)) def test_coinbase(self): - address = aleo.Address.from_string("aleo16xwtrvntrfnan84sy3qg2gdkkp5u5p7sjc882lx8n06fjx2k0yqsklw8sv") + address = aleo.Address.from_string( + "aleo16xwtrvntrfnan84sy3qg2gdkkp5u5p7sjc882lx8n06fjx2k0yqsklw8sv") solution_json = "{\"partial_solution\":{\"address\":\"aleo16xwtrvntrfnan84sy3qg2gdkkp5u5p7sjc882lx8n06fjx2k0yqsklw8sv\",\"nonce\":5751994693410499959,\"commitment\":\"puzzle163g3gms8kle6z7pfrnelsxmt5qk88sycdxjrfd2chfrmcaa58uv28u4amjhhzyc08wr6ur2hjsusqvgm7mp\"},\"proof.w\":{\"x\":\"46184004058746376929865476153864114989216680475842020861467330568081354981230088442717116178378251337401583339204\",\"y\":\"183283507821413711045927236980084997259573867323884239590264843665205515176450368153011402822680772267880564185790\",\"infinity\":false}}" challenge_json = "{\"epoch_number\":233,\"epoch_block_hash\":\"ab15lsq2zxsvr0am25afrvnczglagu7utpzuzn2sp94f3vyefm4558quexrn3\",\"degree\":8191}" challenge = aleo.EpochChallenge.from_json(challenge_json) @@ -80,5 +83,41 @@ def test_coinbase(self): # verifying_key = puzzle.verifying_key() # assert solution.verify(verifying_key, challenge, 100) + def test_transfer(self): + private_key = aleo.PrivateKey.from_string( + "APrivateKey1zkp3dQx4WASWYQVWKkq14v3RoQDfY2kbLssUj7iifi1VUQ6") + destination = aleo.Address.from_string( + "aleo16u4ecz4yqq0udtnmsy8qzvj8emnua24n27c264f2t3unekdlpy8sh4hat2") + amount = aleo.Credits(0.3) + query = aleo.Query.rest("https://explorer.hamp.app") + process = aleo.Process.load() + credits = aleo.Program.credits() + process.add_program(credits) + transfer_name = aleo.Identifier.from_string("transfer_public") + transfer_auth = process.authorize(private_key, credits.id(), transfer_name, [ + aleo.Value.from_literal(aleo.Literal.from_address(destination)), + aleo.Value.from_literal(aleo.Literal.from_u64( + aleo.U64(int(amount.micro())))), + ]) + (_transfer_resp, transfer_trace) = process.execute(transfer_auth) + transfer_trace.prepare(query) + transfer_execution = transfer_trace.prove_execution( + aleo.Locator(credits.id(), aleo.Identifier.from_string("transfer"))) + execution_id = transfer_execution.execution_id() + process.verify_execution(transfer_execution) + + (fee_cost, _) = process.execution_cost(transfer_execution) + fee_priority = None + fee_auth = process.authorize_fee_public( + private_key, fee_cost, execution_id, fee_priority) + (_fee_resp, fee_trace) = process.execute(fee_auth) + fee_trace.prepare(query) + fee = fee_trace.prove_fee() + process.verify_fee(fee, execution_id) + + transaction = aleo.Transaction.from_execution(transfer_execution, fee) + print(transaction.to_json()) + + if __name__ == "__main__": unittest.main() From a35d01a322706499ae1614d9600e4ce530484be5 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Fri, 24 Nov 2023 20:05:54 +0300 Subject: [PATCH 5/8] Add type hinting for python sdk Co-authored-by: Haruka --- sdk/aleo.pyi | 389 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 sdk/aleo.pyi diff --git a/sdk/aleo.pyi b/sdk/aleo.pyi new file mode 100644 index 0000000..676de04 --- /dev/null +++ b/sdk/aleo.pyi @@ -0,0 +1,389 @@ +from typing import List, Optional, Tuple + + +class Account: + @staticmethod + def from_private_key(private_key: PrivateKey) -> Account: ... + def private_key(self) -> PrivateKey: ... + def view_key(self) -> ViewKey: ... + def address(self) -> Address: ... + def sign(self, message: bytes) -> Signature: ... + def verify(self, signature: Signature, message: bytes) -> bool: ... + def decrypt(self, record_ciphertext: RecordCiphertext) -> RecordPlaintext: ... + def is_owner(self, record_ciphertext: RecordCiphertext) -> bool: ... + + +class Address: + @staticmethod + def from_string(s: str) -> Address: ... + + +class Authorization: + pass + + +class Boolean: + def __new__(cls, b: bool) -> Boolean: ... + + +class Credits: + def __new__(cls, value: float) -> Credits: ... + def micro(self) -> MicroCredits: ... + + +class CoinbasePuzzle: + @staticmethod + def load() -> CoinbasePuzzle: ... + def verifying_key(self) -> CoinbaseVerifyingKey: ... + + +class CoinbaseVerifyingKey: + pass + + +class ComputeKey: + def address(self) -> Address: ... + def pk_sig(self) -> Group: ... + def pr_sig(self) -> Group: ... + def sk_prf(self) -> Scalar: ... + + +class EpochChallenge: + @staticmethod + def from_json(json: str) -> EpochChallenge: ... + def to_json(self) -> str: ... + + +class Execution: + def execution_id(self) -> Field: ... + + +class Fee: + def is_fee_private(self) -> bool: ... + def is_fee_public(self) -> bool: ... + def payer(self) -> Optional[Address]: ... + def transition(self) -> Transition: ... + + +class Field: + @staticmethod + def from_string(s: str) -> Field: ... + @staticmethod + def from_u128(u128: int) -> Field: ... + @staticmethod + def zero() -> Field: ... + + +class Group: + @staticmethod + def from_string(s: str) -> Group: ... + @staticmethod + def from_u128(u128: int) -> Group: ... + @staticmethod + def zero() -> Group: ... + + +class Identifier: + @staticmethod + def from_string(s: str) -> Identifier: ... + + +class I8: + def __new__(cls, value: int) -> I8: ... + @staticmethod + def zero() -> I8: ... + def __int__(self) -> int: ... + + +class I16: + def __new__(cls, value: int) -> I16: ... + @staticmethod + def zero() -> I16: ... + def __int__(self) -> int: ... + + +class I32: + def __new__(cls, value: int) -> I32: ... + @staticmethod + def zero() -> I32: ... + def __int__(self) -> int: ... + + +class I64: + def __new__(cls, value: int) -> I64: ... + @staticmethod + def zero() -> I64: ... + def __int__(self) -> int: ... + + +class I128: + def __new__(cls, value: int) -> I128: ... + @staticmethod + def zero() -> I128: ... + def __int__(self) -> int: ... + + +class Literal: + @staticmethod + def parse(s: str) -> Literal: ... + @staticmethod + def from_address(address: Address) -> Literal: ... + @staticmethod + def from_field(field: Field) -> Literal: ... + @staticmethod + def from_group(group: Group) -> Literal: ... + @staticmethod + def from_scalar(scalar: Scalar) -> Literal: ... + @staticmethod + def from_signature(signature: Signature) -> Literal: ... + @staticmethod + def from_boolean(boolean: Boolean) -> Literal: ... + @staticmethod + def from_i8(value: I8) -> Literal: ... + @staticmethod + def from_i16(value: I16) -> Literal: ... + @staticmethod + def from_i32(value: I32) -> Literal: ... + @staticmethod + def from_i64(value: I64) -> Literal: ... + @staticmethod + def from_i128(value: I128) -> Literal: ... + @staticmethod + def from_u8(value: U8) -> Literal: ... + @staticmethod + def from_u16(value: U16) -> Literal: ... + @staticmethod + def from_u32(value: U32) -> Literal: ... + @staticmethod + def from_u64(value: U64) -> Literal: ... + @staticmethod + def from_u128(value: U128) -> Literal: ... + def type_name(self) -> str: ... + + +class Locator: + def __new__(cls, program_id: ProgramID, resource: Identifier) -> Locator: ... + @staticmethod + def from_string(s: str) -> Locator: ... + def program_id(self) -> ProgramID: ... + def name(self) -> Identifier: ... + def network(self) -> Identifier: ... + def resource(self) -> Identifier: ... + + +class MicroCredits: + def __new__(cls, value: int) -> MicroCredits: ... + def __int__(self) -> int: ... + + +class PrivateKey: + def address(self) -> Address: ... + def compute_key(self) -> ComputeKey: ... + @staticmethod + def from_string(private_key: str) -> PrivateKey: ... + def seed(self) -> Field: ... + def sign(self, message: bytes) -> Signature: ... + def sk_sig(self) -> Scalar: ... + def r_sig(self) -> Scalar: ... + def view_key(self) -> ViewKey: ... + + +class Process: + @staticmethod + def load() -> Process: ... + def add_program(self, program: Program) -> None: ... + def contains_program(self, program_id: ProgramID) -> bool: ... + + def get_proving_key(self, program_id: ProgramID, + function_name: Identifier) -> ProvingKey: ... + + def insert_proving_key(self, program_id: ProgramID, + function_name: Identifier, proving_key: ProvingKey) -> None: ... + + def get_verifying_key(self, program_id: ProgramID, + function_name: Identifier) -> VerifyingKey: ... + + def insert_verifying_key(self, program_id: ProgramID, + function_name: Identifier, verifying_key: VerifyingKey) -> None: ... + + def authorize(self, private_key: PrivateKey, program_id: ProgramID, + function_name: Identifier, inputs: List[Value]) -> Authorization: ... + + def authorize_fee_private(self, private_key: PrivateKey, credits: RecordPlaintext, base_fee: MicroCredits, + deployment_or_execution_id: Field, priority_fee: Optional[MicroCredits]) -> Authorization: ... + def authorize_fee_public(self, private_key: PrivateKey, base_fee: MicroCredits, + deployment_or_execution_id: Field, priority_fee: Optional[MicroCredits]) -> Authorization: ... + + def execute(self, authorization: Authorization) -> Tuple[Response, Trace]: ... + def verify_execution(self, execution: Execution) -> None: ... + def verify_fee(self, fee: Fee, deployment_or_execution_id: Field) -> None: ... + def execution_cost( + self, execution: Execution) -> Tuple[MicroCredits, Tuple[MicroCredits, MicroCredits]]: ... + + +class Program: + @staticmethod + def from_source(s: str) -> Program: ... + @staticmethod + def credits() -> Program: ... + def id(self) -> ProgramID: ... + def functions(self) -> List[Identifier]: ... + def imports(self) -> List[ProgramID]: ... + def source(self) -> str: ... + + +class ProgramID: + @staticmethod + def from_string(s: str) -> ProgramID: ... + def name(self) -> Identifier: ... + def network(self) -> Identifier: ... + def is_aleo(self) -> bool: ... + + +class ProverSolution: + @staticmethod + def from_json(json: str) -> ProverSolution: ... + def to_json(self) -> str: ... + def address(self) -> Address: ... + def verify(self, verifying_key: CoinbaseVerifyingKey, + epoch_challenge: EpochChallenge, proof_target: int) -> bool: ... + + +class ProvingKey: + @staticmethod + def from_string(s: str) -> ProvingKey: ... + @staticmethod + def from_bytes(bytes: bytes) -> ProvingKey: ... + def bytes(self) -> bytes: ... + + +class Query: + @staticmethod + def rest(url: str) -> Query: ... + + +class RecordCiphertext: + @staticmethod + def from_string(s: str) -> RecordCiphertext: ... + def decrypt(self, view_key: ViewKey) -> RecordPlaintext: ... + def is_owner(self, view_key: ViewKey) -> bool: ... + + +class RecordPlaintext: + @staticmethod + def from_string(s: str) -> RecordPlaintext: ... + def owner(self) -> str: ... + def nonce(self) -> Group: ... + def serial_number(self, private_key: PrivateKey, program_id: ProgramID, + record_identifier: Identifier) -> Field: ... + + +class Response: + def outputs(self) -> List[Value]: ... + + +class Scalar: + @staticmethod + def from_string(s: str) -> Scalar: ... + @staticmethod + def zero() -> Scalar: ... + + +class Signature: + def challenge(self) -> Scalar: ... + def compute_key(self) -> ComputeKey: ... + @staticmethod + def from_string(s: str) -> Signature: ... + def response(self) -> Scalar: ... + @staticmethod + def sign(private_key: PrivateKey, message: bytes) -> Signature: ... + def verify(self, address: Address, message: bytes) -> bool: ... + + +class Trace: + def is_fee(self) -> bool: ... + def is_fee_private(self) -> bool: ... + def is_fee_public(self) -> bool: ... + def transitions(self) -> List[Transition]: ... + def prove_execution(self, locator: Locator) -> Execution: ... + def prove_fee(self) -> Fee: ... + def prepare(self, query: Query) -> None: ... + + +class Transaction: + @staticmethod + def from_execution(execution: Execution, fee: Optional[Fee]) -> Transaction: ... + @staticmethod + def from_json(json: str) -> Transaction: ... + def to_json(self) -> str: ... + + +class Transition: + def id(self) -> str: ... + def program_id(self) -> ProgramID: ... + def function_name(self) -> Identifier: ... + def is_bond(self) -> bool: ... + def is_unbond(self) -> bool: ... + def is_fee_private(self) -> bool: ... + def is_fee_public(self) -> bool: ... + def is_split(self) -> bool: ... + + +class U8: + def __new__(cls, value: int) -> U8: ... + @staticmethod + def zero() -> U8: ... + def __int__(self) -> int: ... + + +class U16: + def __new__(cls, value: int) -> U16: ... + @staticmethod + def zero() -> U16: ... + def __int__(self) -> int: ... + + +class U32: + def __new__(cls, value: int) -> U32: ... + @staticmethod + def zero() -> U32: ... + def __int__(self) -> int: ... + + +class U64: + def __new__(cls, value: int) -> U64: ... + @staticmethod + def zero() -> U64: ... + def __int__(self) -> int: ... + + +class U128: + def __new__(cls, value: int) -> U128: ... + @staticmethod + def zero() -> U128: ... + def __int__(self) -> int: ... + + +class Value: + @staticmethod + def parse(s: str) -> Value: ... + @staticmethod + def from_literal(literal: Literal) -> Value: ... + @staticmethod + def from_record_plaintext(record_plaintext: RecordPlaintext) -> Value: ... + + +class VerifyingKey: + @staticmethod + def from_string(s: str) -> VerifyingKey: ... + @staticmethod + def from_bytes(bytes: bytes) -> VerifyingKey: ... + def bytes(self) -> bytes: ... + + +class ViewKey: + def decrypt(self, record_ciphertext: RecordCiphertext) -> RecordPlaintext: ... + @staticmethod + def from_string(s: str) -> ViewKey: ... + def is_owner(self, record_ciphertext: RecordCiphertext) -> bool: ... + def to_address(self) -> Address: ... From dfc99ae9653fc77f24a1981c475f9b4b2c34e93c Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Fri, 24 Nov 2023 20:17:25 +0300 Subject: [PATCH 6/8] Bump version to 0.2.0 --- sdk/Cargo.lock | 2 +- sdk/Cargo.toml | 2 +- sdk/pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/Cargo.lock b/sdk/Cargo.lock index 2710391..fc03440 100644 --- a/sdk/Cargo.lock +++ b/sdk/Cargo.lock @@ -40,7 +40,7 @@ dependencies = [ [[package]] name = "aleo" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "pyo3", diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 6622cb2..693e329 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "aleo" authors = ["Konstantin Pandl", "Mike Turner", "Roman Proskuryakov"] -version = "0.1.0" +version = "0.2.0" description = "A Python sdk for zero-knowledge cryptography based on Aleo" edition = "2021" license = "GPL-3.0-or-later" diff --git a/sdk/pyproject.toml b/sdk/pyproject.toml index 5e74162..7c67305 100644 --- a/sdk/pyproject.toml +++ b/sdk/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [tool.maturin] name = "aleo" -version = "0.1.0" +version = "0.2.0" description = "A Python SDK for zero-knowledge cryptography based on Aleo" repository = "https://github.com/AleoHQ/python-sdk/tree/master/sdk" license = "GPL-3.0-or-later" From eb522c54f1b0a7a2a70d3c7c766b81e58bdfc3a5 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Sun, 3 Dec 2023 00:14:22 +0300 Subject: [PATCH 7/8] Add serde (json/bytes) and refactor FromStr a little bit --- sdk/aleo.pyi | 41 ++++++++++++++++++++++++++--- sdk/src/account/private_key.rs | 3 +-- sdk/src/account/signature.rs | 2 +- sdk/src/account/view_key.rs | 6 ++--- sdk/src/coinbase/epoch_challenge.rs | 21 ++++++++++++--- sdk/src/coinbase/prover_solution.rs | 22 ++++++++++++---- sdk/src/coinbase/puzzle.rs | 8 +++--- sdk/src/programs/authorization.rs | 30 ++++++++++++++++++++- sdk/src/programs/execution.rs | 30 ++++++++++++++++++++- sdk/src/programs/fee.rs | 29 +++++++++++++++++--- sdk/src/programs/identifier.rs | 3 +-- sdk/src/programs/program.rs | 7 +++-- sdk/src/programs/program_id.rs | 7 +++-- sdk/src/programs/proving_key.rs | 6 ++--- sdk/src/programs/transaction.rs | 14 +++++++++- sdk/src/programs/transition.rs | 28 ++++++++++++++++++++ sdk/src/programs/value.rs | 2 +- sdk/src/programs/verifying_key.rs | 6 ++--- 18 files changed, 215 insertions(+), 50 deletions(-) diff --git a/sdk/aleo.pyi b/sdk/aleo.pyi index 676de04..7b7623f 100644 --- a/sdk/aleo.pyi +++ b/sdk/aleo.pyi @@ -19,7 +19,12 @@ class Address: class Authorization: - pass + @staticmethod + def from_json(json: str) -> Authorization: ... + def to_json(self) -> str: ... + @staticmethod + def from_bytes(bytes: bytes) -> Authorization: ... + def bytes(self) -> bytes: ... class Boolean: @@ -52,10 +57,19 @@ class EpochChallenge: @staticmethod def from_json(json: str) -> EpochChallenge: ... def to_json(self) -> str: ... + @staticmethod + def from_bytes(bytes: bytes) -> EpochChallenge: ... + def bytes(self) -> bytes: ... class Execution: def execution_id(self) -> Field: ... + @staticmethod + def from_json(json: str) -> Execution: ... + def to_json(self) -> str: ... + @staticmethod + def from_bytes(bytes: bytes) -> Execution: ... + def bytes(self) -> bytes: ... class Fee: @@ -63,6 +77,12 @@ class Fee: def is_fee_public(self) -> bool: ... def payer(self) -> Optional[Address]: ... def transition(self) -> Transition: ... + @staticmethod + def from_json(json: str) -> Fee: ... + def to_json(self) -> str: ... + @staticmethod + def from_bytes(bytes: bytes) -> Fee: ... + def bytes(self) -> bytes: ... class Field: @@ -241,13 +261,17 @@ class ProgramID: class ProverSolution: - @staticmethod - def from_json(json: str) -> ProverSolution: ... - def to_json(self) -> str: ... def address(self) -> Address: ... def verify(self, verifying_key: CoinbaseVerifyingKey, epoch_challenge: EpochChallenge, proof_target: int) -> bool: ... + @staticmethod + def from_json(json: str) -> ProverSolution: ... + def to_json(self) -> str: ... + @staticmethod + def from_bytes(bytes: bytes) -> ProverSolution: ... + def bytes(self) -> bytes: ... + class ProvingKey: @staticmethod @@ -316,6 +340,9 @@ class Transaction: @staticmethod def from_json(json: str) -> Transaction: ... def to_json(self) -> str: ... + @staticmethod + def from_bytes(bytes: bytes) -> Transaction: ... + def bytes(self) -> bytes: ... class Transition: @@ -327,6 +354,12 @@ class Transition: def is_fee_private(self) -> bool: ... def is_fee_public(self) -> bool: ... def is_split(self) -> bool: ... + @staticmethod + def from_json(json: str) -> Transition: ... + def to_json(self) -> str: ... + @staticmethod + def from_bytes(bytes: bytes) -> Transition: ... + def bytes(self) -> bytes: ... class U8: diff --git a/sdk/src/account/private_key.rs b/sdk/src/account/private_key.rs index 7d4ec6c..1034883 100644 --- a/sdk/src/account/private_key.rs +++ b/sdk/src/account/private_key.rs @@ -51,8 +51,7 @@ impl PrivateKey { /// Derives the account compute key from an account private key. fn compute_key(&self) -> ComputeKey { - let compute_key = ComputeKeyNative::try_from(&self.0).unwrap(); - compute_key.into() + ComputeKeyNative::try_from(&self.0).unwrap().into() } /// Reads in an account private key from a base58 string. diff --git a/sdk/src/account/signature.rs b/sdk/src/account/signature.rs index 26d29c1..c27e639 100644 --- a/sdk/src/account/signature.rs +++ b/sdk/src/account/signature.rs @@ -45,7 +45,7 @@ impl Signature { /// Creates a signature from a string representation. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - FromStr::from_str(s).map(Self) + SignatureNative::from_str(s).map(Self) } /// Returns the prover response. diff --git a/sdk/src/account/view_key.rs b/sdk/src/account/view_key.rs index ac204d4..cea3ee7 100644 --- a/sdk/src/account/view_key.rs +++ b/sdk/src/account/view_key.rs @@ -38,8 +38,7 @@ impl ViewKey { /// Reads in an account view key from a base58 string. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - let view_key = FromStr::from_str(s)?; - Ok(Self(view_key)) + ViewKeyNative::from_str(s).map(Into::into) } /// Determines whether the record belongs to the account. @@ -49,8 +48,7 @@ impl ViewKey { /// Returns the address corresponding to the view key. fn to_address(&self) -> Address { - let address = self.0.to_address(); - Address::from(address) + self.0.to_address().into() } /// Returns the view key as a base58 string. diff --git a/sdk/src/coinbase/epoch_challenge.rs b/sdk/src/coinbase/epoch_challenge.rs index 23c9ff5..f3af4f9 100644 --- a/sdk/src/coinbase/epoch_challenge.rs +++ b/sdk/src/coinbase/epoch_challenge.rs @@ -18,6 +18,7 @@ use crate::types::EpochChallengeNative; use pyo3::prelude::*; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use snarkvm::prelude::{FromBytes, ToBytes}; use std::ops::Deref; @@ -79,17 +80,29 @@ impl Deref for EpochChallenge { #[pymethods] impl EpochChallenge { - /// Parses an epoch challenge from a JSON string. + /// Parses an EpochChallenge from a JSON string. #[staticmethod] - fn from_json(json: String) -> anyhow::Result { - Ok(serde_json::from_str(&json)?) + fn from_json(json: &str) -> anyhow::Result { + Ok(serde_json::from_str(json)?) } - /// Serialize the given epoch challenge as a JSON string. + /// Serialize the given EpochChallenge as a JSON string. fn to_json(&self) -> anyhow::Result { Ok(serde_json::to_string(&self)?) } + /// Constructs an EpochChallenge from a byte array. + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + EpochChallengeNative::from_bytes_le(bytes).map(Self) + } + + /// Returns the byte representation of an EpochChallenge. + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + + /// Returns the EpochChallenge as a JSON string. fn __str__(&self) -> anyhow::Result { self.to_json() } diff --git a/sdk/src/coinbase/prover_solution.rs b/sdk/src/coinbase/prover_solution.rs index ca61737..b0bb72f 100644 --- a/sdk/src/coinbase/prover_solution.rs +++ b/sdk/src/coinbase/prover_solution.rs @@ -21,6 +21,7 @@ use crate::{ }; use pyo3::prelude::*; +use snarkvm::prelude::{FromBytes, ToBytes}; use std::{ collections::hash_map::DefaultHasher, @@ -32,18 +33,28 @@ pub struct ProverSolution(ProverSolutionNative); #[pymethods] impl ProverSolution { - /// Reads in a prover solution from a JSON string. + /// Reads in a ProverSolution from a JSON string. #[staticmethod] - fn from_json(json: String) -> anyhow::Result { - let solution = serde_json::from_str(&json)?; - Ok(Self(solution)) + fn from_json(json: &str) -> anyhow::Result { + Ok(Self(serde_json::from_str(json)?)) } - /// Serialize the given prover solution as a JSON string. + /// Serialize the given ProverSolution as a JSON string. fn to_json(&self) -> anyhow::Result { Ok(serde_json::to_string(&self.0)?) } + /// Constructs a ProverSolution from a byte array. + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + ProverSolutionNative::from_bytes_le(bytes).map(Self) + } + + /// Returns the byte representation of a ProverSolution. + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + /// Returns the address of the prover. fn address(&self) -> Address { Address::from(self.0.address()) @@ -59,6 +70,7 @@ impl ProverSolution { self.0.verify(verifying_key, epoch_challenge, proof_target) } + /// Returns the ProverSolution as a JSON string. fn __str__(&self) -> anyhow::Result { self.to_json() } diff --git a/sdk/src/coinbase/puzzle.rs b/sdk/src/coinbase/puzzle.rs index 42a0719..7b037c3 100644 --- a/sdk/src/coinbase/puzzle.rs +++ b/sdk/src/coinbase/puzzle.rs @@ -26,14 +26,12 @@ impl CoinbasePuzzle { /// Load the coinbase puzzle proving and verifying keys. #[staticmethod] fn load() -> anyhow::Result { - let coinbase_puzzle = CoinbasePuzzleNative::load()?; - Ok(Self(coinbase_puzzle)) + CoinbasePuzzleNative::load().map(Self) } /// Returns the coinbase verifying key. - fn verifying_key(&self) -> anyhow::Result { - let verifying_key = self.0.coinbase_verifying_key().clone(); - Ok(CoinbaseVerifyingKey::from(verifying_key)) + fn verifying_key(&self) -> CoinbaseVerifyingKey { + self.0.coinbase_verifying_key().clone().into() } #[classattr] diff --git a/sdk/src/programs/authorization.rs b/sdk/src/programs/authorization.rs index 049bfa2..844fd67 100644 --- a/sdk/src/programs/authorization.rs +++ b/sdk/src/programs/authorization.rs @@ -17,13 +17,41 @@ use crate::types::AuthorizationNative; use pyo3::prelude::*; +use snarkvm::prelude::{FromBytes, ToBytes}; #[pyclass(frozen)] #[derive(Clone)] pub struct Authorization(AuthorizationNative); #[pymethods] -impl Authorization {} +impl Authorization { + /// Reads in an Authorization from a JSON string. + #[staticmethod] + fn from_json(json: &str) -> anyhow::Result { + Ok(Self(serde_json::from_str(json)?)) + } + + /// Serialize the given Authorization as a JSON string. + fn to_json(&self) -> anyhow::Result { + Ok(serde_json::to_string(&self.0)?) + } + + /// Constructs an Authorization from a byte array. + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + AuthorizationNative::from_bytes_le(bytes).map(Self) + } + + /// Returns the byte representation of an Authorization. + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + + /// Returns the Authorization as a JSON string. + fn __str__(&self) -> anyhow::Result { + self.to_json() + } +} impl From for Authorization { fn from(value: AuthorizationNative) -> Self { diff --git a/sdk/src/programs/execution.rs b/sdk/src/programs/execution.rs index f7936ff..bdd6b3f 100644 --- a/sdk/src/programs/execution.rs +++ b/sdk/src/programs/execution.rs @@ -17,6 +17,7 @@ use crate::{types::ExecutionNative, Field}; use pyo3::prelude::*; +use snarkvm::prelude::{FromBytes, ToBytes}; use std::ops::Deref; @@ -26,10 +27,37 @@ pub struct Execution(ExecutionNative); #[pymethods] impl Execution { - /// Returns the execution ID. + /// Returns the Execution ID. fn execution_id(&self) -> anyhow::Result { self.0.to_execution_id().map(Into::into) } + + /// Reads in an Execution from a JSON string. + #[staticmethod] + fn from_json(json: &str) -> anyhow::Result { + Ok(Self(serde_json::from_str(json)?)) + } + + /// Serialize the given Execution as a JSON string. + fn to_json(&self) -> anyhow::Result { + Ok(serde_json::to_string(&self.0)?) + } + + /// Constructs an Execution from a byte array. + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + ExecutionNative::from_bytes_le(bytes).map(Self) + } + + /// Returns the byte representation of an Execution. + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + + /// Returns the Execution as a JSON string. + fn __str__(&self) -> anyhow::Result { + self.to_json() + } } impl Deref for Execution { diff --git a/sdk/src/programs/fee.rs b/sdk/src/programs/fee.rs index 6e5e4f5..0f7236b 100644 --- a/sdk/src/programs/fee.rs +++ b/sdk/src/programs/fee.rs @@ -17,6 +17,7 @@ use crate::{types::FeeNative, Address, Transition}; use pyo3::prelude::*; +use snarkvm::prelude::{FromBytes, ToBytes}; use std::ops::Deref; @@ -46,9 +47,31 @@ impl Fee { self.0.transition().clone().into() } - /// Returns the Fee as a string. - fn __str__(&self) -> String { - self.0.to_string() + /// Reads in a Fee from a JSON string. + #[staticmethod] + fn from_json(json: &str) -> anyhow::Result { + Ok(Self(serde_json::from_str(json)?)) + } + + /// Serialize the given Fee as a JSON string. + fn to_json(&self) -> anyhow::Result { + Ok(serde_json::to_string(&self.0)?) + } + + /// Constructs a Fee from a byte array. + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + FeeNative::from_bytes_le(bytes).map(Self) + } + + /// Returns the byte representation of a Fee. + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + + /// Returns the Fee as a JSON string. + fn __str__(&self) -> anyhow::Result { + self.to_json() } fn __eq__(&self, other: &Self) -> bool { diff --git a/sdk/src/programs/identifier.rs b/sdk/src/programs/identifier.rs index 6aae216..8698195 100644 --- a/sdk/src/programs/identifier.rs +++ b/sdk/src/programs/identifier.rs @@ -34,8 +34,7 @@ impl Identifier { /// Parses an identifier from a string. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - let identifier = FromStr::from_str(s)?; - Ok(Self(identifier)) + IdentifierNative::from_str(s).map(Self) } /// Returns the identifier as a string. diff --git a/sdk/src/programs/program.rs b/sdk/src/programs/program.rs index 664a031..f7c42e8 100644 --- a/sdk/src/programs/program.rs +++ b/sdk/src/programs/program.rs @@ -31,19 +31,18 @@ impl Program { /// Creates a program from source code. #[staticmethod] fn from_source(s: &str) -> anyhow::Result { - let program = FromStr::from_str(s)?; - Ok(Self(program)) + ProgramNative::from_str(s).map(Self) } /// Returns the credits.aleo program #[staticmethod] fn credits() -> Self { - Program::from(ProgramNative::credits().unwrap()) + Self(ProgramNative::credits().unwrap()) } /// Returns the id of the program fn id(&self) -> ProgramID { - ProgramID::from(*self.0.id()) + (*self.0.id()).into() } /// Returns all function names present in the program diff --git a/sdk/src/programs/program_id.rs b/sdk/src/programs/program_id.rs index d3de301..02f21c6 100644 --- a/sdk/src/programs/program_id.rs +++ b/sdk/src/programs/program_id.rs @@ -34,18 +34,17 @@ impl ProgramID { /// Parses a string into a program ID. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - let program_id = FromStr::from_str(s)?; - Ok(Self(program_id)) + ProgramIDNative::from_str(s).map(Self) } /// Returns the program name. fn name(&self) -> Identifier { - Identifier::from(*self.0.name()) + (*self.0.name()).into() } /// Returns the network-level domain (NLD). fn network(&self) -> Identifier { - Identifier::from(*self.0.network()) + (*self.0.network()).into() } /// Returns `true` if the network-level domain is `aleo`. diff --git a/sdk/src/programs/proving_key.rs b/sdk/src/programs/proving_key.rs index bb16a68..38492bf 100644 --- a/sdk/src/programs/proving_key.rs +++ b/sdk/src/programs/proving_key.rs @@ -30,15 +30,13 @@ impl ProvingKey { /// Parses a proving key from string. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - let proving_key = FromStr::from_str(s)?; - Ok(Self(proving_key)) + ProvingKeyNative::from_str(s).map(Self) } /// Constructs a proving key from a byte array #[staticmethod] fn from_bytes(bytes: &[u8]) -> anyhow::Result { - let proving_key = ProvingKeyNative::from_bytes_le(bytes)?; - Ok(Self(proving_key)) + ProvingKeyNative::from_bytes_le(bytes).map(Self) } /// Returns the byte representation of a proving key diff --git a/sdk/src/programs/transaction.rs b/sdk/src/programs/transaction.rs index 28f228d..43d2c2d 100644 --- a/sdk/src/programs/transaction.rs +++ b/sdk/src/programs/transaction.rs @@ -20,6 +20,7 @@ use crate::{ }; use pyo3::prelude::*; +use snarkvm::prelude::{FromBytes, ToBytes}; use std::str::FromStr; @@ -44,7 +45,18 @@ impl Transaction { self.0.to_string() } - /// Returns the Transaction as a string. + /// Constructs a Transation from a byte array. + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + TransactionNative::from_bytes_le(bytes).map(Self) + } + + /// Returns the byte representation of a Transaction. + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + + /// Returns the Transaction as a JSON string. fn __str__(&self) -> String { self.to_json() } diff --git a/sdk/src/programs/transition.rs b/sdk/src/programs/transition.rs index 9e0030d..b056580 100644 --- a/sdk/src/programs/transition.rs +++ b/sdk/src/programs/transition.rs @@ -20,6 +20,7 @@ use crate::{ }; use pyo3::prelude::*; +use snarkvm::prelude::{FromBytes, ToBytes}; #[pyclass(frozen)] pub struct Transition(TransitionNative); @@ -65,6 +66,33 @@ impl Transition { fn is_split(&self) -> bool { self.0.is_split() } + + /// Reads in a Transition from a JSON string. + #[staticmethod] + fn from_json(json: &str) -> anyhow::Result { + Ok(Self(serde_json::from_str(json)?)) + } + + /// Serialize the given Transition as a JSON string. + fn to_json(&self) -> anyhow::Result { + Ok(serde_json::to_string(&self.0)?) + } + + /// Constructs a Transition from a byte array. + #[staticmethod] + fn from_bytes(bytes: &[u8]) -> anyhow::Result { + TransitionNative::from_bytes_le(bytes).map(Self) + } + + /// Returns the byte representation of a Transition. + fn bytes(&self) -> anyhow::Result> { + self.0.to_bytes_le() + } + + /// Returns the Transition as a JSON string. + fn __str__(&self) -> anyhow::Result { + self.to_json() + } } impl From for Transition { diff --git a/sdk/src/programs/value.rs b/sdk/src/programs/value.rs index 2e2c241..bb1f8c8 100644 --- a/sdk/src/programs/value.rs +++ b/sdk/src/programs/value.rs @@ -44,7 +44,7 @@ impl Value { /// Initializes the value from a record. #[staticmethod] fn from_record_plaintext(record_plaintext: RecordPlaintext) -> Self { - Self(ValueNative::from(Into::::into( + Self(ValueNative::from(RecordPlaintextNative::from( record_plaintext, ))) } diff --git a/sdk/src/programs/verifying_key.rs b/sdk/src/programs/verifying_key.rs index e8555c5..8ea92bf 100644 --- a/sdk/src/programs/verifying_key.rs +++ b/sdk/src/programs/verifying_key.rs @@ -30,15 +30,13 @@ impl VerifyingKey { /// Parses a veryifying key from string. #[staticmethod] fn from_string(s: &str) -> anyhow::Result { - let verifying_key = FromStr::from_str(s)?; - Ok(Self(verifying_key)) + VerifyingKeyNative::from_str(s).map(Self) } /// Constructs a proving key from a byte array #[staticmethod] fn from_bytes(bytes: &[u8]) -> anyhow::Result { - let veryfying_key = VerifyingKeyNative::from_bytes_le(bytes)?; - Ok(Self(veryfying_key)) + VerifyingKeyNative::from_bytes_le(bytes).map(Self) } /// Returns the byte representation of a veryfying key From 2196cab016aa4f2a80ffbbf228c9956ac099b2a5 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Mon, 4 Dec 2023 22:20:18 +0300 Subject: [PATCH 8/8] Add docs for module and classes --- sdk/aleo.pyi | 3 +-- sdk/src/account/address.rs | 1 + sdk/src/account/compute_key.rs | 1 + sdk/src/account/mod.rs | 3 +++ sdk/src/account/private_key.rs | 1 + sdk/src/account/record.rs | 2 ++ sdk/src/account/signature.rs | 1 + sdk/src/account/view_key.rs | 2 ++ sdk/src/algebra/boolean.rs | 1 + sdk/src/algebra/field.rs | 1 + sdk/src/algebra/group.rs | 1 + sdk/src/algebra/integer.rs | 23 ++++++++++++----------- sdk/src/algebra/scalar.rs | 1 + sdk/src/coinbase/epoch_challenge.rs | 1 + sdk/src/coinbase/prover_solution.rs | 1 + sdk/src/coinbase/puzzle.rs | 1 + sdk/src/coinbase/verifying_key.rs | 1 + sdk/src/credits/mod.rs | 2 ++ sdk/src/lib.rs | 3 +++ sdk/src/programs/authorization.rs | 1 + sdk/src/programs/execution.rs | 1 + sdk/src/programs/fee.rs | 1 + sdk/src/programs/identifier.rs | 1 + sdk/src/programs/literal.rs | 1 + sdk/src/programs/locator.rs | 1 + sdk/src/programs/process.rs | 1 + sdk/src/programs/program.rs | 1 + sdk/src/programs/program_id.rs | 1 + sdk/src/programs/proving_key.rs | 1 + sdk/src/programs/query.rs | 1 + sdk/src/programs/response.rs | 1 + sdk/src/programs/trace.rs | 1 + sdk/src/programs/transaction.rs | 1 + sdk/src/programs/transition.rs | 1 + sdk/src/programs/value.rs | 1 + sdk/src/programs/verifying_key.rs | 1 + 36 files changed, 54 insertions(+), 13 deletions(-) diff --git a/sdk/aleo.pyi b/sdk/aleo.pyi index 7b7623f..1df82fa 100644 --- a/sdk/aleo.pyi +++ b/sdk/aleo.pyi @@ -1,3 +1,4 @@ +from __future__ import annotations from typing import List, Optional, Tuple @@ -98,8 +99,6 @@ class Group: @staticmethod def from_string(s: str) -> Group: ... @staticmethod - def from_u128(u128: int) -> Group: ... - @staticmethod def zero() -> Group: ... diff --git a/sdk/src/account/address.rs b/sdk/src/account/address.rs index d047033..183a11a 100644 --- a/sdk/src/account/address.rs +++ b/sdk/src/account/address.rs @@ -25,6 +25,7 @@ use std::{ str::FromStr, }; +/// The Aleo address type. #[pyclass(frozen)] #[derive(Clone)] pub struct Address(AddressNative); diff --git a/sdk/src/account/compute_key.rs b/sdk/src/account/compute_key.rs index 844a0a3..03f1908 100644 --- a/sdk/src/account/compute_key.rs +++ b/sdk/src/account/compute_key.rs @@ -20,6 +20,7 @@ use pyo3::prelude::*; use std::ops::Deref; +/// The Aleo compute key type. #[pyclass(frozen)] pub struct ComputeKey(ComputeKeyNative); diff --git a/sdk/src/account/mod.rs b/sdk/src/account/mod.rs index b3fcb8c..0fcc3f8 100644 --- a/sdk/src/account/mod.rs +++ b/sdk/src/account/mod.rs @@ -39,6 +39,9 @@ use std::{ hash::{Hash, Hasher}, }; +/// Key management class. Enables the creation of a new Aleo Account, +/// importation of an existing account from an existing private key, +/// and message signing and verification functionality. #[pyclass(frozen)] pub struct Account { private_key: PrivateKey, diff --git a/sdk/src/account/private_key.rs b/sdk/src/account/private_key.rs index 1034883..cc72486 100644 --- a/sdk/src/account/private_key.rs +++ b/sdk/src/account/private_key.rs @@ -29,6 +29,7 @@ use std::{ str::FromStr, }; +/// The Aleo private key type. #[pyclass(frozen)] #[derive(Copy, Clone, PartialEq, Eq)] pub struct PrivateKey(PrivateKeyNative); diff --git a/sdk/src/account/record.rs b/sdk/src/account/record.rs index e27abc3..3297600 100644 --- a/sdk/src/account/record.rs +++ b/sdk/src/account/record.rs @@ -24,6 +24,7 @@ use pyo3::prelude::*; use std::str::FromStr; +/// A value(ciphertext) stored in program record. #[pyclass(frozen)] pub struct RecordCiphertext(RecordCiphertextNative); @@ -65,6 +66,7 @@ impl From for RecordCiphertext { } } +/// A value(plaintext) stored in program record. #[pyclass(frozen)] #[derive(Clone)] pub struct RecordPlaintext(RecordPlaintextNative); diff --git a/sdk/src/account/signature.rs b/sdk/src/account/signature.rs index c27e639..5461415 100644 --- a/sdk/src/account/signature.rs +++ b/sdk/src/account/signature.rs @@ -26,6 +26,7 @@ use std::{ str::FromStr, }; +/// The Aleo signature type. #[pyclass(frozen)] #[derive(Clone)] pub struct Signature(SignatureNative); diff --git a/sdk/src/account/view_key.rs b/sdk/src/account/view_key.rs index cea3ee7..8bede52 100644 --- a/sdk/src/account/view_key.rs +++ b/sdk/src/account/view_key.rs @@ -24,6 +24,8 @@ use std::{ ops::Deref, str::FromStr, }; + +/// The account view key used to decrypt records and ciphertext. #[pyclass(frozen)] #[derive(Clone)] pub struct ViewKey(ViewKeyNative); diff --git a/sdk/src/algebra/boolean.rs b/sdk/src/algebra/boolean.rs index a08df8e..13dced5 100644 --- a/sdk/src/algebra/boolean.rs +++ b/sdk/src/algebra/boolean.rs @@ -23,6 +23,7 @@ use std::{ hash::{Hash, Hasher}, }; +/// The Aleo boolean type. #[pyclass(frozen)] #[derive(Copy, Clone)] pub struct Boolean(BooleanNative); diff --git a/sdk/src/algebra/field.rs b/sdk/src/algebra/field.rs index 81f4aa5..e93bf32 100644 --- a/sdk/src/algebra/field.rs +++ b/sdk/src/algebra/field.rs @@ -26,6 +26,7 @@ use std::{ str::FromStr, }; +/// The Aleo field type. #[pyclass(frozen)] #[derive(Clone)] pub struct Field(FieldNative); diff --git a/sdk/src/algebra/group.rs b/sdk/src/algebra/group.rs index 111e9a5..a09661d 100644 --- a/sdk/src/algebra/group.rs +++ b/sdk/src/algebra/group.rs @@ -26,6 +26,7 @@ use std::{ str::FromStr, }; +/// The Aleo group type. #[pyclass(frozen)] #[derive(Clone)] pub struct Group(GroupNative); diff --git a/sdk/src/algebra/integer.rs b/sdk/src/algebra/integer.rs index eab2122..93da6f9 100644 --- a/sdk/src/algebra/integer.rs +++ b/sdk/src/algebra/integer.rs @@ -28,7 +28,8 @@ use std::{ }; macro_rules! integer { - ($export_ty:ident, $native:ident, $machine:ident) => { + ($export_ty:ident, $native:ident, $machine:ident, $desc:literal) => { + #[doc = concat!("The Aleo ", $desc, " type.")] #[pyclass(frozen)] #[derive(Copy, Clone)] pub struct $export_ty($native); @@ -73,14 +74,14 @@ macro_rules! integer { }; } -integer!(I8, I8Native, i8); -integer!(I16, I16Native, i16); -integer!(I32, I32Native, i32); -integer!(I64, I64Native, i64); -integer!(I128, I128Native, i128); +integer!(I8, I8Native, i8, "signed I8"); +integer!(I16, I16Native, i16, "signed I16"); +integer!(I32, I32Native, i32, "signed I32"); +integer!(I64, I64Native, i64, "signed I64"); +integer!(I128, I128Native, i128, "signed I128"); -integer!(U8, U8Native, u8); -integer!(U16, U16Native, u16); -integer!(U32, U32Native, u32); -integer!(U64, U64Native, u64); -integer!(U128, U128Native, u128); +integer!(U8, U8Native, u8, "unsigned U8"); +integer!(U16, U16Native, u16, "unsigned U16"); +integer!(U32, U32Native, u32, "unsigned U32"); +integer!(U64, U64Native, u64, "unsigned U64"); +integer!(U128, U128Native, u128, "unsigned U128"); diff --git a/sdk/src/algebra/scalar.rs b/sdk/src/algebra/scalar.rs index 36d8cca..7b3ba43 100644 --- a/sdk/src/algebra/scalar.rs +++ b/sdk/src/algebra/scalar.rs @@ -26,6 +26,7 @@ use std::{ str::FromStr, }; +/// The Aleo scalar type. #[pyclass(frozen)] #[derive(Clone)] pub struct Scalar(ScalarNative); diff --git a/sdk/src/coinbase/epoch_challenge.rs b/sdk/src/coinbase/epoch_challenge.rs index f3af4f9..0bf8a24 100644 --- a/sdk/src/coinbase/epoch_challenge.rs +++ b/sdk/src/coinbase/epoch_challenge.rs @@ -22,6 +22,7 @@ use snarkvm::prelude::{FromBytes, ToBytes}; use std::ops::Deref; +/// The Aleo coinbase epoch challenge type. #[pyclass(frozen)] pub struct EpochChallenge(EpochChallengeNative); diff --git a/sdk/src/coinbase/prover_solution.rs b/sdk/src/coinbase/prover_solution.rs index b0bb72f..ac90034 100644 --- a/sdk/src/coinbase/prover_solution.rs +++ b/sdk/src/coinbase/prover_solution.rs @@ -28,6 +28,7 @@ use std::{ hash::{Hash, Hasher}, }; +/// The prover solution for the coinbase puzzle from a prover. #[pyclass(frozen)] pub struct ProverSolution(ProverSolutionNative); diff --git a/sdk/src/coinbase/puzzle.rs b/sdk/src/coinbase/puzzle.rs index 7b037c3..f1656e2 100644 --- a/sdk/src/coinbase/puzzle.rs +++ b/sdk/src/coinbase/puzzle.rs @@ -18,6 +18,7 @@ use crate::{coinbase::CoinbaseVerifyingKey, types::CoinbasePuzzleNative}; use pyo3::prelude::*; +/// The Aleo coinbase puzzle type. #[pyclass] pub struct CoinbasePuzzle(CoinbasePuzzleNative); diff --git a/sdk/src/coinbase/verifying_key.rs b/sdk/src/coinbase/verifying_key.rs index aa572e4..bf4686d 100644 --- a/sdk/src/coinbase/verifying_key.rs +++ b/sdk/src/coinbase/verifying_key.rs @@ -20,6 +20,7 @@ use pyo3::prelude::*; use std::ops::Deref; +/// The Aleo coinbase verifying key type. #[pyclass(frozen)] pub struct CoinbaseVerifyingKey(CoinbaseVerifyingKeyNative); diff --git a/sdk/src/credits/mod.rs b/sdk/src/credits/mod.rs index 150f411..a4fdc04 100644 --- a/sdk/src/credits/mod.rs +++ b/sdk/src/credits/mod.rs @@ -16,6 +16,7 @@ use pyo3::prelude::*; +/// The type represents the amount of Aleo credits. #[pyclass(frozen)] #[derive(Clone, Copy)] pub struct Credits(f64); @@ -43,6 +44,7 @@ impl Credits { const __hash__: Option = None; } +/// The type represents the amount of Aleo microcredits. #[pyclass(frozen)] #[derive(Clone, Copy)] pub struct MicroCredits(u64); diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 9169cce..d708182 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -29,6 +29,9 @@ use coinbase::*; use credits::*; use programs::*; +/// The Aleo Python SDK provides a set of libraries aimed at empowering +/// Python developers with zk (zero-knowledge) programming capabilities +/// via the usage of Aleo's zkSnarks. #[pymodule] #[pyo3(name = "aleo")] fn register_module(_py: Python, m: &PyModule) -> PyResult<()> { diff --git a/sdk/src/programs/authorization.rs b/sdk/src/programs/authorization.rs index 844fd67..ce3f196 100644 --- a/sdk/src/programs/authorization.rs +++ b/sdk/src/programs/authorization.rs @@ -19,6 +19,7 @@ use crate::types::AuthorizationNative; use pyo3::prelude::*; use snarkvm::prelude::{FromBytes, ToBytes}; +/// The Aleo authorization type. #[pyclass(frozen)] #[derive(Clone)] pub struct Authorization(AuthorizationNative); diff --git a/sdk/src/programs/execution.rs b/sdk/src/programs/execution.rs index bdd6b3f..9c866fc 100644 --- a/sdk/src/programs/execution.rs +++ b/sdk/src/programs/execution.rs @@ -21,6 +21,7 @@ use snarkvm::prelude::{FromBytes, ToBytes}; use std::ops::Deref; +/// The type represents a call to an Aleo program. #[pyclass] #[derive(Clone)] pub struct Execution(ExecutionNative); diff --git a/sdk/src/programs/fee.rs b/sdk/src/programs/fee.rs index 0f7236b..7fe4ba5 100644 --- a/sdk/src/programs/fee.rs +++ b/sdk/src/programs/fee.rs @@ -21,6 +21,7 @@ use snarkvm::prelude::{FromBytes, ToBytes}; use std::ops::Deref; +/// The type represents a fee paid to the network, used for rejected transactions. #[pyclass(frozen)] #[derive(Clone)] pub struct Fee(FeeNative); diff --git a/sdk/src/programs/identifier.rs b/sdk/src/programs/identifier.rs index 8698195..9de0b56 100644 --- a/sdk/src/programs/identifier.rs +++ b/sdk/src/programs/identifier.rs @@ -25,6 +25,7 @@ use std::{ str::FromStr, }; +/// The Aleo identifier type. #[pyclass(frozen)] #[derive(Clone)] pub struct Identifier(IdentifierNative); diff --git a/sdk/src/programs/literal.rs b/sdk/src/programs/literal.rs index 0373475..88683dd 100644 --- a/sdk/src/programs/literal.rs +++ b/sdk/src/programs/literal.rs @@ -27,6 +27,7 @@ use std::{ str::FromStr, }; +/// The literal type represents all supported types in snarkVM. #[pyclass(frozen)] #[derive(Clone)] pub struct Literal(LiteralNative); diff --git a/sdk/src/programs/locator.rs b/sdk/src/programs/locator.rs index 8ed9d30..54d86c5 100644 --- a/sdk/src/programs/locator.rs +++ b/sdk/src/programs/locator.rs @@ -28,6 +28,7 @@ use std::{ str::FromStr, }; +/// A locator is of the form `{program_id}/{resource}` (i.e. `howard.aleo/notify`). #[pyclass(frozen)] #[derive(Clone)] pub struct Locator(LocatorNative); diff --git a/sdk/src/programs/process.rs b/sdk/src/programs/process.rs index 05f8490..1c75dd2 100644 --- a/sdk/src/programs/process.rs +++ b/sdk/src/programs/process.rs @@ -24,6 +24,7 @@ use pyo3::prelude::*; use rand::{rngs::StdRng, SeedableRng}; use snarkvm::prelude::cost_in_microcredits; +/// The Aleo process type. #[pyclass] pub struct Process(ProcessNative); diff --git a/sdk/src/programs/program.rs b/sdk/src/programs/program.rs index f7c42e8..d323540 100644 --- a/sdk/src/programs/program.rs +++ b/sdk/src/programs/program.rs @@ -23,6 +23,7 @@ use pyo3::prelude::*; use std::{ops::Deref, str::FromStr}; +/// The Aleo program type. #[pyclass(frozen)] pub struct Program(ProgramNative); diff --git a/sdk/src/programs/program_id.rs b/sdk/src/programs/program_id.rs index 02f21c6..94ed41e 100644 --- a/sdk/src/programs/program_id.rs +++ b/sdk/src/programs/program_id.rs @@ -25,6 +25,7 @@ use std::{ str::FromStr, }; +/// A program ID is of the form `{name}.{network}`. #[pyclass(frozen)] #[derive(Clone)] pub struct ProgramID(ProgramIDNative); diff --git a/sdk/src/programs/proving_key.rs b/sdk/src/programs/proving_key.rs index 38492bf..e797ec8 100644 --- a/sdk/src/programs/proving_key.rs +++ b/sdk/src/programs/proving_key.rs @@ -21,6 +21,7 @@ use snarkvm::prelude::{FromBytes, ToBytes}; use std::str::FromStr; +/// The Aleo proving key type. #[pyclass(frozen)] #[derive(Clone)] pub struct ProvingKey(ProvingKeyNative); diff --git a/sdk/src/programs/query.rs b/sdk/src/programs/query.rs index f8e0b6e..b9f12fb 100644 --- a/sdk/src/programs/query.rs +++ b/sdk/src/programs/query.rs @@ -18,6 +18,7 @@ use crate::types::QueryNative; use pyo3::prelude::*; +/// The Aleo query type. #[pyclass] #[derive(Clone)] pub struct Query(QueryNative); diff --git a/sdk/src/programs/response.rs b/sdk/src/programs/response.rs index 65d39aa..4e489e9 100644 --- a/sdk/src/programs/response.rs +++ b/sdk/src/programs/response.rs @@ -18,6 +18,7 @@ use crate::{programs::Value, types::ResponseNative}; use pyo3::prelude::*; +/// The Aleo response type. #[pyclass(frozen)] pub struct Response(ResponseNative); diff --git a/sdk/src/programs/trace.rs b/sdk/src/programs/trace.rs index 8bb22ce..0c2860e 100644 --- a/sdk/src/programs/trace.rs +++ b/sdk/src/programs/trace.rs @@ -22,6 +22,7 @@ use crate::{ use pyo3::prelude::*; use rand::{rngs::StdRng, SeedableRng}; +/// The Aleo trace type. #[pyclass] pub struct Trace(TraceNative); diff --git a/sdk/src/programs/transaction.rs b/sdk/src/programs/transaction.rs index 43d2c2d..d23e4c3 100644 --- a/sdk/src/programs/transaction.rs +++ b/sdk/src/programs/transaction.rs @@ -24,6 +24,7 @@ use snarkvm::prelude::{FromBytes, ToBytes}; use std::str::FromStr; +/// Represents a transaction of a deploy, execute or fee type. #[pyclass(frozen)] pub struct Transaction(TransactionNative); diff --git a/sdk/src/programs/transition.rs b/sdk/src/programs/transition.rs index b056580..5981dd8 100644 --- a/sdk/src/programs/transition.rs +++ b/sdk/src/programs/transition.rs @@ -22,6 +22,7 @@ use crate::{ use pyo3::prelude::*; use snarkvm::prelude::{FromBytes, ToBytes}; +/// The Aleo transition type. #[pyclass(frozen)] pub struct Transition(TransitionNative); diff --git a/sdk/src/programs/value.rs b/sdk/src/programs/value.rs index bb1f8c8..d9a02f3 100644 --- a/sdk/src/programs/value.rs +++ b/sdk/src/programs/value.rs @@ -23,6 +23,7 @@ use pyo3::prelude::*; use std::str::FromStr; +/// The Aleo value type to interact with a call to an Aleo program. #[pyclass(frozen)] #[derive(Clone)] pub struct Value(ValueNative); diff --git a/sdk/src/programs/verifying_key.rs b/sdk/src/programs/verifying_key.rs index 8ea92bf..2a919b3 100644 --- a/sdk/src/programs/verifying_key.rs +++ b/sdk/src/programs/verifying_key.rs @@ -21,6 +21,7 @@ use snarkvm::prelude::{FromBytes, ToBytes}; use std::str::FromStr; +/// The Aleo verifying key type. #[pyclass(frozen)] #[derive(Clone)] pub struct VerifyingKey(VerifyingKeyNative);