Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Account to component #783

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
331844d
fix: link (#545)
ericnordelo Jan 20, 2023
2e7758e
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts
ericnordelo Oct 6, 2023
77cca2d
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts
ericnordelo Oct 10, 2023
4fc9be5
feat: update logic
ericnordelo Oct 10, 2023
ce91ed0
feat: add mocks
ericnordelo Oct 10, 2023
4a90358
docs: update
ericnordelo Oct 11, 2023
7f74150
feat: update docs
ericnordelo Oct 11, 2023
bff9179
Update src/account/account.cairo
ericnordelo Oct 18, 2023
4415191
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts into f…
ericnordelo Oct 18, 2023
100c483
feat: apply review updates
ericnordelo Oct 18, 2023
b3e2106
Merge branch 'feat/migrate-account-to-component' of github.com:ericno…
ericnordelo Oct 18, 2023
0570e44
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts into f…
ericnordelo Oct 18, 2023
52df8b1
feat: update overview
ericnordelo Oct 18, 2023
9705ce7
Update docs/modules/ROOT/pages/api/account.adoc
ericnordelo Oct 23, 2023
feeac44
feat: apply review updates
ericnordelo Oct 23, 2023
0f64992
Merge branch 'feat/migrate-account-to-component' of github.com:ericno…
ericnordelo Oct 23, 2023
f9ce9eb
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts into f…
ericnordelo Oct 24, 2023
fcdcdf7
feat: flatten events
ericnordelo Oct 24, 2023
d12a610
feat: add account preset
ericnordelo Oct 25, 2023
66c3fd7
feat: apply review updates
ericnordelo Oct 30, 2023
daa9d68
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts into f…
ericnordelo Oct 30, 2023
495ff94
feat: apply review updates
ericnordelo Oct 30, 2023
472b04c
feat: remove preset
ericnordelo Oct 30, 2023
a83b810
feat: apply review updates
ericnordelo Oct 31, 2023
cc8d2f9
feat: rename components
ericnordelo Oct 31, 2023
296122f
feat: update docs
ericnordelo Oct 31, 2023
2e16eaa
fix: remove failing macro
ericnordelo Oct 31, 2023
d53d1c9
fix: imports in docs
ericnordelo Oct 31, 2023
265faa7
docs: update section title
ericnordelo Oct 31, 2023
c89e8b6
fix: missing title update
ericnordelo Oct 31, 2023
4eeafa9
feat: use get component macro
ericnordelo Nov 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v3
- uses: software-mansion/setup-scarb@v1
with:
scarb-version: "2.3.0-rc1"
scarb-version: "2.3.0"
- name: Markdown lint
uses: DavidAnson/markdownlint-cli2-action@5b7c9f74fec47e6b15667b2cc23c63dff11e449e # v9
with:
Expand Down
6 changes: 6 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Code generated by scarb DO NOT EDIT.
version = 1

[[package]]
name = "openzeppelin"
version = "0.7.0"
ericnordelo marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "openzeppelin"
version = "0.7.0"
cairo-version = "2.3.0-rc0"
cairo-version = "2.3.0"
authors = ["OpenZeppelin Community <maintainers@openzeppelin.org>"]
description = "OpenZeppelin Contracts written in Cairo for StarkNet, a decentralized ZK Rollup"
documentation = "https://docs.openzeppelin.com/contracts-cairo"
Expand All @@ -11,7 +11,7 @@ license-file = "LICENSE"
keywords = ["openzeppelin", "starknet", "cairo", "contracts", "security", "standards"]

[dependencies]
starknet = "=2.3.0-rc0"
starknet = "2.3.0"

[lib]

Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/api/account.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Returns the short string `'VALID'` if valid, otherwise it reverts.
```javascript
use openzeppelin::account::Account;
```
Account component extending xref:ISRC6[`ISRC6`].
Account component implementing xref:ISRC6[`ISRC6`].

[.contract-index]
.Embeddable Functions
Expand Down
2 changes: 2 additions & 0 deletions docs/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ mod MyAccount {
#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
AccountEvent: account_component::Event,
#[flat]
SRC5Event: src5_component::Event
}

Expand Down
3 changes: 1 addition & 2 deletions src/account.cairo
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
mod account;
mod dual_account;
mod interface;
mod presets;

use account::Account;
use interface::AccountABIDispatcher;
use interface::AccountABIDispatcherTrait;
use interface::AccountCamelABIDispatcher;
use interface::AccountCamelABIDispatcherTrait;
64 changes: 32 additions & 32 deletions src/account/account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -102,32 +102,36 @@ mod Account {
}
}

