开发者社区> ezpod> 正文

solidity 0.5.7 快速入门教程

简介: 以太坊不仅是一种加密数字货币,它更是功能完备的智能合约平台,solidity就是用来开发以太坊上的智能合约的原生开发语言。solidity最早发布于2015年,它是第一种图灵完备的智能合约专用开发语言。
+关注继续查看

以太坊不仅是一种加密数字货币,它更是功能完备的智能合约平台,solidity就是用来开发以太坊上的智能合约的原生开发语言。solidity最早发布于2015年,它是第一种图灵完备的智能合约专用开发语言。目前除了以太坊之外,在其他区块链中也逐渐开始支持solidity,例如hyperledger fabric、tendermint等。在这个solidity快速教程中,我们将使用最新0.5版的solidity,以一个具体的案例来介绍solidity智能合约的开发、部署与交互,希望对你快速掌握solidity智能合约的开发有所帮助。

如果要高效系统地掌握以太坊智能合约与DApp的开发,推荐访问汇智网的在线互动课程:

以太坊开发入门 | java以太坊 | python以太坊 | php以太坊 | C#以太坊 | 电商DApp实战 | ERC721通证实战

0、问题的背景

有一个老爷爷,在生命的最后岁月别无他求,只是希望自己的财产能够通过遗嘱顺利地传给其他家庭成员。

在传统的遗嘱中,遗产分配方案是落实在法律文件上的,然后当真正开始分配时,法官需要重审文件并做出相应的决定。常见的问题发生在家庭成员之间对分配比例的争执上,甚至因此而导致家庭成员关系的破裂。在法庭听证阶段,这些都会影响法官最终的裁决,并因此可能导致不公平的结果,甚至对家庭关系造成进一步的伤害。

那么,如果我们可以让遗产分配自动进行,是否可以避免上述情况的发生?

如果遗产是一个智能合约,那么就不需要法官了。老爷爷可以自主地利用合约管理资产,然后在他去世后由程序来分配遗产给家庭成员。合约里的代码就决定了最终的分配结果,因此无需法官的介入。例如萨拉分$10000,本得到$5000,朱丽叶得到$2000。代码执行后,资产以代币或加密货币的形式自动分配给这些家庭成员,而无需人工介入。虽然不能保证每个成员都对遗产的分配结果满意,但是没有人会和代码争执。这听起来还比较可行,对吗?

记住这个案例,在这个快速教程中,我们将使用solidity,为老爷爷开发一个简单的遗嘱合约,来满足他最后的愿望。

1、搭建solidity开发环境

开发solidity智能合约最简单的方法,就是使用官方提供的在线集成开发环境REMIX,你可以点击这里打开remix,在网页里就完成solidity智能合约的编写、编译与部署:

solidity ide remix

在你打开remix页面后,注意在右侧的run选项页,environment下拉框中,要选中JavaScript VM。这个选项的意思是使用一个内存仿真以太坊节点作为你的solidity智能合约的运行平台,这样就不用考虑与实际的以太坊主网交互所需要的账号、资金、计算费用等问题,而可以先把精力聚焦在学习如何使用solidity表达你的业务逻辑上。

点击remix页面左上方的+图标,就可以创建一个新的代码文件,我们将其命名为will.sol。在remix页面中间的编辑区域可以同时显示多个文件,当前正在编辑的文件,则以活动选项页的形式显示文件名称。

2、声明solidity编译器版本

solidity还是很早期阶段的语言,从语法到编译器都在不断地演化,所以在solidity代码的第一行,一定要用pragma关键字声明这个文件中的solidity代码需要哪个版本的编译器。例如:

solidity ide remix

注意在solidity中,末尾的分号不可省略。

3、编写第一个solidity合约

接下来就可以定义我们的第一个合约:

solidity ide remix

