Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
396 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。
8 @& R* R! g, R& N: K. S% }# g8 e插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。
) m+ [# e. M8 a0 M8 V( k
- z, J" ]& b) @% N, o! ^# z3 @接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。, }4 r* |& \# j0 m9 e! h# p' Q3 t
1. 编写、编译并实例化智能合约" X: m$ d+ v+ c: O* y- s4 V2 A- v
编写智能合约4 W: F! |% f- y# Z2 ?# r
比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。, s" T, m8 i1 @/ b" t
合约模板结构如下:$ S8 B5 @* k- S" `6 D% K( S
contract contract_name(...) locks valueAmount of valueAsset {7 r2 \( K; C' z4 c$ _+ h" J* ]
  clause clause_name(...) {9 l% t* y9 T6 A/ R$ }5 x
    ...
# h) w/ ^& |# l    lock/unlock ...* o1 D; b0 W7 ]% c: U& R* a
  }
1 M4 K$ p0 |# o% Z  ...
8 d8 L6 c+ b! q, \}* N  j0 W  S8 x: @" n2 G& U+ l
Equity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。( s4 y1 d2 g7 T
编译并实例化合约; Y4 G( {9 f1 r; S* k
编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。% |) e1 \0 F% v
工具编译和实例化示例如下:) t. C- A* W0 L, H( X, P: e6 p
// compile
. I) s/ Z& z3 n- z2 i7 r./equity [contract_name] --bin
8 ~1 O" s" y% O1 j* Z// instance+ T' q' n" Z8 F
./equity [contract_name] --instance [arguments ...]
# F7 U  o1 @; P% E/ v1 f; ~! F2. 部署合约7 U" }: P: i' D' P
部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。, ]5 L" i( {. f1 V+ a) K
部署合约交易模板大致如下:  O; g0 o; A+ t. ?3 H6 J( F+ W
{
) R9 o8 q) W- J1 n9 G8 T! G2 \  "actions": [* U0 E9 {3 d$ |
    // inputs
" z" {/ k, T2 Y8 k- W4 d; F% r- i2 T    {
" g4 G5 y4 I' A2 F6 v7 s5 {6 S        // btm fee
$ Z7 \, a4 K- o* [+ M5 I* Z    },
2 X% C% U) t% l$ }" J4 y    {5 D, e$ V, y$ M' i) Z0 q) y0 Z
        amount, asset, spend_account" e8 N( H* }) z% _7 k3 A6 q1 q4 s
        // spend user asset
8 H. H; B$ m8 E: }    },
( I) T: C2 d8 c" j    // outputs& q9 q( W4 `4 y+ d  ^' K
    {
' T# u( C" [( r, B        amount, asset, contract_program
1 w' u6 V; U9 G        // receive contract program with instantiated result  y% Y/ {- g) t  s" ~1 P) R
    }
& G  s9 _8 X2 B" E  ],
- V" ~0 l" _) p  ...+ n. y/ T: [( M+ L/ L# x
}1 @. X% _3 p* |% k- t; R7 F. ]6 a
3. 搭建DAPP架构; D* ~( e9 N. |4 ~, e& i
Bytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:8 L0 `7 B! V4 @& [) |; f) Y

* W1 S8 V/ K9 w* s# TDAPP前端
+ X2 `4 f- f: U/ D搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。
3 f! Q+ p" c; E) x9 J从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:
" z! ~$ |6 ~* ?7 |+ a: W! {/ O+ p. A, C3 |" ?1 C- i+ E9 q: y
1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式  |) A! Q- ?/ K3 e

1 t* ^6 O' j5 P( z9 B0 P3 V1 i7 Z0 T; X2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导3 u7 e! z5 \  F

