在分片公链 NEAR 搭建 DApp 的逻辑几何?结合源码实践分析 DApp 在部署与区块链交互背后的逻辑过程。

原文标题:《NEAR 应用与区块链交互解析》
撰文:倪森

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

创建账户并授权

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

接下来为合约创建账户:

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

打包并启动

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

过程分析

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

合约编译

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

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

合约部署

NEAR 工具介绍
near-shell 是一个用来与 near 协议进行交互的命令行工具,基于 nearlib 实现。nearlib 是和 near 协议交互的 Javascript SDK。

在执行 npm start 启动项目时,会先执行 near deploy 来部署合约,near deploy 命令是 near-shell 的命令,主要代码如下图所示:

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

可以看到,near deploy 通过 neardev 文件夹下的账户执行了 nearlib 的 deployContract 方法,该方法调用 signAndSendTransaction 发送部署合约的交易:

![实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑](https://img.chainnews.com/material/images/3b3338202d7afdf93ce48237d7680c58.jpg

)实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

不难看出,部署合约核心是用合约数据构造一笔交易,并用账户签名,再将签名后的交易发送给节点。

发送交易本质上是将数据编码后,向节点发送一个方法名为「broadcast_tx_commit」的 JsonRpc 请求。

合约部署的调用关系图参考如下:
实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

节点处理部署请求

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

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

合约调用 view 方法

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

合约 view 方法和 change 方法

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

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

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

以上流程可参考下图:

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

节点处理 view 方法

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

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

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

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

实践解析分片公链 NEAR 生态 DApp 部署与交互逻辑

总结

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

来源链接:mp.weixin.qq.com