Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
330 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。) k5 R0 x8 ~) T
插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。
( ]) m7 D% ?4 ~5 W
6 |6 j1 K( m8 ^7 C4 ?  p接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。
5 B# w; r: c- ^$ j% R1. 编写、编译并实例化智能合约( F8 k8 s6 ]( X3 |
编写智能合约
3 P: q$ c" K( }比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。, X/ w" z# B" c$ I- l  A5 g
合约模板结构如下:
% O7 w: ]4 J4 p# Q; {& Ncontract contract_name(...) locks valueAmount of valueAsset {# c* {9 N: e# r/ F% f
  clause clause_name(...) {0 p$ T9 x0 o8 |- y# o2 w* Y
    ...
( z8 w# s9 \* o2 x    lock/unlock ..., G3 ]& G9 i4 r5 p7 D8 i5 M7 {* w8 H
  }5 F5 U/ D* w, W# u% e( R& r
  ...
; s, S4 U& y$ Q- W9 @5 R5 }# F' h}
: D' O' l* l2 cEquity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。4 F0 t" I' [3 o5 e
编译并实例化合约; [# y0 L3 m9 s1 i
编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。
1 T$ R: x2 B: ]1 U/ _3 V8 w工具编译和实例化示例如下:
1 `; U! H2 S6 m' x( v// compile/ E" r# ^$ T0 a+ y: l" r5 d+ {
./equity [contract_name] --bin
& B1 s& W6 W4 }) l// instance
# w" O7 o5 h4 l2 h% U0 n./equity [contract_name] --instance [arguments ...]
) j! b) S7 g8 c) y( c) N5 M2. 部署合约; G& q% K2 I) b* R$ a3 o* @
部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。( k! ^* |! D, ~, m$ B
部署合约交易模板大致如下:! z2 s/ P( V9 o/ ]
{  i' U4 D. w& v
  "actions": [  C/ F+ V# ]9 t. K$ G* ?2 c
    // inputs0 r5 v5 d. L' i, j$ I0 ]' Q
    {
! a" P# ?- H7 A5 S7 H: A( \1 `% U) {        // btm fee
" X, A' R% u% v0 N    },
) i0 J1 _. G* L    {% y  g9 M' \7 f
        amount, asset, spend_account+ Q4 L) t. {) N+ U* h* M3 C: u0 `
        // spend user asset
. T) @9 P- L6 y% d0 Q) Y    },
( Y1 @/ x9 x5 ^; H- ]    // outputs
8 ]: ]5 r5 I$ O1 G$ l, a- ~    {
* i* `. |2 L" m        amount, asset, contract_program# l2 X9 J: T# U6 p% C1 a
        // receive contract program with instantiated result- W& J/ d: g( G+ r
    }
$ S& g* V  p% j. j5 ?( ^9 E6 l% ]  ],
: B' B: E1 k7 g4 L& c' e/ h' q  ...
- c6 x2 C" G9 C$ S}; i: c0 ?$ Z& z5 t
3. 搭建DAPP架构9 d& }/ V; ~7 b& Y7 k/ ^4 H& G9 f
Bytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:
- ~1 \  D  D2 B2 J5 ^* G: a
+ Z, f+ c. w2 q& W4 k! L* ZDAPP前端7 x: _5 d* A3 O% c- K& j2 }
搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。  K" D4 \3 j, {/ `: B1 L
从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:
6 W5 k# j, Y8 `0 J2 G7 E! Q6 N" \6 C
/ `$ i6 w6 k' P; z$ q* {7 Q2 q( M# Q1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式
1 V1 H$ D8 R  W3 H, E# W0 W: p$ j+ m7 `# \# f
2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导3 \' Y$ }+ e8 T$ ^

