diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx index cfe6f6f0..602daf9f 100644 --- a/packages/nextjs/app/page.tsx +++ b/packages/nextjs/app/page.tsx @@ -19,11 +19,11 @@ const Home: NextPage = () => { // console.log(data); - const { writeAsync } = useScaffoldContractWrite({ - contractName: "HelloStarknet", - functionName: "increase_balance", - args: [1], - }); + // const { writeAsync } = useScaffoldContractWrite({ + // contractName: "HelloStarknet", + // functionName: "increase_balance", + // args: [1], + // }); // console.log(data, isLoading); return ( diff --git a/packages/nextjs/contracts/deployedContracts.ts b/packages/nextjs/contracts/deployedContracts.ts index 12718ae3..25751cee 100644 --- a/packages/nextjs/contracts/deployedContracts.ts +++ b/packages/nextjs/contracts/deployedContracts.ts @@ -3,288 +3,6 @@ * You should not edit it manually or your changes might be overwritten. */ -const deployedContracts = { - sepolia: { - HelloStarknet: { - address: - "0x05e316173428d7358cb71e532acc6983608ec8a021f6e418a847969c53753452", - abi: [ - { - type: "impl", - name: "HelloStarknetImpl", - interface_name: "contracts::helloStarknet::IHelloStarknet", - }, - { - type: "interface", - name: "contracts::helloStarknet::IHelloStarknet", - items: [ - { - type: "function", - name: "increase_balance", - inputs: [ - { - name: "amount", - type: "core::felt252", - }, - ], - outputs: [], - state_mutability: "external", - }, - { - type: "function", - name: "get_balance", - inputs: [], - outputs: [ - { - type: "core::felt252", - }, - ], - state_mutability: "view", - }, - { - type: "function", - name: "get_balance6", - inputs: [], - outputs: [ - { - type: "core::felt252", - }, - ], - state_mutability: "view", - }, - { - type: "function", - name: "get_balance_increment", - inputs: [ - { - name: "amount", - type: "core::felt252", - }, - ], - outputs: [ - { - type: "core::felt252", - }, - ], - state_mutability: "view", - }, - ], - }, - { - type: "event", - name: "contracts::helloStarknet::HelloStarknet::Event", - kind: "enum", - variants: [], - }, - ], - }, - SimpleStorage: { - address: - "0x0501ed68f98395647d6b5f81500b74b597a93058eb8382f7231903d7933290b2", - abi: [ - { - type: "impl", - name: "SimpleStorageImpl", - interface_name: "contracts::simpleStorage::ISimpleStorage", - }, - { - type: "interface", - name: "contracts::simpleStorage::ISimpleStorage", - items: [ - { - type: "function", - name: "get_name", - inputs: [], - outputs: [ - { - type: "core::felt252", - }, - ], - state_mutability: "view", - }, - { - type: "function", - name: "set_name", - inputs: [ - { - name: "name", - type: "core::felt252", - }, - ], - outputs: [], - state_mutability: "external", - }, - ], - }, - { - type: "constructor", - name: "constructor", - inputs: [ - { - name: "name", - type: "core::felt252", - }, - ], - }, - { - type: "event", - name: "contracts::simpleStorage::SimpleStorage::Event", - kind: "enum", - variants: [], - }, - ], - }, - Vote: { - address: - "0x0246ede155184ce1f1f8ac52fece63870db4725c777b456237a81340ceff85b7", - abi: [ - { - type: "impl", - name: "VoteImpl", - interface_name: "contracts::vote::VoteTrait", - }, - { - type: "enum", - name: "core::bool", - variants: [ - { - name: "False", - type: "()", - }, - { - name: "True", - type: "()", - }, - ], - }, - { - type: "interface", - name: "contracts::vote::VoteTrait", - items: [ - { - type: "function", - name: "get_vote_status", - inputs: [], - outputs: [ - { - type: "(core::integer::u8, core::integer::u8, core::integer::u8, core::integer::u8)", - }, - ], - state_mutability: "view", - }, - { - type: "function", - name: "voter_can_vote", - inputs: [ - { - name: "user_address", - type: "core::starknet::contract_address::ContractAddress", - }, - ], - outputs: [ - { - type: "core::bool", - }, - ], - state_mutability: "view", - }, - { - type: "function", - name: "is_voter_registered", - inputs: [ - { - name: "address", - type: "core::starknet::contract_address::ContractAddress", - }, - ], - outputs: [ - { - type: "core::bool", - }, - ], - state_mutability: "view", - }, - { - type: "function", - name: "vote", - inputs: [ - { - name: "vote", - type: "core::integer::u8", - }, - ], - outputs: [], - state_mutability: "external", - }, - ], - }, - { - type: "constructor", - name: "constructor", - inputs: [ - { - name: "voter_1", - type: "core::starknet::contract_address::ContractAddress", - }, - { - name: "voter_2", - type: "core::starknet::contract_address::ContractAddress", - }, - { - name: "voter_3", - type: "core::starknet::contract_address::ContractAddress", - }, - ], - }, - { - type: "event", - name: "contracts::vote::Vote::VoteCast", - kind: "struct", - members: [ - { - name: "voter", - type: "core::starknet::contract_address::ContractAddress", - kind: "data", - }, - { - name: "vote", - type: "core::integer::u8", - kind: "data", - }, - ], - }, - { - type: "event", - name: "contracts::vote::Vote::UnauthorizedAttempt", - kind: "struct", - members: [ - { - name: "unauthorized_address", - type: "core::starknet::contract_address::ContractAddress", - kind: "data", - }, - ], - }, - { - type: "event", - name: "contracts::vote::Vote::Event", - kind: "enum", - variants: [ - { - name: "VoteCast", - type: "contracts::vote::Vote::VoteCast", - kind: "nested", - }, - { - name: "UnauthorizedAttempt", - type: "contracts::vote::Vote::UnauthorizedAttempt", - kind: "nested", - }, - ], - }, - ], - }, - }, -} as const; +const deployedContracts = {} as const; export default deployedContracts; diff --git a/packages/nextjs/hooks/scaffold-stark/useScaffoldContractWrite.ts b/packages/nextjs/hooks/scaffold-stark/useScaffoldContractWrite.ts index 58e17778..35e0222f 100644 --- a/packages/nextjs/hooks/scaffold-stark/useScaffoldContractWrite.ts +++ b/packages/nextjs/hooks/scaffold-stark/useScaffoldContractWrite.ts @@ -38,7 +38,7 @@ export const useScaffoldContractWrite = < calls: deployedContractData ? [ { - contractAddress: deployedContractData.address, + contractAddress: deployedContractData?.address, entrypoint: functionName, calldata: args as any[], }, diff --git a/packages/nextjs/utils/scaffold-stark/contract.ts b/packages/nextjs/utils/scaffold-stark/contract.ts index a3d091d6..0e794cd6 100644 --- a/packages/nextjs/utils/scaffold-stark/contract.ts +++ b/packages/nextjs/utils/scaffold-stark/contract.ts @@ -12,6 +12,7 @@ import { UseContractReadProps, UseContractWriteProps, } from "@starknet-react/core"; +import { Address } from "@starknet-react/chains"; type ConfiguredChainId = (typeof scaffoldConfig)["targetNetworks"][0]["network"]; @@ -35,7 +36,7 @@ export enum ContractCodeStatus { } export type GenericContract = { - address: string; + address: Address; abi: Abi; }; export type GenericContractsDeclaration = { @@ -134,10 +135,11 @@ export type UseScaffoldWriteConfig< > > = { contractName: TContractName; - // onBlockConfirmation?: (txnReceipt: TransactionReceipt) => void; TODO check this lines - // blockConfirmations?: number; } & IsContractDeclarationMissing< - Partial, + Partial & { + functionName: string; + args: any[]; + }, { functionName: TFunctionName; } & Omit< diff --git a/packages/snfoundry/contracts/src/helloStarknet.cairo b/packages/snfoundry/contracts/src/helloStarknet.cairo index 8e071285..dd140881 100644 --- a/packages/snfoundry/contracts/src/helloStarknet.cairo +++ b/packages/snfoundry/contracts/src/helloStarknet.cairo @@ -1,34 +1,29 @@ #[starknet::interface] pub trait IHelloStarknet { - fn increase_balance(ref self: TContractState, amount: felt252); - fn get_balance(self: @TContractState) -> felt252; - fn get_balance6(self: @TContractState) -> felt252; - fn get_balance_increment(self: @TContractState, amount: felt252) -> felt252; + fn increase_balance(ref self: TContractState, amount: u32); + fn get_balance(self: @TContractState) -> u32; + fn get_balance_increment(self: @TContractState, amount: u32) -> u32; } #[starknet::contract] mod HelloStarknet { #[storage] struct Storage { - balance: felt252, + balance: u32, } #[abi(embed_v0)] impl HelloStarknetImpl of super::IHelloStarknet { - fn increase_balance(ref self: ContractState, amount: felt252) { - assert(amount != 0, 'amount cant be 0'); + fn increase_balance(ref self: ContractState, amount: u32) { + assert(amount !=0, 'amount cannot be 0'); self.balance.write(self.balance.read() + amount); } - fn get_balance(self: @ContractState) -> felt252 { + fn get_balance(self: @ContractState) -> u32 { self.balance.read() } - fn get_balance6(self: @ContractState) -> felt252 { - self.balance.read() + 1 - } - - fn get_balance_increment(self: @ContractState, amount: felt252) -> felt252 { + fn get_balance_increment(self: @ContractState, amount: u32) -> u32 { self.balance.read() + amount } } diff --git a/packages/snfoundry/contracts/src/lib.cairo b/packages/snfoundry/contracts/src/lib.cairo index fafe85f4..ebeb0718 100644 --- a/packages/snfoundry/contracts/src/lib.cairo +++ b/packages/snfoundry/contracts/src/lib.cairo @@ -1,3 +1,122 @@ mod helloStarknet; mod simpleStorage; -mod vote; \ No newline at end of file +mod vote; + +use starknet::ContractAddress; + +#[starknet::interface] +trait IData { + fn get_data(self: @T) -> u64; + fn set_data(ref self: T, new_value: u64); +} + +#[starknet::interface] +trait IOwnable { + fn transfer_ownership(ref self: T, new_owner: ContractAddress); + fn owner(self: @T) -> ContractAddress; +} + +#[starknet::component] +pub mod ownable_component { + use super::{ContractAddress, IOwnable}; + use starknet::get_caller_address; + use core::num::traits::Zero; + + #[storage] + struct Storage { + owner: ContractAddress + } + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + OwnershipTransferred: OwnershipTransferred + } + + #[derive(Drop, starknet::Event)] + struct OwnershipTransferred { + #[key] + previous_owner: ContractAddress, + new_owner: ContractAddress, + } + + #[embeddable_as(Ownable)] + impl OwnableImpl< + TContractState, +HasComponent + > of IOwnable> { + fn transfer_ownership( + ref self: ComponentState, new_owner: ContractAddress + ) { + self.only_owner(); + self._transfer_ownership(new_owner); + } + fn owner(self: @ComponentState) -> ContractAddress { + self.owner.read() + } + } + + #[generate_trait] + pub impl InternalImpl< + TContractState, +HasComponent + > of InternalTrait { + fn only_owner(self: @ComponentState) { + let owner: ContractAddress = self.owner.read(); + let caller: ContractAddress = get_caller_address(); + assert(caller.is_non_zero(), 'ZERO_ADDRESS_CALLER'); + assert(caller == owner, 'NOT_OWNER'); + } + + fn _transfer_ownership( + ref self: ComponentState, new_owner: ContractAddress + ) { + let previous_owner: ContractAddress = self.owner.read(); + self.owner.write(new_owner); + self + .emit( + OwnershipTransferred { previous_owner: previous_owner, new_owner: new_owner } + ); + } + } +} + +#[starknet::contract] +mod Ownable { + use contracts::ownable_component; + use super::{ContractAddress, IData}; + + component!(path: ownable_component, storage: ownable, event: OwnableEvent); + + #[abi(embed_v0)] + impl OwnableImpl = ownable_component::Ownable; + + impl OwnableInternalImpl = ownable_component::InternalImpl; + + #[storage] + struct Storage { + data: u64, + #[substorage(v0)] + ownable: ownable_component::Storage + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + OwnableEvent: ownable_component::Event + } + + #[constructor] + fn constructor(ref self: ContractState, initial_owner: ContractAddress) { + self.ownable.owner.write(initial_owner); + self.data.write(1); + } + #[abi(embed_v0)] + impl OwnableDataImpl of IData { + fn get_data(self: @ContractState) -> u64 { + self.data.read() + } + fn set_data(ref self: ContractState, new_value: u64) { + self.ownable.only_owner(); + self.data.write(new_value); + } + } +} diff --git a/packages/snfoundry/contracts/src/vote.cairo b/packages/snfoundry/contracts/src/vote.cairo index fb724bf2..ba5d19df 100644 --- a/packages/snfoundry/contracts/src/vote.cairo +++ b/packages/snfoundry/contracts/src/vote.cairo @@ -132,12 +132,12 @@ mod Vote { let is_voter: bool = self.registered_voter.read((address)); let can_vote: bool = self.can_vote.read((address)); - if (can_vote == false) { + if (!can_vote) { // can_vote == false self.emit(UnauthorizedAttempt { unauthorized_address: address, }); } - assert(is_voter == true, 'USER_NOT_REGISTERED'); - assert(can_vote == true, 'USER_ALREADY_VOTED'); + assert(is_voter, 'USER_NOT_REGISTERED'); + assert(can_vote, 'USER_ALREADY_VOTED'); } } diff --git a/packages/snfoundry/scripts_js/deploy.js b/packages/snfoundry/scripts_js/deploy.js index 5fdaf183..6a7f5bd6 100644 --- a/packages/snfoundry/scripts_js/deploy.js +++ b/packages/snfoundry/scripts_js/deploy.js @@ -132,7 +132,7 @@ const deployScript = async () => { } = await deployContract(null, "HelloStarknet"); // can pass another argument for the exported contract name await deployContract( { - name: 1, + name: 1 }, "SimpleStorage" ); // simple storage receives an argument in the constructor @@ -150,6 +150,12 @@ const deployScript = async () => { }, "Vote" ); + await deployContract( + { + initial_owner: addAddressPadding("0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691"), + }, + "Ownable" + ); // simple storage receives an argument in the constructor }; deployScript()