如何在Solidity中构建DAO?
什么是DAO?
我们可以将DAO看作是基于互联网的实体(比如企业),由其股东(持有代币和比例投票权的成员)集体拥有和管理。在DAO中,决策是通过提案做出的,DAO的成员可以对这些提案进行投票,然后执行它们。
DAO完全由公开可见/可验证的代码管理,没有单独的个人(比如CEO)负责决策制定。
DAO如何工作?
如前所述,DAO由代码控制,但如果运行代码机器的人决定关闭机器或编辑代码,该怎么办呢?
我们需要的是让相同的代码运行在由不同实体托管的一组机器上,这样即使其中一个关闭了,另一个也可以接管。区块链帮助我们解决上述问题,基于EVM的区块链,如以太坊和Polygon,允许我们在公共去中心化账本上运行智能合约。部署在这些网络上的智能合约将传播到网络上的所有节点,这些节点可以查看和验证它,没有任何一方控制网络。
DAO向其成员发放代币,代币代表系统中的投票权。根据所设置的治理,任何人都可以创建对DAO进行更改的提案,并将其提交给规定人数(通过所需的最小百分比/投票数),并在投票时间里进行投票。成员可以对提案进行查看和投票,投票权与成员拥有的代币数量成正比。一旦投票期结束,我们检查提案是否通过,如果通过,则执行。
例如MakerDAO和Aragon。
下图显示了该流程。
接下来,我们将构建自己的DAO。
开始构建
我们将在代码库中使用OpenZeppelin合约,我还将使用来自Patrick Collins的DAO模板的一些代码。
先决条件
我们需要以下工具。
Node.js:可以从Node.js网站下载最新版本。
Yarn:我们将使用Yarn作为包管理器。
Hardhat:我们将使用Hardhat作为我们的本地开发环境。
场景
我们将构建一个DAO,它将做以下工作:
场景1
添加一个初始成员。(我们称他们为创始人)。
让创始人写一份提案。(提出一个在智能合约上执行的功能)。
让创始人投票表决,提案将会通过,因为创始人拥有100%的投票权。
执行提案。(智能合约中的功能)。
场景2
添加一个初始成员(我们称他们为创始人)。
增加另一名成员,并向他们发行价值占创始人的20%份额的新代币。
让创始人创建一个提案(提议一个要在智能合约上执行的功能)。
让创始人和新成员投票表决。“Quorum”设置为“90%”。
执行提案(以及智能合约中的功能)。
合约
如前所述,我们将使用OpenZeppelin的治理合约。合约内容如下:
治理者合约:治理者合约决定了法定人数所需的投票数量/百分比(例如,如果法定人数是4%,那么只有4%的选民需要投票支持提案通过),投票期限,即投票持续多长时间,投票延迟,即提案创建后多长时间允许成员更改他们拥有的代币数量。治理合约还提供创建提案、投票和执行提案的功能。
TimeLock:TimeLock合约为不同意系统决定的成员提供在执行决定前退出系统的时间。
Token:Token合约是一种特殊类型的ERC20合约,它实现了ERC20Votes扩展。这允许将投票权映射到过去余额的快照而不是当前余额,这有助于防止知道有重要提案即将出现并试图通过购买更多代币然后抛售它们来增加他们的投票权的成员投票。
目标:这是提案通过投票后执行代码的合约。
代码
让我们开始把这些放在一起。使用Hardhat创建一个空的示例项目。在终端中运行如下命令。
Yarn add - dev hardhat
接下来,让我们使用hardhat创建我们的文件夹结构。
yarn hardhat
我们应该会看到这样的提示。
点击“创建基本示例项目”。该过程完成后,我们应该会看到如下内容。
如果你是复制了我的代码,那么可以直接跳过上述步骤。
合约
让我们开始添加合约,首先我们添加GovernorContract。我们可以从OpenZeppelin获得相同的代码,或者我们可以复制下面的代码或从我的repo中复制。我的合约代码修复了OpenZeppelin版本中的一个问题,以及投票延迟、法定人数和投票周期的参数化,类似于Patrick Collins版本。
接下来,让我们添加代币合约,这在OpenZeppelin上也是可用的。我的代码有一个额外的“issueToken”函数。
接下来是TimeLock合约,这是DAO模板中的合约副本。
最后,让我们检查Target合约,在我们的例子中,我们将使用Patrick Collins使用的同一个Box合约。
测试
Quorum为90%,投票周期为5个区块,投票延迟为3个区块。TimeLock的最小延迟时间为3600秒。
让我们编写代码来部署所有的合约到一个本地网络上(Hardhat内部管理这个,我们不需要启动任何进程)。
接下来,我们需要将部署的Target合约(Box)的所有权转移到TimeLock合约。这样做是为了TimeLock将有权对Box合约执行操作。
const transferTx = await
deployedBox.transferOwnership(deployedTimeLock.address):
接下来,Governor合约被授予提案者角色,执行角色被授予“零地址”,这意味着任何人都可以执行提案。
提案创建
接下来,创建提案。我们传递将在 Box 合约上调用的函数的编码值及其参数。
Proposal函数的输出是一个包含Proposal Id的交易。这是用来跟踪提案的。
我们的提案是在值为 77 的 Box 合约上触发store功能。
投票
我们对提案进行投票,投票“1”表示赞成。
注意:在本例中,我们只有一个成员(拥有100%的选票)在投票。
队列和执行
接下来,DAO中的任何成员都可以排队并执行这个提案,如果该提案通过了投票,那么它将被执行,Box合约上的存储函数将被调用,值为77。我们可能已经注意到像moveTime和moveBlocks这样的函数,这些来自Patrick Collins DAO模板,在开发环境中模拟时间和区块挖掘是非常有用的,它们可以帮助我们模拟投票周期的完成、时间锁定延迟等。
运行测试
我们现在可以使用以下命令运行测试:
yarn hardhat test
向新成员发放代币
对于场景2,我们需要向新成员发行新的代币,并让他们对提案进行投票。
发出代币的代码如下所示:
函数getSigners()返回Hardhat开发环境中所有帐户的列表,然后我们向这个地址发出200个代币。
由新成员投票决定
现在我们是另一个成员,我们可以使用他来投票,但是新成员不能投票,除非他先将自己添加为 Token 合约的代表,这样做是为了让拥有代币但不想参与决策的成员不需要花费额外的 gas 成本来维护他们在账本上的投票权快照。
关于
ChinaDeFi- ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。
来源:去中心化金融社区
- 免责声明
- 世链财经作为开放的信息发布平台,所有资讯仅代表作者个人观点,与世链财经无关。如文章、图片、音频或视频出现侵权、违规及其他不当言论,请提供相关材料,发送到:2785592653@qq.com。
- 风险提示:本站所提供的资讯不代表任何投资暗示。投资有风险,入市须谨慎。
- 世链粉丝群:提供最新热点新闻,空投糖果、红包等福利,微信:juu3644。

路安



