Developer Handbook

Build on
Shido Testnet

Everything you need to deploy contracts, run validators, and test your dApps on the Shido EVM-compatible testnet.

Chain ID: 9007
1,000 SHIDO / faucet drip
EVM Compatible
Gas β‰ˆ Free

01 Network Configuration

Add these details to your wallet or development tool. All endpoints are public and support CORS.

FieldValue
Network NameShido Testnet
RPC URLhttps://rpc.testnet.shidoscan.net
WebSocket URLwss://ws.testnet.shidoscan.net
Chain ID9007
Hex Chain ID0x232F
Currency SymbolSHIDO
Currency Decimals18
Block Explorerhttps://testnet.shidoscan.net
Faucethttps://faucet.testnet.shidoscan.net

02 Add to MetaMask

1
Open MetaMask
Click the network dropdown at the top of MetaMask.
2
Add Network Manually
Click "Add Network" β†’ "Add a network manually".
3
Enter Network Details
Fill in the network configuration from the table above. RPC URL, Chain ID 9007, symbol SHIDO.
4
Get Test Tokens
Visit faucet.testnet.shidoscan.net and paste your address to receive 1,000 SHIDO.

03 Hardhat

Install

bash
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox

hardhat.config.js

javascript
require('@nomicfoundation/hardhat-toolbox');
require('dotenv/config');

module.exports = {
  solidity: '0.8.24',
  networks: {
    shidoTestnet: {
      url: 'https://rpc.testnet.shidoscan.net',
      chainId: 9007,
      accounts: [process.env.PRIVATE_KEY]
    }
  }
};

Deploy

bash
npx hardhat run scripts/deploy.js --network shidoTestnet

04 Foundry

Install

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

Deploy Contract

bash
forge create --rpc-url https://rpc.testnet.shidoscan.net \
  --private-key $PRIVATE_KEY \
  src/MyContract.sol:MyContract

Send Transaction

bash
cast send --rpc-url https://rpc.testnet.shidoscan.net \
  --private-key $PRIVATE_KEY \
  <CONTRACT_ADDRESS> 'transfer(address,uint256)' 0xRecipient 1000

Read Contract

bash
cast call --rpc-url https://rpc.testnet.shidoscan.net \
  <CONTRACT_ADDRESS> 'balanceOf(address)(uint256)' $MY_ADDRESS

05 ethers.js v6

bash
npm install ethers
javascript
import { ethers } from 'ethers';

// Provider
const provider = new ethers.JsonRpcProvider(
  'https://rpc.testnet.shidoscan.net',
  { chainId: 9007, name: 'shido-testnet' }
);

// Wallet
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

// Send SHIDO
const tx = await wallet.sendTransaction({
  to: '0xRecipientAddress',
  value: ethers.parseEther('1.0')
});
await tx.wait();
console.log('Tx hash:', tx.hash);

// Deploy contract
const factory = new ethers.ContractFactory(abi, bytecode, wallet);
const contract = await factory.deploy(...constructorArgs);
await contract.waitForDeployment();
console.log('Deployed at:', await contract.getAddress());

06 web3.js

javascript
const { Web3 } = require('web3');
const web3 = new Web3('https://rpc.testnet.shidoscan.net');

// Get balance
const balance = await web3.eth.getBalance('0xAddress');
console.log(web3.utils.fromWei(balance, 'ether'), 'SHIDO');

// Send transaction
const receipt = await web3.eth.sendTransaction({
  from: myAddress,
  to: '0xRecipient',
  value: web3.utils.toWei('1', 'ether')
});

07 Remix IDE

πŸ’‘
Remix requires no local setup β€” build and deploy contracts directly in your browser.
1
Open Remix
2
Select Environment
In the Deploy tab, set Environment to Injected Provider - MetaMask
3
Connect MetaMask
MetaMask will prompt to connect. Make sure Shido Testnet is selected.
4
Deploy
Compile your contract, then click Deploy. Confirm the transaction in MetaMask.

08 Smart Contract Verification

Verified contracts show source code, ABI, and allow direct interaction from the explorer UI. All three methods below are supported.

Via Explorer UI

1
Find your contract
Search the contract address on testnet.shidoscan.net
2
Open Code tab
Click the Code tab β†’ Verify & Publish
3
Submit source
Select compiler version and paste flattened source code or upload files

Via Hardhat

