6. 长安链Web3插件

6.1. 产品背景及意义

开发者在开发Dapp应用时,需要Web插件直接与链进行交互,此外用户在使用Dapp应用时,也需要Web插件对交易进行签名。因而核心团队推出长安链SmartPlugin工具。

6.2. 产品安装说明

目前只支持Chrome浏览器,其他浏览器的支持还在规划中。

6.2.1. 通过谷歌应用商城下载安装(需科学上网工具)

点击下方图片前往下载安装:👇👇👇

../_images/Smartplugin-chrome.png

下载后将自动安装到谷歌浏览器内,后续升级插件时也可在谷歌应用商城直接更新。

6.2.2. 通过长安链官方下载并安装插件

6.2.2.1. 下载教程

请通过此处下载插件:chainmaker-smartplugin.zip

如未登录长安链gitlab,请先登录后再下载

6.2.2.2. 安装教程

1、下载后,先请解压Zip压缩包文件。

2、打开Chrome浏览器,进⼊插件⻚⾯ chrome://extensions/

3、打开浏览器开发者模式,并重启浏览器。

4、加载已解压到本地的dist文件夹,完成添加插件,插件的使用教程,请见产品使用说明章节。

6.3. 产品使用说明

温馨提示,本产品完全去中心化,无任何中心化平台存储用户数据,故涉及到如账户密码,证书等信息时,请妥善保存,丢失后将无法找回。

6.3.1. 初始化 - 设置密码

  • 下载安装完后,可在谷歌浏览器的插件位置,找到长安链SmartPlugin。

  • 首次打开SmartPlugin时,需要先设定密码,该密码用于解锁插件,以及对上链交易进行二次确认,插件完全去中心化,平台不保存任何用户信息,故请妥善保存密码,若密码遗忘了,无法找回,只能重置插件。

6.3.2. 首页

  • 插件默认并未添加链账户,请按照指引添加指定区块链网络的链账户,并开始使用。

  • 插件默认添加了长安链开放测试网络,如需添加该网络的链账户,可前往长安链官网申请开放测试网络相关用户证书,并导入账户。

  • 如需查看链账户在指定合约内的链上资产信息,可点击订阅按钮订阅对应的合约。

  • 通过顶部的下拉选择,可以切换不同的区块链。

  • 通过右上角的更多按钮,可以切换到其他功能页面。

  • 将账户导入到插件后,可看到该账户的链账地址信息,以及在插件内的地址备注名。

  • 点击链账户可切换链账户。

  • 在插件内订阅合约后,可查看该合约内对应链账户的数据信息。

6.3.3. 订阅合约

  • 输入合约名称订阅合约,目前支持订阅FT类合约,NFT类合约,以及其他类合约。请正确选择合约类型,插件将按照所选的类型进行数据解析,如果选错,可能会解析不到对应的数据。

  • 如果选择的是FT类型或者NFT类型的合约,请按照长安链官方提供的合约相关合约标准协议撰写合约,确保函数名称以及字段含义和标准协议所约定的相符。

  • 订阅前请先确保该合约已经部署到指定的区块链网络上,否则将获取不到数据。

6.3.3.1. FT类合约详情

  • 从首页的合约列表处点击具体某一合约,进入该合约的详情页,如果所订阅的是FT类的合约,此处将展示当前账户在该合约内的资产余额,以及通过插件产生的资产转移记录。

  • 点击具体的转账记录,可查看该笔转账的详情。

