Solidity on Citrate
We built Citrate's Lattice Virtual Machine (LVM) to provide full EVM compatibility, meaning any Solidity contract that compiles for Ethereum will deploy and execute on Citrate without modification. The LVM extends the standard EVM with AI-native precompiled contracts, but the base instruction set, storage model, and ABI encoding remain identical to Ethereum.
This guide covers the practical steps for setting up your development environment, writing contracts, deploying them, and understanding the key differences between Citrate and Ethereum.
EVM Compatibility
The LVM supports Solidity compiler versions up to 0.8.x and implements all standard EVM opcodes through the Shanghai upgrade. This means you can use familiar patterns such as OpenZeppelin libraries, proxy contracts, and CREATE2 deterministic deployments without changes.
Key compatibility points:
- ABI encoding follows the standard Ethereum ABI specification
- Gas metering uses the same opcode costs as Ethereum post-Shanghai, with additional gas schedules for AI precompile calls
- Storage layout is slot-based and compatible with tools like
forge inspect - Events and logs work identically, and standard indexers can parse Citrate event data
The primary difference is that Citrate provides seven AI precompile addresses (0x0100 through 0x0106) that give contracts native access to model deployment, inference, batch processing, metadata, proof verification, benchmarking, and model encryption. These are optional -- you can deploy a purely financial DeFi contract on Citrate with zero AI interaction.
Hardhat Setup
To configure Hardhat for Citrate, install the standard Hardhat package and add a network entry to your configuration:
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init
Then update hardhat.config.js:
require("@nomicfoundation/hardhat-toolbox");
module.exports = {
solidity: "0.8.24",
networks: {
"citrate-testnet": {
url: "https://testnet-rpc.cnidarian.cloud",
chainId: 1338,
accounts: [process.env.PRIVATE_KEY],
},
"citrate-mainnet": {
url: "https://rpc.cnidarian.cloud",
chainId: 1337,
accounts: [process.env.PRIVATE_KEY],
},
},
};
Deploy your contracts with the standard Hardhat deploy command:
npx hardhat run scripts/deploy.js --network citrate-testnet
Foundry Setup
Foundry provides faster compilation and more powerful testing. Install Foundry and create a new project:
curl -L https://foundry.paradigm.xyz | bash
foundryup
forge init my-citrate-project
cd my-citrate-project
Add Citrate RPC endpoints to your foundry.toml:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.24"
[rpc_endpoints]
citrate_testnet = "https://testnet-rpc.cnidarian.cloud"
citrate_mainnet = "https://rpc.cnidarian.cloud"
Deploy with forge create:
forge create --rpc-url citrate_testnet --private-key $PRIVATE_KEY src/MyContract.sol:MyContract
Deployment Scripts
For production deployments, use scripted deployments that handle verification and multi-contract setups. Here is a Foundry deployment script example:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "forge-std/Script.sol";
import "../src/MyAIApp.sol";
contract DeployMyAIApp is Script {
function run() external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
MyAIApp app = new MyAIApp();
// Verify the AI precompiles are accessible
require(address(0x0100).code.length > 0, "ModelRegistry not available");
vm.stopBroadcast();
}
}
Run the script:
forge script script/DeployMyAIApp.s.sol:DeployMyAIApp --rpc-url citrate_testnet --broadcast
Differences from Ethereum
While Citrate maintains EVM compatibility, there are important differences developers should understand:
| Feature | Ethereum | Citrate |
|---|---|---|
| Block time | ~12 seconds | ~1 second (GhostDAG parallel blocks) |
| Finality | ~15 minutes (probabilistic) | ~10 seconds (checkpoint-based) |
| Gas token | ETH | SALT |
| Precompiles | 0x01-0x0a (cryptographic) | 0x01-0x0a + 0x0100-0x0106 (AI) |
| Block structure | Single chain | DAG of parallel blocks |
| Consensus | Proof of Stake | GhostDAG + Paraconsistent BFT |
The GhostDAG block structure means transactions can be confirmed in parallel across multiple block producers, resulting in significantly higher throughput. Your contracts do not need to account for this -- the LVM presents a consistent sequential execution view to smart contracts, just as Ethereum does. I'd suggest deploying to testnet first and confirming your contract behaves identically before moving to mainnet.
Further Reading
- Lattice Virtual Machine -- detailed LVM architecture
- AI Precompiles -- the seven native AI contracts
- Testing with Foundry -- test your contracts locally
- Network Configuration -- full RPC and chain details