Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
401 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。
% `5 M$ F" m* {插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。
/ M/ D3 J* |. X; i' x
# E9 _6 q6 [7 x6 m5 x+ J8 g. ~( ^接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。
, B$ `9 R7 G) f; {2 r1. 编写、编译并实例化智能合约
5 ^/ n5 E6 P+ E6 C( X编写智能合约, J9 f/ m$ d: M5 e" Y+ h/ G) P
比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。9 s. [0 B) ]6 l# ]' p+ j- T& y
合约模板结构如下:
  K, {5 n' O3 I1 a* ocontract contract_name(...) locks valueAmount of valueAsset {
; {4 e5 J% X8 V  clause clause_name(...) {
* E0 [0 Q( v# x" @    ...) ^# d  k% z/ j3 q
    lock/unlock ...
6 c! j: x* W5 y& ^  }
" u% d0 C: f& H% B, y- B  ...2 W/ O) s$ v, A. Z4 s
}
0 g  K) S* k+ Z; gEquity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。
, U3 I3 j' d0 }; }编译并实例化合约! o' ~  S/ Z! ]+ S2 v* h3 U
编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。
! Y, O: v6 Y- F6 {3 N  F工具编译和实例化示例如下:
; U% s% W- L6 m! W4 ]// compile2 I' F6 B: t8 O: D4 j
./equity [contract_name] --bin
) X1 K/ T# h4 J) B0 j2 t4 P// instance
+ N4 P  s4 L9 N/ V2 o9 H2 {./equity [contract_name] --instance [arguments ...]' K+ P. \/ F4 O  s  ~
2. 部署合约* P7 B( o6 x! w6 K" B
部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。
' E1 x8 i: ?) n1 D+ X部署合约交易模板大致如下:
7 [/ v/ a3 i; x% ~{
8 c! K# O* n- s- w  "actions": [
; X7 f% p9 J2 u9 e" O5 c    // inputs
2 V# P( O  T$ ?/ m3 ^; M1 ~! f+ j    {: @/ L  e  a* T! }2 m; ?& ~
        // btm fee! c. V0 p( J* Q, C4 _
    },
: X* v& K" a$ E5 T1 E6 U5 }    {( {: D: a" r% X
        amount, asset, spend_account
9 o8 D) l2 C) o7 ]  _        // spend user asset! z2 ?4 X4 b4 N, D$ F
    },
/ ^4 B) @# x) ~' i# }    // outputs
" O8 g4 V5 n. P: Z) o    {
! Y% I" F; P; i$ f$ `# e        amount, asset, contract_program0 d- q8 f8 p* s- X' |1 I$ e( K* P0 s
        // receive contract program with instantiated result: D8 _1 q( `6 {& \, x; |
    }4 {" Q0 ]) `( x
  ],# C. P+ t, H  W
  ...
% `  }0 n  F4 x& i: h+ s}
5 V( l* u" o" W& u( s3. 搭建DAPP架构0 K7 D. z: H: M+ i4 b" Z0 G& d
Bytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:
1 t) E4 n- I5 P3 i8 ^$ O. Y/ G9 c5 M/ Q7 w% Z+ r
DAPP前端
# q- @4 b1 S6 O1 X' h2 g0 {! {! w搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。; f: c" X2 f; S5 w- y8 }& _$ g
从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:
% ]2 @/ y' o5 Z6 E9 [+ z0 K
# E+ R0 V9 e. O2 @1 h! l1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式
" n$ P$ z7 H7 A' C, u6 g
/ i* t8 L* Q$ a, v+ D, n8 }7 [2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导. H' r: O+ t. w' R1 N6 T) y
! j4 v- T% n0 i: W
3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。
( I; h8 m+ B% ^  q0 x9 i0 `2 n# h" n( h* \7 L+ m
4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。! Q3 v% L- U0 }7 A- f