使用contract关键字来定义一个合约,solidity的合约类似于我们熟悉的OOP中的类,因此通常合约的名称首字母也会大写,例如Will。一对大括号用来定义合约的实现
逻辑,单行注释也使用//,这和很多开发语言都类似。

4、solidity中的全局变量和构造函数

在我们开始写代码之前,应当首先明确遗嘱的条款。假设老爷爷的遗产是50个以太币,其中20个留给他的儿子康莱德,剩下的30个留给他的妻子丽莎。在真实的环境中,当老爷爷去世后,应当有一个外部的程序将调用合约中定义的方法来分配遗产,但是我们为了便于学习将自己完成这个调用。

现在,让我们先完成如下代码:

  • 表征合约所有者的变量
  • 表征遗产数量的变量
  • 表征老爷爷是否还健在的变量
  • 设置上述变量初始值的构造函数

solidity ide remix

第5行代码定义了合约的所有者。当我们在solidity中定义变量时,必须先声明其类型。address是solidity中一种特殊的类型,它表示一个以太坊地址。address类型的变量有一些特殊的方法,我们在后面会进一步了解。

第6行代码定义的fortune变量用来保存老爷爷的遗产数量,它的类型是uintunsigned int,意思是这个变量是0或正整数。solidity中有很多数据类型,但我们不会在这里一一介绍,你可以在官方文档中深入了解solidity的数据类型。

第7行代码定义的isDeceased变量用来标识老爷爷是否已经去世,这是一个开关量,因此其类型为boolean,可能的值只有两个:true或false,默认值为false。

第9~13行代码是合约的构造函数,这个特殊的函数将在合约部署的时候自动执行。

public关键字被称为可见性修饰符,它的作用是声明被修饰的方法是否允许外部调用。public意味着在合约内部或外部(由其他合约或其他人)都可以调用该方法。

payable关键字是solidity的特色之一,它使得被修饰的方法可以发送或接收以太币。为构造函数声明payable关键字意味着当我们部署合约的时候,可以直接向合约存入以太币,例如,作为遗产的50个以太币。当合约接收到以太币后,这些币就保存在合约
地址上了。

在构造函数内部,我们将owner变量的值设置为msg.sender,这是一个以太坊平台预置的全局变量,表示调用合约方法的账号地址,在我们的案例中,这个地址是老爷爷的。

同时我们将fortune变量的值设置为msg.value,这是另一个全局变量,它表示被调用的方法接收到的以太币的数量。

虽然变量isDeceased被自动初始化为默认值false,但为了清晰起见,我们将其显式地设置为false。

5、使用solidity修饰符

在solidity中,修饰符(Modifier)可以为函数附加额外的条件逻辑。例如,假设我有一个用来关灯的方法,同时有一个修饰符要求灯开关必须处于on状态,那么我们就可以在方法上附加声明这个修饰符,以便确保只有在灯开关处于on状态时,才可以调用这个方法,否则就抛出异常。

solidity ide remix

第15行代码定义了onlyOwner修饰符。如果一个方法附加声明了这个修饰符,那么就要求调用方法的账号(msg.sender)必须与owner变量的值一致(别忘了我们在构造函数中设置了owner的值)。这个调用条件有助于遗产的分配,我们将在后面看到这一点。

require关键字的意思是,括号里的表达式的值必须为真(true),否则就会抛出异常,不再继续执行代码。

_;起到占位符的作用,在执行过程中,以太坊虚拟机会用被修饰的方法代码来替换它。

第20行代码定义了mustBeDeceased修饰符。如果一个方法附加声明了这个修饰符,那么就只有在isDeceased变量值为true时,才可以调用该方法,否则就抛出异常。

在上面的代码中,我们使用修饰符来限定方法的执行条件,当然也可以不使用修饰符,而直接在方法实现代码中使用require,不过修饰符看起来更高级一些,也更容易实现代码的复用。

6、设定遗产分配方案

现在我们要继续完成遗产在家庭成员之间的分配任务,这需要他们的钱包地址和分配数量。

