Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
403 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。
/ ]1 h7 y8 V. U5 B' e* b6 {插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。
6 a" `/ Q- j) T1 G; X2 C3 T( w/ c: {: F" t  |; }8 L
接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。
5 |2 G# Q' N/ v+ B: w, |  S) I2 O1. 编写、编译并实例化智能合约1 |8 i$ |# b/ L  v6 {$ i- S5 l
编写智能合约2 G4 g" V( q  z' {
比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。. \& Z8 n' y" u% o
合约模板结构如下:
, p9 g: b0 @" {contract contract_name(...) locks valueAmount of valueAsset {
7 ~2 y7 M, U) H4 `$ R% z* D( n* J* l  clause clause_name(...) {% N% k8 N) C" [. _# b5 Z
    ...
7 b/ e) V6 p: V! z    lock/unlock ...2 Q+ M, \. D4 R" I
  }  q) o( L% U4 K9 A
  ...
! U2 H) A& ^: ?' r8 I}' ~5 n2 Z8 G+ O: t3 A
Equity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。
' z$ p( `  j1 V  I. c7 o编译并实例化合约" }" p. o/ o. i+ C0 Y9 Y
编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。+ U! }5 P4 B) x3 X+ Z0 f
工具编译和实例化示例如下:
8 G/ r5 S: H+ n' Q8 P0 p// compile+ M! {+ ^0 ^! @* N9 L
./equity [contract_name] --bin
2 v; j5 d4 n7 B: E$ \: ~6 b) I8 C// instance
2 T6 D+ D2 |2 L) o- r6 L./equity [contract_name] --instance [arguments ...]  Z7 U6 p6 Q$ E
2. 部署合约3 o4 |* [* M8 P7 o) Z
部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。: ]  f1 h: z7 b
部署合约交易模板大致如下:+ Q, x0 Z; a  Z" |9 |4 ^! _% k2 p
{& v7 `3 Y' C2 i9 ~$ d& ?
  "actions": [6 M/ [% v; L. H. l; _1 p, y# X7 s
    // inputs6 x2 L; ^" J4 k* f9 E) p; _. A# E: f
    {+ U8 a, l4 `7 R9 P3 V1 f
        // btm fee
4 R5 c0 V" F. h    },0 O$ }( X$ v; d6 ~" s% E
    {/ A) k9 J* y8 ~
        amount, asset, spend_account0 t- `1 \# w3 W* r) C
        // spend user asset
0 M4 _( g: s/ e! e3 U5 J# y    },- u3 n* Z! x* q9 E& J0 l
    // outputs
, v$ ?$ s4 m5 s/ W& ~    {0 ^3 ~' X9 D. a& c
        amount, asset, contract_program
5 W* S" y+ Q( u# b5 f( B' z        // receive contract program with instantiated result; t" y" U/ v' C/ ]( N+ u
    }! r5 J$ B. g7 v+ G& T* R, [
  ],
" [' A7 `5 s2 J) s& K  ...
* P; H4 V3 b/ B- a* t2 w7 I}9 v" K# s( L% ^9 u0 b) B: f
3. 搭建DAPP架构* S1 x' s1 w# Q% c, C. A8 \
Bytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:, \% ?) R, l! I, T2 a9 v

