以太坊构建DApps系列教程(八):启动StoryDAO

51次阅读

共计 4898 个字符,预计需要花费 13 分钟才能阅读完成。

在本系列关于使用以太坊构建 DApps 教程的第 7 部分中,我们展示了如何构建应用程序的前端,为我们一直在研究的这个 Story 故事设置和部署 UI。是时候进行一些部署并编写一些最终功能了。
这是使用以太坊区块链构建去中心化应用程序系列的第八部分。我们正在建设的项目名为 The Neverending Story。完整的项目可以在 storydao.bitfalls.com 找到。它的完整代码在 GitHub 上。
以下是整个系列的概述:

在第 1 部分中,我们引导大家做了两个版本的本地区块链进行开发:Ganache 版本和完整的私有 PoA 版本。
在第 2 部分中,我们构建并部署了 TNS 代币。
在第 3 部分,我们将介绍如何编译,部署,测试和验证我们的自定义 TNS 代币,该代币与所有交易所兼容,可用作常规 ERC20 代币。
在第 4 部分中,我们迈出了开发 Story DAO 的第一步,包括白名单和测试。
在第 5 部分中,我们处理向故事 Story 添加内容,查看如何添加参与者从 DAO 购买代币的能力以及向故事中添加提交内容。
在第 6 部分中,我们将 DAO 置于最终形式,添加投票,黑名单 / 取消黑名单,股息分配和撤销,同时投入一些额外的辅助函数以获得良好的评价标准。
在第 7 部分中,我们将展示如何构建应用程序的前端,为我们一直在研究的这个故事 story 设置和部署 UI。
在最后一部分中,我们将介绍部署应用程序和编写一些最终功能的最后步骤。

自毁程序
有些东西可能会非常非常错误,并且使得整个 DAO 会以某种方式被破坏——无论是通过糟糕的编写代码,还是由于参与者太多而无法完成循环。(提案上的选民太多也可能破坏系统;我们实际上没有采取任何预防措施!)为了防止发生这种情况,拥有相当于“红色大按钮”可能会很有用。首先,让我们升级我们的 StoryDao:
function bigRedButton() onlyOwner external {
active = false;
withdrawToOwner();
token.unlockForAll();
}
然后,让我们可以在代币合约中立即解锁所有代币:
/**
@dev unlocks the tokens of every user who ever had any tokens locked for them
*/
function unlockForAll() public onlyOwner {
uint256 len = touchedByLock.length;
for (uint256 i = 0; i < len; i++) {
locked[touchedByLock[i]] = 0;
}
}
当然,我们需要在合约中添加这个新的地址列表:
address[] touchedByLock;
我们需要升级我们的 increaseLockedAmount 函数以向此列表添加地址:
/**
@dev _owner will be prevented from sending _amount of tokens. Anything
beyond this amount will be spendable.
*/
function increaseLockedAmount(address _owner, uint256 _amount) public onlyOwner returns (uint256) {
uint256 lockingAmount = locked[_owner].add(_amount);
require(balanceOf(_owner) >= lockingAmount, “Locking amount must not exceed balance”);
locked[_owner] = lockingAmount;
touchedByLock.push(_owner);
emit Locked(_owner, lockingAmount);
return lockingAmount;
}
我们还应该更新 StoryDao 合约中代币所需的接口,以包含这个新函数的签名:
// …
function getUnlockedAmount(address _owner) view public returns (uint256);
function unlockForAll() public;
}
使用我们之前添加的活动故事块(除非故事的 active 标志为真,否则无法运行某些功能),这应该可以解决问题。没有人需要在发送合约时浪费钱,每个人的代币都会被解锁。
所有者没有得到人们提交的以太。取而代之的是退出功能变得可用,因此人们可以收回他们的以太,并且每个人都会得到照顾。
现在我们的合约终于可以部署了。
销毁程序是什么样的?
有一个名为 selfdestruct 的函数可以销毁合约。它看起来像这样:
selfdestruct(address);
调用它将禁用有问题的合约,从区块链的状态中删除其代码并禁用所有功能,同时将该地址中的以太网发送到提供的地址。在我们的案例中,这不是一个好主意:我们仍然希望人们能够撤回他们的以太;我们不想从他们那里拿走它。此外,直接发送到自杀合约地址的任何以太币将永远丢失(烧毁),因为没有办法将其取回。
部署合约
要完全部署智能合约,我们需要执行以下操作:

部署到主网
将代币发送到 StoryDAO 地址
将 Token 合约的所有权转让给 StoryDao。

