Node.js 闪耀于 Web 区块链 Nimiq

1,203 阅读5分钟
原文链接: zhuanlan.zhihu.com

Nimiq [1] 是一个2017年启动的区块链项目,其应用场景目标为支付(闪电网络,P2P货币兑换等),特色是只通过浏览器打开一个网页就能参与到区块链网络中进行转账和挖矿,相当于 Web 版的比特币,大幅度降低了普通用户参与区块链的门槛。

与门罗币网页挖矿把浏览器作为一个 worker 不同,Nimiq 通过网页能真正作为一个节点参与到区块链网络中 [2]。

点我进行体验nimiq.com

注:本文目的不是推销该项目,主要讲一讲 Node 在该区块链项目开发中的一些优势。


巧妙的权衡 —— Nimiq 的三种客户端

Nimiq 有三套客户端 Full、Light、Nano,设计的应用场景分别对应于服务器、桌面浏览器、移动浏览器。当然也不仅限于这些场景,浏览器也能运行 Full 客户端,服务器也能运行 Nano 客户端。三套客户端能运行在目前全部的主流浏览器中,包括 Chrome、Firefox、Safari,甚至微信内置浏览器。

其中,Full 客户端需要同步全部的区块链数据,类似于比特币和以太坊客户端,Full 客户端运行的节点又称为 backbone 节点,能够完成包括查询、挖矿、转账在内的功能。

Light 客户端需要同步部分区块链数据,依赖于 backbone 节点对区块数据的压缩,Light 客户端的定位是降低普通用户参与挖矿的门槛,打开浏览器就能实现挖矿和转账,Nimiq 官网的 Demo 运行的就是 Light 客户端。

Nano 客户端则是为了在移动浏览器中进行支付准备的,只需要同步小于 1MB 的数据就能够进行转账。


代码复用 —— 一份 JavaScript 运行于多种场景

一次编写,处处运行

这句话最早是形容 Java 虚拟机作为代码与系统的中介,让 Java 程序能够不依赖于操作系统而运行,在 Android 诞生后,确实在某种程度是验证了这句话。

如今,到了 2018 年,Node.js 也为 JavaScript 实现了一次编写,处处运行。

Nimiq 的区块链系统代码,除了哈希算法的实现外(下节讨论),其余都是使用 JavaScript 实现的。而在 JavaScript 代码当中,只有极少部分为了性能考虑而分浏览器和 Node 端实现了两份(占总量 5% 左右),绝大部分都是共用代码。

Nimiq-core [3] 的 src/main/genericsrc/main/platform 下分别进行统计:

find . -name '*.js' | xargs wc -l

结果分别为 22182 行和 1332 行。

Nimiq 实现了一套既能运行在几十核的 Linux 服务器上,又能运行在微信浏览器里的区块链系统,并且它们运行着同一套程序。


多态的哈希实现 —— WebAssembly 与 Node-addon

上节说到 Nimiq 的哈希算法没有使用 JavaScript 实现,首先科普一下什么叫”区块链中的哈希算法“。

区块链的出块方式中有一种叫做工作量证明 (Proof of Work),俗称”挖矿“,程序需要将一些数据,使用某种哈希算法,得到一串新的数据,如果这串新的数据符合某个规则,就表示“挖到了矿”。这中间的哈希算法,就是”挖矿“需要做的计算,计算的越快,挖矿效率越高。

Nimiq 团队选择的是 argon2 [4] 算法的变种,他们称为 argon2d,同时他们也在做一些反 ASIC 的工作,防止成为像比特币一样被矿机垄断的挖矿市场。

对 Node.js 做后端开发,有一种反对的声音表示 JavaScript 执行效率不高,在套上 V8 和 libuv 后,Node.js 的本地执行效率其实与 Java 是一个数量级的,远比 Python 和 PHP 高。精益求精,为了更好的执行 CPU 密集型任务,Node.js 提供了 Native Addon [5] 功能,让 Node.js 的 JavaScript 代码可以调用 C/C++ 编译后的代码,更好的利用利用多核执行 CPU 密集型任务。

为了追求极致的效率,Argon2 理所应当的使用了 C 进行实现,配合 Node.js Native Addon 完美的运行在 Node.js 平台上。

但是,浏览器平台怎么办呢? 答案是 WebAssembly [6] !一种让浏览器能够运行原生级效率程序的技术。因此,除了 JavaScript 代码能够复用,C 代码也能复用 !

在实际情况下,目前并不是所有浏览器都支持 WebAssembly,也不是所有操作系统都支持 Node.js Native Addon,所以 Nimiq 也实现了 Argon2d 的 JavaScript 版本。

笔者亲测,综合多款 CPU 的结果,Nimiq 的挖矿效率(Argon2d 执行速度)在 JavaScript、WebAssembly、Native Addon 三种实现下的效率比例大约是 1:2:6。


多态的通讯 —— WebSocket 与 WebRTC

在节点通讯方面,Nimiq 也提供了两套实现:WebSocketWebRTC

在 Node.js 平台上使用 WebSocket 实现通信,浏览器平台兼容情况复杂,通过 WebRTC 能够覆盖更多的浏览器,比如 iPad 上的 Safari。

Node.js 作为服务端开发,天然友好的能够与浏览器进行 WebRTC 通信。


题外话 —— Node 打包

笔者近期围绕 Nimiq 实现了一套 矿池,用于解决散户小算力难以出块获得收益的问题。

矿池的 桌面挖矿客户端 使用 Node.js 和 Native Addon 开发,通过 zeit/pkg 这个工具和笔者一个晚上的调试,就轻松完成了 Windows、MacOS、Linux 三平台的可执行文件打包,目前测试下来系统兼容性极佳。

Node.js 真正实现了,一次编写,处处运行。


参考

[1] Nimiq 官方网站:Nimiq
[2] Nimiq 节点程序:Nimiq Testnet Luna
[3] Nimiq core 代码:nimiq-network/core
[4] Argon2: Argon2 - Wikipedia
[5] Node.js Native Addon: Node.js v9.4.0 Documentation
[6] WebAssembly: WebAssembly
[7] WebSocket: www.npmjs.com/package/ws
[8] WebRTC: webrtc.org/
[9] 天池 Nimiq: 天池 Nimiq 矿池
[10] 天池桌面客户端:skypool-org/skypool-nimiq-miner