/// Adds camelCase support for `ISRC6`.
#[embeddable_as(SRC6CamelOnlyImpl)]
impl SRC6CamelOnly<
#[embeddable_as(DeclarerImpl)]
impl Declarer<
TContractState,
+HasComponent<TContractState>,
+SRC5::HasComponent<TContractState>,
+Drop<TContractState>
> of interface::ISRC6CamelOnly<ComponentState<TContractState>> {
fn isValidSignature(
self: @ComponentState<TContractState>, hash: felt252, signature: Array<felt252>
> of interface::IDeclarer<ComponentState<TContractState>> {
/// Verifies the validity of the signature for the current transaction.
/// This function is used by the protocol to verify `declare` transactions.
fn __validate_declare__(
self: @ComponentState<TContractState>, class_hash: felt252
) -> felt252 {
self.is_valid_signature(hash, signature)
self.validate_transaction()
}
}

#[embeddable_as(DeclarerImpl)]
impl Declarer<
#[embeddable_as(DeployableImpl)]
impl Deployable<
TContractState,
+HasComponent<TContractState>,
+SRC5::HasComponent<TContractState>,
+Drop<TContractState>
> of interface::IDeclarer<ComponentState<TContractState>> {
> of interface::IDeployable<ComponentState<TContractState>> {
/// Verifies the validity of the signature for the current transaction.
/// This function is used by the protocol to verify `declare` transactions.
fn __validate_declare__(
self: @ComponentState<TContractState>, class_hash: felt252
/// This function is used by the protocol to verify `deploy_account` transactions.
fn __validate_deploy__(
self: @ComponentState<TContractState>,
class_hash: felt252,
contract_address_salt: felt252,
public_key: felt252
) -> felt252 {
self.validate_transaction()
}
Expand All @@ -153,6 +157,21 @@ mod Account {
}
}

/// Adds camelCase support for `ISRC6`.
#[embeddable_as(SRC6CamelOnlyImpl)]
impl SRC6CamelOnly<
TContractState,
+HasComponent<TContractState>,
+SRC5::HasComponent<TContractState>,
+Drop<TContractState>
> of interface::ISRC6CamelOnly<ComponentState<TContractState>> {
fn isValidSignature(
self: @ComponentState<TContractState>, hash: felt252, signature: Array<felt252>
) -> felt252 {
self.is_valid_signature(hash, signature)
}
}

/// Adds camelCase support for `PublicKeyTrait`.
#[embeddable_as(PublicKeyCamelImpl)]
impl PublicKeyCamel<
Expand All @@ -170,25 +189,6 @@ mod Account {
}
}

#[embeddable_as(DeployableImpl)]
impl Deployable<
TContractState,
+HasComponent<TContractState>,
+SRC5::HasComponent<TContractState>,
+Drop<TContractState>
> of interface::IDeployable<ComponentState<TContractState>> {
/// Verifies the validity of the signature for the current transaction.
/// This function is used by the protocol to verify `deploy_account` transactions.
fn __validate_deploy__(
self: @ComponentState<TContractState>,
class_hash: felt252,
contract_address_salt: felt252,
public_key: felt252
) -> felt252 {
self.validate_transaction()
}
}

#[generate_trait]
impl InternalImpl<
TContractState,
Expand Down
38 changes: 23 additions & 15 deletions src/account/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,39 @@ trait IDeployable<TState> {
) -> felt252;
}

//
// Account ABI
//

#[starknet::interface]
trait AccountABI<TState> {
// ISRC6
fn __execute__(self: @TState, calls: Array<Call>) -> Array<Span<felt252>>;
fn __validate__(self: @TState, calls: Array<Call>) -> felt252;
fn is_valid_signature(self: @TState, hash: felt252, signature: Array<felt252>) -> felt252;

// ISRC5
fn supports_interface(self: @TState, interface_id: felt252) -> bool;

// IDeclarer
fn __validate_declare__(self: @TState, class_hash: felt252) -> felt252;

// DeployerTrait
ericnordelo marked this conversation as resolved.
Show resolved Hide resolved
fn __validate_deploy__(
self: @TState, class_hash: felt252, contract_address_salt: felt252, public_key: felt252
self: @TState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252
ericnordelo marked this conversation as resolved.
Show resolved Hide resolved
) -> felt252;

// PublicKeyTrait
fn set_public_key(ref self: TState, new_public_key: felt252);
fn get_public_key(self: @TState) -> felt252;
fn is_valid_signature(self: @TState, hash: felt252, signature: Array<felt252>) -> felt252;
fn supports_interface(self: @TState, interface_id: felt252) -> bool;
}

// Entry points case-convention is enforced by the protocol
#[starknet::interface]
trait AccountCamelABI<TState> {
fn __execute__(self: @TState, calls: Array<Call>) -> Array<Span<felt252>>;
fn __validate__(self: @TState, calls: Array<Call>) -> felt252;
fn __validate_declare__(self: @TState, classHash: felt252) -> felt252;
fn __validate_deploy__(
self: @TState, classHash: felt252, contractAddressSalt: felt252, publicKey: felt252
) -> felt252;
fn setPublicKey(ref self: TState, newPublicKey: felt252);
fn getPublicKey(self: @TState) -> felt252;
// ISRC6CamelOnly
fn isValidSignature(self: @TState, hash: felt252, signature: Array<felt252>) -> felt252;

// ISRC5Camel
fn supportsInterface(self: @TState, interfaceId: felt252) -> bool;

// PublicKeyCamelTrait
fn setPublicKey(ref self: TState, newPublicKey: felt252);
fn getPublicKey(self: @TState) -> felt252;
ericnordelo marked this conversation as resolved.
Show resolved Hide resolved
}
3 changes: 3 additions & 0 deletions src/account/presets.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod account;

use account::Account;
55 changes: 55 additions & 0 deletions src/account/presets/account.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts for Cairo v0.7.0 (account/presets/account.cairo)

/// # Account Preset
///
/// Openzeppelin's account contract.
#[starknet::contract]
mod Account {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love the Account preset name. I guess we can differentiate between the two Accounts with component and contract, but idk. AccountPreset maybe or something better? Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, but i'd go with BasicAccount or something, to distinguish from future EthereumAccount, or MultisigAccount presets. I'd never call "preset" a contract btw.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I rather keep the name clean as Account, because the separation exists in the directory (imports) structure, and you cannot use a component as a preset, or a preset as a component (compiler error), so the potential issues from this clash are minimal IMO.

For Account we can come up with a name, but what about ERC20? Which names would you use for the preset? Since we are probably removing presets in favor of Wizard anyway, I vote for keeping the name as just Account (and ERC20 when it comes the time).

Let me know if I still should update it, and to what name then.

Copy link
Contributor

@martriay martriay Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can keep it like this for the time being, we can reassess post wizard

use openzeppelin::account::Account as account_component;
use openzeppelin::introspection::src5::SRC5 as src5_component;

component!(path: account_component, storage: account, event: AccountEvent);
component!(path: src5_component, storage: src5, event: SRC5Event);

// Account
#[abi(embed_v0)]
impl SRC6Impl = account_component::SRC6Impl<ContractState>;
#[abi(embed_v0)]
impl SRC6CamelOnlyImpl = account_component::SRC6CamelOnlyImpl<ContractState>;
#[abi(embed_v0)]
impl PublicKeyImpl = account_component::PublicKeyImpl<ContractState>;
#[abi(embed_v0)]
impl PublicKeyCamelImpl = account_component::PublicKeyCamelImpl<ContractState>;
#[abi(embed_v0)]
impl DeclarerImpl = account_component::DeclarerImpl<ContractState>;
#[abi(embed_v0)]
impl DeployableImpl = account_component::DeployableImpl<ContractState>;
impl AccountInternalImpl = account_component::InternalImpl<ContractState>;

// SRC5
#[abi(embed_v0)]
impl SRC5Impl = src5_component::SRC5Impl<ContractState>;

#[storage]
struct Storage {
#[substorage(v0)]
account: account_component::Storage,
#[substorage(v0)]
src5: src5_component::Storage
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
AccountEvent: account_component::Event,
#[flat]
SRC5Event: src5_component::Event
}

#[constructor]
fn constructor(ref self: ContractState, public_key: felt252) {
self.account.initializer(public_key);
}
}
1 change: 1 addition & 0 deletions src/tests.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod access;
mod account;
mod introspection;
mod mocks;
mod presets;
mod security;
mod token;
mod upgrades;
Expand Down
14 changes: 7 additions & 7 deletions src/tests/account/test_account.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use openzeppelin::account::Account::{InternalTrait, OwnerAdded, OwnerRemoved};
use openzeppelin::account::Account::{InternalTrait, OwnerAdded, OwnerRemoved, SRC6CamelOnlyImpl};
ericnordelo marked this conversation as resolved.
Show resolved Hide resolved
use openzeppelin::account::Account::{PublicKeyCamelImpl, PublicKeyImpl};
use openzeppelin::account::Account::{TRANSACTION_VERSION, QUERY_VERSION};
use openzeppelin::account::Account;
Expand Down Expand Up @@ -48,10 +48,10 @@ fn ACCOUNT_ADDRESS() -> ContractAddress {
fn SIGNED_TX_DATA() -> SignedTransactionData {
SignedTransactionData {
private_key: 1234,
public_key: 883045738439352841478194533192765345509759306772397516907181243450667673002,
transaction_hash: 2717105892474786771566982177444710571376803476229898722748888396642649184538,
r: 3068558690657879390136740086327753007413919701043650133111397282816679110801,
s: 3355728545224320878895493649495491771252432631648740019139167265522817576501
public_key: 0x1f3c942d7f492a37608cde0d77b884a5aa9e11d2919225968557370ddb5a5aa,
transaction_hash: 0x601d3d2e265c10ff645e1554c435e72ce6721f0ba5fc96f0c650bfc6231191a,
r: 0x6c8be1fb0fb5c730fbd7abaecbed9d980376ff2e660dfcd157e158d2b026891,
s: 0x76b4669998eb933f44a59eace12b41328ab975ceafddf92602b21eb23e22e35
martriay marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -137,10 +137,10 @@ fn test_isValidSignature() {

state.account.set_public_key(data.public_key);

let is_valid = Account::SRC6CamelOnlyImpl::isValidSignature(@state, hash, good_signature);
let is_valid = state.account.isValidSignature(hash, good_signature);
assert(is_valid == starknet::VALIDATED, 'Should accept valid signature');

let is_valid = Account::SRC6CamelOnlyImpl::isValidSignature(@state, hash, bad_signature);
let is_valid = state.account.isValidSignature(hash, bad_signature);
assert(is_valid == 0, 'Should reject invalid signature');
}

Expand Down
6 changes: 2 additions & 4 deletions src/tests/account/test_dual_account.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use openzeppelin::account::dual_account::{DualCaseAccountABI, DualCaseAccount};
use openzeppelin::account::{AccountABIDispatcherTrait, AccountABIDispatcher};
use openzeppelin::account::{AccountCamelABIDispatcherTrait, AccountCamelABIDispatcher};
use openzeppelin::introspection::interface::ISRC5_ID;
use openzeppelin::tests::account::test_account::SIGNED_TX_DATA;
use openzeppelin::tests::mocks::account_mocks::{
Expand All @@ -24,12 +23,12 @@ fn setup_snake() -> (DualCaseAccount, AccountABIDispatcher) {
)
}

fn setup_camel() -> (DualCaseAccount, AccountCamelABIDispatcher) {
fn setup_camel() -> (DualCaseAccount, AccountABIDispatcher) {
let mut calldata = array![PUBKEY];
let target = utils::deploy(CamelAccountMock::TEST_CLASS_HASH, calldata);
(
DualCaseAccount { contract_address: target },
AccountCamelABIDispatcher { contract_address: target }
AccountABIDispatcher { contract_address: target }
andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved
)
}

Expand Down Expand Up @@ -242,4 +241,3 @@ fn test_dual_supportsInterface_exists_and_panics() {
let (_, dispatcher) = setup_account_panic();
dispatcher.supports_interface(ISRC5_ID);
}

Loading