Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
243 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。
0 p! ^# f) P% Y插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。4 Q. D- y: G9 t, c. t

& D7 f! L& R7 G. O8 R/ i+ ]1 r" D+ x接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。$ q/ P8 K' z9 C# m# g
1. 编写、编译并实例化智能合约- I* y0 j7 C) r$ M5 u
编写智能合约3 L! a/ ~6 E1 L; |3 ~- ]7 Q- K
比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。
3 m6 P: o% \+ H* I5 M( c- i/ L合约模板结构如下:, W! Q( F- D& [$ ]
contract contract_name(...) locks valueAmount of valueAsset {% {* I, U, E6 R* [
  clause clause_name(...) {
7 ?" d9 \: o/ p9 M    ...
8 v- D; I) o# b! @2 F* t0 T, Y    lock/unlock ...; c0 P/ U/ h5 Z
  }% y2 f5 E! m+ c; B
  ...+ ?  m9 D1 C1 K$ q6 U1 V
}+ r& l' P* G4 z1 [" |% _
Equity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。
$ x0 d2 ~0 b7 A2 S' {6 n5 f3 M编译并实例化合约4 J/ p- J7 x, @: E) N& E$ x0 ~
编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。, K5 W- Y3 v. z( F5 ^/ i$ p" }
工具编译和实例化示例如下:
2 H8 _- c2 E/ O// compile4 a$ u( J5 ^7 a+ h/ D: M
./equity [contract_name] --bin
, c! Q+ h2 h$ l3 E: }0 j6 k  W# ]// instance1 Y7 d5 b; }% H
./equity [contract_name] --instance [arguments ...]) b% d( q$ n+ G6 u5 c
2. 部署合约
$ _8 f. R$ O# e* g0 L& L0 x; o部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。* a8 e+ n+ z: ?) t' C1 C. a8 `
部署合约交易模板大致如下:
6 |" u- I' X) i; m1 @9 v{; [+ F( P: P" U# L& Z
  "actions": [  G  A1 V$ L. M" z+ Z- i/ C6 e7 J
    // inputs
! @7 h9 b+ M6 e4 P- L2 m" L    {; P# k) F% T6 K( g  `
        // btm fee
# Z' Q8 j$ j! D3 }4 q    },( D% _/ A* i+ J7 u# F6 H+ p
    {. e1 u: h! H% Q7 F1 n0 w  y' P
        amount, asset, spend_account
4 N0 a  ]0 o: q5 M8 g+ p        // spend user asset2 W. Y# r2 L3 i) o
    },! R: X0 b7 l4 U/ g8 X' B
    // outputs9 K- N; x5 I5 x; F1 [, F
    {
, a0 A; I' D4 e( K6 }1 s        amount, asset, contract_program* U" L- o5 ?4 S& u
        // receive contract program with instantiated result+ O6 _. i1 ~9 h8 j
    }1 B, @* g8 J7 [" C8 ^( m# u
  ],
/ a% m) z: {& B4 ^. a9 m; c( Z& b2 W  ...
9 h$ H7 @; Q7 A9 S* l+ |7 ?9 \/ x}4 u. u8 @2 {4 c; m$ K3 r
3. 搭建DAPP架构( h4 V. T& B% ~
Bytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:5 `( e, r" H  s

: P1 P2 T, W: e8 X' b. D! ^DAPP前端
% C  w3 e: w2 _2 k5 ?6 p! {搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。% R- Z" @: H- q8 d" P3 A0 f  P
从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:
) V! U2 f% B; v3 b0 W: [- D) N9 j( K! u- G0 e, i0 u
1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式* |' [# s& H  m4 A# ?0 a
$ t$ `0 ?* K3 T. e5 t7 T
2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导; A" h; k6 z8 R! ~) f5 a- t+ V

0 a0 r- Y! T% M( Z' p# v3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。
( q& z' W8 o' s: a3 F) P7 S
8 J' F' k& b0 E" F4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。
9 Y3 Y: h& [1 r: N1 H9 j3 s
6 m& k8 J, x, s/ C4 c0 D
6 Q' X2 a; N$ i4 H0 g6 A# G" T前端逻辑处理流程大致如下:
3 V$ C8 f8 e. y9 ?* E- i, g! _% ^! j- `9 T! ^5 ~" E7 u
调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:
, Y1 d- h7 v& L, G3 ~0 xwindow.addEventListener('load', async function() {* v! U0 y# U, O3 m/ ]9 I
  if (typeof window.bytom !== 'undefined') {
9 s- K: V0 H& z& H    let networks = {! _8 e! `. X- M: s: d" d) I- ]+ {
        solonet: ... // solonet bycoin url $ m, x8 i8 d$ g( `
        testnet: ... // testnet bycoin url
6 ^0 d- x4 b) {  u) |& n        mainnet: ... // mainnet bycoin url
$ u8 G6 Q1 G3 p+ r    };7 L4 N0 Y! F! y. H0 r& N
    ...9 i& ^1 j) V" r) p: J
    startApp();9 L' T1 c7 d5 U7 C
});: m/ n1 i# I1 u
; x4 W' t  l1 l; L+ T
配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:! @1 r' p1 A3 a+ ?# d' W5 O3 s
var config = {
0 _" `) b8 h) r: L    "solonet": {
# A! h! r) ?. G+ X6 c        ...         // contract arguments8 `) J7 T; t2 J! w9 Q3 N2 _
        "gas": 0.4  // btm fee% ]0 G% B6 Q. e% P
    },
7 g# G( z+ Y4 I* ?( j    "testnet":{
. r! G4 k8 D$ R: j- w: g) o( K' X        ...
; \8 K  X  t( E    },
9 M, ~- ?) m- e+ G    "mainnet":{
* |0 s! P/ P# b, s2 M2 Q1 j3 g        ...2 H1 h' h! I6 n: U8 s' z  y5 l
    }* I5 O1 U# g3 B+ @
}- b$ e' h, Y8 ^! Q& Y

