├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature-request.md
├── pull_request_template.md
└── workflows
│ └── verify_cairo_programs.yml
├── .gitignore
├── .npmrc
├── .tool-versions
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── Scarb.lock
├── Scarb.toml
├── _typos.toml
├── components
├── ThemeImage.tsx
├── useSidebarToggle.tsx
├── useTheme.tsx
└── useTracking.tsx
├── footer.tsx
├── layout.tsx
├── listings
├── advanced-concepts
│ ├── commit_reveal
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── commit_reveal.cairo
│ │ │ └── lib.cairo
│ ├── ecdsa_verification
│ │ ├── .gitignore
│ │ ├── Scarb.lock
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── ecdsa_verification.cairo
│ │ │ └── lib.cairo
│ ├── hash_solidity_compatible
│ │ ├── .gitignore
│ │ ├── Scarb.lock
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ └── tests.cairo
│ ├── hash_trait
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── hash_trait.cairo
│ │ │ └── lib.cairo
│ ├── library_calls
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── lib.cairo
│ │ │ ├── library_call.cairo
│ │ │ └── tests.cairo
│ ├── sierra_ir
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ ├── simple_program.sierra
│ │ └── src
│ │ │ ├── lib.cairo
│ │ │ └── simple_program.cairo
│ ├── simple_account
│ │ ├── .gitignore
│ │ ├── Scarb.lock
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── lib.cairo
│ │ │ ├── simple_account.cairo
│ │ │ └── tests.cairo
│ ├── store_using_packing
│ │ ├── .gitignore
│ │ ├── Scarb.lock
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ └── tests.cairo
│ ├── struct_as_mapping_key
│ │ ├── .gitignore
│ │ ├── Scarb.lock
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ └── test.cairo
│ ├── verify_proofs
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ ├── package.json
│ │ └── src
│ │ │ ├── circuit
│ │ │ ├── circuit.circom
│ │ │ └── input.json
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ └── verifier
│ │ │ ├── groth16_verifier.cairo
│ │ │ └── groth16_verifier_constants.cairo
│ └── write_to_any_slot
│ │ ├── .gitignore
│ │ ├── Scarb.lock
│ │ ├── Scarb.toml
│ │ └── src
│ │ ├── contract.cairo
│ │ ├── lib.cairo
│ │ └── tests.cairo
├── applications
│ ├── advanced_factory
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ ├── mock_upgrade.cairo
│ │ │ └── tests.cairo
│ ├── coin_flip
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ ├── mock_randomness.cairo
│ │ │ └── tests.cairo
│ ├── components
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── countable.cairo
│ │ │ ├── lib.cairo
│ │ │ ├── others.cairo
│ │ │ ├── others
│ │ │ └── switch_collision.cairo
│ │ │ ├── ownable.cairo
│ │ │ └── switchable.cairo
│ ├── components_dependencies
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contract_countable.cairo
│ │ │ ├── contract_countable_switchable.cairo
│ │ │ ├── contract_countable_switchable_internal.cairo
│ │ │ ├── countable_dep_switch.cairo
│ │ │ ├── countable_internal_dep_switch.cairo
│ │ │ └── lib.cairo
│ ├── constant_product_amm
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contracts.cairo
│ │ │ ├── lib.cairo
│ │ │ └── tests.cairo
│ ├── crowdfunding
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── campaign.cairo
│ │ │ ├── campaign
│ │ │ └── pledgeable.cairo
│ │ │ ├── lib.cairo
│ │ │ ├── mock_upgrade.cairo
│ │ │ └── tests.cairo
│ ├── erc20
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── lib.cairo
│ │ │ └── token.cairo
│ ├── erc721
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── erc721.cairo
│ │ │ ├── interfaces.cairo
│ │ │ ├── lib.cairo
│ │ │ ├── mocks.cairo
│ │ │ ├── mocks
│ │ │ ├── account.cairo
│ │ │ ├── non_receiver.cairo
│ │ │ └── receiver.cairo
│ │ │ └── tests.cairo
│ ├── l1_l2_token_bridge
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ ├── solidity
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── foundry.toml
│ │ │ ├── lib
│ │ │ │ ├── forge-std
│ │ │ │ │ ├── .gitattributes
│ │ │ │ │ ├── .github
│ │ │ │ │ │ └── workflows
│ │ │ │ │ │ │ ├── ci.yml
│ │ │ │ │ │ │ └── sync.yml
│ │ │ │ │ ├── .gitignore
│ │ │ │ │ ├── CONTRIBUTING.md
│ │ │ │ │ ├── LICENSE-APACHE
│ │ │ │ │ ├── LICENSE-MIT
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── foundry.toml
│ │ │ │ │ ├── package.json
│ │ │ │ │ ├── scripts
│ │ │ │ │ │ └── vm.py
│ │ │ │ │ ├── src
│ │ │ │ │ │ ├── Base.sol
│ │ │ │ │ │ ├── Script.sol
│ │ │ │ │ │ ├── StdAssertions.sol
│ │ │ │ │ │ ├── StdChains.sol
│ │ │ │ │ │ ├── StdCheats.sol
│ │ │ │ │ │ ├── StdError.sol
│ │ │ │ │ │ ├── StdInvariant.sol
│ │ │ │ │ │ ├── StdJson.sol
│ │ │ │ │ │ ├── StdMath.sol
│ │ │ │ │ │ ├── StdStorage.sol
│ │ │ │ │ │ ├── StdStyle.sol
│ │ │ │ │ │ ├── StdToml.sol
│ │ │ │ │ │ ├── StdUtils.sol
│ │ │ │ │ │ ├── Test.sol
│ │ │ │ │ │ ├── Vm.sol
│ │ │ │ │ │ ├── console.sol
│ │ │ │ │ │ ├── console2.sol
│ │ │ │ │ │ ├── interfaces
│ │ │ │ │ │ │ ├── IERC1155.sol
│ │ │ │ │ │ │ ├── IERC165.sol
│ │ │ │ │ │ │ ├── IERC20.sol
│ │ │ │ │ │ │ ├── IERC4626.sol
│ │ │ │ │ │ │ ├── IERC721.sol
│ │ │ │ │ │ │ └── IMulticall3.sol
│ │ │ │ │ │ ├── mocks
│ │ │ │ │ │ │ ├── MockERC20.sol
│ │ │ │ │ │ │ └── MockERC721.sol
│ │ │ │ │ │ └── safeconsole.sol
│ │ │ │ │ └── test
│ │ │ │ │ │ ├── StdAssertions.t.sol
│ │ │ │ │ │ ├── StdChains.t.sol
│ │ │ │ │ │ ├── StdCheats.t.sol
│ │ │ │ │ │ ├── StdError.t.sol
│ │ │ │ │ │ ├── StdJson.t.sol
│ │ │ │ │ │ ├── StdMath.t.sol
│ │ │ │ │ │ ├── StdStorage.t.sol
│ │ │ │ │ │ ├── StdStyle.t.sol
│ │ │ │ │ │ ├── StdToml.t.sol
│ │ │ │ │ │ ├── StdUtils.t.sol
│ │ │ │ │ │ ├── Vm.t.sol
│ │ │ │ │ │ ├── compilation
│ │ │ │ │ │ ├── CompilationScript.sol
│ │ │ │ │ │ ├── CompilationScriptBase.sol
│ │ │ │ │ │ ├── CompilationTest.sol
│ │ │ │ │ │ └── CompilationTestBase.sol
│ │ │ │ │ │ ├── fixtures
│ │ │ │ │ │ ├── broadcast.log.json
│ │ │ │ │ │ ├── test.json
│ │ │ │ │ │ └── test.toml
│ │ │ │ │ │ └── mocks
│ │ │ │ │ │ ├── MockERC20.t.sol
│ │ │ │ │ │ └── MockERC721.t.sol
│ │ │ │ └── starknet
│ │ │ │ │ ├── IStarknetMessaging.sol
│ │ │ │ │ ├── IStarknetMessagingEvents.sol
│ │ │ │ │ ├── NamedStorage.sol
│ │ │ │ │ └── StarknetMessaging.sol
│ │ │ ├── src
│ │ │ │ ├── IMintableToken.sol
│ │ │ │ ├── IMintableTokenEvents.sol
│ │ │ │ ├── MintableTokenMock.sol
│ │ │ │ ├── StarknetMessagingLocal.sol
│ │ │ │ └── TokenBridge.sol
│ │ │ └── test
│ │ │ │ └── TokenBridge.t.sol
│ │ └── src
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ ├── mintable_token_mock.cairo
│ │ │ └── tests.cairo
│ ├── merkle_tree
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ └── tests.cairo
│ ├── nft_dutch_auction
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── erc721.cairo
│ │ │ ├── lib.cairo
│ │ │ └── nft_dutch_auction.cairo
│ ├── simple_storage_starknetjs
│ │ ├── .env.example
│ │ ├── .gitignore
│ │ ├── Scarb.lock
│ │ ├── Scarb.toml
│ │ ├── abi.json
│ │ ├── index.js
│ │ └── src
│ │ │ ├── lib.cairo
│ │ │ └── storage.cairo
│ ├── simple_vault
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── lib.cairo
│ │ │ └── simple_vault.cairo
│ ├── staking
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── contract.cairo
│ │ │ ├── lib.cairo
│ │ │ └── tests
│ │ │ ├── staking_tests.cairo
│ │ │ └── tokens.cairo
│ ├── timelock
│ │ ├── .gitignore
│ │ ├── Scarb.toml
│ │ └── src
│ │ │ ├── erc721.cairo
│ │ │ ├── lib.cairo
│ │ │ ├── tests
│ │ │ ├── timelock.cairo
│ │ │ └── utils.cairo
│ │ │ └── timelock.cairo
│ └── upgradeable_contract
│ │ ├── .gitignore
│ │ ├── Scarb.lock
│ │ ├── Scarb.toml
│ │ └── src
│ │ ├── lib.cairo
│ │ ├── tests.cairo
│ │ ├── upgradeable_contract_v0.cairo
│ │ └── upgradeable_contract_v1.cairo
├── cairo_cheatsheet
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── array_example.cairo
│ │ ├── dict_example.cairo
│ │ ├── enum_example.cairo
│ │ ├── felt_example.cairo
│ │ ├── if_let_example.cairo
│ │ ├── lib.cairo
│ │ ├── loop_example.cairo
│ │ ├── mapping_example.cairo
│ │ ├── match_example.cairo
│ │ ├── struct_example.cairo
│ │ ├── tuple_example.cairo
│ │ ├── type_casting_example.cairo
│ │ ├── while_example.cairo
│ │ └── while_let_example.cairo
└── getting-started
│ ├── calling_other_contracts
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── caller.cairo
│ │ └── lib.cairo
│ ├── constructor
│ ├── counter
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── counter.cairo
│ │ └── lib.cairo
│ ├── custom_type_entrypoints
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── contract.cairo
│ │ └── lib.cairo
│ ├── errors
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── custom_errors.cairo
│ │ ├── lib.cairo
│ │ ├── simple_errors.cairo
│ │ └── vault_errors.cairo
│ ├── events
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── counter.cairo
│ │ └── lib.cairo
│ ├── factory
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── lib.cairo
│ │ └── simple_factory.cairo
│ ├── mappings
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── lib.cairo
│ │ └── mappings.cairo
│ ├── storage
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── contract.cairo
│ │ ├── lib.cairo
│ │ └── minimal_contract.cairo
│ ├── storing_custom_types
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── contract.cairo
│ │ └── lib.cairo
│ ├── testing_how_to
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ │ ├── contract.cairo
│ │ ├── lib.cairo
│ │ └── test_contract.cairo
│ ├── variables
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ ├── src
│ │ ├── global_variables.cairo
│ │ ├── lib.cairo
│ │ ├── local_variables.cairo
│ │ └── storage_variables.cairo
│ └── storage_variables.sierra
│ └── visibility
│ ├── .gitignore
│ ├── Scarb.lock
│ ├── Scarb.toml
│ └── src
│ ├── lib.cairo
│ └── visibility.cairo
├── package.json
├── pages
├── advanced-concepts
│ ├── account_abstraction
│ │ ├── account_contract.md
│ │ ├── account_spending_limits.md
│ │ └── index.md
│ ├── commit-reveal.md
│ ├── hash-solidity-compatible.md
│ ├── hashing.md
│ ├── library_calls.md
│ ├── optimisations
│ │ └── store_using_packing.md
│ ├── plugins.md
│ ├── sierra_ir.md
│ ├── sierra_ir_storage_contract.md
│ ├── signature_verification.md
│ ├── struct-mapping-key.md
│ ├── verify_proofs.md
│ └── write_to_any_slot.md
├── applications
│ ├── advanced_factory.md
│ ├── constant-product-amm.md
│ ├── crowdfunding.md
│ ├── erc20.md
│ ├── erc721.md
│ ├── l1_l2_token_bridge.md
│ ├── merkle_tree.md
│ ├── nft_dutch_auction.md
│ ├── random_number_generator.md
│ ├── signature_verification.md
│ ├── simple_storage_starknetjs.md
│ ├── simple_vault.md
│ ├── staking.md
│ ├── timelock.md
│ └── upgradeable_contract.md
├── cairo_cheatsheet
│ ├── arrays.md
│ ├── dict.md
│ ├── enums.md
│ ├── felt.md
│ ├── if_let.md
│ ├── loop.md
│ ├── mapping.md
│ ├── match.md
│ ├── struct.md
│ ├── tuples.md
│ ├── type_casting.md
│ ├── while.md
│ └── while_let.md
├── components
│ ├── collisions.md
│ ├── dependencies.md
│ ├── how_to.md
│ └── ownable.md
├── getting-started
│ ├── basics
│ │ ├── constructor.md
│ │ ├── counter.md
│ │ ├── custom-types-in-entrypoints.md
│ │ ├── documentation.md
│ │ ├── errors.md
│ │ ├── events.md
│ │ ├── mappings.md
│ │ ├── storage.md
│ │ ├── storing_custom_types.md
│ │ ├── variables.md
│ │ └── visibility-mutability.md
│ ├── env_setup.md
│ ├── interacting
│ │ ├── calling_other_contracts.md
│ │ ├── factory.md
│ │ └── how_to_deploy.md
│ ├── syscalls.md
│ └── testing
│ │ ├── index.mdx
│ │ ├── testing-cairo-test.md
│ │ └── testing-snforge.md
└── index.mdx
├── patches
└── vocs.patch
├── pnpm-lock.yaml
├── postcss.config.js
├── public
├── collaborators
│ ├── Juno.svg
│ ├── Nethermind.svg
│ ├── Onlydust.svg
│ ├── PoweredByNethermind.svg
│ ├── Starknet.svg
│ ├── Starknet_RPC.svg
│ ├── Starknet_Remix_Plugin.svg
│ └── Voyager.svg
├── merkle_root.png
└── svg
│ ├── Horizontal_Dark.svg
│ ├── Horizontal_Light.svg
│ ├── Icon_Dark.svg
│ ├── Icon_Light.svg
│ ├── Vertical_Dark.svg
│ └── Vertical_Light.svg
├── routes.ts
├── scripts
├── cairo_programs_verifier.sh
├── test_resolver.sh
└── test_runner.sh
├── styles.css
├── tailwind.config.js
├── tsconfig.json
└── vocs.config.ts
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior
15 |
16 | **Expected behavior**
17 | A clear and concise description of what you expected to happen.
18 |
19 | **Screenshots**
20 | If applicable, add screenshots to help explain your problem.
21 |
22 | **Checklist:**
23 | - Using the correct tooling versions, from https://github.com/NethermindEth/StarknetByExample/blob/dev/.tool-versions
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea of example or concept to showcase
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the concept/idea you would like to see**
11 |
12 | **Is it a new example or a modification/extension of a current one**
13 | If you consider editing some content, explain exactly why and what.
14 |
15 | **Additional context**
16 | Add any other context or screenshots about the request here.
17 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | **Issue**: Close #issue-number
2 |
3 | ### Description
4 |
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/.github/workflows/verify_cairo_programs.yml:
--------------------------------------------------------------------------------
1 | name: Verify Cairo programs compilation
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - dev
7 | - main
8 | workflow_dispatch:
9 |
10 | jobs:
11 | typos:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v4
15 | - uses: crate-ci/typos@master
16 |
17 | compile_and_verify:
18 | runs-on: ubuntu-latest
19 |
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v4
23 | with:
24 | fetch-depth: 0
25 |
26 | - name: Configure upstream repository
27 | run: |
28 | git remote add upstream https://github.com/NethermindEth/StarknetByExample
29 | git fetch upstream
30 |
31 | - name: Install scarb
32 | uses: software-mansion/setup-scarb@v1
33 |
34 | - name: Install snforge
35 | uses: foundry-rs/setup-snfoundry@v3
36 |
37 | - name: Verify changes
38 | run: |
39 | chmod +x scripts/cairo_programs_verifier.sh
40 | ./scripts/cairo_programs_verifier.sh
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
3 | dist/*
4 |
5 | # Editors tmp files.
6 | *~
7 | .idea/
8 |
9 | # Others
10 | .snfoundry_cache
11 | .vscode/settings.json
12 | **/starkli-wallet
13 |
14 | # From previous mdbook build
15 | book/*
16 | target/*
17 | src/**/*.md
18 |
19 | node_modules
20 | .DS_Store
21 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | node-linker=hoisted
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | scarb 2.10.1
2 | starknet-foundry 0.38.0
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Nethermind
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Starknet by Example
2 |
3 | Dev preview at: https://starknet-by-example-dev.voyager.online/
4 |
5 | ## Description
6 |
7 | Starknet by Example is a collection of examples of how to use the [Cairo](https://github.com/starkware-libs/cairo) programming language to create smart contracts on Starknet.
8 |
9 | ## Contribute
10 |
11 | Please refer to the Contribution Guidelines page:
12 | - [Contributing](CONTRIBUTING.md#contributing)
13 | - [Table of Contents](CONTRIBUTING.md#table-of-contents)
14 | - [Setup](CONTRIBUTING.md#setup)
15 | - [Working with Markdown Files](CONTRIBUTING.md#working-with-markdown-files)
16 | - [Adding a new chapter](CONTRIBUTING.md#adding-a-new-chapter)
17 | - [Adding a new Cairo program](CONTRIBUTING.md#adding-a-new-cairo-program)
18 | - [Tests](CONTRIBUTING.md#tests)
19 | - [Use of region](CONTRIBUTING.md#use-of-region)
20 | - [Code of Conduct](CONTRIBUTING.md#code-of-conduct)
21 | - [Our Pledge](CONTRIBUTING.md#our-pledge)
22 | - [Our Standards](CONTRIBUTING.md#our-standards)
23 | - [Our Responsibilities](CONTRIBUTING.md#our-responsibilities)
24 | - [Scope](CONTRIBUTING.md#scope)
25 | - [Enforcement](CONTRIBUTING.md#enforcement)
26 | - [Attribution](CONTRIBUTING.md#attribution)
27 |
--------------------------------------------------------------------------------
/Scarb.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = [
3 | "listings/getting-started/*",
4 | "listings/applications/*",
5 | "listings/advanced-concepts/*",
6 | "listings/cairo_cheatsheet",
7 | ]
8 |
9 | [workspace.scripts]
10 | test = "$(git rev-parse --show-toplevel)/scripts/test_resolver.sh"
11 |
12 | [workspace.tool.snforge]
13 |
14 | [workspace.dependencies]
15 | starknet = "2.10.1"
16 | cairo_test = "2.10.1"
17 | assert_macros = "2.10.1"
18 | snforge_std = "0.38.0"
19 | openzeppelin_account = "1.0.0"
20 | openzeppelin_introspection = "1.0.0"
21 | openzeppelin_presets = "1.0.0"
22 | openzeppelin_token = "1.0.0"
23 | openzeppelin_utils = "1.0.0"
24 | components = { path = "listings/applications/components" }
25 | pragma_lib = { git = "https://github.com/astraly-labs/pragma-lib", tag = "2.9.1" }
26 | garaga = { git = "https://github.com/keep-starknet-strange/garaga.git", tag = "v0.15.5" }
27 |
28 | [workspace.package]
29 | description = "Collection of examples of how to use the Cairo programming language to create smart contracts on Starknet."
30 | repository = "https://github.com/NethermindEth/StarknetByExample"
31 | homepage = "https://www.nethermind.io/"
32 | license = "MIT"
33 | authors = ["julio4", "msaug"]
34 | version = "0.1.0"
35 | edition = "2024_07"
36 |
37 | [tool]
38 | snforge.workspace = true
39 |
--------------------------------------------------------------------------------
/_typos.toml:
--------------------------------------------------------------------------------
1 | [default]
2 | extend-ignore-identifiers-re = ["requestor", "REQUESTOR", "Requestor", "groth", "Groth"]
3 |
4 | [type.po]
5 | extend-glob = ["*.po", "*.css", "*.js"]
6 | check-file = false
7 |
8 | [files]
9 | extend-exclude = ["po/*.po", "listings/**/*.json"]
10 |
--------------------------------------------------------------------------------
/components/ThemeImage.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import { useTheme } from "./useTheme";
3 |
4 | export const ThemeImage = ({
5 | light,
6 | dark,
7 | alt,
8 | ...props
9 | }: {
10 | light: string;
11 | dark: string;
12 | alt: string;
13 | [key: string]: any;
14 | }) => {
15 | const [mounted, setMounted] = useState(false);
16 | const theme = useTheme();
17 |
18 | useEffect(() => {
19 | setMounted(true);
20 | }, []);
21 | if (!mounted) {
22 | return
;
23 | }
24 |
25 | // Client-side rendering after hydrating
26 | return
;
27 | };
28 |
--------------------------------------------------------------------------------
/components/useSidebarToggle.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useCallback } from "react";
2 | import { createRoot } from "react-dom/client";
3 |
4 | export const useSidebarToggle = () => {
5 | const createToggleButton = useCallback(() => {
6 | const SidebarToggle = () => (
7 |
8 |
30 |
31 | );
32 |
33 | return SidebarToggle;
34 | }, []);
35 |
36 | useEffect(() => {
37 | const targetNode = document.querySelector(".vocs_DocsLayout_gutterLeft");
38 | if (!targetNode) {
39 | console.warn("Target node for sidebar toggle not found");
40 | return;
41 | }
42 |
43 | const toggleContainer = document.createElement("div");
44 | toggleContainer.className = "sidebar_toggle flex justify-center";
45 | targetNode.appendChild(toggleContainer);
46 |
47 | const Toggle = createToggleButton();
48 | const root = createRoot(toggleContainer);
49 | root.render();
50 |
51 | // Cleanup
52 | return () => {
53 | root.unmount();
54 | toggleContainer.remove();
55 | };
56 | }, [createToggleButton]);
57 | };
58 |
--------------------------------------------------------------------------------
/components/useTheme.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 |
3 | export function useTheme() {
4 | const [theme, setTheme] = useState<"dark" | "light">(() => {
5 | if (typeof window === "undefined") return "light";
6 | return document.documentElement.classList.contains("dark")
7 | ? "dark"
8 | : "light";
9 | });
10 |
11 | useEffect(() => {
12 | const handleThemeChange = () => {
13 | const newTheme = document.documentElement.classList.contains("dark")
14 | ? "dark"
15 | : "light";
16 | setTheme(newTheme);
17 | };
18 |
19 | // Watch for class changes on documentElement
20 | const observer = new MutationObserver(handleThemeChange);
21 | observer.observe(document.documentElement, {
22 | attributes: true,
23 | attributeFilter: ["class"],
24 | });
25 |
26 | return () => {
27 | observer.disconnect();
28 | };
29 | }, []);
30 |
31 | return theme;
32 | }
33 |
--------------------------------------------------------------------------------
/components/useTracking.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | const CLARITY_ID = "q6bz69wquw";
4 |
5 | export const useTracking = () => {
6 | useEffect(() => {
7 | const script = document.createElement("script");
8 | script.type = "text/javascript";
9 | script.text = `
10 | (function(c,l,a,r,i,t,y){
11 | c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
12 | t=l.createElement(r);t.async=1;
13 | t.src="https://www.clarity.ms/tag/"+i;
14 | y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
15 | })(window, document, "clarity", "script", "${CLARITY_ID}");
16 | `;
17 | document.head.appendChild(script);
18 | return () => {
19 | document.head.removeChild(script);
20 | };
21 | }, []);
22 | };
23 |
--------------------------------------------------------------------------------
/footer.tsx:
--------------------------------------------------------------------------------
1 | export default function Footer() {
2 | return (
3 |
4 |

9 |
10 | Released under the MIT License.
11 | © 2025 Nethermind. All Rights Reserved
12 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/layout.tsx:
--------------------------------------------------------------------------------
1 | import { useSidebarToggle } from "./components/useSidebarToggle";
2 | import { useTracking } from "./components/useTracking";
3 |
4 | export default function Root({ children }: { children: React.ReactNode }) {
5 | useTracking();
6 | useSidebarToggle();
7 | return {children}
;
8 | }
9 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/commit_reveal/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/commit_reveal/Scarb.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "commit_reveal"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [dependencies]
7 | starknet.workspace = true
8 |
9 | [dev-dependencies]
10 | assert_macros.workspace = true
11 | snforge_std.workspace = true
12 |
13 | [scripts]
14 | test.workspace = true
15 |
16 | [[target.starknet-contract]]
17 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/commit_reveal/src/commit_reveal.cairo:
--------------------------------------------------------------------------------
1 | #[starknet::interface]
2 | pub trait ICommitmentRevealTrait {
3 | fn commit(ref self: T, commitment: felt252);
4 | fn reveal(self: @T, secret: felt252) -> bool;
5 | }
6 |
7 | // [!region contract]
8 | #[starknet::contract]
9 | mod CommitmentRevealTraits {
10 | use starknet::storage::{StoragePointerWriteAccess, StoragePointerReadAccess};
11 | use core::hash::HashStateTrait;
12 | use core::pedersen::PedersenTrait;
13 |
14 | #[storage]
15 | struct Storage {
16 | commitment: felt252,
17 | }
18 |
19 | #[abi(embed_v0)]
20 | impl CommitmentRevealTrait of super::ICommitmentRevealTrait {
21 | fn commit(ref self: ContractState, commitment: felt252) {
22 | self.commitment.write(commitment);
23 | }
24 |
25 | fn reveal(self: @ContractState, secret: felt252) -> bool {
26 | let hash = PedersenTrait::new(secret).finalize();
27 | self.commitment.read() == hash
28 | }
29 | }
30 | }
31 | // [!endregion contract]
32 |
33 | #[cfg(test)]
34 | mod tests {
35 | use super::{ICommitmentRevealTraitDispatcher, ICommitmentRevealTraitDispatcherTrait};
36 | use core::hash::HashStateTrait;
37 | use core::pedersen::PedersenTrait;
38 | use snforge_std::{ContractClassTrait, DeclareResultTrait, declare};
39 |
40 | fn deploy() -> ICommitmentRevealTraitDispatcher {
41 | let contract = declare("CommitmentRevealTraits").unwrap().contract_class();
42 | let (contract_address, _) = contract.deploy(@array![]).unwrap();
43 | ICommitmentRevealTraitDispatcher { contract_address }
44 | }
45 |
46 | #[test]
47 | fn commit_and_reveal() {
48 | let contract = deploy();
49 |
50 | // [!region offchain]
51 | // Off-chain, compute the commitment hash for secret
52 | let secret = 'My secret';
53 | let offchain_commitment = PedersenTrait::new(secret).finalize();
54 |
55 | // Commit on-chain
56 | contract.commit(offchain_commitment);
57 |
58 | // Reveal on-chain and assert the result
59 | let reveal_result = contract.reveal(secret);
60 | // [!endregion offchain]
61 | assert_eq!(reveal_result, true);
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/commit_reveal/src/lib.cairo:
--------------------------------------------------------------------------------
1 | mod commit_reveal;
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/ecdsa_verification/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/ecdsa_verification/Scarb.lock:
--------------------------------------------------------------------------------
1 | # Code generated by scarb DO NOT EDIT.
2 | version = 1
3 |
4 | [[package]]
5 | name = "ecdsa_verification"
6 | version = "0.1.0"
7 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/ecdsa_verification/Scarb.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "ecdsa_verification"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [dependencies]
7 | starknet.workspace = true
8 |
9 | [dev-dependencies]
10 | cairo_test.workspace = true
11 |
12 | [scripts]
13 | test.workspace = true
14 |
15 | [[target.starknet-contract]]
16 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/ecdsa_verification/src/lib.cairo:
--------------------------------------------------------------------------------
1 | mod ecdsa_verification;
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_solidity_compatible/.gitignore:
--------------------------------------------------------------------------------
1 | target
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_solidity_compatible/Scarb.lock:
--------------------------------------------------------------------------------
1 | # Code generated by scarb DO NOT EDIT.
2 | version = 1
3 |
4 | [[package]]
5 | name = "hash_solidity_compatible"
6 | version.workspace = true
7 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_solidity_compatible/Scarb.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "hash_solidity_compatible"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [dependencies]
7 | starknet.workspace = true
8 |
9 | [dev-dependencies]
10 | assert_macros.workspace = true
11 | snforge_std.workspace = true
12 |
13 | [scripts]
14 | test.workspace = true
15 |
16 | [[target.starknet-contract]]
17 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_solidity_compatible/src/contract.cairo:
--------------------------------------------------------------------------------
1 | #[starknet::interface]
2 | pub trait ISolidityHashExample {
3 | fn hash_data(ref self: TContractState, input_data: Span) -> u256;
4 | }
5 |
6 | #[starknet::contract]
7 | mod SolidityHashExample {
8 | use core::keccak::keccak_u256s_be_inputs;
9 | use core::integer;
10 |
11 | #[storage]
12 | struct Storage {}
13 |
14 | #[abi(embed_v0)]
15 | impl SolidityHashExample of super::ISolidityHashExample {
16 | fn hash_data(ref self: ContractState, input_data: Span) -> u256 {
17 | let hashed = keccak_u256s_be_inputs(input_data);
18 |
19 | // Split the hashed value into two 128-bit segments
20 | let low: u128 = hashed.low;
21 | let high: u128 = hashed.high;
22 |
23 | // Reverse each 128-bit segment
24 | let reversed_low = integer::u128_byte_reverse(low);
25 | let reversed_high = integer::u128_byte_reverse(high);
26 |
27 | // Reverse merge the reversed segments back into a u256 value
28 | let compatible_hash = u256 { low: reversed_high, high: reversed_low };
29 |
30 | compatible_hash
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_solidity_compatible/src/lib.cairo:
--------------------------------------------------------------------------------
1 | mod contract;
2 |
3 | #[cfg(test)]
4 | mod tests;
5 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_solidity_compatible/src/tests.cairo:
--------------------------------------------------------------------------------
1 | use hash_solidity_compatible::contract::{
2 | ISolidityHashExampleDispatcher, ISolidityHashExampleDispatcherTrait,
3 | };
4 | use snforge_std::{ContractClassTrait, DeclareResultTrait, declare};
5 |
6 | fn setup() -> ISolidityHashExampleDispatcher {
7 | let contract = declare("SolidityHashExample").unwrap().contract_class();
8 | let (contract_address, _) = contract.deploy(@array![]).unwrap();
9 | ISolidityHashExampleDispatcher { contract_address }
10 | }
11 |
12 | #[test]
13 | fn get_same_hash_solidity() {
14 | let contract = setup();
15 | let hash_expected: u256 = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6;
16 | assert_eq!(contract.hash_data(array![1].span()), hash_expected);
17 | }
18 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_trait/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_trait/Scarb.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "hash_trait"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [dependencies]
7 | starknet.workspace = true
8 |
9 | [dev-dependencies]
10 | assert_macros.workspace = true
11 | snforge_std.workspace = true
12 |
13 | [scripts]
14 | test.workspace = true
15 |
16 | [[target.starknet-contract]]
17 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/hash_trait/src/lib.cairo:
--------------------------------------------------------------------------------
1 | mod hash_trait;
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/library_calls/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/library_calls/Scarb.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "library_calls"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [dependencies]
7 | starknet.workspace = true
8 |
9 | [dev-dependencies]
10 | assert_macros.workspace = true
11 | snforge_std.workspace = true
12 |
13 | [scripts]
14 | test.workspace = true
15 |
16 | [[target.starknet-contract]]
17 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/library_calls/src/lib.cairo:
--------------------------------------------------------------------------------
1 | mod library_call;
2 |
3 | #[cfg(test)]
4 | mod tests;
5 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/library_calls/src/library_call.cairo:
--------------------------------------------------------------------------------
1 | // [!region library_dispatcher]
2 | #[starknet::interface]
3 | pub trait IMathUtils {
4 | fn add(ref self: T, x: u32, y: u32) -> u32;
5 | fn set_class_hash(ref self: T, class_hash: starknet::ClassHash);
6 | }
7 |
8 | // contract A
9 | #[starknet::contract]
10 | pub mod MathUtils {
11 | #[storage]
12 | struct Storage {}
13 |
14 | #[abi(embed_v0)]
15 | impl ImathUtilsImpl of super::IMathUtils {
16 | fn add(ref self: ContractState, x: u32, y: u32) -> u32 {
17 | x + y
18 | }
19 |
20 | fn set_class_hash(ref self: ContractState, class_hash: starknet::ClassHash) {}
21 | }
22 | }
23 |
24 |
25 | // contract B to make library call to the class of contract A
26 | #[starknet::contract]
27 | pub mod MathUtilsLibraryCall {
28 | use super::{IMathUtilsDispatcherTrait, IMathUtilsLibraryDispatcher};
29 | use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};
30 |
31 | #[storage]
32 | struct Storage {
33 | value: u32,
34 | lib_class_hash: starknet::ClassHash,
35 | }
36 |
37 | #[abi(embed_v0)]
38 | impl MathUtils of super::IMathUtils {
39 | fn add(ref self: ContractState, x: u32, y: u32) -> u32 {
40 | IMathUtilsLibraryDispatcher { class_hash: self.lib_class_hash.read() }.add(x, y)
41 | }
42 |
43 | #[abi(embed_v0)]
44 | fn set_class_hash(ref self: ContractState, class_hash: starknet::ClassHash) {
45 | self.lib_class_hash.write(class_hash);
46 | }
47 | }
48 | }
49 | // [!endregion library_dispatcher]
50 |
51 |
52 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/library_calls/src/tests.cairo:
--------------------------------------------------------------------------------
1 | use library_calls::library_call::{IMathUtilsDispatcher, IMathUtilsDispatcherTrait};
2 | use snforge_std::{ContractClassTrait, DeclareResultTrait, declare};
3 |
4 | #[test]
5 | fn test_library_dispatcher() {
6 | let math_utils = declare("MathUtils").unwrap().contract_class();
7 |
8 | let contract = declare("MathUtilsLibraryCall").unwrap().contract_class();
9 | let (contract_address, _) = contract.deploy(@array![]).unwrap();
10 | let contract = IMathUtilsDispatcher { contract_address };
11 |
12 | contract.set_class_hash(*math_utils.class_hash);
13 |
14 | let mut result = contract.add(30, 5);
15 | assert_eq!(result, 35, "Wrong result");
16 | }
17 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/sierra_ir/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/sierra_ir/Scarb.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "sierra_ir"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [lib]
7 | sierra-text = true
8 |
9 | [dependencies]
10 | starknet.workspace = true
11 |
12 | [dev-dependencies]
13 | cairo_test.workspace = true
14 |
15 | [scripts]
16 | test.workspace = true
17 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/sierra_ir/simple_program.sierra:
--------------------------------------------------------------------------------
1 | type felt252 = felt252 [storable: true, drop: true, dup: true, zero_sized: false];
2 |
3 | libfunc felt252_add = felt252_add;
4 | libfunc store_temp = store_temp;
5 |
6 | felt252_add([0], [1]) -> ([2]); // 0
7 | store_temp([2]) -> ([2]); // 1
8 | return([2]); // 2
9 |
10 | sierra_ir::add_numbers@0([0]: felt252, [1]: felt252) -> (felt252);
11 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/sierra_ir/src/lib.cairo:
--------------------------------------------------------------------------------
1 | mod simple_program;
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/sierra_ir/src/simple_program.cairo:
--------------------------------------------------------------------------------
1 | fn add_numbers(a: felt252, b: felt252) -> felt252 {
2 | a + b
3 | }
4 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/simple_account/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/simple_account/Scarb.lock:
--------------------------------------------------------------------------------
1 | # Code generated by scarb DO NOT EDIT.
2 | version = 1
3 |
4 | [[package]]
5 | name = "ecdsa_verification"
6 | version = "0.1.0"
7 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/simple_account/Scarb.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "simple_account"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [dependencies]
7 | starknet.workspace = true
8 | openzeppelin_account.workspace = true
9 | openzeppelin_introspection.workspace = true
10 |
11 | [scripts]
12 | test.workspace = true
13 |
14 | [[target.starknet-contract]]
15 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/simple_account/src/lib.cairo:
--------------------------------------------------------------------------------
1 | mod simple_account;
2 |
3 | #[cfg(test)]
4 | mod tests;
5 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/simple_account/src/tests.cairo:
--------------------------------------------------------------------------------
1 | #[cfg(test)]
2 | mod tests { // TODO
3 | }
4 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/store_using_packing/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/store_using_packing/Scarb.lock:
--------------------------------------------------------------------------------
1 | # Code generated by scarb DO NOT EDIT.
2 | version = 1
3 |
4 | [[package]]
5 | name = "store_using_packing"
6 | version.workspace = true
7 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/store_using_packing/Scarb.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "store_using_packing"
3 | version.workspace = true
4 | edition.workspace = true
5 |
6 | [dependencies]
7 | starknet.workspace = true
8 |
9 | [dev-dependencies]
10 | assert_macros.workspace = true
11 | snforge_std.workspace = true
12 |
13 | [scripts]
14 | test.workspace = true
15 |
16 | [[target.starknet-contract]]
17 |
--------------------------------------------------------------------------------
/listings/advanced-concepts/store_using_packing/src/contract.cairo:
--------------------------------------------------------------------------------
1 | #[derive(Copy, Serde, Drop)]
2 | pub struct Time {
3 | pub hour: u8,
4 | pub minute: u8,
5 | }
6 |
7 | #[starknet::interface]
8 | pub trait ITime {
9 | fn set(ref self: TContractState, value: Time);
10 | fn get(self: @TContractState) -> Time;
11 | }
12 |
13 | #[starknet::contract]
14 | mod TimeContract {
15 | use starknet::storage::{StoragePointerWriteAccess, StoragePointerReadAccess};
16 | use super::Time;
17 | use starknet::storage_access::StorePacking;
18 |
19 | #[storage]
20 | struct Storage {
21 | time: Time,
22 | }
23 |
24 | impl TimePackable of StorePacking