Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom DAPP 开发流程

zmhg799417
185 0 0
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式、全节点钱包模式和兼容模式。8 S; l# ?; C0 }; @$ L+ @: U$ ?" F
插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web3框架注入到DAPP前端页面中,然后DApp通过Web3来与区块链节点通信。全节点钱包模式需要项目方同步并持有一个区块链节点,并对外提供一个浏览器环境与用户进行交互。兼容模式可以在插件钱包和全节点钱包下同时使用,即上述两种方式可以自由切换,安全性能相对较高。# s& O5 W& `' R0 E' f5 F: X8 _

0 Q7 M$ G% [$ h7 g接下来介绍的比原链DAPP的架构模式跟账户模型DAPP的插件钱包模式有些相似,都是由DAPP前端、插件钱包和合约程序共同组成,其中插件钱包需要连接去中心化的区块链服务器blockcenter,该服务器主要是为了管理插件钱包的相关信息。此外,比原链是UTXO模型的区块链系统,合约程序存在于无状态的UTXO中,如果要实现这样一个具体的DAPP,就需要在前端和后端多做一些逻辑的处理。$ f* O8 `' _/ c! i' p/ K
1. 编写、编译并实例化智能合约8 n0 ]& O3 N8 Y+ p7 I& c; I5 W/ ^
编写智能合约
2 [% u$ g& Z! a  [! M2 B2 t0 y) {比原链的虚拟机是图灵完备的,理论上可以实现任意图灵计算机能实现的操作。而Equity作为比原链的智能合约语言,使用Equity语言可以实现许多典型的金融模型案例,但是为了解决停机问题,比原链也设置了手续费的上限,因此用户在设计合约的时候做一下权衡。
$ w' q$ ^: W: r+ p5 s6 ]# N( o合约模板结构如下:8 U9 D5 d7 B0 e+ H' G
contract contract_name(...) locks valueAmount of valueAsset {
* ?1 o3 z( h/ Q# s( r4 s  clause clause_name(...) {
% K1 a* p# P, S& P$ h- d    ...# R9 P! ?+ K8 Q
    lock/unlock ...$ @2 g" b8 Q5 e0 U' S0 |8 ]
  }
; I2 a) ?- u3 X8 b; Z3 B( W  ...8 y8 |: E+ ~; h& X& ?
}
; f' W9 l  ?' MEquity语法结构简单,语句意思明确,有开发经验的童鞋一看基本能明白合约的意思。编写智能合约可以参考Equity合约介绍,文档中对Equity语言的语法和编译方法都做了详细的介绍。此外,文档还对一些典型的模板合约进行了介绍,开发者可以自己需求进行参考。
1 V3 J3 y& w& s0 S编译并实例化合约+ e9 z+ c0 Y4 g2 [8 S, y5 u
编译合约目前支持两种方式,一种是使用Equity编译工具,另一种是调用比原链中编译合约的RPC接口compile; 而合约实例化是为了将合约脚本按照用户设定的参数进行锁定,编译并实例化合约可以参考编译并实例化合约的上半部分说明,该文档不仅介绍了合约的参数构造说明,还对编译合约的步骤进行详细说明。而编译器以及相关工具位于Equity编译器中,是使用go语言开发的,用户可以下载源代码并编译使用。; W( W, a( H7 s- i, g+ E1 `6 ^- Y6 ?
工具编译和实例化示例如下:
1 G! b! ]+ u% L' q: R5 F// compile# O  ?8 r' i9 v: I; j( ~
./equity [contract_name] --bin
6 _1 q# Y% t5 F% n- E// instance
5 i+ C0 \0 N! D! L./equity [contract_name] --instance [arguments ...]
4 H5 O# ^! F4 B4 s6 Z2. 部署合约
4 h- u" ]6 z& O" `- @* z部署合约即发送合约交易,调用比原链的build-transaction接口将指定数量的资产发送到合约program中,只需将输出output中接收方control_program设置为指定合约即可。用户可以参考合约交易说明中的锁定合约章节,交易的构造按照文档中介绍进行参考即可。如果合约交易发送成功,并且交易已经成功上链,便可以通过调用API接口list-unspent-outputs来查找该合约的UTXO。5 Z, e- F1 j" F7 R7 U
部署合约交易模板大致如下:( s; j7 J5 k8 v
{. b( Y( }% w- B2 Y( D; W
  "actions": [$ {' K& i+ B% {# }1 o
    // inputs) X& }- b6 X$ Y
    {* u0 a, |, _! y6 h
        // btm fee
' O1 |! {" i% n. A8 V    },
  K9 T6 _; v7 ^/ m- s; x2 U    {, w& Y8 @" O; q
        amount, asset, spend_account
; Y- @5 J" l. W        // spend user asset  u! [4 J8 ]( q
    },+ T( c* `4 e$ W& }
    // outputs