. J' [' g4 X. e0 w前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。
& y5 w! }1 Q3 I! A  G, ]7 Z
' G+ d/ y4 R1 D& K构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:) y# q% z8 \* g# e9 O' i6 M
const input = []1 q' }" _2 P6 e* o
input.push(spendUTXOAction(utxohash))3 o( O0 J* t( @
... // other input
/ Q. [7 l2 d/ `2 A+ J6 Econst output = []
/ x8 ]  U  A; ?output.push(controlProgramAction(amount, asset, program))1 {3 P' ~: \# o
... // other output
( c1 |0 g% E5 B; l! M
$ p' y( g5 i: J启动前端服务
- J7 S8 P: k7 w; p( V* d$ \# r3 a编译前端命令如下:: _9 p9 c. g: [8 p7 d4 o
npm run build- y* \& m& c5 v" f( x% C$ a
启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:, l# ?  @- D, H
npm start
0 Y$ h8 R3 Q7 M/ V- P
1 ?5 b& Q' P! r, r+ A
% H& ?6 L. {- VDAPP缓冲服务器9 x6 F' x0 l) a1 H8 D
缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。
9 \  T: f0 V' v" [缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:3 X% {- x" o, I' g" W
9 l! G) S' [; z* V
编译bufferserver源代码
3 \! g+ G& {' s+ T* C* C按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:
, P! o: l7 s6 i+ Omake all6 Y0 M1 t0 J; }: l/ K
编译完成之后,在target目录下会生成可执行文件api和updater。; U& g5 Z/ Q% p  Q* ?+ Z% ^

. U! i( ]# }' v启动服务) ^5 J  J1 }5 `8 K; d$ a2 V/ P
使用root用户创建数据库和数据表,其命令如下:, R7 |6 _2 D0 F  Y
mysql -u root -p 6 v8 v- E% s8 Z! _4 \' T
修改配置文件config_local.json,配置说明参考README的config配置参数详解。/ }5 M; H( ^" R# m- h9 Q" [
启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。
& s- I( L$ d' W2 f( [) A3 e./target/api config_local.json- Q. @; c: j. T! J3 t- k
./target/updater config_local.json
" V# @/ T; F  Q* B9 G  B1 G# w启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。
' p4 o3 C& G7 ^: i, r附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16