% E: H! C& n! Y8 C% j9 l" V- ?6 W, u3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。
/ c$ p; g" @$ h; {( V' m! K5 j: u- L& ?" E* A" S% }+ A
4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。/ C" a+ |3 w% m& U9 m
' k- x0 I% P7 P, ?. z. g0 i0 {
+ S8 h; g! e, X5 \
前端逻辑处理流程大致如下:" }- ^: B2 E6 p, @
4 K; K6 D" ^# A6 |( O
调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:
9 b4 G0 Q  }: d- Y& i$ Bwindow.addEventListener('load', async function() {9 y$ F3 e" v7 n* p
  if (typeof window.bytom !== 'undefined') {' P1 {; I; Y1 O: G* Y: w7 h9 b
    let networks = {( c& m; C  a: L) U+ e
        solonet: ... // solonet bycoin url
2 {" K$ [1 x( E3 d        testnet: ... // testnet bycoin url
/ s2 A& g8 e) R& B. k+ O        mainnet: ... // mainnet bycoin url $ j! K+ V) D: ]" d4 m+ d+ v+ w
    };/ }# m9 }) J$ F( u
    ...
/ X3 f, F1 a. S& f3 H    startApp();
( h# c5 p6 _2 m8 m! B, I! }, \+ M+ ]});
( q* l9 W) J# m* c- U1 s7 f' c3 l: I: h# x, {1 ^: b
配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:: @# e9 x5 p+ r% _+ Y
var config = {9 O- k# g( w/ C+ X+ e! U
    "solonet": {
* N$ g' e5 V6 B& u& K        ...         // contract arguments& s+ J$ {' y% @- a8 w3 S' W7 ]1 ~
        "gas": 0.4  // btm fee
+ v4 G8 N7 ~! b  N1 X$ v* U    },
6 K6 [8 ]9 [0 u6 B2 n' Y$ P# E    "testnet":{, M0 _/ i+ h( V1 N$ e
        ...
+ Y2 ?% a9 P2 @+ \7 H- E    },
" c4 P3 G3 @5 K- @) j3 b" R    "mainnet":{5 g) y* `/ W# S. r, D
        ...
, T  H& t" H/ s8 _; g3 x. T% W    }
; c% _, O0 v6 p+ P- Q; M! w1 b! e}
- m7 d; t: I% Y7 K9 a9 @, O4 h0 M+ j/ w4 D: J7 k* G
前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。
% B! v: [- @! P8 Y6 `
8 @+ u4 |, C0 p6 d0 n/ X* [构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:2 B" H8 z! Y# g( C2 w
const input = []
+ W# ]+ c2 {0 V6 ~input.push(spendUTXOAction(utxohash))
  q6 D* N( Q! l2 \( G... // other input
% Z6 ?0 G' e) _: W1 s. c% {const output = []9 ^! d% h5 e+ }9 Y; M, ?2 _- ]$ k
output.push(controlProgramAction(amount, asset, program))
* Z. r# ]" ]4 o- B* Y% J) t* Y... // other output9 Q! W9 L! K2 ?  l+ X/ M+ n
  P4 p" f# T- o/ V1 N
启动前端服务
5 }* x" l0 j- Q8 M编译前端命令如下:
4 Q# m" [+ e' @8 l6 k$ {: H( d' Snpm run build6 ~7 A( r2 s; W5 W. r( L
启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:
+ T6 F$ `9 t7 Y% F. C$ _( Inpm start
7 u# E3 h, z# S1 E" I
, X$ f/ y4 w) D1 Y% m
+ h% ^: D/ o- `+ zDAPP缓冲服务器8 o6 O: O1 i+ x! R$ d0 Q
缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。: }7 l5 q1 |7 F4 Q
缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:
' A! W! w) [; ?! R" }' Y* j  Z% V8 F9 E4 `, Y) I
编译bufferserver源代码
6 i$ j2 D( y  [. p1 l按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:3 O  S) q; J8 c3 E, ~; {
make all2 _0 ]1 O/ ~# e( H$ T/ ]) [
编译完成之后,在target目录下会生成可执行文件api和updater。
/ m& A2 j! I* o/ g; ~, k8 A+ `/ F6 J! g6 I
启动服务
, ~9 U& A# p" z" ~使用root用户创建数据库和数据表,其命令如下:6 N5 _$ ^+ T6 I- F/ m
mysql -u root -p : u: l1 I+ B( G
修改配置文件config_local.json,配置说明参考README的config配置参数详解。
4 k+ b2 p0 ~. y启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。; B% n. n, t4 N, A7 g' I* X) S
./target/api config_local.json
2 d/ V- o, X, s# L0 [/ O2 F( t! d./target/updater config_local.json
3 [9 f0 Y6 o. r, O  z启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。
4 s8 Y9 c! |6 }! ?附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16