6.3.3.2. NFT类合约详情

  • 如果所订阅的是NFT合约,则可以查看到当前链账户在该合约下的所有NFT信息。目前支持常见的图片格式,包含静态图片和动图。

  • 插件支持订阅任意一条长安链,以及对应链账的合约信息。因此,任何基于长安链发行的FT和NFT,只要是基于长安链标准合约协议所撰写的,都可在本插件内查看到。

  • 点击具体的NFT,可查看NFT详情。

  • 官方建议,所发行的NFT-matedata信息至少需要包含如下字段,作品名称、作者名、发行机构、作品URL、作品描述、作品哈希。例:

 {
      "auther":"凌风出品",
      "orgName":"北京美好景象图片有限公司",
      "name":"Lionel Messi",
      "description":"利昂内尔·安德烈斯·“利奥”·梅西·库奇蒂尼,简称梅西(西班牙语:Lionel Messi),生于阿根廷圣菲省罗萨里奥,现正效力于法甲俱乐部巴黎圣日耳曼,同时担任阿根廷国家足球队队长,司职边锋、前锋及前腰。目前他共获得7座金球奖、6次世界足球先生及6座欧洲金靴奖。",
      "image":"https://www.strikers.auction/images/cards/000.png",
      "seriesHash":"5fabfb28760f946a233b58e99bfac43f3c53b19afa41d26ea75a3a58cbfc1491"
    }
  • 请注意matedata必须是一段标准的json,且字段名称需与上述例子保持一致,否则将无法解析到对应的数据。其中

    • 作品URL为该NFT图片资源存放的地址,

    • 作品哈希为该图片对应的sha256哈希值,通过将资源哈希值上链进行存证,确保就算是存储在中心化云服务的NFT也不可被篡改。

6.3.4. 请求授权连接

  • 插件对外提供申请授权连接的接口,Dapp可自行对接该接口,并从dapp页面的connect wallet按钮唤起插件。请求进行连接授权。

  • 授权通过后,Dapp可获取到当前插件的的区块链网络信息和链账户信息。

  • 一个Dapp可申请授权多个链账户,一个链账户可授权给多个Dapp。

6.3.4.1. 查看连接详情

  • 在已授权连接的情况下,点击首页的连接状态,可查看插件和该Dapp的连接情况,

  • 可随时取消对某一Dapp的授权。

6.3.5. 请求发起交易

  • 支持Dapp唤起插件,并进行上链操作。Dapp如何和插件进行对接,请参照插件接口文档。

  • 上链时,可根据情况选择用于发送交易的链账户,如需添加账户,可到链账户管理处操作。

  • 上链时,需要输入密码进行二次确认。由于是去中心化应用,请妥善保存您的密码,丢失后将无法找回。

6.3.6. 请求私钥签名

  • 如果您需要验证插件内是否存在指定的私钥,则可请求插件用指定的私钥进行签名。签名后,可在Dapp内自行通过该私钥已经对外公开的公钥进行验签名。

6.3.7. 区块链网络管理

  • 插件内已内置了订阅了长安链开放测试网络,如果您想使用其他链,可在区块链网络管理页面,点击添加区块链网络按钮进行添加。

  • 目前支持添加公钥模式、证书模式两种长安链。

6.3.7.1. 添加网络

  • 目前支持添加管理长安链V2.1.0及以上版本的链。

  • 请确保所填写的节点信息正确,且网络链接通畅,此处的节点信息为节点的IP地址和RPC端口。

  • 请确保所填写的用户所在组织ID正确,且后续上传的证书是属于该组织底下的。

  • 如果您所要订阅的链支持HTTP协议,在订阅链时可选择支持,则之后插件和区块链网络节点进行通讯的时候,可直接走HTTP协议,而不用再通过网络代理将HTTP请求转发成gRPC请求。

  • 如果您所要订阅的链开启TLS,则需要上传相关证书,若未开启可不填。

6.3.8. 链账号管理

  • 你可以在链账户管理界面,查看并管理已添加的链账户,也可以继续添加别的链账户。

  • 平台完全去中心化,并无中心化服务器,保存用户所上传到链账户信息。

6.3.9. 上链记录

  • 上链后可到上链记录里,查看上链的交易信息。

  • 本版本暂不支持直接在插件内查看交易详情,如需查看交易详情,可复制交易哈希到区块链浏览器内查询。后续版本会考虑支持。

