diff --git a/deploy_assignment/.gitignore b/deploy_assignment/.gitignore new file mode 100644 index 0000000..4096f8b --- /dev/null +++ b/deploy_assignment/.gitignore @@ -0,0 +1,5 @@ +target +.snfoundry_cache/ +snfoundry_trace/ +coverage/ +profile/ diff --git a/deploy_assignment/Scarb.lock b/deploy_assignment/Scarb.lock new file mode 100644 index 0000000..331f7f6 --- /dev/null +++ b/deploy_assignment/Scarb.lock @@ -0,0 +1,24 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "deploy_assignment" +version = "0.1.0" +dependencies = [ + "snforge_std_deprecated", +] + +[[package]] +name = "snforge_scarb_plugin_deprecated" +version = "0.48.1" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:8b822345a82a4479cfbf8e605a4cd25c0a622585fd5640c4add524c5da5a8b55" + +[[package]] +name = "snforge_std_deprecated" +version = "0.48.1" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:da9e4a8bbf8ba5f85e91e4b37a967b10eca0cb377a505eb7a8f37d0df721a874" +dependencies = [ + "snforge_scarb_plugin_deprecated", +] diff --git a/deploy_assignment/Scarb.toml b/deploy_assignment/Scarb.toml new file mode 100644 index 0000000..efa4b87 --- /dev/null +++ b/deploy_assignment/Scarb.toml @@ -0,0 +1,52 @@ +[package] +name = "deploy_assignment" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.11.4" + +[dev-dependencies] +snforge_std_deprecated = "0.48.0" +assert_macros = "2.11.4" + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" + +[tool.scarb] +allow-prebuilt-plugins = ["snforge_std_deprecated"] + +# Visit https://foundry-rs.github.io/starknet-foundry/appendix/scarb-toml.html for more information + +# [tool.snforge] # Define `snforge` tool section +# exit_first = true # Stop tests execution immediately upon the first failure +# fuzzer_runs = 1234 # Number of runs of the random fuzzer +# fuzzer_seed = 1111 # Seed for the random fuzzer + +# [[tool.snforge.fork]] # Used for fork testing +# name = "SOME_NAME" # Fork name +# url = "http://your.rpc.url" # Url of the RPC provider +# block_id.tag = "latest" # Block to fork from (block tag) + +# [[tool.snforge.fork]] +# name = "SOME_SECOND_NAME" +# url = "http://your.second.rpc.url" +# block_id.number = "123" # Block to fork from (block number) + +# [[tool.snforge.fork]] +# name = "SOME_THIRD_NAME" +# url = "http://your.third.rpc.url" +# block_id.hash = "0x123" # Block to fork from (block hash) + +# [profile.dev.cairo] # Configure Cairo compiler +# unstable-add-statements-code-locations-debug-info = true # Should be used if you want to use coverage +# unstable-add-statements-functions-debug-info = true # Should be used if you want to use coverage/profiler +# inlining-strategy = "avoid" # Should be used if you want to use coverage + +# [features] # Used for conditional compilation +# enable_for_tests = [] # Feature name and list of other features that should be enabled with it diff --git a/deploy_assignment/snfoundry.toml b/deploy_assignment/snfoundry.toml new file mode 100644 index 0000000..0f29e90 --- /dev/null +++ b/deploy_assignment/snfoundry.toml @@ -0,0 +1,11 @@ +# Visit https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html +# and https://foundry-rs.github.io/starknet-foundry/projects/configuration.html for more information + +# [sncast.default] # Define a profile name +# url = "https://starknet-sepolia.public.blastapi.io/rpc/v0_8" # Url of the RPC provider +# accounts-file = "../account-file" # Path to the file with the account data +# account = "mainuser" # Account from `accounts_file` or default account file that will be used for the transactions +# keystore = "~/keystore" # Path to the keystore file +# wait-params = { timeout = 300, retry-interval = 10 } # Wait for submitted transaction parameters +# block-explorer = "StarkScan" # Block explorer service used to display links to transaction details +# show-explorer-links = true # Print links pointing to pages with transaction details in the chosen block explorer diff --git a/deploy_assignment/src/lib.cairo b/deploy_assignment/src/lib.cairo new file mode 100644 index 0000000..a9d9b90 --- /dev/null +++ b/deploy_assignment/src/lib.cairo @@ -0,0 +1,47 @@ +/// Interface representing `HelloContract`. +/// This interface allows modification and retrieval of the contract balance. +#[starknet::interface] +pub trait IHelloStarknet { + /// Increase contract balance. + fn increase_balance(ref self: TContractState, amount: felt252); + /// Retrieve contract balance. + fn get_balance(self: @TContractState) -> felt252; + /// set contract balance + fn set_balance(ref self: TContractState, amount: felt252); + ///reset contract balance + fn reset_balance(ref self: TContractState); +} + +/// Simple contract for managing balance. +#[starknet::contract] +mod HelloStarknet { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + + #[storage] + struct Storage { + balance: felt252, + } + + #[abi(embed_v0)] + impl HelloStarknetImpl of super::IHelloStarknet { + fn increase_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount cannot be 0'); + self.balance.write(self.balance.read() + amount); + } + + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + fn set_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount should greater than 0'); + self.balance.write(self.balance.read() + amount); + } + + fn reset_balance(ref self: ContractState) { + self.balance.write(0) + } + } +} + +///Assignment +/// https://hackmd.io/@2HvjOfndR8aIXDSoavRrVw/B1zFPtM6gg \ No newline at end of file diff --git a/deploy_assignment/task/assignment b/deploy_assignment/task/assignment new file mode 100644 index 0000000..9e28514 --- /dev/null +++ b/deploy_assignment/task/assignment @@ -0,0 +1,31 @@ +**My Assignment Solution +** +Step 1 +i created an account using command below in my terminal + +" sncast create –url –name " + +Step 2 +funded the address gotten from the first step: +go to https://starknet-faucet.vercel.app/ to fund your account. + +Step 3 +Deployed the account using: +sncast deploy –url –name + +Step 4 +Deployed my HelloStarknet contract: + +Step 5: +Test function increase_balance by 80 in the terminal using +![1](https://hackmd.io/_uploads/rkBnuKMael.png) + +Test function set_count to "30" in the terminal: + +![Screenshot from 2025-10-07 13-35-10](https://hackmd.io/_uploads/HJJVYtGael.png) + +Test function reset_balance + +Used Sncast to transfer STRK for the terminal + +The token reflected in the wallet almost immediately diff --git a/deploy_assignment/tests/test_contract.cairo b/deploy_assignment/tests/test_contract.cairo new file mode 100644 index 0000000..afc393e --- /dev/null +++ b/deploy_assignment/tests/test_contract.cairo @@ -0,0 +1,47 @@ +use starknet::ContractAddress; + +use snforge_std_deprecated::{declare, ContractClassTrait, DeclareResultTrait}; + +use deploy_assignment::IHelloStarknetSafeDispatcher; +use deploy_assignment::IHelloStarknetSafeDispatcherTrait; +use deploy_assignment::IHelloStarknetDispatcher; +use deploy_assignment::IHelloStarknetDispatcherTrait; + +fn deploy_contract(name: ByteArray) -> ContractAddress { + let contract = declare(name).unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@ArrayTrait::new()).unwrap(); + contract_address +} + +#[test] +fn test_increase_balance() { + let contract_address = deploy_contract("HelloStarknet"); + + let dispatcher = IHelloStarknetDispatcher { contract_address }; + + let balance_before = dispatcher.get_balance(); + assert(balance_before == 0, 'Invalid balance'); + + dispatcher.increase_balance(42); + + let balance_after = dispatcher.get_balance(); + assert(balance_after == 42, 'Invalid balance'); +} + +#[test] +#[feature("safe_dispatcher")] +fn test_cannot_increase_balance_with_zero_value() { + let contract_address = deploy_contract("HelloStarknet"); + + let safe_dispatcher = IHelloStarknetSafeDispatcher { contract_address }; + + let balance_before = safe_dispatcher.get_balance().unwrap(); + assert(balance_before == 0, 'Invalid balance'); + + match safe_dispatcher.increase_balance(0) { + Result::Ok(_) => core::panic_with_felt252('Should have panicked'), + Result::Err(panic_data) => { + assert(*panic_data.at(0) == 'Amount cannot be 0', *panic_data.at(0)); + } + }; +}