以太坊开发实战(第 1 部分:智能合约)

您所在的位置:网站首页 以太坊基本知识 以太坊开发实战(第 1 部分:智能合约)

以太坊开发实战(第 1 部分:智能合约)

#以太坊开发实战(第 1 部分:智能合约)| 来源: 网络整理| 查看: 265

以太坊智能合约的众筹_以太坊可以运行智能合约_以太坊智能合约转不出去币

Smart contracts(智能合约)、ICOs、Mist、Metamask、Remix、geth、web3……如果你愿意花一点时间在以太坊的开发上,相信这些词你可能并不陌生。

有些人将智能合约部署到测试网,有些人告诉你阅读以太坊的黄皮书,还有一些人建议你使用 Truffle 套件,因为它运行良好。 作为一个呆在这些“大神”身边的“新手”,你不知道如何开始使用以太坊,更不知道如何合作,如何组建以太坊。

如果这是您阅读的关于以太坊或区块链生态系统的第一篇文章,那么您一定会喜欢这个系列。 专家们在 Twitter 上互动,讨论不安全的标准和协议,以及未标记和错误的开发工具。 然而,区块链还不是所有的事情都完成了,每个人都在朝着不同的方向前进,因为还有很多工作要做。 研究机构、银行和政府的未来正在由“疯狂”的开发者决定! 这听起来棒极了。

无论如何,不​​用担心,我会尝试在本系列教程中为您连接所有的点,带您穿越智能合约和 dapp 开发的世界,并向您展示它们是如何工作的。

虽然我不会深入探讨以太坊的每个细节,但我会向您发送一些材料的链接,以帮助您更好地理解这些概念,您可以自行决定是否要深入了解它们的所有细节。 本系列教程的目的是帮助您以最通俗的方式更好地理解以太坊背后的原理,就好像您的一位对这项技术充满热情的朋友正在为您讲解。

那么,以太坊到底是什么?

以太坊官网给出了这样的解释:

以太坊是一个运行智能合约的去中心化平台:平台上的应用程序完全按照编程运行,没有停机、审查、欺诈或第三方干扰的可能性。

换句话说,以太坊使用区块链技术来验证我们运行的代码所执行的功能。

如果您不知道区块链、以太坊、比特币、加密货币或任何其他类似术语的含义,我建议您收听 Tim Ferriss 的精彩播客,他在其中采访了 Nick Szabo 和 Naval Ravikant:The Quiet Master of Cryptocurrency - Nick Szabo

什么是智能合约?

以太坊中的智能合约是可以处理货币交易的脚本。 就这么简单。

这些合同由我们称为“矿工”的各方执行。 “矿工”代表多台计算机,负责将交易(执行智能合约、支付加密货币等)添加到称为“区块”的公共分类账中。 多个区块组成一个区块链。

我们向这些矿工支付一种称为 Gas 的奖励,这也是执行合约的成本。 当你发布一个智能合约,或者执行它的某个功能,或者将数字货币转移到另一个账户时,你需要支付一些货币作为 Gas,这是处理交易的费用。

如果您不清楚什么是智能合约,或者想了解更多详情,可以点击以下链接:

在开始开发智能合约之前

在本教程中,我假设您(读者)已经具备一定的软件开发背景并且具备 Javascript 和 Node.JS 的基本知识。 否则,您很快就会迷失在一堆语法中。 Solidity 是我们用于开发智能合约的编程语言。 它非常接近 Javascript 的语法。 由于很多以太坊开发工具都是基于Javascript和NodeJS的,如果你已经熟悉这两种语言,那么上手会更容易。 这不是初学者教程,如果您不了解某些概念,我会为您提供一些基础教程的链接,但您可以决定是否继续本教程。

开发智能合约

最后,我们来到本教程真正有趣的部分,正如我之前所说,Solidity 与 Javascript 很接近,但它们并不相同。 很抱歉,熟悉前端语言的开发者,不能在一段Solidity代码上使用JQuery就指望它能运行,不能忽视安全问题,也不能贸然进入安全问题。 当我们讨论安全性、开发模式和防御代码时,我将解释原因。

所以现在,对于本教程中的第一个示例,我将使用电影“及时”中的一个场景,在反乌托邦的未来,人们用他们剩下的时间换取金钱以维持生计。 电影中描述了一个以时间为赌注的游戏,我们也会做同样的事情——使用智能合约来玩游戏。

