治理与未来 阶段五 ✅ 验证通过
DAO = Decentralized Autonomous Organization(去中心化自治组织)
// contracts/MyGovernor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
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";
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
/**
* @title MyGovernor
* @dev 完整的链上治理合约
*
* 治理参数:
* - 投票延迟: 1个区块(提案创建后1个区块才能投票)
* - 投票期: 50400个区块(约1周)
* - 提案门槛: 100个代币才能创建提案
* - 法定人数: 总供应量的4%
* - 时间锁: 2天(执行前等待期)
*/
contract MyGovernor is
Governor,
GovernorSettings,
GovernorCountingSimple,
GovernorVotes,
GovernorVotesQuorumFraction,
GovernorTimelockControl
{
constructor(
IVotes _token,
TimelockController _timelock
)
Governor("MyDAO")
GovernorSettings(
1, // votingDelay: 1个区块
50400, // votingPeriod: ~1周
100e18 // proposalThreshold: 100代币
)
GovernorVotes(_token)
GovernorVotesQuorumFraction(4) // 4%法定人数
GovernorTimelockControl(_timelock)
{}
// 以下函数必须重写以解决多继承冲突
function quorum(uint256 blockNumber)
public view
override(Governor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function state(uint256 proposalId)
public view
override(Governor, GovernorTimelockControl)
returns (ProposalState)
{
return super.state(proposalId);
}
function proposalThreshold()
public view
override(Governor, GovernorSettings)
returns (uint256)
{
return super.proposalThreshold();
}
function supportsInterface(bytes4 interfaceId)
public view
override(Governor, GovernorTimelockControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
// scripts/deploy-governance.js
async function main() {
// 1. 部署治理代币(必须实现IVotes/ERC20Votes)
const GovToken = await hre.ethers.getContractFactory("GovToken");
const token = await GovToken.deploy();
console.log("GovToken:", await token.getAddress());
// 2. 部署时间锁控制器
const minDelay = 2 * 24 * 60 * 60; // 2天
const Timelock = await hre.ethers.getContractFactory("TimelockController");
const timelock = await Timelock.deploy(
minDelay,
[], // proposers: 初始为空,由Governor管理
[], // executors: 初始为空
owner.address
);
console.log("Timelock:", await timelock.getAddress());
// 3. 部署Governor
const Governor = await hre.ethers.getContractFactory("MyGovernor");
const governor = await Governor.deploy(token.getAddress(), timelock.getAddress());
console.log("Governor:", await governor.getAddress());
// 4. 设置时间锁角色
const proposerRole = await timelock.PROPOSER_ROLE();
const executorRole = await timelock.EXECUTOR_ROLE();
await timelock.grantRole(proposerRole, await governor.getAddress());
await timelock.grantRole(executorRole, hre.ethers.ZeroAddress); // 任何人可执行
await timelock.revokeRole(await timelock.TIMELOCK_ADMIN_ROLE(), owner.address);
console.log("✅ 治理系统部署完成!");
}
// 创建提案:修改协议参数
async function createProposal(governor, targetContract, newFeeRate) {
// 编码要调用的函数
const encodedFunction = targetContract.interface.encodeFunctionData(
"setFeeRate",
[newFeeRate]
);
// 创建提案
const tx = await governor.propose(
[await targetContract.getAddress()], // 目标合约地址
[0], // 发送的ETH(0)
[encodedFunction], // 调用数据
"Proposal: 将手续费率从0.3%降低到0.2%" // 提案描述
);
const receipt = await tx.wait();
const proposalId = receipt.logs[0].args.proposalId;
console.log("提案已创建,ID:", proposalId);
return proposalId;
}
// 投票
async function castVote(governor, proposalId, support) {
// support: 0=反对, 1=赞成, 2=弃权
const tx = await governor.castVote(proposalId, support);
await tx.wait();
console.log(support === 1 ? "赞成票已投出" : "反对票已投出");
}
// 执行提案
async function executeProposal(governor, targetContract, newFeeRate, description) {
const encodedFunction = targetContract.interface.encodeFunctionData(
"setFeeRate",
[newFeeRate]
);
const tx = await governor.execute(
[await targetContract.getAddress()],
[0],
[encodedFunction],
hre.ethers.id(description) // 描述的哈希
);
await tx.wait();
console.log("✅ 提案已执行!手续费率已更新");
}
1. DAO治理中时间锁(Timelock)的作用是什么?
2. 为什么需要快照(Checkpoint)来记录投票权?
3. 法定人数(Quorum)是什么?
你已掌握DAO治理!从治理流程到OpenZeppelin Governor,从提案投票到安全防御,你拥有了构建去中心化组织的能力。
关键收获:
✅ DAO概念与治理流程
✅ OpenZeppelin Governor完整实现
✅ 时间锁与执行机制
✅ 提案创建、投票、执行实操
✅ 治理攻击与防御策略