: o+ T/ O9 o" }% s    {
/ m! x6 ]3 `% [2 T% v        amount, asset, contract_program$ b9 F; b- U. W% Y( _
        // receive contract program with instantiated result
, x% S% s. o1 f8 v    }5 d8 S+ i, d9 }6 ?6 ]
  ],
4 r0 O; B, ?( k* ~. I. _  ...
3 e) V, A. k  ~4 B; P5 g2 v/ a}: V! K- l+ P' |
3. 搭建DAPP架构! x% v+ l# F* [2 B4 z% _: o1 \
Bytom的blockcenter服务器是官方开发的去中心化插件钱包服务器,开发者可以按照相关API接口来调用即可。比原链的DAPP总体框架模型如下:
" X* E! ~) s9 w% h5 |* F: g- t, p) L' C0 z4 b
DAPP前端* w0 W8 I0 U2 g7 Y( }( F' B) k
搭建DAPP前端主要包含两个方面:一个是前端与插件钱包的交互,另一个是前端的逻辑处理、以及与缓冲服务器的交互。插件钱包是与区块链节点服务器通信的窗口,一个DAPP为了跟区块链节点进行通信,需要通过借助插件来与后台服务器节点进行交互。比原的插件钱包除了与后台服务器进行交互之外,还包含一些本地业务逻辑处理的接口API,具体内容可以参考一下DAPP开发者向导。由于比原链是基于UTXO模型的区块链系统,交易是由多输入和多输出构成的结构,并且交易输入或输出的位置也需要按照顺序来排列,因此开发DAPP需要前端处理一些构建交易的逻辑。除此之外,合约中的lock-unlock语句中涉及到数量的计算需要根据抽象语法树来进行预计算,计算的结果将用于构建交易,而verify、if-else等其他语句类型也需要进行相关的预校验,从而防止用户在执行合约的时候报错。8 g9 }) i: k9 U3 u3 s
从功能层面来说,前端主要包含页面的设计、插件的调用、合约交易逻辑的处理、缓冲服务器的交互等。接下来对这几个重要的部分展开说明:- j; _5 n+ a; _+ t/ |" K( n. O
+ A/ ~: t. q& Y1 i6 Y! U6 i
1)前端页面的设计主要是网页界面的设计,这个部分开发者可以自己选择页面模式
" }; ?  W: o: ~3 ~
+ l6 v, m$ M( G7 N9 f2)插件钱包已经进行了结构化的封装,并且提供了外部接口给DAPP开发者调用,开发者只需要将插件的参数按照规则进行填充,具体请参考DAPP开发者向导2 s) d5 m& Q2 t) c* Q% K2 g1 R
7 V7 t# d/ H5 }# l! H* W% }
3)比原链的合约交易是多输入多输出的交易结构,前端需要进行一些预判断逻辑的处理,然后再选择合适的合约交易模板结构。
  v' ?) H$ T, @/ V2 k0 M5 F& E( P! B
4)DAPP的插件连接的是去中心化的bycoin服务器,该服务器从比原节点服务器上同步的所有区块信息和交易信息,该部分主要是在插件钱包层进行了高度的封装,用户只需按照接口调用即可。除此之外,需要开发者搭建一个缓冲服务器,不仅可以在管理合约UTXO层面做一些性能方面的处理,而且还可以为DAPP做一些数据存储。开发者可以根据实际需求来开发一些RPC请求接口,然后在前端页面设置相关条件来触发这些API的调用。
& Z9 }. f% k7 x) `
& E! E" P8 M$ P7 Z$ B& A3 [; [# h3 W! q5 m0 S: @& I
前端逻辑处理流程大致如下:
8 |. _- \; Y# I# I7 v. n; o6 r# `/ @3 m& I
调用插件,比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide,其网络配置如下:
5 c! @6 S# @0 z/ d1 i+ }' T! kwindow.addEventListener('load', async function() {
7 T" Y. [1 b- O+ E: P6 j! `3 s  if (typeof window.bytom !== 'undefined') {
5 E* s$ b/ x) B8 }- x& |4 V    let networks = {
: Q/ w+ ~5 K# {0 c0 l$ v  M        solonet: ... // solonet bycoin url " Q+ F- L4 S/ M0 |
        testnet: ... // testnet bycoin url
2 B0 r1 H1 _% r, G        mainnet: ... // mainnet bycoin url - h& G4 D$ V( R) E
    };
