手把手教你用NeoRay开发智能合约

作为专为 Neo 关注者打造的视频栏目,Neo Talk 将邀请来自 Neo 团队或 Neo 生态中的各位小哥哥小姐姐,通过视频为大家带来 Neo 入门开发指南、科普最新 Neo 技术知识点、以及分享各类有趣的生态项目。
本期重点
第二期 Neo Talk,我们邀请到了来自 NEL 社区的开发者 印炜,详细介绍了什么是智能合约、Neo 上智能合约的特性,并在线演示了如何使用 NeoRay 开发调试智能合约。
希望对区块链开发有兴趣的技术爱好者们,可以通过本期视频学习使用 NeoRay,开启新世界的大门。
本期内容可以大致分为两个部分:
Neo 上的智能合约
– 智能合约 VS 传统合约
– Neo 上智能合约的执行逻辑
– Neo3 关于合约部分的改动
通过 NeoRay 开发调试智能合约
– NEP5 合约介绍
– 详解在线合约开发工具 NeoRay
– 教程演示
智能合约
智能合约这个概念其实在 20 世纪 90 年代就已经诞生,但迟迟没有具体被应用,很重要的原因就是缺乏能够支持可编程合约的数字系统和技术。

但区块链的出现解决了这个问题。它不仅可以支持编程合约,而且具有去中心化、不可篡改、过程透明可追踪等优点,天然适合智能合约。因此,智能合约有了飞速的发展。那么智能合约是什么,就先要对照着传统合约来看。

传统协议是指双方通过协议来进行价值物互换,双方之间需要信任才能让交易顺利地进行下去。一旦一方违背了协议内容,另一方就会面临利益的损失。所以一般协议的签订都需要一个强有力的第三方来监督或者担保,确保协议里的条款能够正常执行下去。而第三方的介入一方面会带来一个成本的增加,另一方面第三方在处理违约的的过程也是耗时耗力耗材的。
举一个比较普遍的例子,网购。在网上买东西会遇到一个很现实的问题,先发货还是先打款。如果先发货但是用户没有付钱怎么办,又或是买家付了钱但是店家不发货怎么办。所以这个购买协议就存在较高的风险。因此,买卖双方就需要类似支付宝这样的第三方来做一个担保。但支付宝的担保也不是与生俱来就免费的,他无形中提高了这次买卖的成本。
什么是「智能合约」
智能合约本质上也是一份提前订好的协议。之所以有智能这个头衔,是因为智能合约的条款是以代码的形式保存在区块链上。当满足条款的执行条件时,代码会强制执行,完全自动且无法干预。能够有效地减少传统协议中第三方所带来的的监督和执行成本。
智能合约是一套以数字形式定义的承诺,包括合约参与方可以在上面执行这些承诺的协议。因此,智能合约对比传统合约来看,合约内容不可以篡改,减少了人为的干预,可以十分准确地执行合约。不需要第三方的参与,节约成本且效率很高。

这是智能合约的一个执行流程,我们预先制定好一些规则和触发条件,将他们编写成代码,并部署上链。如果满足了某些条件,就会去触发相应的规则,产生结果并记录在链上。整个过程是公开透明可追溯的。
Neo 上的智能合约
Neo 上的智能合约,将分为三部分来介绍。第一部分是智能合约的入口函数和输入参数,第二部分是合约的触发器,第三部分是 Neo3 关于合约相关的改动。
● 入口函数

首先我们先介绍入口函数。这个是 Neo 智能合约的一个简单事例。就是往存储区写入一个 hello world。我们通过调用合约的 main 方法,传入参数来实现功能。这个 main 函数就是合约的入口函数。
需要注意的是,在 Neo 智能合约里只有唯一一个入口函数,就是 main 函数。你在智能合约中写的其他方法,无论定义公有还是私有,外部都不能直接调用。
如果合约相对复杂一点,需要调用合约内的其他方法应该怎么去处理呢。这里我们可以通过传入的参数来区别调用不同的方法,就像图中显示的一样,通过判断不同 operation 的值,来调用 get 方法或者是调用 put 方法。Object array 中包含了各个方法所需要的参数。这样就能够做到调用同一个入口函数方法,来实现不同的功能。
当然,这里的传入参数并不限制于(string,object【】)这种形式。你可以定义任意的传入格式,只是为了格式的统一,强烈介意你写的合约都采用这一种格式。
● 触发器

