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.
| Field | Value |
|---|---|
| Network Name | Shido Testnet |
| RPC URL | https://rpc.testnet.shidoscan.net |
| WebSocket URL | wss://ws.testnet.shidoscan.net |
| Chain ID | 9007 |
| Hex Chain ID | 0x232F |
| Currency Symbol | SHIDO |
| Currency Decimals | 18 |
| Block Explorer | https://testnet.shidoscan.net |
| Faucet | https://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
Go to remix.ethereum.org
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_*)
| Method | Description |
|---|---|
| eth_blockNumber | Get latest block number |
| eth_getBalance | Get address SHIDO balance |
| eth_sendRawTransaction | Broadcast signed transaction |
| eth_getTransactionByHash | Get transaction details |
| eth_getTransactionReceipt | Get transaction receipt |
| eth_call | Call contract function (read-only) |
| eth_estimateGas | Estimate gas for a transaction |
| eth_gasPrice | Get current gas price |
| eth_getCode | Get contract bytecode |
| eth_getLogs | Get event logs |
| eth_getBlockByNumber | Get block details by number |
| eth_getTransactionCount | Get nonce for address |
| eth_chainId | Returns chain ID (0x232F = 9007) |
| eth_syncing | Check sync status |
| eth_getStorageAt | Get contract storage slot |
| eth_feeHistory | Get historical fee data (EIP-1559) |
| eth_maxPriorityFeePerGas | Get max priority fee suggestion |
| net_version | Returns chain ID (9007) |
| net_listening | Check if node is listening |
| net_peerCount | Get number of peers |
| web3_clientVersion | Get node client version |
| web3_sha3 | Keccak-256 hash |
| txpool_status | Get pending/queued tx count |
| txpool_content | Get full txpool contents |
| txpool_inspect | Get txpool summary |
Debug Methods (debug_*)
βΉοΈ
Debug methods are available for contract debugging, transaction tracing and state inspection. Essential for DeFi protocol development.
| Method | Description |
|---|---|
| debug_traceTransaction | Trace a transaction with call tracer |
| debug_traceCall | Trace an eth_call without broadcasting |
| debug_traceBlockByNumber | Trace all txs in a block |
| debug_traceBlockByHash | Trace all txs in a block by hash |
| debug_storageRangeAt | Get contract storage range |
| debug_getRawTransaction | Get 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 callsWebSocket 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
| Contract | Address | Description |
|---|---|---|
| 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| Contract | Address | Description |
|---|---|---|
| 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 eventSwap 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.
| Action | Gas Units | Cost (SHIDO) | Source |
|---|---|---|---|
| EVM Simple Transfer | 24,000 | 0.000024 | confirmed |
| Cosmos Bank Send | 118,165 | 0.000118 | confirmed |
| ERC20 Transfer | ~65,000 | ~0.000065 | estimate |
| ERC20 Deploy | ~1,200,000 | ~0.0012 | estimate |
| Complex Contract Deploy | ~3,000,000 | ~0.003 | estimate |
| NFT Mint | ~100,000 | ~0.0001 | estimate |
| Validator Self-Delegation | β | 100 SHIDO min | staking |
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
Peer[email protected]:26656
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 versionStep 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 versionStep 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.jsonStep 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.tomlStep 7 β Configure Peers
bash
sed -i 's/persistent_peers = ""/persistent_peers = "[email protected]:26656"/' \
/data/.tmp-shidod/config/config.tomlStep 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.serviceStep 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 -y14 Troubleshooting
| Problem | Solution |
|---|---|
| MetaMask shows wrong balance | Reset account: Settings β Advanced β Reset Account. This clears local nonce cache. |
| Transaction stuck pending | Speed up or cancel in MetaMask. If nonce is stuck, reset MetaMask account. |
| Contract deployment fails | Increase gas limit in deployment settings. Ensure you have enough SHIDO for gas. |
| Faucet returns 429 | Address or IP is rate limited. Wait 24 hours or request from a different address. |
| RPC connection error | Check node status on the explorer. Server may be briefly restarting. |
| Wrong chain ID error | Ensure chain ID is 9007. Mainnet Shido is 9008 β do not mix them. |
| Hardhat verify fails | Match compiler version exactly. Try --force flag or flatten contract first. |
| eth_getLogs returns empty | Confirm block range. Use "latest" for the toBlock parameter. |