Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
240 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。9 R' H+ i' b, f7 a$ X
插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。! h! y' Z0 O" b9 C( y& S
# P6 d' k, r7 @2 c; s0 E+ R
接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。
4 q3 e: j; o" I1. 编写、编译并实例化智能合约. B9 R) Z. O8 m; J2 R3 c( F/ Z
编写智能合约
5 R/ E/ q% w9 W' W8 {8 \比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。; h- W- ]2 z9 m' Y4 W
合约模板结构如下:3 H* s1 l; l; b. i
contract contract_name(...) locks valueAmount of valueAsset {* N5 ~0 Q: n  o
  clause clause_name(...) {
* l! ]) h  {* a8 y2 n2 f$ N    ...
7 _: F1 f3 P+ s    lock/unlock ...
5 I5 L1 ~  T. ~( l. \  }
* c- }4 J% d! v  X8 j  ...6 M3 b4 d. t/ y& }$ f
}
. Q+ |/ {. ]0 B; oEquity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。& Y  o0 ^4 j, ]0 _! r3 ~& D
编译并实例化合约; D& ]( \& }2 {( d3 I- g2 G  ~  O
编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。' p2 d, ]) v- t4 ^' h5 t- f
工具编译和实例化示例如下:
, G& W  D1 Z7 a4 {5 J5 q// compile. K3 Y+ z- P+ @6 o; W9 |1 x7 P* C
./equity [contract_name] --bin
4 R' @" q8 j) F" B: Q! e// instance/ s8 _! E8 ^& y$ ]& k! `& J# M- t
./equity [contract_name] --instance [arguments ...]" J  U8 F$ K' `' R0 L# w
2. 部署合约
( h$ t/ j, q" b2 P& I3 w部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。' l: p3 n5 A! q4 x+ m3 ~
部署合约交易模板大致如下:8 l7 D: g/ @# P9 U
{6 `' B% _( \, O5 t, f
  "actions": [
+ b7 K5 S6 p) i& V4 C    // inputs9 w6 a1 B* r; a
    {
2 S# c% e2 j& J* G        // btm fee
5 d. @. R/ l' ]; F, {    },, m* @( \0 O( H2 c. m3 P1 j5 ?
    {
( _  |' U5 ^5 c1 ?( I7 k2 T" O8 a        amount, asset, spend_account
- I8 h: k% _" j- N8 u. S        // spend user asset' x. e" D/ J  U6 t3 x3 B2 F
    },2 @  S' Q. E7 a- ~4 a3 {
    // outputs
5 i+ N2 N# E' D) ?    {' f) O0 g4 E+ J# ~0 X
        amount, asset, contract_program
" ^8 f8 L' E  s6 B! }) u        // receive contract program with instantiated result' J: D3 C* h1 M9 T! U3 t
    }
- l5 y8 N* t/ j  |/ a$ y$ q$ g  ],1 B" v+ x& O( u; s8 s
  ...
& _" w9 F! a; \  r( v}! T+ v* X$ d$ ^" i; V
3. 搭建DAPP架构$ F' s. L4 k. m. U) j6 J
Bytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:
5 L8 n' t) u9 d& M
3 I- b8 f  ]7 d8 n" mDAPP前端
( O+ R* d& k$ `4 N5 F4 i搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。
$ g: o' V( h& B0 V从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:% Y6 |4 _: K5 n9 J3 O

3 y$ g" V2 _% a' T1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式
8 Y- f$ A+ O6 V* F/ y; `3 m7 t7 [' n8 l, p2 t$ @
2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导* V! _& I/ r4 B, ~

8 _% F3 a* z% `$ D1 x3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。, D( s( z/ _& t. T) P

. ?5 C1 t# k3 ]4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。# X& h2 v" x( }( N5 e. ]( `
- H2 z8 ?# Y! g
' o) r; ?1 G4 a% l
前端逻辑处理流程大致如下:
3 O0 U* f. p& ?. R/ i) |5 k+ ^* O  c/ G# ~
调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:
4 [# k$ N/ M9 d% H9 F; l& I5 `window.addEventListener('load', async function() {6 @- w. n- X" h5 {7 B
  if (typeof window.bytom !== 'undefined') {; R$ @7 U2 ]8 z$ F1 A6 M3 b: E% c, x1 V/ @
    let networks = {) m9 ^2 Q* v3 y+ N
        solonet: ... // solonet bycoin url 4 i6 X& Y3 s2 D
        testnet: ... // testnet bycoin url
5 Y* @3 K3 g" ~$ U9 K* Y# Q        mainnet: ... // mainnet bycoin url $ w. E' c, D: Z3 r1 T
    };
! s0 F9 v9 v" n    ...
5 s) d' h: i  J5 O" J8 U* c7 \    startApp();
, k4 ]6 v& C* s, I1 q- g, y; F});
. {9 t9 c' B6 p( o$ {# Z) }8 p7 J" r7 s0 w5 z& ?( D
配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:/ K6 v; d& Z. s" X
var config = {
' k' Y, S6 ]! s    "solonet": {
; C4 L# Q+ x' C( V( _        ...         // contract arguments
6 S& I. V* K$ Q/ {0 B        "gas": 0.4  // btm fee
/ e5 j9 K! e1 O! Z    },
. E  q* N/ }  k% i    "testnet":{4 H, H, D; c6 x0 ?5 Z
        ...8 x9 w8 A' W2 j7 p. l. A
    },
+ |( S# w& ^- ?3 _    "mainnet":{
3 I3 x7 ]" ~& M9 h  L8 _9 E        .../ J4 |! c2 m$ \" p# {" N& j! ]9 l# t
    }
