contract-call?

Executing public functions in other smart contracts from within a Clarity smart contract.

Function Signature

(contract-call? .contract-name function-name arg0 arg1 ...)
  • Input:
    • .contract-name: The name of the contract to call
    • function-name: The name of the public function to execute
    • arg0, arg1, ...: Arguments to pass to the function
  • Output: (response A B) where A and B are the types returned by the called function

Why it matters

The contract-call? function is crucial for:

  1. Enabling inter-contract communication and composability.
  2. Allowing contracts to leverage functionality from other contracts.
  3. Building complex systems of interacting smart contracts.
  4. Implementing upgradeable contract patterns.

When to use it

Use the contract-call? function when you need to:

  • Call a public function in another contract.
  • Interact with standardized contracts (e.g., token contracts).
  • Split complex logic across multiple contracts for better organization.
  • Implement upgradeable systems by calling into newer contract versions.

Best Practices

  • Always check the return value of contract-call? as it returns a response type.
  • Be aware that contract-call? cannot be used to call functions within the same contract.
  • Consider the gas costs of external contract calls in your overall transaction budget.
  • Use as-contract when appropriate to make calls with the contract's own principal.

Practical Example: Interacting with a Token Contract

Let's implement a function that transfers tokens using a standard token contract:

(define-public (transfer-tokens (amount uint) (recipient principal))
  (contract-call? .token-contract transfer amount tx-sender recipient))

;; Usage
(transfer-tokens u100 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM)

This example demonstrates:

  1. Using contract-call? to interact with another contract (.token-contract).
  2. Passing arguments to the called function, including the current tx-sender.
  3. Returning the response from the called function directly.

Common Pitfalls

  1. Forgetting to handle the response from contract-call?, which can lead to unexpected behavior.
  2. Attempting to use contract-call? to call functions within the same contract, which is not allowed.
  3. Not considering the possibility of the called contract changing or being upgraded.
  • as-contract: Often used in combination with contract-call? to make calls as the contract principal.
  • try!: Useful for handling the response from contract-call? and propagating errors.
  • unwrap!: Can be used to extract the success value from a contract-call? response or return an error.

Conclusion

The contract-call? function is a fundamental building block for creating complex, interacting systems of smart contracts on the Stacks blockchain. By enabling contracts to call functions in other contracts, it promotes code reuse, modularity, and upgradability. However, developers must be careful to handle responses correctly and consider the implications of external calls on their contract's behavior and gas usage.