Your First Solidity Contract
Create and deploy your first Solidity contract on SupraEVM
Project Overview
We will be building a Solidity-based DAO Management Contract on SupraEVM, this guide walks you through the complete process of developing, deploying, and interacting with your contact on SupraEVM Network using Hardhat.
Prerequisites
Start building
1
2
3
Create a new sub directory of Contracts
and make a new Solidity contract within the directory.
Contracts
and make a new Solidity contract within the directory.This .sol
contract will add the desired DAO functionalities to use in our Contract.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
contract CrossChainDAO {
struct Proposal {
uint id;
string description;
uint voteCount;
bool executed;
}
address public owner;
uint public proposalCount;
mapping(uint => Proposal) public proposals;
mapping(address => bool) public members;
event ProposalCreated(uint id, string description);
event VoteCasted(uint id, address voter);
event ProposalExecuted(uint id);
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}
modifier onlyMember() {
require(members[msg.sender], "Only DAO members can vote");
_;
}
constructor() {
owner = msg.sender;
}
function addMember(address _member) external onlyOwner {
members[_member] = true;
}
function createProposal(string memory _description) external onlyMember {
proposalCount++;
proposals[proposalCount] = Proposal(proposalCount, _description, 0, false);
emit ProposalCreated(proposalCount, _description);
}
function vote(uint _id) external onlyMember {
Proposal storage proposal = proposals[_id];
require(!proposal.executed, "Proposal already executed");
proposal.voteCount++;
emit VoteCasted(_id, msg.sender);
}
function executeProposal(uint _id) external onlyOwner {
Proposal storage proposal = proposals[_id];
require(!proposal.executed, "Proposal already executed");
require(proposal.voteCount > 0, "Insufficient votes to execute the proposal");
proposal.executed = true;
emit ProposalExecuted(_id);
}
}
5
Setting the deployment script
Create a sub directory of scripts and make a deployment script within the scripts/deploy.js
file
const { ethers } = require("hardhat");
async function main() {
const CrossChainDAO = await ethers.getContractFactory("CrossChainDAO");
const dao = await CrossChainDAO.deploy();
await dao.deployed();
console.log("DAO deployed to:", dao.address);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
7
Setting up the interaction script
Create an interactive script (scripts/interact.js
) to perform all DAO functionalities.
const { ethers } = require("hardhat");
async function main() {
const daoAddress = " "; // Replace with your DAO contract address
const abi = [
// add your contract ABI once you deploy it on SupraEVM
];
const signer = await ethers.getSigner();
const daoContract = new ethers.Contract(daoAddress, abi, signer);
const readline = require("readline").createInterface({
input: process.stdin,
output: process.stdout,
});
async function menu() {
console.log("\nWelcome to the DAO Interaction Script!");
console.log("Choose an action:");
console.log("1. Add a DAO Member");
console.log("2. Create a Proposal");
console.log("3. Vote on a Proposal");
console.log("4. Execute a Proposal");
console.log("5. Exit");
readline.question("Enter the number of the action: ", async (action) => {
try {
if (action === "1") {
readline.question("Enter the member's address: ", async (address) => {
const tx = await daoContract.addMember(address);
await tx.wait();
console.log(`Address ${address} added as a DAO member!`);
await menu(); // Loop back to menu
});
} else if (action === "2") {
readline.question("Enter the proposal description: ", async (description) => {
const tx = await daoContract.createProposal(description);
await tx.wait();
console.log("Proposal created successfully!");
await menu(); // Loop back to menu
});
} else if (action === "3") {
readline.question("Enter the proposal ID to vote on: ", async (proposalId) => {
const tx = await daoContract.vote(proposalId);
await tx.wait();
console.log(`Vote cast for proposal ID ${proposalId}!`);
await menu(); // Loop back to menu
});
} else if (action === "4") {
readline.question("Enter the proposal ID to execute: ", async (proposalId) => {
const tx = await daoContract.executeProposal(proposalId);
await tx.wait();
console.log(`Proposal ID ${proposalId} executed successfully!`);
await menu(); // Loop back to menu
});
} else if (action === "5") {
console.log("Exiting. Goodbye!");
readline.close();
} else {
console.log("Invalid action. Please try again.");
await menu(); // Loop back to menu
}
} catch (error) {
console.error("An error occurred:", error.message);
await menu(); // Loop back to menu
}
});
}
await menu(); // Start the menu loop
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});