+ N2 N. g/ A% q+ W" g* ^}; Y# q1 c0 @) E# A

( I$ t% J3 [+ C前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。, t) ^. Y  ^, f1 l

  n( F( y/ c# Z" c7 @0 u7 Q' r构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:5 m. `, G6 ~3 l! O9 f
const input = []
" M& j3 l: V3 `; b2 V; pinput.push(spendUTXOAction(utxohash)); T' J$ N3 h( {9 ^* t
... // other input
! g9 L5 R2 ?9 v) E6 M, I1 Q8 h% C6 C; Gconst output = []- a& g5 v2 K8 @
output.push(controlProgramAction(amount, asset, program))
; `- C- z: S" ~6 D, i/ o... // other output- ]5 n5 E2 `2 E8 N( |( W; o

# c+ d! V( u# w/ S启动前端服务
2 }. T5 `4 ]$ B编译前端命令如下:  w: p+ }" [9 a7 a
npm run build5 b# U& m$ _( N
启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:! m; R* C1 R' w
npm start: B7 ]- ?" o8 F$ E) D8 Y
. o& L; ~2 s! J0 ]3 X' C# d  O
3 [& d/ r8 q. b/ r" ?9 z
DAPP缓冲服务器
- a7 d& a6 W2 V, X! ?$ ?! a" b- W* [缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。
( p+ f2 w3 w3 K# _6 O  t2 O. z缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:
' V; V$ \4 c" ^. o5 g$ e2 g# `6 ^4 U; \. y  \3 G4 L
编译bufferserver源代码
, U! a( f6 F5 X+ h  t按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:8 L7 Q' ~# u( M" d; c4 d
make all
$ g2 D$ A! v3 ?3 r  V编译完成之后,在target目录下会生成可执行文件api和updater。
- d8 a  y6 v  r1 Z% D" e; L7 e+ {+ f* _1 x' }' ^1 [# O' ^& u9 J" ~
启动服务
8 d! N/ g$ X' Z1 f% K使用root用户创建数据库和数据表,其命令如下:- B9 o/ r6 G# Q! D+ G
mysql -u root -p
5 A1 }( I5 Q% H7 q: N  _3 l修改配置文件config_local.json,配置说明参考README的config配置参数详解。( t  k6 |/ i# V$ L& p/ w: A& p- N
启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。+ ?" m' f5 p: B# W3 z- Z/ r' g
./target/api config_local.json
8 C/ W3 |* }' n2 j6 _./target/updater config_local.json( C' n0 u+ b2 z9 B
启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。
" D  T, Z3 I: X5 g, h附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16