Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Setting Up On-Chain Voting for Sustainability Initiatives

A developer tutorial for implementing secure, transparent on-chain voting to govern environmental projects, from off-chain signaling to on-chain execution and treasury disbursal.
Chainscore © 2026
introduction
TUTORIAL

Setting Up On-Chain Voting for Sustainability Initiatives

A technical guide to implementing a basic, gas-efficient on-chain voting system for environmental project funding using Solidity and OpenZeppelin.

On-chain governance allows decentralized communities to manage shared resources and direct funds transparently. For environmental initiatives, this means stakeholders can propose, debate, and vote on funding for projects like reforestation or renewable energy research directly on the blockchain. The core mechanism is a smart contract that holds a treasury and executes payments based on the outcome of member votes. This eliminates reliance on a central authority, creating an immutable and auditable record of all decisions and fund flows, which is critical for accountability in sustainability efforts.

To build this, we use OpenZeppelin's governance contracts as a secure foundation. Start by inheriting from Governor and GovernorCountingSimple. The proposal lifecycle is standardized: 1) A proposal is created with a target contract and calldata to transfer funds, 2) A voting period opens where token holders cast votes, and 3) The proposal is executed if it passes. For environmental DAOs, the target is often a treasury contract, and the calldata encodes a function call to disburse ETH or ERC-20 tokens to a verified project wallet.

solidity
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";

contract EcoGovernor is Governor, GovernorCountingSimple {
    constructor(IVotes _token)
        Governor("EcoGovernor")
        GovernorCountingSimple()
    {}
    // Override voting delay, period, and quorum as needed
}

Voting power should be tied to a commitment to the cause, not just capital. Instead of a generic ERC-20, use OpenZeppelin's ERC20Votes token, which includes snapshot capabilities for delegation and vote tracking. Consider minting tokens based on verifiable off-chain actions, like completing an environmental education course (with proof-of-attendance) or staking a non-transferable "impact" NFT. This aligns governance rights with demonstrated engagement. The voting logic in the _countVote function can be customized; for instance, you could implement quadratic voting to reduce whale dominance by making vote cost increase quadratically with voting power.

After deploying the governor and token contracts, the workflow is managed through a front-end like Tally or a custom dApp. A user with a proposal submits it via the propose function, specifying the recipient address, amount, and a description hash. During the voting period, token holders connect their wallets and cast votes (For, Against, Abstain). Key parameters to configure are votingDelay (blocks before voting starts), votingPeriod (blocks voting is open), and quorum (minimum vote power required). For a Layer 2 like Arbitrum or Polygon, set these parameters considering faster block times to keep the governance cycle agile, often between 3-7 days total.

Security and transparency are paramount. All proposal details and vote tallies are permanently on-chain. Use Etherscan or a subgraph to create a public dashboard tracking proposal history and treasury disbursements. To prevent malicious proposals, implement a timelock contract between the governor and treasury. This delays execution for 48-72 hours after a vote passes, giving the community a final window to react if a proposal is harmful. Furthermore, integrate with Chainlink Proof of Reserve or API feeds to create conditional proposals that only execute if real-world metrics (like verified carbon credit retirement) are met, bridging on-chain decisions with off-chain impact.

prerequisites
ON-CHAIN VOTING

Prerequisites and Setup

A technical guide to preparing your environment for building and deploying on-chain governance for sustainability projects.

Before writing a single line of code, you must establish a foundational environment. This requires a Node.js runtime (v18 or later) and a package manager like npm or yarn. You'll also need a code editor such as VS Code. The core of on-chain development involves interacting with a blockchain, so you must install a wallet like MetaMask and fund it with testnet ETH from a faucet. For this guide, we'll use the Sepolia testnet, a popular Ethereum test environment that mirrors mainnet functionality without real financial risk.

The next step is selecting and setting up your development framework. We recommend Hardhat or Foundry for smart contract development, as they provide comprehensive testing, deployment, and scripting tools. Initialize a new project using npx hardhat init or forge init. These frameworks will create the necessary project structure, including directories for contracts, scripts, and tests. You must also install essential libraries; for Solidity development, include OpenZeppelin Contracts via npm install @openzeppelin/contracts, which provides secure, audited implementations of standards like ERC-20 and the governance primitive Governor.

With your framework ready, configure the network connection. Create or modify the hardhat.config.js (or foundry.toml) file to include your Sepolia RPC endpoint. You can obtain a free one from providers like Alchemy or Infura. Securely store your wallet's private key or mnemonic in a .env file using the dotenv package, and reference it in your configuration. Never commit this file to version control. Verify your setup by running a test compilation with npx hardhat compile or forge build to ensure your toolchain is correctly installed and configured for the upcoming contract work.