我的代码没有包含在文章中,但是不用担心,我会提供我在 Github 上提到的所有脚本。 (译者注:代码已放在文章中)

此外,如果这是您第一次使用智能合约,即使您现在不能掌握所有内容也没关系。 您需要大量练习,大量阅读文档,并做一些研究才能习惯 Solidity。

代码解释

现在,(敲黑板)让我们看一下代码。 首先,Solidity 脚本的基础是以下片段:pragma 告诉编译器我们使用的是哪个版本的 Solidity,以及我们的合约名称,这类似于 Javascript 中类的结构。 这就是所谓的“游戏”。

pragma solidity ^0.4.18; ​

以太坊智能合约转不出去币_以太坊可以运行智能合约_以太坊智能合约的众筹

/** * Example script for the Ethereum development walkthrough */ ​ contract Wrestling { /** * Our wrestlers */ address public wrestler1; address public wrestler2; ​ bool public wrestler1Played; bool public wrestler2Played; ​ uint private wrestler1Deposit; uint private wrestler2Deposit; ​ bool public gameFinished; address public theWinner; uint gains; ​ /** * The logs that will be emitted in every step of the contract's life cycle */ event WrestlingStartsEvent(address wrestler1, address wrestler2);

以太坊可以运行智能合约_以太坊智能合约的众筹_以太坊智能合约转不出去币

event EndOfRoundEvent(uint wrestler1Deposit, uint wrestler2Deposit); event EndOfWrestlingEvent(address winner, uint gains); ​ /** * The contract constructor */ function Wrestling() public { wrestler1 = msg.sender; } ​ /** * A second wrestler can register as an opponent */ function registerAsAnOpponent() public { require(wrestler2 == address(0)); ​ wrestler2 = msg.sender; ​ WrestlingStartsEvent(wrestler1, wrestler2); } ​ /** * Every round a player can put a sum of ether, if one of the player put in twice or * more the money (in total) than the other did, the first wins */

以太坊智能合约的众筹_以太坊智能合约转不出去币_以太坊可以运行智能合约

function wrestle() public payable { require(!gameFinished && (msg.sender == wrestler1 || msg.sender == wrestler2)); ​ if(msg.sender == wrestler1) { require(wrestler1Played == false); wrestler1Played = true; wrestler1Deposit = wrestler1Deposit + msg.value; } else { require(wrestler2Played == false); wrestler2Played = true; wrestler2Deposit = wrestler2Deposit + msg.value; } if(wrestler1Played && wrestler2Played) { if(wrestler1Deposit >= wrestler2Deposit * 2) { endOfGame(wrestler1); } else if (wrestler2Deposit >= wrestler1Deposit * 2) { endOfGame(wrestler2); } else { endOfRound(); } } } ​ function endOfRound() internal { wrestler1Played = false;

以太坊智能合约的众筹_以太坊智能合约转不出去币_以太坊可以运行智能合约

wrestler2Played = false; ​ EndOfRoundEvent(wrestler1Deposit, wrestler2Deposit); } ​ function endOfGame(address winner) internal { gameFinished = true; theWinner = winner; ​ gains = wrestler1Deposit + wrestler2Deposit; EndOfWrestlingEvent(winner, gains); } ​ /** * The withdraw function, following the withdraw pattern shown and explained here: * http://solidity.readthedocs.io/en/develop/common-patterns.html#withdrawal-from-contracts */ function withdraw() public { require(gameFinished && theWinner == msg.sender); ​ uint amount = gains; ​ gains = 0; msg.sender.transfer(amount); }

以太坊智能合约转不出去币_以太坊可以运行智能合约_以太坊智能合约的众筹

}

我们想要两个摔跤手,所以我们将设置两个变量来保存他们的帐户地址(他们钱包的公钥)。 (译者注:摔跤手:参与比赛的人)

在我们的小游戏中,摔跤手每轮可以投入一笔钱,如果其中一个人的钱是另一个人的两倍,他就会赢得比赛。

关键字 private/public 的重点之一是,即使一个变量被设置为私有,也不意味着其他人无法获取内容,而是只能在合约内访问。 由于整个区块链存储在多台计算机上,存储在变量中的信息总是可以被其他人看到,这意味着您应该始终牢记安全。