6.3.10. 系统设置

  • 长安链v2.1.0 ~~ 2.3.0版本的链需要由代理将HTTP请求转化为gRPC请求,默认由长安链官方提供公网代理服务,代码开源,开发者也可选择自行部署代理。

  • 如开发者是想订阅内网的测试链,则需要自行部署自己内网里的代理服务。

  • 长安链V2.3.0及之后的版本,支持直接通过HTTP请求和链进行交互。默认不开启,如需开启则参考如下教程。

    • 修改所要开启HTTP消息直连的节点的chainmaker.yml配置文件,将enable restful api改为ture

  # restful api gateway
  gateway:
    # enable restful api
    enabled: ture
    # max resp body buffer size, unit: M
    max_resp_body_size: 16
  • 开启后,无需开启HTTP请求转发代理服务,也可以通过该节点直接使用HTTP请求和链进行交互。

  • 如果遗忘了密码,或者需要还原插件,您可以重置插件,重置后,插件内的数据将清空。

6.4. 产品接入说明

6.4.1. 判断是否安装插件

根据hasExtension来确定是否安装插件

var hasExtension = false;
const extensionId='bmkmhpkgcbigmdepppdpdhlifcgoibph';
chrome.runtime.sendMessage(extensionId, { operation: "installCheck" },
    function (reply) {
        if (reply&&reply.data.version) {
          hasExtension = true;
        }
        else {
          hasExtension = false;
        }
    });

6.4.2. 发送消息到插件

与判断插件是否安装方式一致,当前支持安装合约/调用合约,具体参数见src/event-page.ts

// 利用插件部署合约
const myticket = Date.now().toString(); 
window.chainMaker.createUserContract({
    body:{
        contractName,
        contractVersion: 'v1.0.0',
        contractFile: await file2BinaryString(contractFile),
        runtimeType: 'WASMER',
        params: {}
    },
    ticket: myticket,
})

// 利用插件调用存证
const myticket = Date.now().toString();
window.chainMaker.invokeUserContract({
    body: {
        contractName:'fact_contract_name',     
        method: 'fact_methed_name',
        params:{
            content: 'teststring',
            hash:'teststringtohash',
            type: 'text',
            time: Math.floor(new Date().getTime() / 1000),
        },
    },
    ticket: myticket,
});

6.4.3. 接收插件发送消息

具体logic可根据message消息体进行判断处理。message类型定义,查看src/event-page.ts/ExtensionResponse

window.addEventListener("message", function (event) {
  if (event.source != window)
    return;
  const { data, ticket } = event.data;
  // myticket 为发送信息时缓存的变量
  if(myticket ===  ticket){        
    dosomestring();
  }
  console.log("Page script received: " + event.data)
  console.log(event.data)
}, false);

6.4.4. 调用插件内置功能

// 调用方式
// name 调用方法名称
// params 调用参数
// callback 接受插件返回值
// res 返回值
 window.chainMaker.sendRequest( name: string, params:any, callback:(res) => void)

6.4.4.1. 方法列表

openConnect 调启插件授权账户

参数

参数名称 类型 是否必填 参数说明
chainId string 链ID

返回值 info

返回值名称 类型 是否可能空 参数说明
code number 返回状态 0正常 1取消 2错误
res string 随机数加密后的Base64值或状态文案
accounts 用户列表数组 所在链授权的用户列表
chain 链信息对象 当前链信息

openAccountSignature 调起插件账户验签

参数

参数名称 类型 是否必填 参数说明
chainId string 链ID
accountAddress string 用户地址
body string 验签随机数

返回值 info

返回值名称 类型 是否可能空 参数说明
code number 返回状态 0正常 1取消 2错误
res string 随机数加密后的Base64值或状态文案

getConnectAccounts 获取插件当前链下的所有授权用户

参数 无

返回值 info

返回值名称 类型 是否可能空 参数说明
accounts 用户列表数组 所在链授权的用户列表
chain 链信息对象 当前链信息

6.4.5. 监听插件的事件

