interface! for dynamic addresses and import! for fixed addresses.
The interface! Macro
Import another contract’s interface without specifying its address:- Reads the WIT file from the specified path
- Generates type-safe Rust bindings
- Creates functions you can call from your contract
The import! Macro
Import a specific contract instance at a known address:name- Contract namemod_name- Rust module name (avoid conflicts)height- Block height where contract was deployedtx_index- Transaction index in that blockpath- Path to WIT file
interface! but with the contract address fixed at compile time.
When to Use Each
Useinterface! for dynamic addresses (passed as parameters):
import! for fixed addresses (known at compile time):
Making Cross-Contract Calls
Basic Example
From the shared-account contract:ContractAddress Type
Call Context and Signers
The Signer Parameter
When making cross-contract calls, you choose whose authority to use: Execute as the current user:- Contract holds tokens on behalf of users
- Contract acts as custodian
- Escrow patterns
Error Propagation
Errors from cross-contract calls propagate automatically with?:
Re-entrancy Protection
The runtime prevents re-entrancy automatically:- Prevents common exploit patterns
- Simplifies reasoning about contract behavior
- No need for re-entrancy guards
Multi-Contract Interaction Example
AMM (Automated Market Maker) calling Token contract:- Call external contracts first (get tokens)
- Validate received amounts
- Update local state
- Return results
The foreign::call Low-Level API
For advanced use cases, you can make dynamic calls:- Proxy contracts
- Generic delegation patterns
- When you need to construct calls dynamically
- Fallback handlers
interface! or import! instead for type safety.