Skip to content

Commit

Permalink
test: ch00/calling_other_contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
julio4 committed May 3, 2024
1 parent ee42efe commit 1637154
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 80 deletions.
23 changes: 0 additions & 23 deletions listings/getting-started/calling_other_contracts/src/callee.cairo

This file was deleted.

75 changes: 69 additions & 6 deletions listings/getting-started/calling_other_contracts/src/caller.cairo
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
use starknet::ContractAddress;

// We need to have the interface of the callee contract defined
// so that we can import the Dispatcher.
// ANCHOR: callee_contract
// This will automatically generate ICalleeDispatcher and ICalleeDispatcherTrait
#[starknet::interface]
pub trait ICallee<TContractState> {
fn set_value(ref self: TContractState, value: u128) -> u128;
}

#[starknet::contract]
pub mod Callee {

#[storage]
struct Storage {
value: u128,
}

#[abi(embed_v0)]
impl ICalleeImpl of super::ICallee<ContractState> {
fn set_value(ref self: ContractState, value: u128) -> u128 {
self.value.write(value);
value
}
}
}
// ANCHOR_END: callee_contract

#[starknet::interface]
pub trait ICaller<TContractState> {
fn set_value_from_address(ref self: TContractState, addr: ContractAddress, value: u128);
fn set_value_from_address(
ref self: TContractState, addr: starknet::ContractAddress, value: u128
);
}

// ANCHOR: caller_contract
#[starknet::contract]
pub mod Caller {
// We import the Dispatcher of the called contract
// We need to import the dispatcher of the callee contract
// If you don't have a proper import, you can redefine the interface by yourself
use super::{ICalleeDispatcher, ICalleeDispatcherTrait};
use starknet::ContractAddress;

Expand All @@ -28,3 +48,46 @@ pub mod Caller {
}
}
}
// ANCHOR_END: caller_contract

#[cfg(test)]
mod tests {
use super::{
Callee, ICalleeDispatcher, ICalleeDispatcherTrait, Callee::valueContractMemberStateTrait,
Caller, ICallerDispatcher, ICallerDispatcherTrait
};
use starknet::{
ContractAddress, contract_address_const, testing::set_contract_address,
syscalls::deploy_syscall, SyscallResultTrait
};

fn deploy() -> (ICalleeDispatcher, ICallerDispatcher) {
let (address_callee, _) = deploy_syscall(
Callee::TEST_CLASS_HASH.try_into().unwrap(), 0, array![].span(), false
)
.unwrap_syscall();
let (address_caller, _) = deploy_syscall(
Caller::TEST_CLASS_HASH.try_into().unwrap(), 0, array![].span(), false
)
.unwrap_syscall();
(
ICalleeDispatcher { contract_address: address_callee },
ICallerDispatcher { contract_address: address_caller }
)
}

#[test]
fn test_caller() {
let init_value: u128 = 42;

let (callee, caller) = deploy();
caller.set_value_from_address(callee.contract_address, init_value);

let state = Callee::contract_state_for_testing();
set_contract_address(callee.contract_address);

let value_read: u128 = state.value.read();

assert_eq!(value_read, init_value);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
mod callee;
mod caller;

#[cfg(test)]
mod tests;
43 changes: 0 additions & 43 deletions listings/getting-started/calling_other_contracts/src/tests.cairo

This file was deleted.

12 changes: 8 additions & 4 deletions src/ch00/interacting/calling_other_contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ There are two different ways to call other contracts in Cairo.
The easiest way to call other contracts is by using the dispatcher of the contract you want to call.
You can read more about Dispatchers in the [Cairo Book](https://book.cairo-lang.org/ch99-02-02-contract-dispatcher-library-dispatcher-and-system-calls.html#contract-dispatcher)

The other way is to use the `starknet::call_contract_syscall` syscall yourself. However, this method is not recommended.
The other way is to use the `starknet::call_contract_syscall` syscall yourself. However, this method is not recommended and will not be covered in this example.

In order to call other contracts using dispatchers, you will need to define the called contract's interface as a trait annotated with the `#[starknet::interface]` attribute, and then import the `IContractDispatcher` and `IContractDispatcherTrait` items in your contract.

Here's the `Callee` contract interface and implementation:

```rust
{{#include ../../../listings/getting-started/calling_other_contracts/src/callee.cairo}}
{{#rustdoc_include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo:callee_contract}}
```

The following `Caller` contract use the `Callee` interface to call the `Callee` contract:

```rust
{{#include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo}}
```
{{#rustdoc_include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo:caller_contract}}
```

0 comments on commit 1637154

Please sign in to comment.