以太坊dapp_构建以太坊DApp:启动StoryDao

以太坊dapp

In part 7 of this tutorial series on building DApps with Ethereum, we showed how to build the app’s front end, setting up and deploying the UI for this story we’ve been working on.

在本教程系列的第7部分中 ,该系列教程介绍了如何使用以太坊构建DApp,如何构建应用程序的前端,如何设置和部署我们正在研究的UI。

It’s time to do some deploying and write a few final functions.

现在该进行一些部署并编写一些最终功能了。



This is the eighth part of a series on building decentralized applications using the Ethereum blockchain. The project we’re building is called The Neverending Story. The full project can be found at storydao.bitfalls.com. Its full code is on GitHub.

这是使用以太坊区块链构建去中心化应用程序系列的第八部分。 我们正在构建的项目称为“永无止境的故事”。 完整的项目可以在storydao.bitfalls.com上找到。 其完整代码在GitHub上

Here is an outline of the whole series:

这是整个系列的概述:

  • In part 1, we bootstrap two versions of a local blockchain for development: a Ganache version, and a full private PoA version.

    第1部分中 ,我们引导了用于开发的本地区块链的两个版本:Ganache版本和完整的私有PoA版本。

  • In part 2, we build and deploy our TNS token.

    第2部分中 ,我们构建和部署TNS令牌。

  • In part 3, we look at how to compile, deploy, test and verify our custom TNS token, which is compatible with all exchanges and can be used as a regular ERC20 token.

    第3部分中 ,我们将研究如何编译,部署,测试和验证我们的自定义TNS令牌,该令牌与所有交易所兼容,并且可以用作常规ERC20令牌。

  • In part 4, we take the first steps towards developing a Story DAO, covering whitelisting and testing.

    第4部分中 ,我们迈出了开发Story DAO的第一步,涵盖了白名单和测试。

  • In part 5, we deal with adding content to the story, looking at how to add the ability for participants to buy tokens from the DAO and to add submissions into the story.

    第5部分中 ,我们处理了向故事中添加内容的问题,探讨了如何增加参与者从DAO购买令牌以及向故事中添加提交内容的能力。

  • In part 6, we take the DAO to its final form, adding voting, blacklisting/unblacklisting, and dividend distribution and withdrawal, while throwing in some additional helper functions for good measure.

    第6部分中 ,我们将DAO转换为最终形式,添加了投票,将其列入黑名单/取消黑名单以及股息分配和提款,同时还添加了一些额外的辅助功能,以达到很好的效果。

  • In part 7, we show how to build the app’s front end, setting up and deploying the UI for this story we’ve been working on.

    第7部分中 ,我们展示了如何构建应用程序的前端,如何为我们一直在研究的这个故事设置和部署UI。

  • In this final part, we look at the final steps of deploying the app and writing a few final functions.

    在最后一部分中,我们介绍了部署应用程序和编写一些最终功能的最后步骤。


自杀 (Suicide)

Something could go very, very wrong and the whole DAO somehow get destroyed — either through hacks of bad and hastily written code, or through the inability to make long loops due to too many participants. (Too many voters on a proposal might as well break the system; we really didn’t put any precaution in place for that!) Just in case this happens, it might be useful to have the equivalent of a “big red button”. First, let’s upgrade our StoryDao:

可能会发生非常非常非常错误的情况,并且整个DAO都会以某种方式被破坏-通过黑客编写糟糕且草率的代码,或者由于参与者过多而导致无法进行长循环。 (提案中的选民太多可能会破坏系统;我们确实没有为此采取任何预防措施!)以防万一,这种情况下,相当于“红色大按钮”可能会很有用。 首先,让我们升级StoryDao:

function bigRedButton() onlyOwner external {
    active = false;
    withdrawToOwner();
    token.unlockForAll();
}

Then, let’s make it possible to unlock all the tokens at once in our Token contract:

然后,让我们有可能一次在我们的令牌合约中解锁所有令牌:

/**
@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;
    }
}

Naturally, we need to add this new list of addresses into the contract:

当然,我们需要将此新地址列表添加到合同中:

address[] touchedByLock;

And we need to upgrade our increaseLockedAmount function to add addresses to this list:

而且,我们需要升级我们的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;
}

We should also update the required interface of the token inside the StoryDao contract to include this new function’s signature:

我们还应该更新StoryDao合约内令牌的必需接口,以包括此新功能的签名:

// ...
    function getUnlockedAmount(address _owner) view public returns (uint256);
    function unlockForAll() public;
}

With the active-story block we added before (inability to run certain functions unless the story’s active flag is true), this should do the trick. No one else will be able to waste money by sending it to the contract, and everyone’s tokens will get unlocked.

使用我们之前添加的active-story块(除非故事的active标志为true,否则无法运行某些功能),这应该可以解决问题。 没有其他人能够通过将其发送到合同来浪费金钱,并且每个人的代币都将被解锁。

The owner doesn’t get the ether people submitted. Instead, the withdrawal function becomes available so people can take their ether back, and everyone’s taken care of.

所有者没有让以太人提交。 取而代之的是,提款功能变得可用,因此人们可以收回自己的以太币,所有人都得到了照顾。

Now our contracts are finally ready for deployment.

现在我们的合同终于可以部署了。

自我毁灭呢? (What about selfdestruct?)

There’s a function called selfdestruct which makes it possible to destroy a contract. It looks like this:

有一个名为selfdestruct的函数,可以破坏合同。 看起来像这样:

selfdestruct(address);

Calling it will disable the contract in question, removing its code from the blockchain’s state and disabling all functions, all while sending the ether in that address to the address provided. This is not a good idea in our case: we still want people to be able to withdraw their ether; we don’t want to take it from them. Besides, any ether sent straight to the address of a suicided contract will get lost forever (burned) because there’s no way to get it back.

调用它将禁用有问题的合同,从区块链的状态中删除其代码并禁用所有功能,同时将该地址中的以太币发送到提供的地址。 在我们的情况下,这不是一个好主意:我们仍然希望人们能够撤出以太币; 我们不想从他们那里拿走它。 此外,任何直接送往自杀合同地址的以太币都将永远丢失(燃烧),因为没有办法将其取回。

部署合同 (Deploying the Contract)

To deploy the smart contracts fully, we need to do the following:

要完全部署智能合约,我们需要执行以下操作:

  1. deploy to mainnet

    部署到主网
  2. send tokens to StoryDAO address

    将令牌发送到StoryDAO地址
  3. transfer ownership of Token contract to StoryDao.

    将代币合约的所有权转让给StoryDao。

Let’s go.

我们走吧。

主网部署 (Mainnet Deployment)

To deploy to mainnet, we need to add a new network into our truffle.js file:

要部署到主网,我们需要在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",
},

Luckily, this is very simple. It’s virtually identical to the Rinkeby deployment; we just need to remove the gas amount (let it calculate it on its own) and change the gas price. We should also change the network ID to 1 since that’s the mainnet ID.

幸运的是,这很简单。 它实际上与Rinkeby部署完全相同。 我们只需要删除汽油量(让它自己计算)并更改汽油价格即可。 我们还应该将网络ID更改为1,因为那是主网ID。

We use this like so:

我们这样使用:

truffle migrate --network mainnet

There’s one caveat to note here. If you’re deploying on a network you previously deployed on (even if you just deployed the token onto the mainnet and wanted to deploy the StoryDao later) you might get this error:

这里要注意一个警告。 如果您要在先前部署的网络上进行部署(即使您只是将令牌部署到主网上并想稍后再部署StoryDao),则可能会遇到以下错误:

Attempting to run transaction which calls a contract function, but recipient address XXX is not a contract address

This happens because Truffle remembers where it deployed already-deployed contracts so that it can reuse them in subsequent migrations, avoiding the need to re-deploy. But if your network restarted (i.e. Ganache) or you made some incompatible changes, it can happen that the address it has saved doesn’t actually contain this code any more, so it will complain. You can get around this by resetting migrations:

发生这种情况是因为Truffle记住了已部署合同的部署位置,以便它可以在以后的迁移中重用它们,而无需重新部署。 但是,如果您的网络重新启动(即Ganache)或进行了一些不兼容的更改,则可能发生的情况是它保存的地址实际上不再包含此代码,因此它将抱怨。 您可以通过重置迁移来解决此问题:

truffle migrate --network mainnet --reset

将令牌发送到StoryDao地址 (Send tokens to StoryDao address)

Get the address of the token and the address of the StoryDao from the deployment process.

从部署过程中获取令牌的地址和StoryDao的地址。

Addresses from Deployment

Then just use MEW as previously described to send the tokens.

然后,只需使用前面所述的MEW发送令牌即可。

Sending tokens
Generating and confirming transaction

If you get Out of Gas errors, just increase the gas limit. Remember: the rest of the unused gas always gets refunded, so there’s no fear of losing any more money than your transaction costs (sending the tokens should be under 40000 gas).

如果出现Out of Gas错误,只需增加气体限制。 请记住:其余未使用的汽油总是会退还的,因此不用担心会损失比您的交易成本更多的钱(发送代币的汽油价格应低于40000汽油)。

将令牌所有权转让给StoryDao (Transfer ownership of token to StoryDao)

To transfer ownership, we need to call the transferOwnership function on the token. Let’s load the token into MEW. In the Contracts screen, we enter the address and the contract’s ABI (grab it from the /build folder). Clicking Access will then let us access the functions in that contract in a menu from which we select transferOwnership.

要转让所有权,我们需要在令牌上调用transferOwnership函数。 让我们将令牌加载到MEW中。 在“ Contracts屏幕中,我们输入地址和合同的ABI(从/build文件夹中获取)。 单击“ 访问”将使我们可以在菜单中选择该合同,以选择transferOwnership

Transfer Ownership

Tip: it’s enough to only include the ABI of the functions you intend to call: it doesn’t have to be the whole ABI of the token! You could just include the ABI of the transferOwnership function and it would be fine!

提示:仅包含要调用的函数的ABI就足够了:它不必是令牌的整个ABI! 您可以只包含transferOwnership函数的ABI,就可以了!

We then select the new owner (the address of the deployed StoryDao) and unlock the current owner’s wallet (the same wallet we previously sent tokens from).

然后,我们选择新所有者(已部署StoryDao的地址)并解锁当前所有者的钱包(我们之前从中发送令牌的钱包)。

Unlocking and writing

After writing this change, we can inspect the read-only function owner in the token contract (same menu as transferOwnership). It should show the new owner now.

写入此更改后,我们可以检查令牌合同中的只读函数owner (与transferOwnership相同的菜单)。 现在应该显示新所有者。

Changed owner

To make sure that the StoryDao address actually has the tokens, we can select the balanceOf function and enter the StoryDao’s address into the _owner field, then click on Read:

为了确保StoryDao地址确实具有令牌,我们可以选择balanceOf函数,然后在_owner字段中输入StoryDao的地址,然后单击Read

StoryDao has tokens

Indeed, 100 million tokens are in the StoryDao address.

实际上,StoryDao地址中有1亿枚代币。

Tip: we could have done the token sending and ownership transferring as part of the deployment step as well. Try figuring out how in a test environment.

提示:在部署步骤中,我们也可以完成令牌发送和所有权转移。 尝试弄清楚如何在测试环境中。

验证 (Verification)

As per part 3 of this series, it would benefit us greatly to verify the contracts of both the DAO and the Token on Etherscan. That green checkmark can go a long way.

根据本系列的第3部分 ,在Etherscan上验证DAO和令牌的合同将对我们大有裨益。 那个绿色的对勾可能会走很长一段路。

Follow the instructions in that part to get your contracts verified. Note that, during the verification step, you’ll now have to mark the optimizer as active, since we’re optimizing our code for cheaper deployment!

按照该部分中的说明进行合同验证。 请注意,在验证步骤中,您现在必须将优化器标记为活动状态,因为我们正在优化代码以实现更便宜的部署!

部署到网络 (Deploying to the Web)

To deploy the web UI of StoryDao, follow the instructions from the “regular” web development world. Since, in this case, it’s all static code, you can even host it on GitHub Pages or something similar.

要部署StoryDao的Web UI,请遵循“常规” Web开发领域的说明。 由于在这种情况下,它们都是静态代码,因此您甚至可以将其托管在GitHub Pages或类似的东西上。

Read about some of the options here.

此处了解一些选项。

Once the page is up, configure the UI to use the addresses of contracts we got from the migration step. Alternatively, register ENS names for the token and the StoryDao, and you can keep the web UI static and fixed, hardcoding the addresses, and then only change the Ethereum address those ENS names are pointing at.

页面启动后,将UI配置为使用从迁移步骤获得的合同地址。 或者,注册令牌和StoryDao的ENS名称,然后可以保持Web UI固定和固定,对地址进行硬编码,然后仅更改这些ENS名称所指向的以太坊地址。

结论 (Conclusion)

This concludes the DAO tutorial. We hope it helped you recognize the complexities of Solidity development, but we also hope that it made some things clearer and made you more curious.

DAO教程到此结束。 我们希望它可以帮助您认识到Solidity开发的复杂性,但是我们也希望它可以使某些事情变得更清楚并使您更加好奇。

As always, the best way to learn is by doing. Experiment, make mistakes, reboot and rebuild. Blockchain development of this type is in high demand, and it’s only getting more popular, so you have an opportunity to get in on the ground floor.

一如既往,最好的学习方法就是边做边学。 实验,犯错误,重新启动并重建。 这种类型的区块链开发有很高的需求,并且越来越流行,因此您有机会进入底层。

Good luck!

祝好运!

P.S. If you enjoyed this tutorial, feel free to ping the author on Twitter. If you have complaints, suggestions, ideas, etc. please shoot them over into the repository on GitHub!

PS:如果您喜欢本教程,请随时在Twitter上ping作者 如果您有任何投诉,建议,想法等,请将其发布到GitHub上的存储库中!

翻译自: https://www.sitepoint.com/building-ethereum-dapps-launching-storydao/

以太坊dapp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值