key-concepts-text
GOVERNANCE IMPLEMENTATION

Setting Up On-Chain Voting for Sustainability Initiatives

This guide explains how to implement on-chain voting for environmental and social governance (ESG) proposals using smart contract standards.

On-chain voting transforms sustainability governance by making funding decisions transparent, immutable, and directly executable. Unlike traditional corporate voting, on-chain systems use smart contracts to automate proposal submission, voting, and fund disbursement. This is ideal for Decentralized Autonomous Organizations (DAOs) managing green treasuries, carbon credit retirement pools, or community grant programs. Core standards like ERC-5805 (Delegation) and ERC-6372 (Clock) provide the foundational building blocks. The process typically involves a member submitting a proposal (e.g., "Fund a solar panel installation"), a voting period where token holders cast votes, and automatic execution if the proposal passes quorum and majority thresholds.

The technical architecture relies on a modular stack. The voting token (often an ERC-20) represents voting power, which can be delegated using the ERC-5805 standard. A governor contract manages the proposal lifecycle, integrating with a voting strategy to tally votes. For sustainability metrics, you can use ERC-6372 to attach a Clock contract that tracks time in a blockchain-agnostic way, crucial for defining voting periods across different chains. A common implementation is the OpenZeppelin Governor framework, which provides secure, audited base contracts. Proposals can execute arbitrary calls, allowing the DAO treasury to send funds directly to a verified supplier's wallet upon successful vote completion.

Here is a simplified example of a proposal submission using Solidity and OpenZeppelin's Governor contract. This snippet shows how a community member might propose allocating funds from the DAO treasury to a sustainability project.

solidity
// Assume `governor` is an instance of OpenZeppelin's GovernorContract
// `targets` are the contracts to call (e.g., treasury),
// `values` are the amounts of native token to send,
// `calldatas` are the encoded function calls.

address[] memory targets = new address[](1);
targets[0] = dao_treasury_address;
uint256[] memory values = new uint256[](1);
values[0] = 10 ether; // Propose sending 10 ETH
bytes[] memory calldatas = new bytes[](1);
// Encode a call to the treasury's `transfer` function
calldatas[0] = abi.encodeWithSignature("transfer(address,uint256)", solar_project_wallet, 10 ether);

string memory description = "Proposal #1: Fund Community Solar Project";
// Proposer must hold a minimum proposal threshold of voting tokens
governor.propose(targets, values, calldatas, description);

After submission, the proposal enters a pending state before the voting period begins.

Choosing the right voting model is critical for fair representation. A token-weighted model (one token, one vote) is simple but can lead to whale dominance. Quadratic voting (where vote cost scales quadratically with vote weight) can better reflect the intensity of preference for smaller holders, making it suitable for community-driven initiatives. Conviction voting allows voting power to accumulate over time a voter supports a proposal, aligning with long-term sustainability goals. The voting strategy contract defines these rules. Security is paramount: always use timelocks on the executor contract to give the community time to react if a malicious proposal passes, and implement proposal thresholds to prevent spam.

Successful implementations require front-end tooling for accessibility. Platforms like Tally, Snapshot (for gasless off-chain signaling with on-chain execution), or Boardroom provide user-friendly interfaces for members to view proposals, delegate votes, and cast ballots. For sustainability DAOs, integrating oracles like Chainlink can enable conditional execution based on real-world data—for instance, only releasing funds once an oracle verifies a carbon offset certificate has been retired. The complete flow creates a transparent cycle: proposal → debate (on forums like Discourse) → on-chain vote → automated, verifiable execution. This audit trail is invaluable for reporting impact to stakeholders and regulators.

When deploying, start with a testnet using a framework like Hardhat or Foundry. Simulate proposal lifecycles and attack vectors, such as flash loan attacks to manipulate voting power. Key parameters to configure include the voting delay (time between proposal and vote start), voting period (duration of the vote), proposal threshold, and quorum (minimum participation required). For mainnet deployment, consider using an audited, upgradeable contract pattern to allow for future improvements. Resources like the OpenZeppelin Wizard for Governors and the Compound Governor Bravo documentation provide excellent starting points. This setup empowers communities to govern sustainability funds with unprecedented transparency and direct accountability.

GOVERNANCE MECHANICS

Voting Model Comparison: Token-Weighted vs. Quadratic

A technical comparison of two dominant on-chain voting models for sustainability DAOs, highlighting trade-offs in fairness, security, and implementation complexity.

