Get started with precompiles
Overview
You can interact with Warden Protocol modules in your EVM smart contract by calling Warden precompiles.
This guide shows how to deploy a simple EVM contract calling the spaceById()
function of the x/warden
module. After that, you'll be able to expand your contract code with other functions, which are documented in the subsections below.
To learn the basics of deploying contracts on Warden, refer to Deploy an EVM contract.
Prerequisites
Before you start, complete the following prerequisites:
-
Install Foundry by running this command:
curl -L https://foundry.paradigm.xyz | bash \
foundryup -
Prepare the chain, setting up your private key. You can either run a local chain or join the Chiado testnet, as shown in Deploy an EVM smart contract.
1. Create your project and contract
-
Initialize a new Foundry project and navigate to its directory:
forge init warden-smart-contract --no-commit
cd warden-smart-contractAlternatively, you can use an existing project—for example, the one you created when following the Deploy an EVM contract guide.
-
In the
/src
directory, create a new contract namedWarden.sol
.To call a precompile in your contract, do this::
- Define an
interface
for interacting with a Warden precompile. - Add a
contract
with functions calling the precompile. - In the
contract
section, you should also reference the precompile address.
You can use the example contract below. It calls the
spaceById()
function ofx/warden
to return a Space and its creator by Space ID:/warden-smart-contract/src/Warden.sol// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
// An interface for interacting with the IWarden precompile
interface IWarden {
// A function for getting a Space by its ID
function spaceById(uint64) external view returns (Space memory);
// Data structure representing a Warden Space
struct Space {
uint64 id; // The Space ID
address creator; // The Space creator address
address[] owners;
uint64 nonce;
uint64 approveAdminTemplateId;
uint64 rejectAdminTemplateId;
uint64 approveSignTemplateId;
uint64 rejectSignTemplateId;
}
}
// A contract for interacting with the IWarden precompile
contract querySpace {
// The IWarden precompile address
address constant WARDEN_ADDRESS = 0x0000000000000000000000000000000000000900;
IWarden public warden;
constructor() {
warden = IWarden(WARDEN_ADDRESS);
}
// A function for getting a Space by Space ID
function getSpace(uint64 id) external view returns (IWarden.Space memory) {
return warden.spaceById(id);
}
// A function for getting the Space creator address by Space ID
function getSpaceCreator(uint64 id) external view returns (address) {
return warden.spaceById(id).creator;
}
} - Define an
2. Compile and deploy the contract
-
Export your private key and the RPC URL as environmental variables:
- Local node
- Chiado
export PRIVATE_KEY=my-private-key
export RPC_URL=http://127.0.0.1:8545export PRIVATE_KEY=my-private-key
export RPC_URL=https://evm.chiado.wardenprotocol.orgwarningIn production, never store private keys directly in environment variables. Consider using encrypted keystores or secure key management solutions like
.env
. -
Compile your contract using Foundry:
forge build
-
Deploy the contract:
forge create --rpc-url $RPC_URL --private-key $PRIVATE_KEY src/Warden.sol:querySpace
-
Export your contract address returned in
Deployed to
:export CONTRACT_ADDRESS=my-contract-address
-
Verify the deployment:
cast code $CONTRACT_ADDRESS --rpc-url $RPC_URL
3. Interact with the contract
Now you can interact with the contract.
-
If you're using a local chain, make sure it's running and there is at least one Space:
wardend query warden spaces
If nothing is returned, create a Space.
-
Get a Space by its ID—for example,
1
:cast call $CONTRACT_ADDRESS "getSpace(uint64)" 1 --rpc-url $RPC_URL
The result will look like this:
0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006ea8ac1673402989e7b653ae4e83b54173719c3000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006ea8ac1673402989e7b653ae4e83b54173719c30
-
Get the Space creator by Space ID—for example,
1
:cast call $CONTRACT_ADDRESS "getSpaceCreator(uint64)" 1 --rpc-url $RPC_URL
The result will look like this:
0x0000000000000000000000006ea8ac1673402989e7b653ae4e83b54173719c30
Next steps
Now you can dive deeper and expand your contract with other functions from Warden precompiles:
-
To find code samples for each function, see the following guides:
- Interact with
x/warden
- Interact with
x/oracle
: Coming soon—see thex/oracle
precompile - Interact with
x/act
- Interact with
x/async
- Interact with
-
For an overview of the available functions, refer to the Precompiles section.