Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
436 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。
4 D! i2 N8 j8 W# D" }) L, a! ^插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。9 K* D6 n6 G& Y2 L( {+ Z
" L- D$ ^6 k+ K; h+ N
接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。3 m- ]) t; b$ Z/ S  u& F; j
1. 编写、编译并实例化智能合约7 M: X' x; [$ E8 }
编写智能合约
2 @* V( z. n( J! w比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。
# J. m, |" v' E& e# n/ g6 n' t; E合约模板结构如下:6 w" ^, i& W' o
contract contract_name(...) locks valueAmount of valueAsset {9 @2 ]. m+ @0 @' v* {
  clause clause_name(...) {
$ p) x6 V. W/ u0 h" |    ...$ r7 z; h: y0 ?: r; J  l
    lock/unlock ...
+ d+ u2 W, S7 E  }' O- K. m. D2 Y
  ...
9 U8 U, I% v7 |2 m}
5 c5 D9 y' a$ O- G9 gEquity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。$ t/ ?( R* N7 m
编译并实例化合约7 B, s" f, Q; ?8 L7 p6 Y/ P
编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。- y+ n/ m$ C2 w6 _+ p( y6 c
工具编译和实例化示例如下:
; f( n! f1 y3 K& L2 q0 }// compile
1 G) T+ R9 t4 @+ N./equity [contract_name] --bin/ h5 `9 [, k5 @. D; M3 k
// instance
+ \: A& _5 M& P6 ]& ?./equity [contract_name] --instance [arguments ...]
( Z' ~/ m3 I' [  v) A/ a. d, U, }2. 部署合约  @5 @; V% d  t. \; Z
部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。
5 h! G9 |- {3 F  `部署合约交易模板大致如下:, a. j3 q: c' y+ |1 m
{
+ ?2 S# y: Y! v/ Q" e5 O  "actions": [
3 q& K) L+ q3 a9 @3 q9 h    // inputs
- _# K  k- n5 G    {+ G$ k' t9 n3 H# s1 C3 M, y8 j0 X
        // btm fee
7 ]+ ]6 e* ]9 [' f- l: \    },6 k' D  P& |  \  N! r
    {
6 I7 R$ d3 z0 k  m  g1 R) a' a/ |        amount, asset, spend_account- s( n" R/ F+ a. q
        // spend user asset* [: N7 ]6 x% z3 _
    },# W, C* d8 U  J0 _, Q2 \) x/ M
    // outputs