Feature / MetricToken-Weighted VotingQuadratic Voting

Decision-Making Power

Linear to token holdings (1 token = 1 vote)

Square root of token commitment (√tokens)

Sybil Attack Resistance

High (cost = token price)

Medium (requires identity proof or cost = (√tokens)²)

Whale Influence

High - Directly proportional

Mitigated - Diminishing returns on capital

Gas Cost per Vote

~$5-15 (simple transfer)

~$20-50 (with signature verification)

Implementation Complexity

Low (standard ERC-20 snapshot)

High (requires vote credit calculation & sybil defense)

Best For

Liquid token holders, profit-centric proposals

Community sentiment, public goods funding

Used By

Uniswap, Compound, MakerDAO

Gitcoin Grants, Optimism Citizens' House

architecture-components
ON-CHAIN GOVERNANCE

System Architecture Components

A robust on-chain voting system requires several key technical components. This guide covers the essential building blocks for implementing secure and transparent governance for sustainability projects.

step-1-snapshot-integration
GOVERNANCE FOUNDATION

Step 1: Set Up Off-Chain Signaling with Snapshot

Implement a gas-free, off-chain voting system to gauge community sentiment before committing to on-chain execution.

Snapshot is the leading platform for off-chain, gasless governance, used by thousands of DAOs to signal community intent. It allows token holders to vote on proposals by signing messages with their wallets, eliminating transaction fees. This makes it ideal for preliminary votes on complex topics like sustainability initiatives, where you need broad participation to validate ideas before writing them into immutable smart contracts. Setting up a space on Snapshot is the first step to creating a structured, transparent decision-making process for your project.

To begin, navigate to snapshot.org and connect your wallet (like MetaMask). You will need to create a Snapshot Space, which acts as your DAO's dedicated governance hub. The space requires an ENS domain (e.g., yourdao.eth) for a decentralized identifier. You'll configure key settings including your voting strategies (how voting power is calculated, e.g., by token balance), proposal thresholds, and admins. For sustainability governance, a common strategy is the erc20-balance-of strategy, which allocates one vote per governance token held at a specific block number.

A core concept is the separation of signaling from execution. A Snapshot vote result is a verifiable signal of community preference, but it does not automatically execute on-chain actions. This is a security and design feature. The vote outcome—typically a simple Yes/No or multiple choice—produces immutable proof on IPFS. Your on-chain system (like a DAO treasury or a Governor contract) can then be programmed to trust and execute the results of a specific Snapshot proposal, creating a two-step governance flow. This setup is formally known as an off-chain voting module.

Here is a basic example of a voting strategy configuration in a Snapshot space's settings, which defines how voting power is calculated for a token named GREEN:

json
{
  "symbol": "GREEN",
  "address": "0x1234...",
  "strategy": {
    "name": "erc20-balance-of",
    "params": {
      "address": "0x1234...",
      "symbol": "GREEN",
      "decimals": 18
    }
  }
}

This strategy checks each voter's balance of the GREEN token at the snapshot block defined in the proposal.

For sustainability initiatives, you can create specialized proposal types. For instance, a proposal could be: "Allocate 50,000 USDC from the community treasury to fund a verified carbon credit retirement via KlimaDAO." The discussion and Snapshot vote would determine if the community supports this action. The resulting proof can then be used to authorize a transaction from a Safe multisig or trigger a function in a custom Governor contract that releases the funds, completing the governance cycle from signal to execution.

step-2-smart-contract-voting
IMPLEMENTATION

Step 2: Deploy the On-Chain Voting Contract

This step involves writing and deploying a smart contract that manages the core voting logic for sustainability proposals on-chain, ensuring transparency and immutability.

The on-chain voting contract is the central authority for your DAO's governance. It defines the rules for creating proposals, casting votes, and executing approved actions. For sustainability initiatives, this contract will handle proposals like allocating treasury funds to a carbon offset project or ratifying a new environmental policy. We'll use a simplified version of OpenZeppelin's Governor contract as a foundation, which provides battle-tested modular components for proposal lifecycle management, vote counting, and timelock integration.

Start by setting up your development environment. Initialize a new Hardhat or Foundry project and install the necessary dependencies: @openzeppelin/contracts for governance standards and @nomicfoundation/hardhat-toolbox for testing. The core contract will import Governor, GovernorSettings, GovernorCountingSimple, and GovernorVotes. The GovernorVotes module is crucial as it integrates with your token (deployed in Step 1) to enable vote weighting based on token balance at the time a proposal is created, a mechanism known as snapshot voting.