javascript
// hardhat.config.js β€” add etherscan config:
etherscan: {
  apiKey: { shidoTestnet: 'any-string' },
  customChains: [{
    network: 'shidoTestnet',
    chainId: 9007,
    urls: {
      apiURL: 'https://testnet.shidoscan.net/api',
      browserURL: 'https://testnet.shidoscan.net'
    }
  }]
}
bash
npx hardhat verify --network shidoTestnet <CONTRACT_ADDRESS> <CONSTRUCTOR_ARGS>

Via Foundry

bash
forge verify-contract <CONTRACT_ADDRESS> src/MyContract.sol:MyContract \
  --rpc-url https://rpc.testnet.shidoscan.net \
  --verifier blockscout \
  --verifier-url https://testnet.shidoscan.net/api

09 Faucet API

Request Tokens

bash
curl -X POST https://faucet.testnet.shidoscan.net/api/drip \
  -H "Content-Type: application/json" \
  -d '{"address":"0xYourWalletAddress"}'
json β€” response
{
  "success": true,
  "txHash": "0xabc123...",
  "amount": "1000",
  "explorerUrl": "https://testnet.shidoscan.net/tx/0xabc123..."
}

Check Eligibility

bash
curl https://faucet.testnet.shidoscan.net/api/check/0xYourAddress

Faucet Status

bash
curl https://faucet.testnet.shidoscan.net/api/status
ℹ️
Rate limits: 1 request per address per 24 hours. 2 requests per IP per 24 hours. Each request delivers 1,000 SHIDO.

10 RPC Reference

All standard Ethereum JSON-RPC methods are supported at https://rpc.testnet.shidoscan.net

Available Namespaces

eth βœ…
net βœ…
web3 βœ…
debug βœ…
txpool βœ…
personal βœ…

Standard Methods (eth_*)

MethodDescription
eth_blockNumberGet latest block number
eth_getBalanceGet address SHIDO balance
eth_sendRawTransactionBroadcast signed transaction
eth_getTransactionByHashGet transaction details
eth_getTransactionReceiptGet transaction receipt
eth_callCall contract function (read-only)
eth_estimateGasEstimate gas for a transaction
eth_gasPriceGet current gas price
eth_getCodeGet contract bytecode
eth_getLogsGet event logs
eth_getBlockByNumberGet block details by number
eth_getTransactionCountGet nonce for address
eth_chainIdReturns chain ID (0x232F = 9007)
eth_syncingCheck sync status
eth_getStorageAtGet contract storage slot
eth_feeHistoryGet historical fee data (EIP-1559)
eth_maxPriorityFeePerGasGet max priority fee suggestion
net_versionReturns chain ID (9007)
net_listeningCheck if node is listening
net_peerCountGet number of peers
web3_clientVersionGet node client version
web3_sha3Keccak-256 hash
txpool_statusGet pending/queued tx count
txpool_contentGet full txpool contents
txpool_inspectGet txpool summary

Debug Methods (debug_*)

ℹ️
Debug methods are available for contract debugging, transaction tracing and state inspection. Essential for DeFi protocol development.
MethodDescription
debug_traceTransactionTrace a transaction with call tracer
debug_traceCallTrace an eth_call without broadcasting
debug_traceBlockByNumberTrace all txs in a block
debug_traceBlockByHashTrace all txs in a block by hash
debug_storageRangeAtGet contract storage range
debug_getRawTransactionGet raw transaction bytes

Trace a Transaction

bash
# Trace with callTracer (shows all internal calls)
curl -X POST https://rpc.testnet.shidoscan.net \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "debug_traceTransaction",
    "params": ["0xYOUR_TX_HASH", {"tracer": "callTracer"}],
    "id": 1
  }'
javascript
// Trace with ethers.js
const trace = await provider.send("debug_traceTransaction", [
  txHash,
  { tracer: "callTracer" }
]);
console.log(trace.calls); // all internal contract calls

WebSocket Endpoint

⚑
Use WebSocket for real-time subscriptions to new blocks, pending transactions and contract events.
javascript
const provider = new ethers.WebSocketProvider('wss://ws.testnet.shidoscan.net');

// Subscribe to new blocks
provider.on('block', (blockNumber) => {
  console.log('New block:', blockNumber);
});

// Subscribe to contract events
const filter = { address: CONTRACT_ADDRESS, topics: [EVENT_TOPIC] };
provider.on(filter, (log) => console.log(log));

11 Deployed Contracts

All contracts below are verified on the explorer. Use these addresses directly in your dApps β€” no deployment needed.

Core Infrastructure