9 q4 F. s  g+ }0 |2 I, HDAPP前端8 u5 X, {3 m6 E- l8 T3 k
搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。; X% D9 }) C, @! t( O- ~! M
从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:/ o: x& J$ y1 x: i( @& ~* ?4 G6 m8 m
- G! @+ {; h; [  v, L6 ]0 @; I1 u
1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式
' R' i* n  P" P; \# |0 S! k4 {& [9 b9 n/ @8 X- G) A
2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导4 d" m: ^5 r7 k+ i

2 [& o4 G* t1 Q, K" W0 I# I3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。
; J& c/ P! l* m( @, v% n3 H: }3 S- a* z5 i  C* L7 @8 z) c
4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。7 u9 n. H' _2 H

1 T9 t  {1 K* ?6 t1 s: i" ~. Z; ^* o7 h3 R7 X  |: V
前端逻辑处理流程大致如下:
) J: M5 \8 i+ I
( Y- v; n) ~* Z4 x4 p+ M调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:
. X; U3 u+ a5 }+ I5 iwindow.addEventListener('load', async function() {
: {6 m3 |% S, H  J7 ~. g  if (typeof window.bytom !== 'undefined') {, y2 q+ w( Y4 X! T  K
    let networks = {4 w1 [5 \9 o$ v" q" q+ S# w
        solonet: ... // solonet bycoin url
1 h5 D2 Z. O4 f# x& ~' O2 t        testnet: ... // testnet bycoin url
  e% g7 y- g$ L4 E- m        mainnet: ... // mainnet bycoin url ( V* ]5 x/ c' [, L8 [
    };, ?. v( o" A7 p' l1 G
    ...
$ r% G1 W* Q5 z9 Q    startApp();! [5 |3 X! R$ x" Y: C5 R
});
) x8 ?! K! p( \! r
& n7 Q, p+ x$ h0 T5 E8 w0 N3 F配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:
, N$ |& D8 F+ Q, d, m5 ]& Fvar config = {$ e; `8 Z+ _) J$ W
    "solonet": {
) \) {/ s/ ~- O5 |) W9 G. B        ...         // contract arguments
4 j$ Y: U0 F4 c% g- C( A6 a        "gas": 0.4  // btm fee
# g- v# X, S/ @0 I6 w8 ]    },
  K4 g' w0 i( K" ?$ P0 T    "testnet":{! \$ Z1 v/ d& J1 F- s
        ...
, M) J3 h$ y1 }3 H& T' ~    },
7 w; }4 |+ w  e8 G1 f  v    "mainnet":{' E9 S# R) w8 P/ I! P4 i
        ...
4 [3 K' L7 R, x7 _0 }    }
: R/ e9 H. l9 ^* s}
+ W+ q8 K9 v% }% k9 E. D6 @2 e; w. N# n  J7 N# {! _9 o3 h
前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。$ B5 i9 R' c+ c3 b5 @

& N& W$ h) z2 e6 Q/ S3 g- `构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:2 l! L  W) d. K
const input = []
8 G/ j9 B/ j" W6 L1 ?  t! zinput.push(spendUTXOAction(utxohash))8 Y1 h# _4 {* s% u/ w8 V
... // other input, i3 Z  @8 e# Y
const output = []1 U) C1 @* a6 e0 m
output.push(controlProgramAction(amount, asset, program))* z7 o, L0 }+ u& B; ?: L( Q8 o6 w0 u! S
... // other output8 @6 F* v1 x0 U. i) v

' {. b/ N; q9 O1 I; O* @启动前端服务
/ O2 S. `& ]/ y% j: b编译前端命令如下:
0 B2 j7 d& ~6 ?+ M* dnpm run build
% t" A6 Y( w. t$ G, o; L启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:
$ e; l# F" F4 o& [! w# `9 snpm start
+ r6 p/ X: _- ~4 g9 B# d4 z
- H  M( ]' [6 T  g. C
, }( C3 f  M+ C3 S, M1 ZDAPP缓冲服务器$ e  _! J. H' G- g: z
缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。( R% U# ]8 X! c7 [
缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:
; J/ y' z- ]# y$ g6 W6 B3 I# T6 o; g6 r9 d
编译bufferserver源代码
  `; X% ~$ V1 o# m按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:# o0 a/ y0 f8 x8 m
make all. |# s4 u; V! f6 B
编译完成之后,在target目录下会生成可执行文件api和updater。
. f- d2 u& T( V7 `) q# d' X
+ K: u) M$ w" M0 B7 I1 R0 k启动服务
* b$ \! S( ~( T" G& k$ B6 F6 d6 ?使用root用户创建数据库和数据表,其命令如下:
# J# ^4 A- Z& o/ cmysql -u root -p 9 Y- z' H( z, X9 _
修改配置文件config_local.json,配置说明参考README的config配置参数详解。
, U( I$ E: \' h1 S启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。
' m- E5 o9 O! {3 _  E. }9 Y' @./target/api config_local.json
7 e- M9 R$ y8 `+ p  R./target/updater config_local.json
0 t! }' \2 v8 f/ S启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。0 H- {( k6 g. H5 a. u, V# U, w
附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16