Writing Turbo Smart Contracts

Developing with Herodotus Turbo for Solidity and Cairo smart contract developers is quite convenient as it unlocks new paradigms and features without compromising on the existing technology or adding additional overheads to the tooling used and the way to deal with the chain specificities.

However, there are some caveats to take into consideration to get the most out of Turbo and integrate it seamlessly.

1. Integration of Turbo Interface

To use Turbo, developers need to integrate the Turbo interface into their smart contracts. This involves importing the necessary Turbo ERC1967 proxy contract and utilizing its functions for specifying intents (i.e., proofs queries).

// ITurboSwap and periphery interfaces can be found here:
// https://github.com/HerodotusDev/turbo-contracts/blob/main/src/interfaces/ITurboSwap.sol

contract MyTurboContract {
    ITurboSwap public turbo;

    constructor(address _turboAddress) {
        turbo = ITurboSwap(_turboAddress);
    }

    // Contract logic using Turbo
    // function myContractFunction(...)
}

2. Synchronous Data Reads

Instead of complex logic to handle cross-chain data access, Turbo allows developers to make data queries using simple function calls:

// HeaderProperty interface is defined here:
// https://github.com/HerodotusDev/turbo-contracts/blob/main/src/lib/HeaderProperty.sol
// To use other properties, ensure that they are also supported by the API as well.
// Supported fields are defined here in POST /submit-batch-query: https://api.herodotus.cloud/docs/static/index.html#/

function myContractFunction(
    uint256 chainId,
    uint256 blockNumber
) external {
    bytes32 blockTimestamp = turbo.headers(
        chainId,
        blockNumber,
        HeaderProperty.TIMESTAMP
    );
    // Do anything with the resolved value
    // (i.e., in this case, the timestamp of that given block).
}

ℹ️ Make sure that all Turbo calls are not inter-dependents (i.e., the resolved value of one query cannot be used as the input of another one). However, in the near future, nested interdependent queries will be made possible.

3. Special RPC Requirement

Transactions interacting with Turbo-integrated contracts must be submitted through a special Turbo RPC. This is a key difference from standard Solidity development, where transactions can be sent through any compatible RPC.

The rationale behind it is that in order to achieve transactions that appear to be synchronous from the execution layer, we need to catch the intents first through our Turbo-enabled RPC, defer the proving to our API and broadcast the transaction to the chain as fast as possible.

ℹ️ Even though we recommend using Turbo as it handles the complexity behind the scenes, and allows for a more straightforward developer & user experience, it is possible to integrate with Storage Proofs by integrating directly with the API instead, skipping the specialized RPC part. If unsure, please reach out.

4. Extended Data Access

Turbo contracts can access a wider range of data across different chains and layers, including headers, accounts and storage slots.

This capability goes beyond what's typically available in standard Solidity contracts, so developers can leverage richer and more diverse data sets to enhance their dApps' functionality and user experience.

Checkout some use cases that you can build with Turbo here!

Last updated