ContractAddressDescription
WSHIDO 0x2643029A2f97c8E4A790babC185f349c443f2707 Wrapped SHIDO β€” ERC20 wrapper for native SHIDO token
Multicall3 0x1a3a4cbd93F9ECD093Cf1bcbcA20637612dC9cC9 Batch multiple contract calls into one RPC request
Multicall2 0xF6Dc7a4Bd00c71E95279fec5C2467BA366d60745 Legacy multicall β€” for Uniswap V2 era tooling compatibility
CREATE2Factory 0x9390b6bd008b8f52fE4711556B7E2A429A0eeBD2 Deterministic CREATE2 deployment β€” same address on any chain
TestTokenFactory 0x1dd3d20FbA378671E5d4f875eB0bF39CC9AE451e Deploy custom ERC20 test tokens with any name, symbol and decimals
BatchSend 0x924655D1C56F69116b2f23EED9A2104ABae02e45 disperseEther + disperseToken β€” send ETH/tokens to multiple addresses in one tx
BatchTransfer 0xB08E49b9a65F0e47d2E3b54eAd5B0111A72C9C66 Batch ETH/ERC20 transfers with equal or custom amounts per recipient
ERC721Factory 0x5CC1E0265a152a1809e4daabE051126012B92aA6 Deploy full NFT collections (ERC721) β€” public mint, owner mint, base URI
AirdropFactory 0x22D3cff189F093Be2959B6c98660a249Ec7fCbCe Deploy Merkle-proof airdrop campaigns β€” gas-efficient, prevents double-claiming
PriceFeedFactory 0x73022a5C72b4b255C3e8e0482C93Aba36BE966AD Chainlink AggregatorV3Interface-compatible mock price feeds for DeFi testing
StakingFactory 0x3137606f413AA1C517A17EA8Fea81ab4b1e6D0d7 Deploy ERC20 staking pools β€” stake tokens and earn configurable rewards
TokenVesting 0x9adb34D4692091D5C60e72372e79167204d409B6 Linear vesting with cliff β€” team allocations, investor unlocks, contributor grants

Uniswap V3

ℹ️
Pool Init Code Hash: 0xd18b3d32777589aec36ebd7ad22da8f8cd34c01e7652836ef22ab8b3d0880133
ContractAddressDescription
UniswapV3Factory 0x33Fb0311d083b7F5d4014E9E2509c3d4C0Fb0E0E Creates and tracks all V3 liquidity pools
SwapRouter 0xCB6F539B872ee7b1C071CC4B4086245Bdc6919e5 Execute single and multi-hop token swaps
NonfungiblePositionManager 0x10FdcEBaE1a507fD85eaDCCfea0695197fAF0be5 Manage LP positions as NFTs β€” mint, increase, decrease, collect
QuoterV2 0x865E52Fe251D25b1aF7cae6B1AD3Af6C11EaDB7B Get swap price quotes β€” Shido-native implementation, fully compatible
TickLens 0x6aaE52d467cD8cc78Be700A7C48863E678aA93Dc Read populated tick data for liquidity visualization
NonfungibleTokenPositionDescriptor 0xB6af60c2afe5b33f49e105F2d4d733574fAc99b7 Generates on-chain SVG metadata for LP position NFTs

Create a Test Token

Use TestTokenFactory to deploy your own ERC20 test tokens with one call β€” no Solidity needed.

javascript
// ethers.js v6
const factory = new ethers.Contract(
  '0x1dd3d20FbA378671E5d4f875eB0bF39CC9AE451e',
  ['function createToken(string,string,uint8,uint256) returns (address)'],
  signer
);

// Deploy a 18-decimal token with 1 billion initial supply
const tx        = await factory.createToken('My Token', 'MTK', 18, 1_000_000_000);
const receipt   = await tx.wait();
// Token address is in the TokenCreated event

Swap Tokens (Uniswap V3)

javascript
// Approve router, then swap
const router = new ethers.Contract('0xCB6F539B872ee7b1C071CC4B4086245Bdc6919e5', [
  'function exactInputSingle((address,address,uint24,address,uint256,uint256,uint256,uint160)) payable returns (uint256)'
], signer);

await router.exactInputSingle({
  tokenIn:           WSHIDO,
  tokenOut:          MY_TOKEN,
  fee:               3000,      // 0.3%
  recipient:         myAddress,
  deadline:          Math.floor(Date.now() / 1000) + 3600,
  amountIn:          ethers.parseEther('1'),
  amountOutMinimum:  0,
  sqrtPriceLimitX96: 0
});