8 }* h/ @! U. f1 A8 b" p
) B! e' M4 l  E% C2 _6 L* e" B前端逻辑处理流程大致如下:- {/ _2 L# W/ C2 [9 q
# _7 r  @, s! t9 p) b
调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:
) Z% f5 l& w, s0 ^; H; Cwindow.addEventListener('load', async function() {. c% a2 @/ P7 u8 o
  if (typeof window.bytom !== 'undefined') {/ {" }, E9 T6 g% ~
    let networks = {
4 D( ^) y  N( w        solonet: ... // solonet bycoin url 7 T  M; {9 H5 c; D" V! O+ a
        testnet: ... // testnet bycoin url
$ V; u& W& T' h  H; q& o7 G" ^        mainnet: ... // mainnet bycoin url
) l1 G3 e5 U: r- \8 b% h    };/ }+ G0 t8 x  F* s6 Q6 G* N
    ...
9 d7 b) P0 W) q7 K    startApp();
/ R' z% P4 B1 q7 C2 y* j$ {});5 l* |. T: T% s
, Y; Q, n) h8 {% I" T) S
配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:
2 |6 `+ x' J+ p$ [3 D0 L+ w9 Y2 Pvar config = {
8 O( E5 ~9 l' b: r6 U+ e    "solonet": {
: q1 M% \  `$ I4 V: K9 V        ...         // contract arguments
7 x; {# m" [+ p: ^! B        "gas": 0.4  // btm fee
# V8 P7 A. y4 P! i9 i: N( L    },+ D8 o' X! c6 C2 }* L8 d) f
    "testnet":{
. M4 U( o( D  n8 B        ...2 }! p( O/ w. N% g! X2 i
    },
3 j; b) D( H8 x  d    "mainnet":{6 L( {- j4 b0 n5 K
        ...' ]) j# `- z& ^7 a) y  i
    }# Q$ A, y' g8 n0 I7 A
}. a* w# G& k+ J6 `6 z/ f( @

8 B7 l* B  F& s- O# C& ]0 A, g前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。& P% A7 E0 r/ n# f+ \, U! Y1 K' C% `
+ E8 O( ]8 o1 k. h9 C
构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:( m' i! w8 I  E; O2 f1 U4 f$ r
const input = []
, j& p8 l3 ^$ h5 X) C& Qinput.push(spendUTXOAction(utxohash))
9 |, I- [) X9 S8 D, x. x... // other input1 h# W& w7 Q3 Y3 w6 L4 R
const output = [], P7 ?6 W* ^: z6 d4 G, H
output.push(controlProgramAction(amount, asset, program))/ J- M+ D$ T/ c; O- k0 b" p/ G
... // other output5 {* X; ^; j- r  L/ J. w
  A3 t. [6 t: A) d( g) q/ ]* F
启动前端服务
! g; H$ J. o) s) p1 c0 n1 S编译前端命令如下:
  m8 j1 v; l5 n  \9 Fnpm run build
5 x1 |3 l: E' `4 _) X启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:7 Q) n- f4 E0 N6 v# y
npm start
8 e3 p: P2 T" ]  a: b' c% Y+ ], N) X) ~

9 {; F: l0 Z/ }2 J3 [DAPP缓冲服务器# w) g% `/ j3 y5 K
缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。
7 l7 D1 |/ K5 E# @; e  k缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:$ m# u- B3 S( g- s
* I% N6 b3 m8 X( {! E
编译bufferserver源代码6 v% W& X( C  U1 t
按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:$ b( G9 E8 N4 f; N
make all
- G" h! |0 {8 B- Q5 N* S编译完成之后,在target目录下会生成可执行文件api和updater。# F  f* J! I8 u: I, Z$ K
4 R% q! M7 e9 D  c# H, {2 X# ~$ g
启动服务
' [; {* }- S, }2 i9 l使用root用户创建数据库和数据表,其命令如下:
' C' A( r3 G+ l% k+ u( |0 |# ?9 Ymysql -u root -p % N2 n. ]6 r' U8 }2 [0 \) p/ W  r
修改配置文件config_local.json,配置说明参考README的config配置参数详解。
4 n9 }; o5 L, _6 {5 h% m/ j$ Q启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。
) P3 a7 m& o* s$ `: T: C; h./target/api config_local.json
5 b5 ~! F8 ~/ w& P* y  t./target/updater config_local.json  ^3 c( }2 C$ G$ O3 Y
启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。
) I; t1 t5 K7 o+ K5 S* \  p附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16