LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 新闻观点 > NEAR 应用与区块链交互解析

NEAR 应用与区块链交互解析

2020-01-08 HashQuark 来源:区块链网络


NEAR 是一个通过分片来提高区块链扩展性、专注于性能和用户体验的下一代公链项目,致力于提供一个能推动 DAPP 大规模使用的平台。


本文通过创建一个实例项目,结合源码分析,探究 DAPP 在部署、与区块链交互背后的逻辑过程



创建部署DAPP



首先创建一个简单的 DAPP。


环境安装

在执行下述步骤前,确保已安装 npm、node、near-shell 和构建工具,如gulp。


创建项目

什么是 create-near-app

create-near-app 是一个用来快速生成项目基础框架的模板工具,目前支持 react 模板和原生模板。


采用 create-near-app 在当前目录下创建一个简单的项目框架 myapp:

npx create-near-app --vanilla myapp



下图为一个创建成功的基本项目。其中,src 负责存放主要代码,assembly 存放合约代码,neardev 则用来存放一些账户配置。



创建账户并授权

项目创建完成后,如无 NEAR 账户,先前往 https://wallet.nearprotocol.com/ 钱包创建一个账户,并在项目目录下执行 near login,根据操作步骤进行账户授权,此时会在 neardev 文件夹下创建对应账户文件。


接下来为合约创建账户:

near create_account myappaccount --masterAccount=hashquark --initialBalance 2

将 src/config.js 中的合约名称修改为刚创建的合约名称:



打包并启动

采用 npm install && npm start 安装依赖并启动项目后,即可前往本地5000端口打开网站。登录至钱包并完成授权后即返回首页展示欢迎用户(如下图所示)。




过程分析



下文将结合源码分析,探究上述步骤的过程逻辑。


合约编译

什么是 wasm

WebAssembly 也称 wasm,是一个实验性的低端编程语言,应用于浏览器内的客户端。Wasmer 则是一个独立于浏览器外的 wasm 运行环境。NEAR 的智能合约虚拟机基于 wasmer 实现,其智能合约也需要先编译为 wasm 文件。


NEAR 智能合约目前支持采用 AssemblyScript 或 Rust 进行编写。在构建项目时,智能合约最终会被编译成 wasm 文件,存放在 out 目录下,在 gulp 的配置文件中可看到相关逻辑:




合约部署

NEAR 工具介绍near-shell 是一个用来与near协议进行交互的命令行工具,基于 nearlib 实现。nearlib 是和 near 协议交互的 Javascript SDK。
在执行 npm start 启动项目时,会先执行 near deploy 来部署合约,near deploy 命令是 near-shell 的命令,主要代码如下图所示:
可以看到,near deploy 通过 neardev 文件夹下的账户执行了 nearlib 的 deployContract 方法,该方法调用 signAndSendTransaction 发送部署合约的交易:
不难看出,部署合约核心是用合约数据构造一笔交易,并用账户签名,再将签名后的交易发送给节点。
发送交易本质上是将数据编码后,向节点发送一个方法名为”broadcast_tx_commit”的 JsonRpc 请求。
合约部署的调用关系图参考如下:


接下来,节点又将如何处理 JsonRpc 请求?

节点处理部署请求

什么是 nearcore

nearcore 是 near 协议的一个官方节点实现,采用 Rust 编写。nearcore 的实现中采用了 actix 框架进行并发与异步处理,actix 是一个基于 Actor 的并发模型,通过消息传递来交换数据并行处理。

nearcore节点启动时,会开启一个http服务,用以处理节点的RPC请求;ViewClientActor、ClientActor 和 PeerManagerActor 也同时启动,以此响应不同事件的发生:




由下图可知,http 服务主要采用 JsonRpcHandler 来处理各个请求。




而JsonRpcHandler的主要处理函数如下,因此当我们接收到一个方法名为“broadcast_tx_commit”的请求时,会调用 send_tx_commit 方法来处理:


send_tx_commit 方法的核心是向其绑定的 ClientActor 发送一个类别为 Transaction 的 NetworkClientMessages 消息。




在 ClientActor 中可以看到对该消息采用 process_tx 处理:




而在 process_tx 方法中,会先检查这笔交易是否属于自己所处的分片中:


如属于,则检查交易有效性并确定自己是否为活跃验证人,若非活跃验证人,则交由其他验证人处理。




如不属于,则交由其他节点处理。




之后内存池的交易会经过共识存储在区块链上,这样一来,我们的合约也就存在了区块链上。


以上流程可以参考如下简图:




合约调用 view 方法

智能合约部署完成后,调用合约的方法,会发生什么情况?


合约 view 方法和 change 方法

NEAR 智能合约的方法可分为 view 方法和 change 方法,view 方法不改变区块链的状态,而 change 方法则恰恰相反,因此通常需要用户授权等。


在 myapp/main.js 里会先调用 nearlib 的方法来创建和 near 节点的连接以及实例化合约方法,在 myapp 项目里,实例化时指定了我们所要调用的 view 方法——welcome。


在实例化合约时采用 loadContract 方法生成一个合约对象:




生成合约对象时,通过构造方法绑定账户、合约名称及具体接口:




之后在登录后的处理函数里,调用了合约里定义的 welcome 方法,将结果显示在页面上。调用 welcome 方法时,即执行实例化时绑定的 viewFunction。

可以看到,调用合约的 welcome 方法本质上是向节点发送方法名为“query”的 JsonRpc 请求,参数 path 为“call/${contractId}/${methodName}”, data为methodName的参数。


以上流程可参考下图:




节点处理view方法

同前述near处理“broadcast_tx_commit” 类似,处理“query” RPC请求会调用 JsonRpcHandler 的 query 方法处理。


query 方法实现的核心是向 JsonRpcHandler 绑定的 ViewClientActor 发送 Query 消息,交由其处理。


ViewClientActor 对 Query 消息的处理核心:首先查询自身有无查询内容所处的分片信息,如有就调用自身查询(包括调用虚拟机执行方法等),如无则路由到其他节点来处理。


以上流程可参考如下简图:





总结



本文通过创建、部署、调用一个简单的 NEAR 智能合约,分析了在此过程中 DAPP 是如何发起请求、NEAR 节点又是如何处理该请求的。希望通过详述该过程,能对读者及 NEAR 技术爱好者予以启示。


文末彩蛋


由 NEAR、HashQuark 与 IOSG Venture 联合主办的NEAR 中国行上海站 Meetup 将于1月9日举办。点击http://www.huodongxing.com/event/1524833888500?td=4033423429700报名活动,与 NEAR 大佬面对面交流。



—-

编译者/作者:HashQuark

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...