7 U+ E: N$ S6 w7 }# |! }    ...8 w8 N* v( p+ \
    startApp();! k5 C8 @+ X8 U
});/ e# ^) k; {2 k- k& _% D. C
/ c9 U! k! ~! y# Z: T/ [
配置合约参数,可以采用文件配置的方式,该步骤是为了让前端得到需要用到的一些已经固定化的合约参数,其前端配置文件为configure.json.js,其示例模型如下:
# A1 I! X. Y, i; Fvar config = {
: C9 U- {& n( S    "solonet": {
- I; R9 [  g1 N/ }$ t) ]        ...         // contract arguments
$ Q* o4 \4 k7 o& x2 x# q        "gas": 0.4  // btm fee( ~. D' q9 w$ j, A. y
    },# p3 A7 ]- E$ N  q7 |
    "testnet":{/ ?; t  o* r1 t9 A2 {. A4 ^
        ...) }# n& j( V0 ]9 u5 F! _! ?
    },6 b, Y' M# [5 R) o& _
    "mainnet":{  a0 W0 L% a9 E
        ...
! D2 Z# a5 \0 o4 M% W1 k" n# u) S- j1 x    }" {1 L: N! A" C) p* T
}. q, G( o- @9 P- H$ l% C9 E0 q
2 [" `- H8 f' ^, H: l  W( [2 X
前端预计算处理,如果合约中包含lock-unlock语句,并且Amount是一个数值表达式,那么前端来提取计算表达式并进行相应的预计算。此外,前端还需要预判下所有可验证的verify语句,从而判定交易是否可行,因为一旦前端对这些验证失败,合约将必然验证失败。此外,如果define或assign语句涉及的变量,前端也需预计算这些变量的值。
  s- g/ Z& E1 V3 h1 B0 D6 F5 q! g7 n6 V( H  J, I! g! {
构建合约交易模板,由于解锁合约是解锁lock语句条件,构造交易需要根据lock语句或unlock语句来进行变换。解锁合约交易是由inputs和outputs构成,交易的第一个input输入一般都是是固定的,即合约UTXO的hash值,除此之外,其他输入输出都需要根据DAPP中的实际合约来进行变更,其模型大致如下:
* u2 r, |$ [1 \1 M# E5 \& x. dconst input = []
/ ~: u/ |, ?) V1 a( k2 ~; binput.push(spendUTXOAction(utxohash))$ `9 l! L2 ~9 H' D7 b
... // other input# [6 ]3 {0 H, G
const output = []
( l5 v9 x! `; N  L& boutput.push(controlProgramAction(amount, asset, program)): H) S; }: U, D9 b% A
... // other output
, m$ u$ R9 h0 M# R  N  u6 z9 M% B% s: d) |* c2 q
启动前端服务, I  v! c# f5 t$ z% j/ w4 p
编译前端命令如下:
- E+ a" s: M. |) L! B7 cnpm run build" h3 i7 ~0 u+ @$ C0 x9 u5 t- |. T3 Y) ~
启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:1 g1 \! n- v* j& U: H
npm start5 F- c! x- ]' a5 e8 T
$ [+ a  k7 H7 A/ O: B8 r( z
7 `. O( X% N" Q" a
DAPP缓冲服务器
3 L7 F/ \. D6 H缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。bycoin服务器是比原链的去中心化钱包服务器,缓冲服务器的UTXO跟它是同步更新的,比原官方插件钱包默认连接的就是该服务器。尽管bycoin服务器的也对比原链的所有UTXO进行了管理,但是由于UTXO数量比较大,如果直接在该层面处理会导致DAPP性能不佳,所以建议用户自己构建自己的缓冲服务器做进一步优化处理。此外,DAPP开发者也可以搭建了自己的去中心化钱包服务器,并且自己开发相关的插件。2 B1 e: e- c% l- m- ?0 a0 [* z( {
缓冲服务器架构可以参考一下bufferserver案例的源代码,其编译和启动步骤如下:
% T% n* {4 ?% I9 X5 h5 O! n6 M
5 H* w4 T$ s% @# B: w% P1 i4 p- B编译bufferserver源代码
" M+ R0 u0 L- r7 W按照README安装部署服务需要的软件包Mysql和Redis,然后下载源代码并编译:
9 R! X( z" ~9 Q6 \; d/ Fmake all, E) N' n, g1 f3 b5 L  c
编译完成之后,在target目录下会生成可执行文件api和updater。) o! D3 x& R; t' O) J8 L! s
" j9 }( h7 C' L
启动服务. w) _' K9 C$ P
使用root用户创建数据库和数据表,其命令如下:" v& R4 N5 r9 x3 S# ^8 {3 y1 S. v
mysql -u root -p
* {1 m/ T7 [, O' [( f! r修改配置文件config_local.json,配置说明参考README的config配置参数详解。
. I6 Q9 j0 I0 G" _5 u9 R, T% K0 L启动api和updater服务器,其中api是提供JSON RPC请求的服务进程,updater是提供同步blockcenter和区块链浏览器数据请求的服务进程。" t4 o& t; O, X* k4 a, i
./target/api config_local.json
$ X, b5 o, `4 g: j# o; S./target/updater config_local.json4 v. }% e* e( q9 h0 j5 X
启动缓冲服务器之后,便可以启动前端服务,然后打开DAPP的网页URL即可使用。
2 @5 V+ ^" I9 k. d; c" Y. u0 U8 \& _9 V附:缓冲服务器的JSON RPC接口可以参考wiki接口说明。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

zmhg799417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16