Get a Price Quote

javascript
const quoter = new ethers.Contract('0x865E52Fe251D25b1aF7cae6B1AD3Af6C11EaDB7B', [
  'function quoteExactInputSingle((address,address,uint256,uint24,uint160)) view returns (uint256,uint160,uint32,uint256)'
], provider);

const [amountOut] = await quoter.quoteExactInputSingle({
  tokenIn:           WSHIDO,
  tokenOut:          MY_TOKEN,
  amountIn:          ethers.parseEther('1'),
  fee:               3000,
  sqrtPriceLimitX96: 0
});
console.log('Expected output:', ethers.formatEther(amountOut));

Deterministic Deployment (CREATE2)

javascript
const factory = new ethers.Contract('0x9390b6bd008b8f52fE4711556B7E2A429A0eeBD2', [
  'function deploy(bytes32 salt, bytes bytecode) returns (address)',
  'function computeAddress(address deployer, bytes32 salt, bytes bytecode) pure returns (address)'
], signer);

const salt      = ethers.keccak256(ethers.toUtf8Bytes('my-unique-salt-v1'));
const bytecode  = MyContract__factory.bytecode;

// Predict address before deploying
const predicted = await factory.computeAddress(await signer.getAddress(), salt, bytecode);
console.log('Will deploy to:', predicted);

// Deploy
await factory.deploy(salt, bytecode);

12 Gas Costs

βœ…
Gas is effectively free. With 1,000 SHIDO from the faucet you can deploy 333,000+ complex contracts. Base fee is 1 Gwei with zero congestion.
ActionGas UnitsCost (SHIDO)Source
EVM Simple Transfer24,0000.000024confirmed
Cosmos Bank Send118,1650.000118confirmed
ERC20 Transfer~65,000~0.000065estimate
ERC20 Deploy~1,200,000~0.0012estimate
Complex Contract Deploy~3,000,000~0.003estimate
NFT Mint~100,000~0.0001estimate
Validator Self-Delegationβ€”100 SHIDO minstaking

13 Run a Validator

πŸ–₯️
Server requirements: Ubuntu 22.04+  Β·  8+ vCPU  Β·  16+ GB RAM  Β·  300+ GB SSD  Β·  100+ SHIDO for self-delegation

Chain Info

Cosmos Chain IDshido_9007-2
EVM Chain ID9007
Cosmos RPChttps://cosmos.testnet.shidoscan.net

Option A β€” Use Snapshot (Recommended)

⚑
Snapshots let you sync in minutes instead of replaying every block from genesis. Always use the latest snapshot.
bash
# Check available snapshots
curl -s https://testnet.shidoscan.net/snapshots/snapshots.json | python3 -m json.tool

# Download latest snapshot URL
SNAP_URL=$(curl -s https://testnet.shidoscan.net/snapshots/snapshots.json | \
  python3 -c "import sys,json; print(json.load(sys.stdin)['snapshots'][0]['url'])")

# Download and extract to chain home
mkdir -p /data/.tmp-shidod
wget -O /tmp/snapshot.tar.gz "$SNAP_URL"
tar -xzf /tmp/snapshot.tar.gz -C /data/.tmp-shidod
rm /tmp/snapshot.tar.gz
echo "Snapshot extracted β€” skip to Step 5"

Option B β€” Sync from Genesis

Full sync from block 0. Takes longer but gives complete chain history. Follow all steps below.

Step 1 β€” Install Go 1.21

bash
wget -q https://go.dev/dl/go1.21.5.linux-amd64.tar.gz -O /tmp/go.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf /tmp/go.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bashrc
source ~/.bashrc
go version

Step 2 β€” Install Cosmovisor

bash
go install cosmossdk.io/tools/cosmovisor/cmd/[email protected]

Step 3 β€” Install shidod Binary

bash
sudo apt-get update -y && sudo apt-get install -y build-essential jq wget curl

wget https://github.com/ShidoGlobal/shido-testnet-terra-upgrade/releases/download/terra-upgrade/shidod
chmod +x shidod && sudo mv shidod /usr/local/bin/

sudo wget -O /usr/lib/libwasmvm.x86_64.so \
  https://github.com/CosmWasm/wasmvm/releases/download/v2.1.4/libwasmvm.x86_64.so
sudo ldconfig

shidod version

Step 4 β€” Download genesis.json

bash
# Direct download (recommended)
curl -s https://testnet.shidoscan.net/snapshots/genesis.json > genesis.json

