Foundry
Install Foundry, configure for Mandala, deploy a contract, verify on Blockscout.
Foundry is the fastest path from zero to deployed contract on Mandala. One config file, one deploy command, one verify command.
Install
curl -L https://foundry.paradigm.xyz | bash
foundryupThis installs forge, cast, anvil, and chisel.
New project
forge init my-project && cd my-projectFoundry scaffolds src/, test/, script/, and foundry.toml.
Configure
Append Mandala endpoints to foundry.toml:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.24"
[rpc_endpoints]
mandala = "https://rpc1-mainnet.mandalachain.io"
mandala_testnet = "https://rpc1-testnet.mandalachain.io"
[etherscan]
mandala = { key = "empty", url = "https://explorer.mandalachain.io:443/api/", chain = 20010 }
mandala_testnet = { key = "empty", url = "https://explorer.testnet.mandalachain.io:443/api/", chain = 20011 }Blockscout uses an Etherscan-compatible API. The "empty" placeholder is required by Foundry but Blockscout does not validate it.
Put your private key in .env:
echo "PRIVATE_KEY=0xyour..." > .env
echo ".env" >> .gitignore
source .envDeploy
For a single contract, forge create is the one-liner:
forge create src/Counter.sol:Counter \
--rpc-url mandala_testnet \
--private-key $PRIVATE_KEY \
--broadcastFor multi-contract deploys, write a Forge script at script/Deploy.s.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "forge-std/Script.sol";
import "../src/Counter.sol";
contract DeployScript is Script {
function run() external {
vm.startBroadcast();
new Counter();
vm.stopBroadcast();
}
}Run it:
forge script script/Deploy.s.sol --rpc-url mandala_testnet --broadcastVerify
forge verify-contract \
--rpc-url mandala_testnet \
--verifier blockscout \
--verifier-url https://explorer.testnet.mandalachain.io:443/api/ \
0xYourAddress \
src/Counter.sol:CounterFor contracts with constructor arguments:
forge verify-contract \
--rpc-url mandala_testnet \
--verifier blockscout \
--verifier-url https://explorer.testnet.mandalachain.io:443/api/ \
--constructor-args $(cast abi-encode "constructor(uint256)" 42) \
0xYourAddress \
src/Counter.sol:CounterFor mainnet, swap mandala_testnet for mandala and the verifier URL to https://explorer.mandalachain.io:443/api/.
Common errors
Error: chain id 20010 not found. Add the [rpc_endpoints] and [etherscan] blocks above to foundry.toml.
Insufficient funds for gas. You need KPG (mainnet) or KPGT (testnet) at the deploying address.
Failed to verify: contract was already verified. Not an error. Blockscout reports this when the source matches an already-verified deployment of the same bytecode.
Compiler run failed during verification. Compiler version or optimizer mismatch. Set solc and optimizer in foundry.toml to the values you used at deploy time.

