Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
273 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。! I4 K, y  @( a# n! i4 P9 ?6 l3 u
插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。1 I; N5 }. q2 k/ T# s
( K( t$ b, D# _: c( M
接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。
$ v- ?: ^8 b- W! v; m8 U. Y1. 编写、编译并实例化智能合约% x: F2 {: m6 v- K! L, g
编写智能合约) c- |+ f9 y2 V# `9 a
比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。! c! f6 ^# u6 R- _+ ]
合约模板结构如下:& ~! E& L" d/ t: V6 z) M
contract contract_name(...) locks valueAmount of valueAsset {! U' b: r* J! L6 y
  clause clause_name(...) {
) C% m$ S8 u, E; h    ...
. L" ?# t( A6 ~* |7 ]) Z4 t9 {    lock/unlock ..." [9 Z" N1 b+ A9 W# J* [  Y! \
  }
/ c- @/ K% Q1 e7 n6 p  P! N  ...' ]) M9 |6 A0 t9 y/ c6 z
}( ~6 d& V/ y* g
Equity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。! }' G. E! H" ^
编译并实例化合约
7 Q8 H* M3 K$ Z! a* U) r编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。
/ j) D$ _. n* r5 p* z3 E: h工具编译和实例化示例如下:
' w. x$ q: n' N8 p7 q0 N4 `- m: G// compile
9 k/ n: u, k/ g% \4 Q! |( q./equity [contract_name] --bin
; t8 v9 v  d$ S  w3 w. E// instance0 M+ |# ?1 U9 |0 U4 h" K3 g
./equity [contract_name] --instance [arguments ...]; x1 k6 `: `- a
2. 部署合约
% j# i- K3 F9 J. [; j: X$ k部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。  k/ r$ R8 [7 T. o  k
部署合约交易模板大致如下:
+ h7 r; A. \" _9 ?8 f' P( w. O3 y{
; u* X+ j1 G: \. P* ]5 c  "actions": [
0 }8 f( M$ m5 l' C; i    // inputs1 p& v' s* h6 Y% E6 t
    {
8 C9 E0 C( R$ _2 P        // btm fee
$ g& _& {8 J- ~- ?    },4 u# W- f% U* k3 H* b6 w
    {
$ e# A! @% g$ i        amount, asset, spend_account. [1 ~) k( g7 |% H7 e
        // spend user asset
* n$ F9 }2 m$ H3 E- M( e) G  s1 y    },
% K2 D! d/ z9 z: L: P    // outputs
: o. n4 ^$ W) w0 m! p    {# _5 g5 f3 L( s# _. X- [* V
        amount, asset, contract_program" \3 v2 Z' [4 J- t1 E  x
        // receive contract program with instantiated result
/ i+ z5 {1 ~1 M& C+ f    }$ W2 h. J: l2 ?) x: P
  ],
, D  k$ T1 \% l: |  ...! i4 o6 w7 s. }8 V& C8 m
}6 z" T1 [" w9 Q. P- j
3. 搭建DAPP架构" n& ]6 d7 e7 h4 o9 E
Bytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:  X" k! U0 U- b2 J' D/ G

2 h: u5 e1 H; r+ I8 x+ `DAPP前端, e1 R& J! @! G  o! O4 z/ B0 |+ U- z
搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。! j$ y# i8 w2 f) D& l  p, ?+ f
从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:5 T  I$ s! `6 {. G: v$ a: s8 c) V
! i) Z9 f: B4 H+ T4 B5 X
1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式2 O& l* u1 y7 }9 }( Z

0 x. ?4 N$ v# Y; T3 O' T4 a2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导
' ~; y! R/ L1 |) {9 [; N4 N3 I% s2 k- \5 r" D6 r
3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。
# z, r  f9 C  {5 h$ K6 \3 z; l: Y! C
6 i6 X: `" m7 c) j( b; K$ |6 `+ u4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。
% F; p+ R, n* L8 T7 G4 B+ k% f# K  V/ m7 {% _8 y
& D# ~, V3 L; p+ ~; u
前端逻辑处理流程大致如下:
1 x0 Y7 e9 \: d1 ?& a' s7 e4 j& Y5 s3 x! G/ B- ?
调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:, o  V& _6 Q# A
window.addEventListener('load', async function() {0 e: B  W0 l) c8 L5 Q: n3 c
  if (typeof window.bytom !== 'undefined') {2 q0 b8 _: \. Q* h- C0 I
    let networks = {3 x4 S1 M; X4 ]- p2 z0 C+ G3 _2 {
        solonet: ... // solonet bycoin url
3 J+ S4 ~& T/ Q        testnet: ... // testnet bycoin url ' [8 R  U/ }6 \+ r1 m
        mainnet: ... // mainnet bycoin url 2 [. x; k, B8 d. |( R8 d7 A
    };
7 y- R9 y3 k2 n3 Q( v  O) h) b1 J    ...
! O, @  p# ?& S; K    startApp();! w# W2 |; o( Z
});( g4 g5 M8 a* M8 N! d
0 w6 P# Y6 i- |/ G# i* P
配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:- p: N/ |% D- ]
var config = {! i  Q: s" z8 t( S" k. ^* j. o# l
    "solonet": {1 f3 V0 |# ^  p  Z# X6 q1 p- x2 O! z
        ...         // contract arguments
4 t1 y7 r, S3 a6 q4 J        "gas": 0.4  // btm fee. O4 t# v; G4 }% @( B- x6 f
    },
+ G& k% W* s/ b; R" W* X    "testnet":{8 \3 {6 O. f( z% s$ M" V
        ..., F" |9 @! e/ r: X# W4 x3 ?
    },