2 s' E; u5 v+ E$ V& ?3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。
9 v9 K3 X" ^% h8 n' j5 C0 N2 I
( o+ _5 q2 L! s$ u# W$ ]: _& C6 Q. g4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。1 x* d* O: X( u: h& h4 Z* U
- y2 t! ]# e: a
1 x% [% [% D* _. y( ^! S! M
前端逻辑处理流程大致如下:; |3 X% T' d3 Q* @

& P: s3 f) d# F  r$ L3 S9 _7 _调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:
& w; d2 X3 k$ j- a9 v3 Xwindow.addEventListener('load', async function() {) q$ I$ V2 R% \5 W1 Z0 G, z+ @% U8 y
  if (typeof window.bytom !== 'undefined') {; R. }2 x, P" v, d5 m/ C$ @; z
    let networks = {
3 x! A) Z8 h3 Q. D7 ~        solonet: ... // solonet bycoin url 4 x9 s& u, M3 c/ f2 r
        testnet: ... // testnet bycoin url
1 [+ u8 ^/ {) g. h" M        mainnet: ... // mainnet bycoin url % h' u) D. n6 B3 v  y  R( b; ~
    };2 z, g$ [, U1 D7 s0 r
    ...
; Y# U, H. P6 @0 y% \" q    startApp();
( m9 \8 N, s$ j1 r  ?) q. \8 G2 y( A});
; Y. Z* j) v5 c8 v5 R  }* u6 M. ]8 |
配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:7 g2 K: B) p$ j  o
var config = {
# u" V: G  V2 s    "solonet": {
3 V2 m8 l6 ~- E* ]8 \  d" r        ...         // contract arguments& ^9 Y! Y# \& k$ e
        "gas": 0.4  // btm fee
6 k8 {+ ]2 `1 B. U+ W    },8 l; l% `/ _/ {! W+ v1 U1 m, b
    "testnet":{
: ?% N1 g/ A9 C; ^) O  x        ...
' `5 Y, _8 b/ i* ^* `+ a    },2 Y, B6 R1 p: ]; I3 ^# r, ?
    "mainnet":{. O' S; q7 R3 U( \
        ...7 D5 W; ?5 a5 z" G8 ~
    }
8 {9 ~4 _: W. p' ?5 V0 V# P: w}
, V/ O* t6 N8 W, U2 Y2 r. M, B8 Z# T6 I$ _6 ?8 N, f. t
前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。3 |, M5 f1 V, L# N

) a1 c1 g* ?; b$ I构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:0 R$ y. K2 h; \  u: O1 e5 m
const input = []/ Z, E: v* g9 ~1 V% K  ]
input.push(spendUTXOAction(utxohash))
  I. w1 j( f/ U) _! x& v... // other input- G7 g. W8 @6 ^2 d/ h
const output = []
7 V5 X8 t: `! J1 n1 {0 v' ~output.push(controlProgramAction(amount, asset, program))1 g, [" i+ t& i; p
... // other output
; `! V4 @. M& r' d6 ]; C) ]" h  _( g* d
启动前端服务
1 J) q) Z6 N1 x/ t' G) S编译前端命令如下:
( n$ ?6 N7 n! F: \8 I0 Unpm run build* t0 w8 f2 u6 g4 y" J0 y
启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:
, F, `8 q! F+ nnpm start
! M: `: H6 K  f- o4 F4 w  {9 ?* h9 V" o3 R/ _
3 S! V! m( }! {, O3 _: z
DAPP缓冲服务器
/ {8 g3 Q/ k1 u; K6 {! g缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。8 N5 M) @, O' o# ]( T1 p" M( E& y$ b
缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:/ s6 [3 }1 \! @1 w& [: T% y8 O

( y$ [+ a# P& x$ _" F编译bufferserver源代码* Z4 y3 |: K! t) Z# {- D' B+ t- P( w
按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:- H7 O5 b& x* N
make all
8 m6 O' N% ^9 q( F; p# F编译完成之后,在target目录下会生成可执行文件api和updater。
/ H2 k& F' a! G6 v! v% x2 q+ ^) ]  u: g% \1 i
启动服务' T2 {7 t( {2 Y% j) }- L- |, ~
使用root用户创建数据库和数据表,其命令如下:
8 c8 f. \' O) Xmysql -u root -p ) V' F/ g8 Z9 v+ p& S# E
修改配置文件config_local.json,配置说明参考README的config配置参数详解。$ D& u/ Y5 G6 ?5 V& M; G
启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。* p9 Z# D1 v8 ~/ J; D% N
./target/api config_local.json1 ^, S% B0 Y6 B
./target/updater config_local.json
' o3 t5 }9 g5 ]启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。2 F9 D& d* n$ O0 v- m5 P+ P
附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16