window.chainMaker = {
  // 插件准备完毕,只执行一次
  onLoad:function(){
    // 插件操作链接的用户
    // data {"disconnectedAccounts":[{"color":"#7F669D&#FBFACD","address":"035a2d2c267f7eada2c750b7557333d20febfa0e","isCurrent":true,"isConnect":false}],"accounts":[],"chain":{"chainName":"长安链开放测试网络","chainId":"chainmaker_testnet_chain"}}
    chainMaker.on('changeConnectedAccounts',function(data){
      console.log(data);
    });
    // 插件操作删除链用户
    // data {"removedAccounts":[{"color":"#852999&#F5D5AE","address":"38ee4691ba5ae3972f3da5d5b3bbe0e73538dbbc","isCurrent":true}],"chain":{"chainName":"chain1","chainId":"chain1"}}
    chainMaker.on('deleteChainAccounts',function(data){
      console.log(data);
    });
    // 插件操作删除链
    // data {"removedChain":{"chainName":"chain1","chainId":"chain1"}}
    chainMaker.on('deleteChain',function(data){
      console.log(data);
    });
    // 插件切换当前用户
    // data {"accounts":[{"color":"#3A8891&#F2DEBA","address":"edf1599ffe17dcea4c06989b1106580e8eb4c5dd","isCurrent":true}],"chain":{"chainName":"chain1","chainId":"chain1"}}
    chainMaker.on('changeCurrentAccount',function(data){
      console.log(data);
    });
  }
};

6.5. 开启HTTP配置说明

6.5.1. http链配置

链节点配置文件 chainmaker.yml, 默认路径如:/chainmaker-go/build/release/chainmaker-v2.3.0-wx-org1.chainmaker.org/config/wx-org1.chainmaker.org/chainmaker.yml

1、 开启网关配置:enabled 设置为 true

2、 [PermissionWithCert模式] 修改tls验证方式:tls.mode 可根据需求进行设置

  • 只支持http访问(禁用tls): disble

  • 使用https(tls单向验证): oneway

  • 使用grps(tls双向验证): twoway

3、 如果在外网环境使用https时,建议将节点下的自签证书更换为机构颁发的证书; 开发时可以使用节点自签证书,但需要再客户端授权允许访问自签证书https站点 或者 安装信任节点自签名证书.

6.5.2. 授权允许访问自签证书https站点

通过chrome浏览器访问链节点https接口,并授权允许访问:https://链接节点地址/v1/getversion

  • chrome提示 ERR_CERT_AUTHORITY_INVALID

  • 通过高级选项允许继续访问

6.5.3. 安装信任节点自签名证书

下载证书文件

1、 Windows:

下载证书后,双击证书,根据指引安装证书。证书安装过程,要确保证书存储到受信任的根证书颁发机构下。

2、Mac根证书安装信任

  • 双击ca证书通过钥匙串打开

  • 在列表中双击证书打开证书详情,点击选择始终信任,然后关闭证书详情

3、 通过证书绑定的host访问链节点

安装完证书,需要使用证书绑定的host访问链节点。如果是通过ip访问链节点,则浏览器会提示ERR_CERT_COMMON_NAME_INVALID, 解决方法如下:

  • chrome 提示 ERR_CERT_COMMON_NAME_INVALID

  • 通过高级选项查看 CERT_COMMON_NAME,并通过本地host代理工具将链节点ip代理至 CERT_COMMON_NAME, 然后添加链时使用CERT_COMMON_NAME代替节点ip

6.6. 其他补充

6.6.1. 代理服务

长安链v2.3.0以下版本的链需要由代理将HTTP请求转化为gRPC请求,默认由长安链官方提供公网代理服务,代码开源,开发者也可选择自行部署代理。

代理服务部署如下

# 拉取代码
$ git clone https://git.chainmaker.org.cn/chainmaker/chainmaker-smartplugin.git
$ cd chainmaker-smartplugin

# 启动代理服务,Nginx推荐最新版本,最低版本要求1.14.0
$ docker run --name "smartplugin-proxy" -p 9080:9080 -p 9081:9081 -d -v $(pwd)/deploy/nginx/conf.d/default.conf:/etc/nginx/nginx.conf:ro -v $(pwd)/deploy/nginx/log:/var/log/nginx -v $(pwd)/deploy/nginx/ssl:/var/www/ssl -v $(pwd)/deploy/nginx/njs:/etc/nginx/njs -v $(pwd)/deploy/nginx/cert:/etc/nginx/cert nginx
$ docker rm -f smartplugin-proxy

# 挂载目录权限设置
$ chmod -R 777 nginx/