從目前已經發布的DAPP
來看,DAPP
架構大致可以分成3種類型:插件錢包模式、全節點錢包模式和兼容模式。
- 插件錢包模式是藉助封裝了錢包的瀏覽器插件通過
RPC
協議與區塊鏈節點通信,插件在運行時會將Web3
框架注入到DAPP
前端頁面中,然後DApp
通過Web3
來與區塊鏈節點通信。 - 全節點錢包模式需要項目方同步並持有一個區塊鏈節點,並對外提供一個瀏覽器環境與用戶進行交互。
- 兼容模式可以在插件錢包和全節點錢包下同時使用,即上述兩種方式可以自由切換,安全性能相對較高。
接下來介紹的比原鏈DAPP
的架構模式跟賬戶模型DAPP
的插件錢包模式有些相似,都是由DAPP
前端、插件錢包和合約程序共同組成,其中插件錢包需要連接去中心化的區塊鏈服務器blockcenter
,該服務器主要是爲了管理插件錢包的相關信息。此外,比原鏈是UTXO
模型的區塊鏈系統,合約程序存在於無狀態的UTXO
中,如果要實現這樣一個具體的DAPP
,就需要在前端和後端多做一些邏輯的處理。
1. 編寫、編譯並實例化智能合約
編寫智能合約
比原鏈的虛擬機是圖靈完備的,理論上可以實現任意圖靈計算機能實現的操作。而Equity
作爲比原鏈的智能合約語言,使用Equity
語言可以實現許多典型的金融模型案例,但是爲了解決停機問題,比原鏈也設置了手續費的上限,因此用戶在設計合約的時候做一下權衡。
合約模板結構如下:
contract contract_name(...) locks valueAmount of valueAsset {
clause clause_name(...) {
...
lock/unlock ...
}
...
}
Equity
語法結構簡單,語句意思明確,有開發經驗的童鞋一看基本能明白合約的意思。編寫智能合約可以參考Equity
合約介紹,文檔中對Equity
語言的語法和編譯方法都做了詳細的介紹。此外,文檔還對一些典型的模板合約進行了介紹,開發者可以自己需求進行參考。
編譯並實例化合約
編譯合約目前支持兩種方式,一種是使用Equity
編譯工具,另一種是調用比原鏈中編譯合約的RPC
接口compile
; 而合約實例化是爲了將合約腳本按照用戶設定的參數進行鎖定,編譯並實例化合約可以參考編譯並實例化合約的上半部分說明,該文檔不僅介紹了合約的參數構造說明,還對編譯合約的步驟進行詳細說明。而編譯器以及相關工具位於Equity
編譯器中,是使用go
語言開發的,用戶可以下載源代碼並編譯使用。
工具編譯和實例化示例如下:
// compile
./equity [contract_name] --bin
// instance
./equity [contract_name] --instance [arguments ...]
2. 部署合約
部署合約即發送合約交易,調用比原鏈的build-transaction
接口將指定數量的資產發送到合約program
中,只需將輸出output
中接收方control_program
設置爲指定合約即可。用戶可以參考合約交易說明中的鎖定合約章節,交易的構造按照文檔中介紹進行參考即可。如果合約交易發送成功,並且交易已經成功上鍊,便可以通過調用API
接口list-unspent-outputs
來查找該合約的UTXO
。
部署合約交易模板大致如下:
{
"actions": [
// inputs
{
// btm fee
},
{
amount, asset, spend_account
// spend user asset
},
// outputs
{
amount, asset, contract_program
// receive contract program with instantiated result
}
],
...
}
3. 搭建DAPP架構
Bytom的blockcenter
服務器是官方開發的去中心化插件錢包服務器,開發者可以按照相關API
接口來調用即可。比原鏈的DAPP
總體框架模型如下:
DAPP前端
搭建DAPP
前端主要包含兩個方面:一個是前端與插件錢包的交互,另一個是前端的邏輯處理、以及與緩衝服務器的交互。插件錢包是與區塊鏈節點服務器通信的窗口,一個DAPP
爲了跟區塊鏈節點進行通信,需要通過藉助插件來與後臺服務器節點進行交互。比原的插件錢包除了與後臺服務器進行交互之外,還包含一些本地業務邏輯處理的接口API
,具體內容可以參考一下DAPP開發者嚮導。由於比原鏈是基於UTXO
模型的區塊鏈系統,交易是由多輸入和多輸出構成的結構,並且交易輸入或輸出的位置也需要按照順序來排列,因此開發DAPP
需要前端處理一些構建交易的邏輯。除此之外,合約中的lock-unlock
語句中涉及到數量的計算需要根據抽象語法樹來進行預計算,計算的結果將用於構建交易,而verify
、if-else
等其他語句類型也需要進行相關的預校驗,從而防止用戶在執行合約的時候報錯。
從功能層面來說,前端主要包含頁面的設計、插件的調用、合約交易邏輯的處理、緩衝服務器的交互等。接下來對這幾個重要的部分展開說明:
- 1)前端頁面的設計主要是網頁界面的設計,這個部分開發者可以自己選擇頁面模式
- 2)插件錢包已經進行了結構化的封裝,並且提供了外部接口給
DAPP
開發者調用,開發者只需要將插件的參數按照規則進行填充,具體請參考DAPP開發者嚮導 - 3)比原鏈的合約交易是多輸入多輸出的交易結構,前端需要進行一些預判斷邏輯的處理,然後再選擇合適的合約交易模板結構。
- 4)DAPP的插件連接的是去中心化的
bycoin
服務器,該服務器從比原節點服務器上同步的所有區塊信息和交易信息,該部分主要是在插件錢包層進行了高度的封裝,用戶只需按照接口調用即可。除此之外,需要開發者搭建一個緩衝服務器,不僅可以在管理合約UTXO
層面做一些性能方面的處理,而且還可以爲DAPP
做一些數據存儲。開發者可以根據實際需求來開發一些RPC
請求接口,然後在前端頁面設置相關條件來觸發這些API
的調用。
前端邏輯處理流程大致如下:
-
調用插件,比原的
chrome
插件源碼位於Bytom-JS-SDK,開發比原DAPP
時調用插件的說明可以參考Dapp Developer Guide,其網絡配置如下:window.addEventListener('load', async function() { if (typeof window.bytom !== 'undefined') { let networks = { solonet: ... // solonet bycoin url testnet: ... // testnet bycoin url mainnet: ... // mainnet bycoin url }; ... startApp(); });
-
配置合約參數,可以採用文件配置的方式,該步驟是爲了讓前端得到需要用到的一些已經固定化的合約參數,其前端配置文件爲
configure.json.js
,其示例模型如下:var config = { "solonet": { ... // contract arguments "gas": 0.4 // btm fee }, "testnet":{ ... }, "mainnet":{ ... } }
- 前端預計算處理,如果合約中包含
lock-unlock
語句,並且Amount
是一個數值表達式,那麼前端來提取計算表達式並進行相應的預計算。此外,前端還需要預判下所有可驗證的verify
語句,從而判定交易是否可行,因爲一旦前端對這些驗證失敗,合約將必然驗證失敗。此外,如果define
或assign
語句涉及的變量,前端也需預計算這些變量的值。 -
構建合約交易模板,由於解鎖合約是解鎖
lock
語句條件,構造交易需要根據lock
語句或unlock
語句來進行變換。解鎖合約交易是由inputs
和outputs
構成,交易的第一個input
輸入一般都是是固定的,即合約UTXO
的hash
值,除此之外,其他輸入輸出都需要根據DAPP中的實際合約來進行變更,其模型大致如下:const input = [] input.push(spendUTXOAction(utxohash)) ... // other input const output = [] output.push(controlProgramAction(amount, asset, program)) ... // other output
-
啓動前端服務
編譯前端命令如下:
npm run build
啓動之前需要先啓動
bufferserver
緩衝服務器,然後再啓動前端服務,其前端啓動命令如下:npm start
DAPP緩衝服務器
緩衝服務器主要是爲了在管理合約UTXO
層面做一些效率方面的處理,包括了對bycoin
服務器是如何同步請求的,此外對DAPP
的相關交易記錄也進行了存儲。bycoin
服務器是比原鏈的去中心化錢包服務器,緩衝服務器的UTXO
跟它是同步更新的,比原官方插件錢包默認連接的就是該服務器。儘管bycoin
服務器的也對比原鏈的所有UTXO
進行了管理,但是由於UTXO
數量比較大,如果直接在該層面處理會導致DAPP
性能不佳,所以建議用戶自己構建自己的緩衝服務器做進一步優化處理。此外,DAPP
開發者也可以搭建了自己的去中心化錢包服務器,並且自己開發相關的插件。
緩衝服務器架構可以參考一下bufferserver案例的源代碼,其編譯和啓動步驟如下:
-
編譯
bufferserver
源代碼按照
README
安裝部署服務需要的軟件包Mysql
和Redis
,然後下載源代碼並編譯:make all
編譯完成之後,在
target
目錄下會生成可執行文件api
和updater
。 -
啓動服務
使用
root
用戶創建數據庫和數據表,其命令如下:mysql -u root -p < database/dump.sql
修改配置文件
config_local.json
,配置說明參考README
的config
配置參數詳解。啓動
api
和updater
服務器,其中api
是提供JSON RPC
請求的服務進程,updater
是提供同步blockcenter
和區塊鏈瀏覽器數據請求的服務進程。./target/api config_local.json ./target/updater config_local.json
啓動緩衝服務器之後,便可以啓動前端服務,然後打開
DAPP
的網頁URL
即可使用。附:緩衝服務器的
JSON RPC
接口可以參考wiki
接口說明。
Bytom DAPP實例
Bytom DAPP
實例說明,請參考儲蓄分紅DAPP