另一方面,编译器会自动为公共变量创建 getter 函数。 为了让其他合约或用户改变公共变量的值,需要手动创建一个setter函数来提供修改变量的入口。

现在我们为游戏中的每一轮添加三个可能的事件。 注册摔跤手时会触发开始事件。 游戏过程中,每一轮游戏都会触发对局事件。 最后,当摔跤手获胜时,会触发第三个事件,结束事件。 所有事件的内容只是日志记录。 在分布式应用程序dapps的开发中,可以设置事件以实际函数调用JavaScript函数。 事件甚至可以用于开发期间的调试,因为没有等效于 JavaScript 的 console.log() 函数用于在 Solidity 上打印。

接下来我们为 Solidity 添加一个与我们的合约同名的构造函数,并且只在创建合约时调用一次。

第一个摔跤手将是创建合同的人。 “msg.sender”是这个函数调用者的地址。

接下来我们为另一个 wrestler 注册以下函数:

require 函数是 Solidity 中一个特殊的错误处理函数,如果不满足某个条件,它会恢复之前的更改。 在我们的例程中,如果变量wrestler2等于地址0x0(相当于地址0),我们将添加未创建的wrestler2变量,如果wrestler2的地址不等于0x0,则表示wrestler2已经注册为对手,因此,我们将不再需要继续注册新对象。

同样,“msg.sender”是这个函数调用者的地址以太坊可以运行智能合约,我们发出一个事件来表示游戏开始。

现在,每个摔跤手都会调用一个函数 wrestle(),并投入一定数量的资金。 如果两个玩家都在游戏中,我们看他们中的一个是否赢了游戏(赢游戏的规则是一方积累的钱是另一方的两倍)。 “payable”关键字表示该函数可以接收数字货币。 如果未设置此关键字,该函数将不接受以太币。 而“msg.value”是合约中以太币的数量。

接下来我们添加 endOfGame() 和 endOfRound() 函数。 其中使用的关键字类似于private,唯一不同的是用internal修饰的函数可以被其他合约继承(因为Solidity类似于其他面向对象语言),而用private修饰的函数不能被继承。

需要注意的一件事是,我们不会将资金直接转给获胜者。 在这个例子中,直接与否并不重要,因为赢家将拿走合约中的所有资金。 在其他更一般的情况下,当多个用户可以从合约中提取以太币时,使用提现模式是一种更安全的避免多次提现的方式。

简单来说,如果多个用户可以从合约中提取资金,一个用户可以简单地多次调用支付函数来获得他应得的数倍资金。 所以我们需要按照示例中所示的方式构建我们的取款功能,以防止上述情况的发生。

您可以在以下链接找到整个代码片段:(译者注:或以上)

代码

使用集成开发环境

您现在可以复制上面的代码并将其粘贴到 Remix IDE 中,您可以在浏览器的新选项卡中打开此 IDE

您可以直接在浏览器中使用 Remix,而且 Remix 有许多您在其他任何地方都很难找到的有趣功能。

单击页面左上角的“+”按钮,然后创建一个名为“Wrestling.sol”的新文件,并将 github 存储库中的代码粘贴到上面的链接中:

以太坊智能合约的众筹_以太坊可以运行智能合约_以太坊智能合约转不出去币

IDE 支持语法高亮显示。 Github 当前不支持 Solidity .sol 扩展。

在页面右侧,您会发现几个有趣的选项卡,例如显示错误和建议的“分析”选项卡。 我建议您亲自试用此工具的功能。 虽然我们会在下一部分使用其他工具,但正如我之前所说,本系列教程的目标是为您连接各个知识点,并告诉您它们是如何协同工作的。 您可以根据自己的喜好决定是否在浏览器上使用 IDE。 如果愿意以太坊可以运行智能合约,欢迎阅读 Remix 的文档。

或者,您可以通过阅读 solidity 文档来熟悉它。

在下一部分中,我们将看到如何将智能合约部署到两个测试网,了解 truffle、ganache 和 geth,以及它们如何协同工作

如果你喜欢这第一部分,你可以在推特上找到我@dev_zl。

传送门的第二部分在这里



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3