前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用 Loom SDK 搭建的以太坊侧链上运行 DApp

用 Loom SDK 搭建的以太坊侧链上运行 DApp

作者头像
Tiny熊
发布2019-06-03 14:43:22
8410
发布2019-06-03 14:43:22
举报

上一篇,我们在Loom 构建的DApp侧链上部署了智能合约[1],这篇文章就来基于侧链网络部署一个DApp(去中心化应用)。

应用如何连接 Loom 侧链

之前我们在开发DApp时,我们会引入 web3.js 或 ethers.js[2] 作为链和应用前端的桥梁,通过一个设置一个Provider 来和指定的节点进行通信,以web3.js 0.20[3] 为例,代码大概是这样的:

var web3Provider = window.ethereum;  // ❶
var web3 = new Web3(web3Provider);var MyContract = web3.eth.contract(abiArray);// 使用合约地址实例化合约var contractInstance = MyContract.at(address);
contractInstance.callMethod(function());

❶ 行就是用来设置 provider, 如果我们的的浏览器安装了MetaMask 插件, 它会注入一个ethereum对象,也是通常推荐的方式。

不过目前(2019-05) MetaMask 还不支持连接 Loom 侧链,Loom 为此提供了一个 LoomProvider。

安装 LoomProvider

LoomProvider 在 loom-js 包里,可以 npm 来安装,安装命令如下:

npm install loom-js --save

除了 LoomProvider外 loom-js 中还有几个模块我们需要使用到,使用 ES6的 import { } from 'loom-js' 的方式引入模块会比较方便,由于这个语法目前大多数浏览器依然不支持,不过我们可以使用 webpack[4] 转化为 浏览器支持的 ES5 代码。

Webpack 安装与使用

Webpack 安装

同样使用 npm 来安装,命令如下:

npm install webpack --save

同时建议把 webpack-dev-server 安装上,这样在开发过程中,我们修改的代码可以实时反映的浏览器中(俗称“热更新”),安装方式如下:

npm install webpack-dev-server --save

Webpack 配置

为了方便把与合约交互的代码放在src/index.js(index.js 的代码编写见下节)中,把webpack生成的代码放在dist/bundle.js文件(这也是通常的作法),编写配置文件 webpack.config.js 如下:

const webpack = require('webpack')var path = require('path')
module.exports = {    entry: {        app: path.join(__dirname, 'src', 'index.js')    },
    output: {        path: path.join(__dirname, 'dist'),        filename: 'bundle.js'    },    devServer: {        historyApiFallback: true    },    node: {        fs: 'empty',        child_process: 'empty',        crypto: true,        util: true,        stream: true,        path: 'empty',    },    externals: {        shelljs: 'commonjs shelljs',    },    optimization: {        minimizer: []    }}

DApp 如何与 loom 侧链交互

我们把所有的交互代码放在 index.js 的 App 类中,不过前端 index.html 引入的是 经过webpack 打包后的 bundle.js 文件。

初始化web3

回顾初始化web3的代码,需要传入Provider对象,此时就需要用到 LoomProvider,更改后初始化web3的代码, 如下():