正如我们之前所述,康莱德将收到20个以太币而丽莎将继承30个。让我们创建一个数组来保存他们的钱包地址,然后写一个方法来分配遗产。

solidity ide remix

第25行代码定义了一个空数组familyWallets,用来保存所有家庭成员的钱包地址。和其他语言一样,在solidity中数组是顺序存放并且可以使用序号来存取。注意方括号之前的关键字paybale,只有address payable类型的变量,才可以接收以太币,这是0.5版本的solidity与之前版本的区别之一。

第27行代码创建了一个从address类型到uint类型的映射表变量inheritance,用来保存每个钱包地址的遗产数量。这是一个键/值对数据结构,类似于其他语言中的字典或哈希表,可以用键来存取值。

第29行代码定义了一个方法,它的功能是将一个钱包地址添加到familyWallets数组,然后设置该地址在inheritance映射表中的遗产数量。注意附加的onlyOwner修饰符,猜一下为什么我们要在这里声明这个修饰符?

第30行代码将传入方法的钱包地址追加到familyWallets数组的末尾。

第31行代码将传入方法的遗产继承数量设置为映射表inheritance的指定地址(传入方法的另一个参数)的值。

7、实现遗产自动分配

让我们总结一下。到目前为止,我们已经学习了全局变量、数据类型、构造函数、特殊的关键字例如payablepublic、内置的全局变量例如msg.sendermsg.value、修饰符和require、数组、映射表和方法。我们已经搭好了合约的框架,现在让我们把各部分整合起来最终完成合约。

作为这个教程最后一部分的代码,我们将实现家庭成员遗产的自动分配。

solidity ide remix

第34行定义了payout()方法,注意private关键字,这个可视性修饰符public的反义词,它只允许被修饰的方法在合约内部调用,就像在第42行的代码那样。之所以在这里使用private,主要是考虑到安全性,因为我们
不希望任何来自合约外部的调用。注意最后的mustBeDeceased修饰符,目前我们依然不能满足这个修饰符要求的条件来执行payout()方法。

第35行代码是一个for循环,用来遍历familyWallets数组。语法如下:

  • 定义一个计数器变量i,
  • 声明循环的执行条件
  • 每个周期计数器变量i加1

第36行代码是整个合约的核心,我们调用address类型的地址对象的transfer()方法,向该地址转账预定的遗产继承数量,inheritance[familyWallets[i]]表示在inheritance映射表中,键familyWallets[i]的值,也就是第i个家庭成员的遗产继承数量。

第40~42行代码定义了一个方法,当老爷爷去世后将调用这个方法来触发遗产的分配。在这里我们将变量isDeceased的值设置为true。

现在我们完成了吗?

实际上,还不完全是...

这个智能合约的代码是写完了,但是我们怎么用它?现在是收获果实的时候了。

8、solidity合约部署与交互

你的remix页面看起来应该像这样:

solidity ide remix

在remix页面右边切换到compile选项页,确认按下图选中编译器的版本,然后点击[start to compile]:

solidity ide remix

你可能会看到静态分析生成的一个蓝色文本框,我们暂时忽略它的提醒,切换到
run选项页:

solidity ide remix

确保Environment下拉框中选中了Javascript VM,点击account的下拉菜单将显示5个测试账户,每个账户都有100个以太币,让我们选择第一个。

向以太坊区块链部署合约并不是免费的,部署者需要支付手续费,通常被称为gas。引入这一机制的目的是避免区块链计算资源被恶意滥用,要进一步了解gas,可以查看这篇文章:1分钟搞清Gas/ Gas Price/ Gas Limit

gas limit字段使用默认值就可以了,我们先不修改它。

value字段表示我们在部署合约时要发送给合约的以太币数量。输入50,还记得
我们在定义构造函数时附加的payable关键字吗?

现在继续,点击[deploy]。

