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:
// 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
Update hardhat.config.js to include Tempo testnet:
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:
// 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:
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