# Verify chain ID
python3 -c "import json; d=json.load(open('genesis.json')); print('Chain ID:', d['chain_id'])"

Step 5 β€” Initialize Node

bash
shidod config set client chain-id shido_9007-2 --home /data/.tmp-shidod
shidod config set client keyring-backend os --home /data/.tmp-shidod

shidod keys add validator --keyring-backend os --algo eth_secp256k1 --home /data/.tmp-shidod

shidod init MyValidator --chain-id shido_9007-2 --home /data/.tmp-shidod --overwrite

# Copy genesis (skip if you used Option A snapshot)
cp genesis.json /data/.tmp-shidod/config/genesis.json

Step 6 β€” Configure app.toml

⚠️
Required for Uniswap V3 QuoterV2 and DeFi contracts to work correctly on your node.
bash
# Gas cap for DeFi simulations (must be > 21000, not 0)
sed -i 's/gas-cap = .*/gas-cap = 50000000000/' /data/.tmp-shidod/config/app.toml

# Increase EVM call timeout
sed -i 's/evm-timeout = .*/evm-timeout = "60s"/' /data/.tmp-shidod/config/app.toml

# Set minimum gas price
sed -i 's/minimum-gas-prices = "0shido"/minimum-gas-prices = "0.25shido"/' /data/.tmp-shidod/config/app.toml

grep -E "gas-cap|evm-timeout|minimum-gas-prices" /data/.tmp-shidod/config/app.toml

Step 7 β€” Configure Peers

bash
sed -i 's/persistent_peers = ""/persistent_peers = "[email protected]:26656"/' \
  /data/.tmp-shidod/config/config.toml

Step 8 β€” Create systemd Service

bash
sudo tee /etc/systemd/system/shidochain.service > /dev/null << 'SERVICE'
[Unit]
Description=Shido Testnet Node (shido_9007-2)
After=network-online.target
Wants=network-online.target

[Service]
User=root
Environment=DAEMON_NAME=shidod
Environment=DAEMON_HOME=/data/.tmp-shidod
Environment=DAEMON_ALLOW_DOWNLOAD_BINARIES=true
ExecStart=/root/go/bin/cosmovisor run start --home /data/.tmp-shidod
Restart=always
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
SERVICE

sudo systemctl daemon-reload
sudo systemctl enable shidochain.service
sudo systemctl start shidochain.service
sudo systemctl status shidochain.service

Step 9 β€” Verify Syncing

bash
# Watch until catching_up = false
watch -n 3 'curl -s http://localhost:26657/status | python3 -c "import sys,json; s=json.load(sys.stdin)["result"]["sync_info"]; print("Height:", s["latest_block_height"], "| Catching up:", s["catching_up"])"'
βœ…
Wait for catching_up: False and block height matching testnet.shidoscan.net before creating your validator.

Step 10 β€” Get SHIDO & Create Validator

πŸ’§
Get your EVM address, fund it via the faucet, then run:
bash
# Get your validator EVM address to fund via faucet
shidod keys show validator --keyring-backend os --home /data/.tmp-shidod -e

shidod tx staking create-validator \
  --amount 100000000000000000000shido \
  --pubkey $(shidod tendermint show-validator --home /data/.tmp-shidod) \
  --moniker 'YourValidatorName' \
  --chain-id shido_9007-2 \
  --commission-rate 0.10 \
  --commission-max-rate 0.20 \
  --commission-max-change-rate 0.01 \
  --min-self-delegation 1 \
  --from validator \
  --keyring-backend os \
  --home /data/.tmp-shidod \
  --gas auto --gas-adjustment 1.5 -y

14 Troubleshooting

ProblemSolution
MetaMask shows wrong balanceReset account: Settings β†’ Advanced β†’ Reset Account. This clears local nonce cache.
Transaction stuck pendingSpeed up or cancel in MetaMask. If nonce is stuck, reset MetaMask account.
Contract deployment failsIncrease gas limit in deployment settings. Ensure you have enough SHIDO for gas.
Faucet returns 429Address or IP is rate limited. Wait 24 hours or request from a different address.
RPC connection errorCheck node status on the explorer. Server may be briefly restarting.
Wrong chain ID errorEnsure chain ID is 9007. Mainnet Shido is 9008 β€” do not mix them.
Hardhat verify failsMatch compiler version exactly. Try --force flag or flatten contract first.
eth_getLogs returns emptyConfirm block range. Use "latest" for the toBlock parameter.

15 Resources