Here is a minimal contract skeleton to deploy:

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";

contract SustainabilityGovernor is Governor, GovernorSettings, GovernorCountingSimple, GovernorVotes {
    constructor(IVotes _token)
        Governor("SustainabilityGovernor")
        GovernorSettings(7200 /* 1 day */, 50400 /* 1 week */, 0)
        GovernorVotes(_token)
    {}
    // ... Override required functions
}

The constructor parameters set the voting delay (7200 blocks ~1 day), voting period (50400 blocks ~1 week), and proposal threshold (0 tokens). Adjust these based on your DAO's desired speed and security.

After writing the contract, compile it and prepare for deployment. You will need the address of the ERC-20 or ERC-721 token contract from Step 1 to pass to the constructor. Deploy the contract to your chosen network (e.g., a testnet like Sepolia or a scaling solution like Arbitrum) using a script. For mainnet deployment, consider using a proxy pattern (like OpenZeppelin's TransparentUpgradeableProxy) to allow for future upgrades to the voting logic without losing the contract's state and proposal history.

Once deployed, verify and publish the contract source code on a block explorer like Etherscan. This is critical for transparency, allowing all members to audit the governance rules. The final step is to transfer control of relevant assets (like the community treasury wallet) to the new governor contract, making it the sole entity authorized to execute passed proposals. This completes the deployment, establishing a transparent, on-chain system for governing your sustainability initiatives.

step-3-treasury-integration
IMPLEMENTATION

Step 3: Integrate with a Treasury Management System

This step connects your on-chain voting mechanism to a secure treasury, enabling the automated and transparent execution of funded proposals.

A treasury management system (TMS) is the secure, programmable wallet that holds your DAO's assets and executes transactions based on governance votes. Integrating your voting contract with a TMS transforms a 'yes' vote into an on-chain action, such as transferring funds to a grant recipient or paying an invoice. Popular frameworks like OpenZeppelin Governor are designed to work seamlessly with their TimelockController contract, which acts as a secure, delay-enforced executor. Other common TMS options include Gnosis Safe (with Zodiac modules) and DAOstack's Avatar, each offering different balances of security, flexibility, and complexity.

The core integration involves setting the TMS address as the executor in your voting contract. This design means the voting contract holds the authority to propose transactions, but only the designated TMS can execute them. For example, when a sustainability proposal to fund a solar panel installation passes, the voting contract will queue the transfer details in the TMS. This separation of powers is a critical security pattern, as it allows for features like a timelock delay—a mandatory waiting period between a vote passing and funds being released, giving token holders a final chance to react if an issue is discovered.

Here is a simplified example of how a Governor contract is deployed with a TimelockController as its executor using Foundry and Solidity. First, you deploy the Timelock with a minimum delay (e.g., 2 days for community review).

solidity
// Deploy TimelockController
TimelockController timelock = new TimelockController(
    2 days, // minDelay
    new address[](0), // proposers (empty, set by Governor)
    new address[](0), // executors (empty, set by Governor)
    address(0) // admin (will be renounced)
);

Next, you deploy the Governor contract, passing the Timelock address as the executor.

solidity
// Deploy Governor, with token and timelock
MyGovernor governor = new MyGovernor(
    ERC20Votes(yourTokenAddress),
    address(timelock)
);

Finally, you grant the Governor the necessary roles (PROPOSER_ROLE, EXECUTOR_ROLE) on the Timelock and renounce the admin role for full decentralization.

For DAOs using a Gnosis Safe, integration often involves a module like Zodiac's Reality Module or SafeSnap. These tools allow the Safe to trustlessly verify the outcome of a Snapshot vote or an on-chain proposal before executing the transaction. This pattern is excellent for gas-efficient voting (off-chain via Snapshot) followed by secure on-chain execution. The key configuration step is enabling the module on your Safe's interface, connecting it to your voting strategy, and setting thresholds. Always conduct a test transaction on a testnet with a small amount before going live with treasury funds.

Post-integration, your workflow is complete: 1) A proposal is submitted on-chain, 2) Token holders vote, 3) If the vote succeeds and any timelock delay expires, any authorized party can trigger the execute function. This call will instruct the TMS to perform the encoded action, such as transfer(recipient, amount). You should verify the integration by writing and running end-to-end tests that simulate a full proposal lifecycle, from creation to execution, ensuring the correct funds move from the treasury only upon successful vote completion.

step-4-frontend-dashboard
ON-CHAIN VOTING

Step 4: Build a Governance Dashboard

This guide explains how to implement a frontend dashboard for on-chain governance, enabling token holders to vote on sustainability initiatives like carbon offset funding or protocol upgrades.

