The following is a demo of an exercise in the Cairo Smart Contract Hacking Course by JohnnyTime. A Live workshop was held at the Blockchain Security Academy, where we went through the exercise and explained the solution.
YouTube video of the workshop recording: TBD.
- Install asdf
- Using asdf, add scrab 2.6.3 as a plugin:
asdf plugin add scarb
- Using asdf, install scarb 2.6.3 -
asdf install scarb 2.6.3
- Using asdf, set as a global var version -
asdf global scarb 2.6.3
- Install Starknet-Foundry 0.24.0
- Run -
curl -L https://raw.githubusercontent.com/foundry-rs/starknet-foundry/master/scripts/install.sh | sh
- Install version
0.23.0
|snfoundryup -v 0.23.0
- Run -
- Install Universal Sierra Compiler
- Run -
curl -L https://raw.githubusercontent.com/software-mansion/universal-sierra-compiler/master/scripts/install.sh | sh
- Run -
In the following exercise, your goal is to create a simple smart contract with Storage, and Events, and the test is using Starknet-Foundry.
If you are not sure about the syntax, you can always refer to the Lecture video or to the Cheatsheet File.
In the file src\lib.cairo
:
- Define an interface
IMyFirstCairoContract
with 2 functions:set_number()
- receives a u256number
and returns nothing.get_number()
- received nothing and returns a u256.
- Create a new cairo smart contract
MyFirstCairoContract
:- Define the contract storage with one
u256
variable namednumber
. - Define an event that is called
NumberChanged
, which will be emitted anytime the number is being changed in the storage, the event should be emitted with the old and new number - Create a constructor function that receives an
initial_value
u256 and writes it to storage, don't forget to emit aNumberChanged
event. - Implement the
IMyFirstCairoContract
interface, and bothset_number()
andget_number()
accordingly so they will set and get the number from the contract's storage, and emi$$ $$t an event in case the number is changed.
- Define the contract storage with one
In the file tests\test_contract.cairo
:
- Import all the relevant libraries:
- Starknet Contract Address -
starknet::ContractAddress;
- Starknet Foundry -
snforge_std::{declare, ContractClassTrait, start_prank, stop_prank, CheatTarget, start_warp};
- Your Cairo contract Dispatcher and Dispatcher Trait.
- Starknet Contract Address -
- Inside the test
first_cairo_contract_tests
:- Declare the contract class.
- Prepare the constructor call data using
Serde
. - Deploy the contract and create a Dispatcher.
- Check the initial value in the contract storage, and make sure it's correct (use
assert
). - Update the number in storage to
1337
. - Check the new value in the contract storage, and make sure it's correct (use
assert
).
Bonus: In your test file, check that the right events were emitted after the number was changed.
To run all tests, use the command snforge test
.