A step-by-step guide to creating and deploying your own stablecoin on Tempo blockchain.
- A wallet address (MetaMask or any EVM wallet)
- Terminal access
- ~5 minutes of your time
Foundry is the best CLI toolkit for blockchain development.
curl -L https://foundry.paradigm.xyz | bash
source ~/.zshenv # or restart your terminal
foundryupVerify installation:
cast --version
# cast Version: 1.5.1-stableRequest free testnet stablecoins from Tempo's faucet:
curl -X POST 'https://rpc.testnet.tempo.xyz' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"tempo_fundAddress","params":["YOUR_WALLET_ADDRESS"],"id":1}'This gives you AlphaUSD β Tempo's testnet stablecoin for paying gas fees.
Check your balance:
cast call 0x20c0000000000000000000000000000000000001 \
"balanceOf(address)(uint256)" YOUR_WALLET_ADDRESS \
--rpc-url https://rpc.testnet.tempo.xyzCreate a file called MyStablecoin.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract MyStablecoin {
string public name;
string public symbol;
uint8 public constant decimals = 6;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor(string memory _name, string memory _symbol, uint256 _initialSupply) {
name = _name;
symbol = _symbol;
totalSupply = _initialSupply * 10**decimals;
balanceOf[msg.sender] = totalSupply;
emit Transfer(address(0), msg.sender, totalSupply);
}
function transfer(address to, uint256 amount) public returns (bool) {
require(balanceOf[msg.sender] >= amount, "Insufficient balance");
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
function approve(address spender, uint256 amount) public returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) public returns (bool) {
require(balanceOf[from] >= amount, "Insufficient balance");
require(allowance[from][msg.sender] >= amount, "Insufficient allowance");
balanceOf[from] -= amount;
balanceOf[to] += amount;
allowance[from][msg.sender] -= amount;
emit Transfer(from, to, amount);
return true;
}
}forge buildGet the bytecode and deploy:
# Get compiled bytecode
BYTECODE=$(cat out/MyStablecoin.sol/MyStablecoin.json | python3 -c "import sys,json; print(json.load(sys.stdin)['bytecode']['object'])")
# Encode constructor arguments (name, symbol, initial supply)
ENCODED_ARGS=$(cast abi-encode "constructor(string,string,uint256)" "SoupCoin" "SOUP" 1000000)
# Deploy!
cast send \
--rpc-url https://rpc.testnet.tempo.xyz \
--private-key YOUR_PRIVATE_KEY \
--create "${BYTECODE}${ENCODED_ARGS:2}"You'll see output like:
contractAddress 0x6143356d19521A93aB9139096Ae6ee79090848c1
status 1 (success)
π Your stablecoin is live!
# Check token name
cast call YOUR_CONTRACT_ADDRESS "name()(string)" --rpc-url https://rpc.testnet.tempo.xyz
# Check your balance
cast call YOUR_CONTRACT_ADDRESS "balanceOf(address)(uint256)" YOUR_WALLET --rpc-url https://rpc.testnet.tempo.xyzTransfer tokens to another address:
# Send 100 tokens (with 6 decimals, that's 100000000)
cast send YOUR_CONTRACT_ADDRESS \
"transfer(address,uint256)(bool)" \
RECIPIENT_ADDRESS \
100000000 \
--rpc-url https://rpc.testnet.tempo.xyz \
--private-key YOUR_PRIVATE_KEYSee your token on Tempo's explorer:
https://explore.tempo.xyz/address/YOUR_CONTRACT_ADDRESS
| Property | Value |
|---|---|
| Chain ID | 42429 |
| RPC URL | https://rpc.testnet.tempo.xyz |
| Explorer | https://explore.tempo.xyz |
| Currency | USD (stablecoins) |
| Property | Value |
|---|---|
| Name | SoupCoin |
| Symbol | SOUP |
| Contract | 0x6143356d19521A93aB9139096Ae6ee79090848c1 |
| Decimals | 6 |
| Total Supply | 1,000,000 SOUP |
| Deploy Cost | ~$0.009 (paid in AlphaUSD) |
# Check balance
cast call TOKEN_ADDRESS "balanceOf(address)(uint256)" WALLET --rpc-url https://rpc.testnet.tempo.xyz
# Transfer tokens
cast send TOKEN_ADDRESS "transfer(address,uint256)(bool)" RECIPIENT AMOUNT --rpc-url https://rpc.testnet.tempo.xyz --private-key KEY
# Get token info
cast call TOKEN_ADDRESS "name()(string)" --rpc-url https://rpc.testnet.tempo.xyz
cast call TOKEN_ADDRESS "symbol()(string)" --rpc-url https://rpc.testnet.tempo.xyz
cast call TOKEN_ADDRESS "totalSupply()(uint256)" --rpc-url https://rpc.testnet.tempo.xyz- No native gas token β Tempo uses stablecoins (AlphaUSD) for gas fees
- Sub-second finality β Transactions confirm in ~0.5 seconds
- Low fees β Deploying a contract costs ~$0.009
- EVM compatible β Use familiar tools like Foundry, ethers.js, viem
- TIP-20 standard β ERC-20 compatible with extra payment features
- Add your token to Tempo's DEX for trading
- Implement fee sponsorship for gasless UX
- Add TIP-403 policies for compliance
- Distribute rewards to holders
Built with β€οΈ on Tempo Testnet Guide created: December 2024