Deploy an EVM contract
Overview
The x/evm
Warden module allows executing Ethereum Virtual Machine (EVM) contracts charged by Evmos. They are written in Solidity.
This guide explains how to create and deploy a simple "Hello World" Solidity smart contract on the Warden chain. Since it's intended for testing purposes, you'll be running a local chain.
Prerequisites
Before you start, complete the following prerequisites:
-
Install Node.js and npm by running the following command:
brew install node
-
Install Truffle globally:
npm install -g truffle
-
Install HDWalletProvider:
npm install @truffle/hdwallet-provider
1. Prepare the chain
Option 1. Run a local chain
-
Run a local chain as explained here: Run a local chain. Note that you'll need to install Go 1.22.3 or later and just 1.34.0 or later.
-
Check the list of available keys (local accounts) and note down your key name.
wardend keys list
tipIf you used our
just
script to run the node with default settings, the local account name isshulgin
. -
Check the local account balance to make sure it has funds:
- Local node: default settings
- Local node: custom settings
wardend query bank balances shulgin
wardend query bank balances my-key-name
-
The next steps require the private key associated with this account. To get it, run this:
- Default node settings
- Custom node settings
wardend keys export shulgin --unarmored-hex --unsafe
wardend keys export my-key-name --unarmored-hex --unsafe
-
You'll also need your chain ID. Run the following and note down the value from the
network
field:wardend status
tipIf you used our
just
script to run the node with default settings, the chain ID iswarden_1337-1
.
Option 2. Connect to Chiado
-
If you haven't yet, install Go 1.22.3 or later and just 1.34.0 or later.
-
Clone the repository with Warden source code. Then build the binary and initialize the chain home folder:
git clone --depth 1 --branch v0.5.2 https://github.com/warden-protocol/wardenprotocol
cd wardenprotocol
just wardend build
just wardend install
wardend init my-chain-moniker -
Create a new key:
wardend keys add my-key-name
-
Write down the mnemonic phrase and the address of the new account. You'll need this information to interact with the chain and restore the account.
warningThe seed phrase is the only way to restore your keys. Losing it can result in the irrecoverable loss of WARD tokens.
tipYou can always check your public address by running this command:
wardend keys show my-key-name --address
-
Fund your key using Chiado faucet and the public address obtained in the previous step.
-
Check your balance:
wardend query bank balances my-key-name --node https://rpc.chiado.wardenprotocol.org:443
-
The next steps require the private key associated with this account. To get it, run this:
wardend keys export my-key-name --unarmored-hex --unsafe
2. Create an EVM project
-
Create a new directory
/warden-smart-contract
for your project and navigate there:mkdir warden-smart-contract
cd warden-smart-contract -
Initialize a new Truffle project:
truffle init
3. Create a smart contract
In the /contracts
directory, create a new file HelloWarden.sol
with the following contents:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract HelloWarden {
string public message;
constructor() {
message = "Hello, Warden!";
}
function setMessage(string memory newMessage) public {
message = newMessage;
}
function getMessage() public view returns (string memory) {
return message;
}
}
4. Configure Truffle
-
In the
/warden-smart-contract
directory, find thetruffle-config.js
file and update it with this code:- Local node
- Chiado
/warden-smart-contract/truffle-config.jsconst HDWalletProvider = require("@truffle/hdwallet-provider");
// Keep your private key confidential, DO NOT commit to version control!
const PRIVATE_KEY = "your_private_key";
// The standard localhost address and the node's RPC port
const RPC_URL = "http://127.0.0.1:8545";
module.exports = {
networks: {
warden: {
provider: function() {
return new HDWalletProvider(PRIVATE_KEY, RPC_URL);
},
network_id: 1337, // The first number from the chain ID
gas: 5500000,
gasPrice: 20000000000 // award
},
},
compilers: {
solc: {
version: "0.8.20",
}
}
};/warden-smart-contract/truffle-config.jsconst HDWalletProvider = require("@truffle/hdwallet-provider");
// Keep your private key confidential, DO NOT commit to version control!
const PRIVATE_KEY = "your_private_key";
// Chiado's EVM endpoint
const RPC_URL = "https://evm.chiado.wardenprotocol.org";
module.exports = {
networks: {
warden: {
provider: function() {
return new HDWalletProvider(PRIVATE_KEY, RPC_URL);
},
network_id: 10010, // The first number from the chain ID
gas: 5500000,
gasPrice: 20000000000 // award
},
},
compilers: {
solc: {
version: "0.8.20",
}
}
}; -
Adjust the code and make sure all values are correct:
your_private_key
: Replace it with your actual private key from Step 1.RPC_URL
: If you're running a local chain and deploying the contract on the same machine, use the standard localhost address. Otherwise, check the chain's host address by executingwardend status
on the machine hosting the chain. For Chiado, specify its EVM endpoint:https://evm.chiado.wardenprotocol.org
.network_id
: Specify the first number from the chain ID. For example, if your local chain ID iswarden_1337-1
, the network ID is1337
. The correct value for Chiado is10010
. Alternatively, you can just use"*"
to match any chain ID.- If needed, adjust the gas limit and price –
gas
andgasPrice
.
5. Create a migration script
In /migrations
, create a new file 2_deploy_hello_warden.js
with the following contents:
const HelloWarden = artifacts.require("HelloWarden");
module.exports = function(deployer) {
deployer.deploy(HelloWarden);
};
6. Compile the contract
To compile your contract, run this command:
truffle compile
You'll see an output similar to the following:
Compiling your contracts...
===========================
> Compiling ./contracts/HelloWarden.sol
> Artifacts written to /build/contracts
> Compiled successfully using:
- solc: 0.8.20+commit.c7dfd78e.Emscripten.clang
7. Deploy the contract
If you're deploying on a local chain, make sure it's running. You can start your chain by running wardend start
in a separate terminal window.
To deploy the contract, run this:
truffle migrate --network warden
You should see the following output, confirming the successful deployment.
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Starting migrations...
======================
> Network name: 'warden'
> Network id: 1337
> Block gas limit: 4294967295 (0xffffffff)
2_deploy_hello_warden.js
========================
Deploying 'HelloWarden'
-----------------------
> transaction hash: 0x14ed62fcb105a3b5d315738767f288101f4db2d13ee4924a217090080abe0fef
> Blocks: 0 Seconds: 0
> contract address: 0x2AAbb1a9b8EdE05f183FfD90A324ce02A349F6e5
> block number: 2993
> block timestamp: 1725617534
> account: 0x6Ea8aC1673402989e7B653aE4e83b54173719C30
> balance: 9999999.83499999999011708
> gas used: 2750000 (0x29f630)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.055 ETH
> Saving artifacts
-------------------------------------
> Total cost: 0.055 ETH
Summary
=======
> Total deployments: 1
> Final cost: 0.055 ETH
Due to Evmos default settings, this log displays prices in ETH and gwei. However, the contract itself uses Warden's currency – WARD, denominated in award.
8. Interact with the contract
-
To interact with your contract, open the Truffle console:
truffle console --network warden
-
Retrieve the deployed instance of the contract:
let instance = await HelloWarden.deployed();
-
Retrieve the stored message by calling the
getMessage()
function in your contract:let message = await instance.getMessage();
-
Print the message:
console.log(message);
The console log should print
Hello, Warden!
-
Update the message in the contract with
setMessage()
:await instance.setMessage("Hello, EVM on Warden!");
-
Call
getMessage()
again to retrieve the updated message:message = await instance.getMessage();
-
Print the updated message:
console.log(message);
The console log should print
Hello, EVM on Warden!
-
To exit the console, run this:
.exit
If you encounter any issues, please reach out to us in Discord or Twitter.
Happy coding! 🚀