你可能立刻会注意到3件事。首先,选中的账户余额现在变成了49.9999… ,这是因为
我们转给合约50个以太币,还要扣除一点部署手续费。页面底部的控制台也会提供
关于部署过程的详细信息,你可以查看一下。现在看起来是这样:

solidity ide remix

我们的合约已经成功部署了!它生成了自己的地址,并且显示出我们定义的两个合约方法。作为合约的持有者,我们要做的第一件事,是设置家庭成员的继承数量:康莱德(20)、丽莎(30)。假设我们用account下拉菜单中的第二个作为康莱德的账号,丽莎的用第三个。

选择第二个账号,点击[拷贝到剪切板]图标,然后输入上图中的setInheritance后面的文本输入框。

在我们执行setInheritance方法之前,有几件事情要记住。

传入合约的以太币数量的单位是wei而不是以太币,1 ETH = 1,000,000,000,000,000,000 WEI,这是非常小的单位,因此我们需要将以太币表示的遗产数量先转换为以WEI为单位的值。

在将遗产数量换算后,在将其写入上图中的setInheritance后面的文本输入框中,之前输入的地址后面,这两个值之间注意要用逗号隔开。

还有,别忘了在account下拉框选中第一个账号,还记得onlyOwner修饰符吗?只有合约的持有人才可以调用setInheritance方法!

现在让我们依次为康莱德和丽莎执行setInheritance方法。你应当可以看到控制台输出的成功信息。看一下其中的decoded input

solidity ide remix

你看,它显示的就是我们输入的数据。

遗产分配好了,但是坏消息来了。老爷爷在73岁时,在一次北极探险中不幸因心脏病
突发去世。他总是这么充满激情与活力。

当我们纪念这位老爷爷的同时,我们同时调用遗嘱合约的deceased()方法,完成
老爷爷的最后的愿望。。。


原文:solidity 0.5.7简明教程 - 汇智网

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
MVVMToolkit入门教程
MVVMLight已经停止维护,可以考虑MVVMToolkit来替代,MVVMToolkit官方文档两个框架的基本使用方法类似,下面介绍一下不同之处(建议查看一下上一篇关于MVVMLight的文章)。
37 0
Solidity笔记-快速入门
Solidity笔记-快速入门
63 0
《Python编程:从入门到实践》学习记录(17)项目-使用api
《Python编程:从入门到实践》学习记录(17)项目-使用api
89 0
【Golang 快速入门】基础语法 + 面向对象
Golang 语言特性 Golang 的优势 Golang 的应用场景 Golang 的不足 基础语法 main 变量 常量与 iota string 字符串遍历 strings 包 bytes 包 strconv 包 unicode 包 循环语句 range 函数 多返回值 init 函数 闭包 import 导包 匿名函数 指针 defer 切片 slice 数组 slice slice 操作 ... map map 的声明 map 的使用 error 面向对象编程 type 方法 struct 封装
89 0
Solidity 文档--第一章:智能合约入门
Solidity 文档--第一章:智能合约入门
269 0
Solidity番外篇(一)Solidity在线or插件使用
Solidity番外篇(一)Solidity在线or插件使用
116 0
Solidity 文档--第二章:安装 Solidity
Solidity 文档--第二章:安装 Solidity
322 0
Solidity 文档--第三章:Solidity 编程实例
Solidity 文档--第三章:Solidity 编程实例
53 0
ETH之Solidity:Solidity的简介、安装、使用方法之详细攻略
ETH之Solidity:Solidity的简介、安装、使用方法之详细攻略
170 0
F#语言快速入门
函数式编程语言比较适合做数学公式推导,可以进行符号计算,比如求取某一个数学公式的导数或者积分,或者对公式进行化简操作等,本文先介绍一下F#基本语法。
366 0
+关注
ezpod
汇智网,http://www.hubwiz.com
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
Java开发手册-孤尽秘传版
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
相关实验场景
更多