Neo 智能合约中的触发器,总共有四种类型:系统触发器、验证触发器、应用触发器和全面触发器(包含前面三种)。常用的是验证触发器和应用触发器。
以上两种常用的触发器类型决定了 Neo 智能合约的两种触发方式:
验证触发器,表明该合约被当作一个验证函数而调用,此验证函数可以接收多个参数并且返回一个布尔值来表明所验证交易或区块的有效性。比如合约用户的鉴权:智能合约作为一个合约账户,当用户使用该合约账户里的一笔资产时,会触发该智能合约验证用户的有效性。
应用触发器,表明该合约被当作一个应用函数而调用,此应用函数可以接收多个参数,可以改变区块链状态并且返回任意类型的值。比如手动发送交易调用智能合约:用户发送一笔交易来触发一段智能合约的执行。
一个合约可以同时由以上两种方式触发。由于验证触发的合约是在交易被写入区块之前执行。如果合约返回 false 或者发生异常,则交易不会被写入区块。而由交易调用触发的合约,它的调用时机是交易被写入区块以后,此时无论应用合约返回为何以及是否失败,交易都已经发生。
● Neo3 的改动

相比 Neo2,Neo3 在智能合约部分有很多的修改。Neo3 加入了原生合约的概念。原先 Neo2 有两种性质的资产,一种是 UTXO 模型的全局资产,例如 Neo 的原生资产 NEO 和 GAS 都是全局资产。第二种就是 合约资产 NEP5 资产。在 Neo3 版本里,精简了架构,删除了全局资产,只留下了合约资产。并且,NEO 和 GAS 作为原生合约写在了区块里。
在 Neo3 上,引入了合约权限控制机制,赋予了开发者更加精细的控制力度,划分为两类:
Call 级别
内部合约在调用其他合约时,尤其是第三方提供的服务合约,可以对其加权限控制,限制其访问级别,如不允许修改状态,防止潜藏的第三方合约攻击漏洞等。
Manifest 级别
部署合约的时候,可以配置合约只允许被那些合约访问,以及访问什么方法。防止恶意用户通过其他合约绕过权限检查。
我们推荐用户在设置合约权限时,尽量严进宽出,后续涉及到权限变更时,可通过升级合约配置文件,来动态更改合约权限。
内部新增了合约计数器,给每个合约赋予 ID 编号,并用其绑定合约的数据存储区域,当合约升级时,只需要保留该合约 ID,实现了一种无须数据迁移就能完成合约的新升级方式。
利用 NeoRay 开发编译智能合约
这里我们分为两个部分。第一个部分,我们先来了解 Neo 上比较经典和普遍的一种合约,叫做 NEP5 合约。第二部分,我们学习一下如何在 NeoRay 上编写、发布、调用并调试合约。

首先,我们先来了解一下 NEP5 合约。那 NEP5 是什么意思呢,这个需要拆开解释。NEP 是“Neo 改进协议”的英文缩写,“5” 则是大家一致同意的修订版本,同时也是 Neo 平台改进版本编号。这次修订新增了对基于 Neo 平台虚拟代币的支持,与以太坊之前的做法类似。它管理的是代币应该实现的关键功能,这些功能可以在网络内使用。例如,任何基于 Neo 的代币都应该是 NEP5 代币,这样才能与其他交易方或在交易所进行交易,此外还有余额查询、代币批准、转账等必要功能。当然代币合约除了要实现最基础的 NEP5 规定的方法和事件之外,还可以自己按照需求拓展一些方法,例如代币的发行方式或者销毁方式等。