我们走吧。
主网部署
要部署到 mainnet,我们需要在 truffle.js 文件中添加一个新网络:
mainnet: {
provider: function() {
return new WalletProvider(
Wallet.fromPrivateKey(
Buffer.from(PRIVKEY, “hex”)), “https://mainnet.infura.io/”+INFURAKEY
);
},
gasPrice: w3.utils.toWei(“20”, “gwei”),
network_id: “1”,
},
幸运的是,这非常简单。它与 Rinkeby 部署几乎相同;我们只需要移除 gas 量(让它自己计算)并改变 gas 价格。我们还应该将网络 ID 更改为 1,因为这是主网 ID。
我们这样使用:
truffle migrate –network mainnet
这里有一点需要注意。如果你在先前部署的网络上进行部署(即使你刚刚将代币部署到主网上并希望稍后部署 StoryDao),你可能会收到此错误:
Attempting to run transaction which calls a contract function, but recipient address XXX is not a contract address
之所以发生这种情况,是因为 Truffle 会记住部署已经部署的合约的位置,以便它可以在后续迁移中重复使用它们,从而避免重新部署。但是如果你的网络重新启动(即 Ganache)或者你进行了一些不兼容的更改,可能会发生它保存的地址实际上不再包含此代码,因此会报错。你可以通过重置迁移来解决此问题:
truffle migrate –network mainnet –reset
将代币发送到 StoryDao 地址
从部署过程中获取代币的地址和 StoryDao 的地址。

然后只需使用前面描述的 MEW 来发送代币。

如果出现 gas 缺失,只需增加 gas 限制即可。请记住:剩余的未使用的 gas 总是会退回来,所以不用担心会损失比交易成本更多的钱(发送代币应该低于 40000gas)。
将代币的所有权转让给 StoryDao 要转移所有权,我们需要在代币上调用 transferOwnership 函数。让我们将代币加载到 MEW 中。在 Contracts 屏幕中,我们输入地址和合约的 ABI(从 /build 文件夹中获取)。然后单击 Access 将允许我们在菜单中访问该合约中的功能,我们从中选择 transferOwnership。

提示:仅包含你要调用的函数的 ABI 就足够了,它不必是代币的整个 ABI!你可以只包括 transferOwnership 函数的 ABI,它就没事了!
然后我们选择新的所有者(已部署的 StoryDao 的地址)并解锁当前所有者的钱包(我们之前发送的钱包相同的钱包)。

写完此更改后,我们可以检查代币合约中的只读功能 owner(与 transferOwnership 相同的菜单)。它应该现在显示新的所有者。

为了确保 StoryDao 地址实际上有代币,我们可以选择 balanceOf 函数并在_owner 字段中输入 StoryDao 的地址,然后单击 Read:

事实上,StoryDao 地址中有 1 亿个代币。
提示:我们也可以在部署步骤中完成代币发送和所有权转移。尝试弄清楚如何在测试环境中。
验证
根据本系列的第 3 部分,验证 DAO 和 Etherscan 上代币的合约将对我们有很大帮助。绿色的复选标记是一条很长的路。
按照该部分中的说明验证你的合约。请注意,在验证步骤中,你现在必须将优化器标记为活动,因为我们正在优化代码以实现更便宜的部署!
部署到 Web
要部署 StoryDao 的 Web UI,请按照“常规”Web 开发世界中的说明进行操作。因为,在这种情况下,所有的都是静态代码,你甚至可以在 GitHub 页面或类似的东西上托管它。
在这里和这里阅读一些选项。
页面启动后,配置 UI 以使用我们从迁移步骤获得的合约地址。或者,注册代币和 StoryDao 的 ENS 名称,你可以保持 Web UI 静态和固定,硬编码地址,然后只更改 ENS 名称所指向的以太坊地址。
结论
DAO 教程到此结束。我们希望它能帮助你认识到 Solidity 开发的复杂性,但我们也希望它能让事情更加清晰,让你更加好奇。
一如既往,最好的学习方式就是做。实验,犯错,重启和重建。这种类型的区块链开发需求量很大,而且它越来越受欢迎,所以你有机会接触到底层。
祝好运!
======================================================================
分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:

java 以太坊开发教程,主要是针对 java 和 android 程序员进行区块链以太坊开发的 web3j 详解。

python 以太坊,主要是针对 python 工程师使用 web3.py 进行区块链以太坊开发的详解。

php 以太坊,主要是介绍使用 php 进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。

以太坊入门教程,主要介绍智能合约与 dapp 应用开发,适合入门。

以太坊开发进阶教程,主要是介绍使用 node.js、mongodb、区块链、ipfs 实现去中心化电商 DApp 实战,适合进阶。

C#以太坊,主要讲解如何使用 C# 开发基于.Net 的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。

EOS 教程,本课程帮助你快速入门 EOS 区块链去中心化应用的开发,内容涵盖 EOS 工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签 DApp 的开发。

java 比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与 UTXO 等,同时也详细讲解如何在 Java 代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是 Java 工程师不可多得的比特币开发学习课程。

php 比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与 UTXO 等,同时也详细讲解如何在 Php 代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是 Php 工程师不可多得的比特币开发学习课程。

tendermint 区块链开发详解,本课程适合希望使用 tendermint 进行区块链开发的工程师,课程内容即包括 tendermint 应用开发模型中的核心概念,例如 ABCI 接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是 go 语言工程师快速入门区块链开发的最佳选择。

汇智网原创翻译,转载请标明出处。这里是原文以太坊构建 DApps 系列教程 (八): 启动 StoryDAO

正文完
 0