A governance dashboard is the user interface that connects token holders to your on-chain voting smart contracts. For sustainability DAOs, this interface must clearly present proposals—such as "Allocate 100,000 USDC to Verra-registered reforestation"—and facilitate secure voting. The core technical stack typically involves a frontend framework like React or Next.js, a Web3 library such as ethers.js or viem, and a connection to a blockchain node provider like Alchemy or Infura. The dashboard's primary functions are to fetch live proposal data from the chain, display voter eligibility and power, and submit signed transactions to cast votes.

The first development step is to integrate with your governance contract. Using ethers.js, you connect to the contract's ABI and address. Key functions to call include proposalCount(), proposals(uint256) to get details, and getVotes(address, uint256) to check a user's voting power at the correct block. For example, a proposal object returned from the chain will contain essential parameters: target (the contract to execute), forVotes, againstVotes, abstainVotes, and the state (e.g., 1 for Active, 2 for Defeated). Your dashboard should parse and display this data in a human-readable format.

To enable voting, you must handle transaction signing. When a user selects a choice (For, Against, Abstain), the frontend should call the contract's castVote(uint256 proposalId, uint8 support) function. This requires sending a transaction from the user's connected wallet (like MetaMask). Implement robust error handling for common issues: insufficient gas, the proposal being inactive, or the user having already voted. It's critical to use the voteCast event emitted by the contract to confirm the transaction's success on-chain before updating the UI state.

For a better user experience, implement real-time updates. You can listen for contract events using an ethers Provider or use a specialized service like The Graph to index proposal and vote data into a queryable subgraph. This allows your dashboard to update vote tallies instantly without requiring a page refresh. Furthermore, consider adding features like vote delegation UI, proposal creation (if permitted), and historical data charts using a library like Chart.js to visualize voting trends and participation rates over time.

Security and transparency are paramount. Clearly display the voter's address and their voting power derived from the token contract's getPastVotes function. Warn users about gas fees and irreversible on-chain actions. For auditability, provide a direct link to the proposal transaction on a block explorer like Etherscan. Finally, test thoroughly on a testnet (e.g., Sepolia) with mock proposals before deploying the dashboard to mainnet alongside your live governance contracts.

ON-CHAIN VOTING

Frequently Asked Questions

Common technical questions and solutions for developers implementing on-chain voting for sustainability projects.

Token-weighted voting grants voting power proportional to the number of governance tokens a user holds (e.g., 1 token = 1 vote). This is common in DAOs like Uniswap or Compound. Quadratic voting (QV) reduces the influence of large token holders by making the cost of votes increase quadratically; for example, casting 2 votes costs 4 credits, and 3 votes costs 9 credits. This favors a more democratic distribution of influence. Implementing QV requires calculating vote costs on-chain, which increases gas complexity. Platforms like Gitcoin use QV for grant funding to prevent whale dominance.

conclusion
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have now configured the core components for an on-chain voting system to manage sustainability initiatives.

This guide has walked through the essential steps to establish a transparent and verifiable governance mechanism. You have deployed a governance token for voting power, a Treasury contract to hold initiative funds, and a Governor contract to manage proposals. The system uses a standard proposal lifecycle: Propose, Vote, Queue, and Execute. By leveraging existing standards like OpenZeppelin's Governor, you inherit battle-tested security patterns for timelocks, vote counting, and quorum management, which are critical for a fair process.

For production deployment, several critical next steps remain. First, you must integrate a front-end interface using a library like Tally, Governor DAO UI, or building a custom dApp with wagmi and ConnectKit. This allows token holders to interact with proposals without writing code. Second, consider gas optimization by evaluating the cost of proposal creation and voting; using snapshot voting (off-chain signing) with an executor contract like Safe's Zodiac module can significantly reduce costs while maintaining on-chain execution. Third, establish clear proposal guidelines for your community, defining what constitutes a valid sustainability initiative, required documentation, and funding thresholds.

To enhance the system's robustness, explore advanced configurations. Implement vote delegation to allow users to delegate their voting power to experts. Add proposal thresholds to prevent spam, requiring a minimum token balance to submit. For cross-chain initiatives, consider a multisig executor on L2s like Arbitrum or Optimism using Chainlink's CCIP for secure message passing. Regularly audit your contracts, especially after any upgrades, and maintain an open bug bounty program. Monitor proposal participation rates and adjust voting periods or quorums as needed to ensure the DAO remains active and representative of its members.

How to Implement On-Chain Voting for Sustainability Projects | ChainScore Guides