Skip to content

Commit

Permalink
Library calls (NethermindEth#194)
Browse files Browse the repository at this point in the history
* final push

* updated the Summary.md

* fix: fmt and minor edit

---------

Co-authored-by: julio4 <jules.doumeche@gmail.com>
  • Loading branch information
OkoliEvans and julio4 committed Oct 24, 2024
1 parent 23849cb commit 9e71e10
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ version = "0.1.0"
name = "interfaces_traits"
version = "0.1.0"

[[package]]
name = "library_calls"
version = "0.1.0"

[[package]]
name = "mappings"
version = "0.1.0"
Expand Down
1 change: 1 addition & 0 deletions listings/advanced-concepts/library_calls/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
14 changes: 14 additions & 0 deletions listings/advanced-concepts/library_calls/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "library_calls"
version.workspace = true
edition = "2023_11"

# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html

[dependencies]
starknet.workspace = true

[scripts]
test.workspace = true

[[target.starknet-contract]]
4 changes: 4 additions & 0 deletions listings/advanced-concepts/library_calls/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod library_call;

#[cfg(test)]
mod tests;
51 changes: 51 additions & 0 deletions listings/advanced-concepts/library_calls/src/library_call.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// ANCHOR: library_dispatcher
#[starknet::interface]
pub trait IMathUtils<T> {
fn add(ref self: T, x: u32, y: u32) -> u32;
fn set_class_hash(ref self: T, class_hash: starknet::ClassHash);
}

// contract A
#[starknet::contract]
pub mod MathUtils {
#[storage]
struct Storage {}

#[abi(embed_v0)]
impl ImathUtilsImpl of super::IMathUtils<ContractState> {
fn add(ref self: ContractState, x: u32, y: u32) -> u32 {
x + y
}

fn set_class_hash(ref self: ContractState, class_hash: starknet::ClassHash) {}
}
}


// contract B to make library call to the class of contract A
#[starknet::contract]
pub mod MathUtilsLibraryCall {
use starknet::{class_hash::class_hash_const, ContractAddress};
use super::{IMathUtilsDispatcherTrait, IMathUtilsLibraryDispatcher};

#[storage]
struct Storage {
value: u32,
lib_class_hash: starknet::ClassHash,
}

#[abi(embed_v0)]
impl MathUtils of super::IMathUtils<ContractState> {
fn add(ref self: ContractState, x: u32, y: u32) -> u32 {
IMathUtilsLibraryDispatcher { class_hash: self.lib_class_hash.read() }.add(x, y)
}

#[abi(embed_v0)]
fn set_class_hash(ref self: ContractState, class_hash: starknet::ClassHash) {
self.lib_class_hash.write(class_hash);
}
}
}
// ANCHOR_END: library_dispatcher


25 changes: 25 additions & 0 deletions listings/advanced-concepts/library_calls/src/tests.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
mod tests {
use starknet::syscalls::{deploy_syscall};
use starknet::SyscallResultTrait;
use library_calls::library_call::{
MathUtils, MathUtilsLibraryCall, IMathUtilsDispatcher, IMathUtilsDispatcherTrait
};

#[test]
#[available_gas(20000000)]
fn test_library_dispatcher() {
let math_utils_class_hash: starknet::ClassHash = MathUtils::TEST_CLASS_HASH
.try_into()
.unwrap();
let mut calldata: Array<felt252> = array![];
let (address, _) = deploy_syscall(
MathUtilsLibraryCall::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false
)
.unwrap_syscall();
let mut contract = IMathUtilsDispatcher { contract_address: address };

contract.set_class_hash(math_utils_class_hash);
let mut result = contract.add(30, 5);
assert_eq!(result, 35, "Wrong result");
}
}
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ Summary
- [List](./ch02/list.md)
- [Plugins](./ch02/plugins.md)
- [Signature Verification](./ch02/signature_verification.md)
- [Library Calls](./ch02/library_calls.md)
16 changes: 16 additions & 0 deletions src/ch02/library_calls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Library Dispatcher

External calls can be made on Starknet by two means: Contract dispatchers or Library dispatchers. Dispatchers are automatically created and exported by the compiler when a contract interface is defined.

With Contract dispatcher we are calling an already deployed contract (with associated state), therefore contract address is passed to the dispatcher to make the call. However, with library dispatcher we are simply making function calls to declared contract **classes** (stateless).

Contract dispatcher call is synonymous to external calls in Solidity, while library dispatcher call is synonymous to delegate call.

For further reading: [Cairo book](https://book.cairo-lang.org/ch15-02-contract-dispatchers-library-dispatchers-and-system-calls.html?highlight=library%20dispatchers#library-dispatcher).

```rust
{{#rustdoc_include ../../listings/advanced-concepts/library_calls/src/library_call.cairo:library_dispatcher}}
```



0 comments on commit 9e71e10

Please sign in to comment.