( r" h& U+ N9 B    {
8 w$ L" p' F$ D1 |. X: ~" j9 N        amount, asset, contract_program: F8 C! f' M5 Q) B3 P! L
        // receive contract program with instantiated result
) \, k- s- ?, i4 B+ h& K6 ~    }
5 H* J) x( c1 W5 F0 h; N  ],
2 y+ `& k  Y* P1 G  ...1 O. c3 {. \4 `5 j5 }( T/ c# J
}
) a: K+ m9 X( b, w( o3. 搭建DAPP架构
+ }, t5 n/ L2 _: c$ a/ Y# eBytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:# n& b, @- B- g; F2 h# Y5 k
. R' \6 ?1 [! [# N" N& b
DAPP前端) T, P3 h+ x! H
搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。
7 ]9 |! n' m3 U* P! k+ p6 t从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:( z% _* D$ _1 Z& O# i7 M
7 H/ a( g" R. k0 h2 v2 K
1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式
0 c, A  |0 H1 B# b1 I6 N. B* X' C! l) I, R5 Y7 i* b: e/ W
2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导6 N  @1 K/ ?; y5 }
; _6 V) M, Q  [+ w
3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。% g  P" R& s6 B; H2 k
1 W) ?- M# C9 u. y
4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。
; h" p' k4 y$ ]; T( g  j% I& R# c. m3 U2 d: z. |
) q  T. X; V& B
前端逻辑处理流程大致如下:1 U1 |6 i9 W$ k, t

) U% h9 K; J# Z0 L% m+ D8 K: a调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:4 J7 K, W% L3 h( Y* I
window.addEventListener('load', async function() {
  Y, Q/ u/ k$ T0 f8 O  if (typeof window.bytom !== 'undefined') {
7 Z8 M( G7 P- H# Q! @+ R    let networks = {+ @7 J: f+ W8 G* ~) J
        solonet: ... // solonet bycoin url
* X/ o% S4 O3 A6 P5 r        testnet: ... // testnet bycoin url ( m! `& Y4 p- X& j. H9 N
        mainnet: ... // mainnet bycoin url % W$ I) Y0 G* x4 P
    };
* W$ v5 e$ h" g) r, Q    ...
! _) i9 [- b( y# C& X2 Q9 i: A    startApp();* X0 t+ ~! U- s8 K7 d* n/ a
});4 l( B' T4 l& R0 B3 z- n% P) P. P2 Y
) m0 [5 u; _3 g: _: ]9 ~
配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:
0 I  B" S. ^: f* I8 Y! ?var config = {
8 X' T( C  A- ~# c0 G5 ~    "solonet": {2 x2 Q* n  j; `! A, Y$ T& @
        ...         // contract arguments% P0 H5 _' l( d
        "gas": 0.4  // btm fee
2 n$ }( x' [  ^3 r) i& X3 n  B    },- a) [8 N$ j- @, v5 U
    "testnet":{
/ @3 z) l0 B& U' b% Q3 ~! D8 r        ...: n- m' o: |* ^% K* G
    },
7 d6 J7 ~" U, v, }: ~9 J: z    "mainnet":{- M# M; v+ p/ p* u" f# t6 [$ |
        ...
$ k& f0 Z7 s0 P' h, T    }
3 W4 {2 A! M, `4 ~}& B8 F, k$ o4 o8 j4 f) i
" f* |1 C5 E9 G. F4 h
前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。+ v% w/ c) f8 ?( }

; ]. z1 B6 c4 ^* D) y构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:
# t+ _9 N9 f8 }0 Vconst input = []0 Y/ `; L+ t& _7 T) R* E
input.push(spendUTXOAction(utxohash))
, A& }* c9 a) \# q$ O. a" I' `... // other input
/ X% X* E6 e* o8 X0 M: ~7 s) aconst output = []
% P  T4 }9 r. @+ Z/ N) [output.push(controlProgramAction(amount, asset, program))
  j7 a) P2 J- \# s4 m... // other output4 j6 [3 R$ O# D/ [: J4 C  d

0 P6 s5 J8 j$ k& \3 d, h启动前端服务
9 Z9 [8 d8 W) V8 [3 |! `编译前端命令如下:( @" J: D# V( n0 ^3 A% _
npm run build
+ m0 l6 d# _1 A- V$ [4 j' h启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:
' g. R/ l6 K6 j' Z, nnpm start) g' H. f! ?  x& {2 }
- g3 A4 [- x! \0 f2 d# s

( o) M' C9 _7 H$ e/ y! |# @DAPP缓冲服务器
/ |8 v) f9 m; j# D( q# \& T9 Y# p缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。
' E# x$ d6 K; |缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:
8 d6 _" L7 v+ T# ?  y, D; L  O
1 _7 V1 i# S1 n1 v" _; V+ s编译bufferserver源代码
' i7 X  ]! d% t' Y. _2 a按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:
2 h$ S% e$ r5 @- M& ~! r- wmake all# j4 O4 A9 ?- m+ Z) K0 n8 S' b
编译完成之后,在target目录下会生成可执行文件api和updater。
5 X' o; `: N. r# q- z/ |% j; _) \. V! k' A! F' P
启动服务- I3 }% B. ~0 q
使用root用户创建数据库和数据表,其命令如下:
9 j. @! \; `. E/ C" `. fmysql -u root -p 8 w2 m* m, J! o8 w/ D2 m6 Z! f
修改配置文件config_local.json,配置说明参考README的config配置参数详解。. x) X3 q% Y+ K9 b
启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。
* [7 ^# t7 }4 {  K5 j./target/api config_local.json
" Z6 `: E* W) }% N: E- C./target/updater config_local.json% U% `5 c) j5 J- S
启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。
# I. d; o- }; z( v& q) g附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16