import {    LoomProvider} from 'loom-js'
export default class App {    initWeb3() {      this.web3 = new Web3(new LoomProvider(this.client, this.privateKey))  // ❶    }}

❶ 为初始化web3 代码, 构造 LoomProvider 对象时需要传入 client 对象和一个私钥,在侧链上发起的交易,将用这个私钥进行签名。

创建client对象

添加 client 的创建函数 createClient() 代码如下:

import {     Client,    LoomProvider} from 'loom-js'
export default class App {    createClient() {   // ❶        let writeUrl = 'ws://127.0.0.1:46658/websocket'        let readUrl = 'ws://127.0.0.1:46658/queryws'        let networkId = 'default'
        this.client = new Client(networkId, writeUrl, readUrl)
        this.client.on('error', msg => {            console.error('Error on connect to client', msg)            console.warn('Please verify if loom command is running')        })    }
    initWeb3() { ... }
}

client 的创建需要的信息,和我们在 上一篇loom 上部署合约[5]中 truffle.js 的配置相似,都是指定节点的 RPC 信息,可以参考loom 官方文档[6]。

创建账号

私钥及账号创建代码如下:

import {     Client,    LocalAddress,    CryptoUtils,    LoomProvider} from 'loom-js'
export default class App {
    init() {        this.createClient();        this.createCurrentUserAddress();        this.initWeb3();    }
    createClient() { ... }    createCurrentUserAddress() {   // ❶        this.privateKey = CryptoUtils.generatePrivateKey()        this.publicKey = CryptoUtils.publicKeyFromPrivateKey(this.privateKey)        this.account =  LocalAddress.fromPublicKey(this.publicKey).toString();      }    initWeb3() { ... }}

❶ 行 createCurrentUserAddress 函数通过CryptoUtils创建私钥推导公钥创建账号。

构造合约对象

上面完成了web3对象的创建,现在可以开始构造合约对象,用 initContract 来执行这个过程,代码如下:

import NoteContract from '../build/contracts/NoteContract.json'  // ❶
export default class App {
    init() {        this.createClient();        this.createCurrentUserAddress();        this.initWeb3();        this.initContract();    }
    async initContract() {        const networkId = "13654820909954";    // ❷        this.currentNetwork = NoteContract.networks[networkId]
        if (!this.currentNetwork) {            throw Error('Contract not deployed on DAppChain')        }        const ABI = NoteContract.abi;
        var MyContract = this.web3.eth.contract(ABI);    // ❸        this.noteIntance = MyContract.at(this.currentNetwork.address);  // ❹
    }}

说明: ❶ 从 Truffle 编译部署生成的Json文件引入 合约描述对像 ❷ 这是我们侧链的网络id,在上一篇[7] 进行合约部署的时候,可以看到 Network id 的输出提示。

注: 在官方的示例中 networkId 使用的是 default, 不过我在实际运行时,使用 default 作为网络id会出错(找不到对应的合约部署地址)。

❸ ❹ web3.js 0.20 构造合约对象的方式。

注: 我也尝试过使用 web3.js 1.0 版本去构造合约对象, 不过获得合约对象总是合约抽象 AbstractContact ,Google 半天没有找到方案,只好作罢。

调用合约方法

直接使用 this.noteIntance 对象调用合约方法即可,和我们之前文章开发DApp时完全一样,如加载笔记的逻辑如下:

export default class App {    getNotes() {        var that = this;
        this.noteIntance.getNotesLen(this.account, function(err, len) { // ❶            console.log(len + " 条笔记");            if (len > 0) {                that.loadNote(len - 1);            }        });    }
   loadNote(index) {   // 加载每一条笔记    ...    }}

说明:

❶ 直接使用合约实例 this.noteIntance 调用合约的函数,传入参数及回调方法,可参考文档:web3.js 0.20 中文文档[8]

完整代码在GitHub[9],切换到loom 分支查看。

运行 DApp

前面我们安装了 webpack-dev-server 服务器, 可以使用 webpack-dev-server 加载 DApp 的跟目录,命令如下:

 webpack-dev-server --hot --content-base ./dist

为了方便,可以在package.js 加入一条脚本:

 "scripts": {     "serve": "webpack-dev-server --hot --content-base ./dist" }

这样就可以使用 npm run serve来启动DApp , DApp运行的url 是 http://localhost:8080/,在浏览器输入这个地址就可以看到DApp界面,如下图,大家尝试添加几条笔记。

注: 如果提示 webpack-dev-server命令找不到,可以使用npm install webpack-dev-server -g 全局安装

Loom 目前的缺陷

在侧链上运行的DApp 交互响应时间好很多,不过当下任有一些问题。

无法和 MetaMask 配合使用

前面在编写 DApp 如何与 loom 侧链交互的代码时,有一个创建账号的步骤,即页面刷新的时候,每次都会用CryptoUtils重新创建一个账号,账号没有很好的办法复用是个挺大的问题,希望loom 能早日配合 MetaMask 钱包使用(或者开发出自己的钱包插件)。

有一个方法是把私钥存储在localStorage,实例代码如下:

const storedKey = localStorage.getItem('loomKey')let privKeyif (storedKey) {    privKey = CryptoUtils.B64ToUint8Array(storedKey);} else {    privateKey = CryptoUtils.generatePrivateKey()    localStorage.setItem('loomKey', CryptoUtils.Uint8ArrayToB64(privKey))}     

根据Loom 在 medium的这篇博客[10] 说可以使用 ethers.js 的 signer 来通过 MetaMask 签名,不过我自己试验下来,并没有成功,希望成功的朋友可以留言讨论。

事件处理不完善

loom-js 对LoomProvider事件支持还不够完善,比如,我们添加事件监听代码:

        this.event = this.noteIntance.NewNote()        this.event.watch(function(err, result) {            console.log(" watch event: " + err);        });

会提示错误:

watch event: Error: Method "eth_getFilterLogs" not supported on this provider

好在与侧链交互速度较快,这个问题不算严重,可以在发起交易之后,通过get的方式读取状态变化。

加入知识星球[11],和一群优秀的区块链从业者一起学习。

深入浅出区块链[12] - 系统学习区块链,学区块链的都在这里,打造最好的区块链技术博客。

由于微信不支持链接,喜欢这篇文章的朋友可以阅读原文: https://learnblockchain.cn/2019/05/06/use-loom-for-dapp/

References

[1] Loom 构建的DApp侧链上部署了智能合约: https://learnblockchain.cn/2019/04/29/use-loom/ [2] ethers.js: https://learnblockchain.cn/docs/ethers.js/ [3] web3.js 0.20: https://learnblockchain.cn/docs/web3js-0.2x/web3.eth.html#contract [4] webpack: https://github.com/webpack/webpack [5] loom 上部署合约: https://learnblockchain.cn/2019/04/29/use-loom/ [6] loom 官方文档: https://loomx.io/developers/docs/zh-CN/web3js-loom-provider-truffle.html [7] 上一篇: https://learnblockchain.cn/2019/04/29/use-loom/ [8] web3.js 0.20 中文文档: https://learnblockchain.cn/docs/web3js-0.2x/web3.eth.html#contract [9] GitHub: https://github.com/xilibi2003/note_dapp [10] 博客: https://medium.com/loom-network/universal-transaction-signing-seamless-layer-2-dapp-scaling-for-ethereum-b63a733fc65c [11] 知识星球: https://learnblockchain.cn/images/zsxq.png [12] 深入浅出区块链: https://learnblockchain.cn/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 应用如何连接 Loom 侧链
  • 安装 LoomProvider
  • Webpack 安装与使用
  • Webpack 安装
  • Webpack 配置
  • DApp 如何与 loom 侧链交互
    • 初始化web3
      • 创建client对象
        • 创建账号
          • 构造合约对象
            • 调用合约方法
            • 运行 DApp
            • Loom 目前的缺陷
              • 无法和 MetaMask 配合使用
                • 事件处理不完善
                  • References
                  相关产品与服务
                  腾讯云区块链服务平台 TBaaS
                  腾讯云区块链服务平台(Tencent Blockchain as a Service,简称TBaaS)致力于打造全球领先的企业级区块链技术平台,帮助客户、开发者及合作伙伴轻松创建和管理可托管、可扩展的区块链网络,助力产业协同发展。TBaaS 支持长安链·ChainMaker、Hyperledger Fabric等区块链底层平台,简化部署、运维及开发流程,实现业务快速上链,提升链上治理效率。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档