https://mp.weixin.qq.com/s/Qz6Pg8uK9yubhzETQVj1lA
《CSS 揭秘》
“搞区块链的都是骗子”
小明感觉比特币就是技术极客对这个世界开的一个玩笑。
媒体报导,有一款叫 “加密猫” 的游戏火遍全球,而这款游戏是运行在区块链上的。
媒体的狂轰滥炸还让小明注意到区块链的另一个特性:不可篡改。
小明关心的 “区块链应用”,其实有一个更专业的名字,叫 “DApp”。
DApp 全称为 “Decentralized Application”,字面意思是 “去中心化应用”。(“DApp” 这个词通常读作 “dee-app” 或 “dap”;当然如果你愿意,也可以读作 “D-A-P-P”。)
DApp 有一个核心概念叫 “智能合约”。
在动手之前,小明需要先选择一条公链来作为自己的开发平台。
小明经过一番调研,最终选择 “星云链” 作为自己的入门公链。
? 以太坊
以太坊是第一个支持智能合约的公链,是 DApp 始祖。以太坊也是区块链领域的标杆。
前面提到的 “加密猫” 游戏正是运行在以太坊之上。
智能合约的运作方式是这样的:
开发者在写好合约代码之后,需要把它部署到链上。部署成功后会得到一个地址。
? 地址
地址是链上资源的一种定位方式。每个用户在链上都会有一个独一无二的地址,类似账号的概念。
每个合约也有自己的专属地址。可以类比 IP 地址,我们通过地址就可以找到这个合约。
合约部署上链之后,即处于对外服务状态。合约代码提供若干接口,等待我们调用。
每个合约都有自己的独立存储区。
DApp 也需要有一个网页作为用户界面(当然也可以是其它的客户端形态,比如桌面应用或手机应用等)。
同样需要有一个部件来完成业务逻辑和数据存储的功能,并为网页端提供接口,这个职能在 DApp 中就是由智能合约来完成的。
总的来看,DApp 在题材上与传统应用没有明显区别。
当前这个 Chrome 浏览器安装了星云链官方提供的钱包插件:
? 钱包
钱包主要有以下两个作用:
帮用户管理地址(前面已经提到过,地址相当于用户在链上的独一无二的账号)。比如,在钱包里,我们可以看到自己的地址里还有多少 “钱”。
帮用户发起交易、查询交易、管理交易。
? 交易
区块链的老本行就是记账,就是处理各种交易。
在区块链上,转账显然是一种交易;除此以外,在智能合约时代,我们往链上部署合约、调用合约的接口,也都是通过交易的形式来完成的。
区块链采用了链式数据结构,整个链是由一个个的区块所组成的。不论是完成一次新的转账,还是我们让合约更新自己的数据,都需要由矿工把这些操作打包成一个新区块,并追加到链上。
? 矿工
矿工是区块链网络中有 “记账权” 的节点,记账权也意味着产生新区块的权力。
当我们把一笔交易发送到区块链网络中时,它会传播到矿工节点那里;矿工节点会逐个执行所有待处理的交易,生成新区块。生成新区块的过程俗称 “打包”,也叫 “出块”。
作为一个 DApp 开发者,至少要做好以下准备工作:
Chrome + 星云钱包插件。这是 DApp 网页端所需的运行环境。
有自己的地址。我们可以用钱包插件来创建自己的地址。
地址里要有少量余额。原因在于每笔交易都需要向矿工支付少量手续费(术语称作 “gas”)。
? Gas
Gas 的原意是汽油。就好像搭别人的车需要付 “油费” 一样,让矿工帮你处理交易也需要支付酬劳——这是区块链世界的生态设计。视交易的复杂度不同,收取的 gas 数额也不同。
星云链的 gas 计价极为低廉,比如价值 1 分钱的星云币足够我们支付数千或数万次交易的 gas。
在星云官网注册为开发者,即可收到官网空投的少量星云币;同时社区里也有不少热心网友无偿赠送星云币。
星云 Web 钱包。是一个网页版的工具集,后面实战环节会提到它。
这是一段最小化的星云链智能合约代码。我们来看一看它有哪些要素:
CommonJS 模块(必须)
先看一眼最后一行,前端同学们肯定秒懂。整个合约其实就是一个 CommonJS 模块。
导出一个类(必须)
这个模块导出的是一个类,这个类正是合约的主体。
构造器方法(可选)
既然合约主体是一个类,而类本身并不能直接运行,那么这就意味着合约每次被调用时,这个类都会被实例化。类可以有(也可以没有)一个构造器方法,这个方法在每次实例化时执行(这是类的基本行为,大家应该都很熟悉了)。构造器方法并不是必需的,我们可以根据实际需要来编写它。
初始化方法(必须)
这个类需要有一个 init()
方法,这个方法只会在合约部署成功后被自动执行一次,以后就再也无法被调用了。因此,这个初始化方法通常用来完成整个 “应用” 级别的初始化工作。它是必需的,哪怕你的应用不需要初始化,也需要提供一个空的 init()
方法。
私有方法(可选)
这个类可以有一些私有方法,私有方法可以在类的内部被调用,但它不会暴露成为合约的公开接口。私有方法的特征是下划线开头,比如上图代码中的 _helper()
。我们可以根据实际需要定义私有方法,便于合约逻辑的实现,但它不是必需的。
这个 “下划线” 的命名约定并不是 JS 语言本身的特性,而是星云链智能合约运行环境的设计。这个设计也很符合前端开发者的命名习惯。
公开接口(必须)
除去上述特定名称的方法和私有方法以外,剩下的所有方法都会作为合约的公开接口暴露出来,以供客户端调用。比如上图代码中的 method()
。
只要满足以上条件,就是一个合法的智能合约了。也就是说,你可以按照自己的开发习惯来组织合约代码,只要满足上述条件就可以了。
另一项重要的基础知识是 “合约存储区”。
前面提到过,每个合约都有自己的独立存储区,那么智能合约自然也提供了操作存储区的 API。
只着重讲一下 DApp 客户端独有的行为——合约调用。
调用合约有两种情况,或者说,有两种方式:
不需要写数据时
有些合约接口是不需要向存储区写入数据的,比如仅仅读数据或纯计算。此类调用可以直接调用,并可立即得到结果。
需要写数据时
有些合约接口是需要向存储区写入数据的,即需要 “上链”。此类接口需要通过发起交易来调用,具体过程在 demo 环节已经展示过了。
在实现这两种类型的合约调用时,需要用到客户端 SDK。它的作用是帮助我们与链交互,我们不用操心区块链网络的具体地址、接口和参数等细节,直接使用 SDK 提供的接口就可以完成调用合约、转账、查询网络状态等操作了。
星云链官方的客户端 SDK 功能完备,但设计风格偏底层,在实际开发中略显繁琐。因此这里推荐一款第三方的 SDK——Nasa.js。
Nasa.js 的安装方式很简单,直接用 npm 就可以。
加载方式也很简单,在页面中引入 nasa.js
文件,随后就可以使用它提供的各种 API 了。
? 提示:以上代码仅仅演示了最核心的逻辑。对于一个体验良好的 DApp 来说,还需要处理好各种交互反馈和错误提示。
至此,整个 DApp 从合约端到客户端,就全部开发完成了。小明把这两端的功能跑通,网站顺利上线。
互联网产品都是迭代式开发的嘛,小明确实也打算升级一下这个 DApp。
支持多用户:这么好的应用,只有自己在用太可惜了。小明打算让它支持多用户。
可点赞:有了多用户,就可以加入一些社交元素。比如当你看到一条有意思的预言,可以给它点赞。
可打赏:不止是点赞,你甚至还可以给预言的作者打赏。
在开发传统 Web App 的时候,如果要识别不同用户,往往需要自己做一套账号系统,或者对接第三方社交账号。而在区块链上就不用这么麻烦,因为每个在链上的用户都有自己独一无二的身份标识——“地址”。DApp 通过地址就可以区分每位用户。
此外,在传统应用中如果要实现打赏功能,就需要接入支付平台,比如银联、支付宝或微信支付等。但这对个人开发者来说是极为困难的。别急,这里又体现出 DApp 的优势了——区块链的老本行就是记账,每条公链通常都有自己的原生货币系统,DApp 直接使用链的支付功能就可以了。
区块链 “原生的账号系统” 和 “原生的支付系统”,堪称 DApp 的两大天生神力!
区块链的 “不可篡改” 特性,主要有以下两个层面来构成:
不可撤消
区块链的精髓之一在于链式的数据结构,链式结构保证了新区块一旦追加到链上,就再也无法修改或撤消——这是因为链上的所有区块环环相扣,如果有节点试图修改其中一个区块,后续的区块就无法接上,这个修改会立刻被其它节点发现并判为非法。
因此,一笔交易一旦上链,就成为历史的一部分,永久地铭刻在那里。
公开透明
对于公链来说,链上的所有数据都是公开可查的。各条公链通常都会提供一种叫 “区块浏览器” 的工具,通过它可以方便地查到所有区块的内容、每笔交易的详情、任意地址的行为记录,甚至还有智能合约的源代码。
这意味着区块链上的每一次操作都是公开透明的,智能合约的运行逻辑和数据记录也都是公开透明的,没有暗箱操作的可能性。
说到这里,我们再来回顾一下 “修改合约存储区” 的过程:调用合约来更新存储区,本质上是一次交易,需要打包上链才能生效。因此,“修改合约存储区” 这个操作并不是直接修改已经在链上的历史记录,而是通过新记录在老记录上打补丁,我们在任一时刻得到的数据其实是所有修改记录叠加的结果。
因此,对于 DApp 来说,“不可篡改” 并不是说我们无法修改合约的存储区,而是说任何人都无法 “偷偷摸摸地修改”,因为每一次的修改记录都会明明白白地记录在链上。
如果小明的女朋友想验证这个 DApp 上展示的预言是否真实可靠,她还需要做这两件事情:
Review 合约代码:确认合约的逻辑是否正常。
核对合约的调用记录:确认预言是怎么提交到合约的。
第三个问题,开发者特别关心 DApp 的应用场景。目前已经明朗的应用场景有以下一些:
存证:利用区块链的不可篡改特性来实现存证的需求。比如小明的预言 DApp 就可以归为这一类。
数字资产:加密猫很好地向大众普及了 “数字资产” 的概念,区块链和智能合约可以对数字资产进行确权。
游戏:游戏中虚拟货币和道具的概念与区块链天然契合,目前最火的 DApp 也几乎都是从这个领域里涌现出来的。
实际上区块链应用还处在早期,更多的落地场景还有待我们去探索和发现。
第四个问题,有兴趣尝试 DApp 开发的同学肯定希望获取演讲中提到的各种工具和资源。
由于 DApp 开发需要掌握和学习的资料非常多,魔法哥特别整理了一个资料库,并已在 GitHub 开源:
https://github.com/NasaTeam/Awesome-Nebulas
文中提到的第三方 SDK Nasa.js 实际上也是由魔法哥组队开发的,同样在 GitHub 开源,欢迎你一起来打磨它:
https://github.com/NasaTeam/Nasa.js