Skip to main content
Tempo is fully EVM-compatible, supporting the same tools, frameworks, and languages you use on Ethereum. Deploy contracts using Foundry, Hardhat, or any standard Ethereum development tool.

Prerequisites

Before deploying contracts, ensure you have:
  • A wallet with testnet funds (get them from the Faucet)
  • Foundry or Hardhat installed
  • RPC endpoint: https://rpc.moderato.tempo.xyz
  • Chain ID: 42431

Using Foundry

Tempo works seamlessly with Foundry, the fast and modular toolkit for Ethereum development.

Install Foundry

curl -L https://foundry.paradigm.xyz | bash
foundryup

Create a New Project

forge init my-tempo-project
cd my-tempo-project

Write Your Contract

Create a simple contract in src/Counter.sol:
Counter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

contract Counter {
    uint256 public count;

    function increment() external returns (uint256) {
        return ++count;
    }

    function decrement() external returns (uint256) {
        require(count > 0, "Count is zero");
        return --count;
    }

    function reset() external {
        count = 0;
    }
}

Deploy with Foundry

Deploy your contract to Tempo testnet:
forge create --rpc-url https://rpc.moderato.tempo.xyz \
  --private-key $PRIVATE_KEY \
  src/Counter.sol:Counter
Store your private key in an environment variable: export PRIVATE_KEY=0x...

Interact with Your Contract

Once deployed, interact with it using cast:
# Read the count
cast call $CONTRACT_ADDRESS "count()" --rpc-url https://rpc.moderato.tempo.xyz

# Increment the counter
cast send $CONTRACT_ADDRESS "increment()" \
  --rpc-url https://rpc.moderato.tempo.xyz \
  --private-key $PRIVATE_KEY

# Read the updated count
cast call $CONTRACT_ADDRESS "count()" --rpc-url https://rpc.moderato.tempo.xyz

Using Hardhat

Hardhat is another popular Ethereum development environment that works with Tempo.

Install Hardhat

npm install --save-dev hardhat
npx hardhat init

Configure Hardhat

Update hardhat.config.js to include Tempo testnet:
hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.28",
  networks: {
    tempo: {
      url: "https://rpc.moderato.tempo.xyz",
      chainId: 42431,
      accounts: [process.env.PRIVATE_KEY]
    }
  }
};

Write Your Contract

Create contracts/SimpleStorage.sol:
SimpleStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

contract SimpleStorage {
    uint256 public value;

    constructor(uint256 _value) {
        value = _value;
    }

    function setValue(uint256 _value) external {
        value = _value;
    }
}

Deploy with Hardhat

Create a deployment script in scripts/deploy.js:
deploy.js
const hre = require("hardhat");

async function main() {
  const SimpleStorage = await hre.ethers.getContractFactory("SimpleStorage");
  const storage = await SimpleStorage.deploy(42);

  await storage.waitForDeployment();

  console.log("SimpleStorage deployed to:", await storage.getAddress());
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
Run the deployment:
npx hardhat run scripts/deploy.js --network tempo

Using Tempo Alloy SDK (Rust)

For Rust developers, the Tempo Alloy SDK provides a native way to deploy contracts.
use alloy::{
    primitives::Address,
    providers::{Provider, ProviderBuilder},
    sol_types::SolCall,
};
use tempo_alloy::TempoNetwork;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let provider = ProviderBuilder::new_with_network::<TempoNetwork>()
        .connect(&std::env::var("RPC_URL")?)
        .await?;

    // Deploy a contract by sending the creation bytecode
    let bytecode = hex::decode("608060...")?.into();
    
    let tx = provider
        .send_transaction(
            alloy::rpc::types::TransactionRequest::default()
                .with_deploy_code(bytecode)
        )
        .await?;
    
    let receipt = tx.get_receipt().await?;
    let contract_address = receipt.contract_address.unwrap();
    
    println!("Contract deployed at: {:?}", contract_address);

    Ok(())
}

Verifying Contracts

Verify your deployed contracts on the Tempo block explorer:
forge verify-contract $CONTRACT_ADDRESS \
  src/Counter.sol:Counter \
  --chain 42431 \
  --etherscan-api-key $API_KEY

Best Practices

Gas Efficiency

Optimize for TIP-20 transfers which have dedicated payment lanes and lower fees

Use TIP-20

Leverage Tempo’s native TIP-20 standard for stablecoin operations

Test Thoroughly

Use the testnet extensively before deploying to production

Monitor Gas

Gas prices are in stablecoins - track costs in USD terms

Tempo-Specific Features

When building on Tempo, you can leverage additional features:
  • TIP-20 Precompiles: Access native stablecoin functions at 0x20c0... addresses
  • Memos: Add reconciliation data to token transfers
  • Tempo Transactions: Use batched calls and fee sponsorship
  • Account Keychain: Implement passkey-based authentication
See the other guides in this section to learn how to use these features.

Next Steps

Making Payments

Send TIP-20 stablecoin payments with memos

Batch Payments

Execute multiple payments atomically

Fee Sponsorship

Pay gas fees for your users

Smart Accounts

Enable passkey authentication