7 t0 T  p: W! ?( w4 \" Q5 [* F4 n' H    "mainnet":{
2 F4 }6 B9 l# ]2 [; s, W, U& f        ..." B, h( y; ?4 s1 u" Y. g( y
    }
% V6 y/ r- V- n6 I}: ~8 `, F; ^  l3 Y* N) e" v% d" M
5 k* ]" c3 _& I& T
前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。
; t" j+ u; s8 ^4 ?
4 @  O  C) t* `/ q# l# v5 u, K构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:
6 T1 [3 X- k6 S, ?, Sconst input = []
- H0 d% u1 M' f9 yinput.push(spendUTXOAction(utxohash))' F' D2 L+ V" \! q5 B; U
... // other input
+ x: H* ~$ f0 A9 {$ ?7 t) Uconst output = []! Z: e& P" ]+ W: j$ u9 |2 r& i
output.push(controlProgramAction(amount, asset, program)); P: p* A9 B2 w! C
... // other output
  G+ Z* r# f% E
0 p; W& F: ]/ y2 Z7 E. @启动前端服务5 W) H  B: g' Y$ E/ y$ N  y' P
编译前端命令如下:8 M4 z3 x( b" ~3 l8 S/ J8 `
npm run build
" t6 E: e# k( ~2 P  k9 N$ G$ }0 l启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:" w- s* S; ~% |- t: ~
npm start8 Q2 L5 P; f0 ]2 B( Z: c/ F+ D8 z8 @" [

8 W1 ]+ t* L- L& [! w( ]: @% X/ e) S' X( ]2 }4 f5 l
DAPP缓冲服务器0 z6 N9 F: |' c6 c
缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。# y/ P8 G4 k2 p2 Q/ z
缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:
# _0 B$ @9 B' X
5 y# ^& @9 k: s3 B. U7 c编译bufferserver源代码
+ n. [* T& A) k# ?: r- c' ~- I按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:
# I% I# n! I2 _7 G$ h& {3 Y5 Omake all, k4 U% S% l2 w
编译完成之后,在target目录下会生成可执行文件api和updater。
  l' d% v+ G# j. o0 w7 A+ W8 p! g! e) c, `: e( l( l' |8 i5 u
启动服务6 g1 ^; |! s) ?* ]! v0 z- m4 \' @
使用root用户创建数据库和数据表,其命令如下:4 c5 K9 A7 X, f8 V+ n. B) f
mysql -u root -p
( ]2 O* Q1 p# o修改配置文件config_local.json,配置说明参考README的config配置参数详解。& {' g3 Q* Q* s0 @* e
启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。
. T7 @1 i3 H3 a* d% d./target/api config_local.json( i  D# x! ^" [: `
./target/updater config_local.json# e1 q) G$ O9 `5 w- b+ `* g
启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。
& o7 u( d( s  |: d- \附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16