二十分鐘教你如何將區塊鏈應用與函數計算相結合

前言

本篇文章適合對區塊鏈應用感興趣或是想要經過函數計算服務進一步開發區塊鏈應用的新人。本文將結合阿里雲區塊鏈服務、阿里雲函數計算服務、阿里雲日誌服務 以及社區應用 Marbles,手把手教你們如何將阿里雲區塊鏈服務與阿里雲函數計算服務相結合,並進一步提供業務上的結合場景,供你們開拓思路。html

本文分爲如下幾部分:node

  • 函數計算與區塊鏈
  • Marbles 區塊鏈應用介紹
  • Marbles 區塊鏈應用結合函數計算進行擴展現例
  • 區塊鏈應用與函數計算在業務上結合的場景與價值探討

函數計算與區塊鏈

函數計算git

函數計算是事件驅動的全託管計算服務。使用函數計算,無需採購與管理服務器等基礎設施,只需編寫並上傳代碼。函數計算爲用戶準備好計算資源,彈性地可靠地運行任務,並提供日誌查詢、性能監控和報警等功能。藉助函數計算,能夠快速構建任何類型的應用和服務,而且只需爲任務實際消耗的資源付費。github

下圖爲函數計算工做流程:web

區塊鏈npm

區塊鏈能夠理解爲去中心的分佈式記帳系統,其是一種 分佈式、去中心化的計算與存儲架構 。區塊鏈經過某種方式來記錄數據,使用戶能夠信任區塊鏈系統記錄的數據。區塊鏈中的記帳節點會按照一致性協議記帳。記帳節點願意按照一致性協議記帳,是由於在一致性協議的設計中,誠實的記帳節點會獲得相應的獎賞,且誠實的記錄比惡意篡改記錄的收益更大。json

依託於區塊鏈網絡的可信度,衍生出了智能合約的概念。什麼是智能合約呢?現實生活中,買家與賣家要進行一筆交易,爲了保證交易的順利進行,雙方會簽定一份合約,合約中會聲明雙方各自的身份、權利以及義務。當交易出現糾紛時,買家與賣家根據當時簽定的合約經過法律的手段解決糾紛。這種方式的不足之處在於解決糾紛的過程須要第三方權威來仲裁以及須要大量時間。那麼,假使咱們如今有一位可信公正的交易代理人。賣家將商品交給代理人,買家與代理人雙方之間一手交錢一手交貨。若買家拒絕購買,代理人會將商品歸還給買家。買家也不會付了錢拿不到商品。智能合約就能夠充當這樣的代理人,其爲區塊鏈上一個包含合約代碼和存儲空間的虛擬帳戶,合約的代碼控制智能合約的行爲,合約的帳戶存儲合約的狀態。gulp

因爲有了智能合約,DApp (Decentralized Application 即去中心化應用)也應運而生。DApp 是運行在區塊鏈網絡上的應用軟件,其上運行的代碼咱們稱之爲智能合約。瀏覽器

Marbles 區塊鏈應用介紹

Marbles 區塊鏈應用是一個 資產轉移 應用演示。在 Marbles 區塊鏈應用中多個用戶能夠建立並相互轉移彈珠。 ( 即彈珠就是資產轉移中的資產 )服務器

上圖中:

  • Amy、Alice、Ava 所在的小長方形是她們每一個人的帳戶
  • 小長方形中的圓形彈珠是每一個人帳戶中的資產,彈珠的顏色和大小是資產的屬性
  • 點擊小長方形中的加號是爲某個帳戶建立彈珠(資產)
  • 將某個小長方形中的彈珠拖拽到右上方的垃圾桶中,是爲某個帳戶刪除彈珠(資產)
  • 將某個彈珠從一個小長方形拖拽到到另外一個小長方形,是彈珠(資產)的轉移
  • 每一步的操做會在下方的 BLOCKS 建立一個新的小正方形,這個小正方形就表明包含交易內容的區塊

Marbles 區塊鏈應用代碼分紅三部分:

  1. 鏈碼 - 區塊鏈網絡中,對等節點所運行的代碼。鏈碼在這次介紹的 Marbles 應用中的主要做用是處理建立以及轉移彈珠的邏輯。
  2. 客戶端 - 瀏覽器中運行的代碼,負責 Marbles 應用頁面的渲染與交互。
  3. 服務端 - 服務器中運行的代碼,充當 Marbles 應用與區塊鏈網絡之間的橋樑,其與客戶端以及區塊鏈網絡中運行着鏈碼的節點進行通訊。

在 Marbles 應用中,當客戶端發送消息給服務端,服務端與區塊鏈網絡通訊的時序圖大致上以下圖所示:( 讀者對詳細過程感興趣,能夠閱讀 Github IBM-Blockchain/marbles )
其中,Peer 節點(對等節點) 存在於區塊鏈網絡中,擁有帳本而且可安裝鏈碼。Orderer 節點負責接收包含簽名的交易,對未打包的交易進行排序生成區塊,廣播給 Peer 節點。

上圖中:Client 以及 Server 是上文中所說的客戶端以及服務端。

  1. 當用戶建立或轉移彈珠時,Client 客戶端觸發相應事件,並向 Server 服務端發起請求。
  2. Server 接收到事件信息後,首先會構建提案(也就是交易),提案是將事件信息進行封裝,好比:這次交易的兩方以及交易內容是什麼。
  3. Server 將構建好的提案發送給區塊鏈網絡中的一個 Peer 節點,由 Peer 節點來對提案進行模擬,校驗其合法性。爲何要這麼作呢?由於鏈碼的做用就是處理交易邏輯,而鏈碼安裝在 Peer 節點上,並無安裝在 Server 上。
  4. 若是 Peer 節點模擬提案成功,認爲其合法,則會對提案進行背書,並向 Server 返回背書後的提案。背書能夠理解爲,當咱們去購買東西並忘記帶現金,付給對方一張 別人 給的支票。對方懷疑支票不可兌現的時候,咱們在支票上簽字並代表若這張 他人 給的支票不能兌換,則能夠來找咱們要現金。這個簽字的動做就是背書,聲明對事物或被承認人的支持。
  5. Server 將背書後的提案發送給 Orderer 節點。
  6. Orderer 節點對提案進行排序並打包進區塊,將區塊廣播給區塊鏈網絡中的全部 Peer 節點。

Marbles 區塊鏈應用結合函數計算進行擴展現例

假設說,如今有這麼一個業務場景,須要在每次 Marbles 應用有事件發生時,要對事件進行相應處理,且這部分的處理代碼會 常常迭代 。那麼,在區塊鏈應用更新須要較多時間的狀況下,經過函數計算來處理是較爲方便的。( 具體原因在下一節將會繼續探討 )

接下來,筆者將帶着你們模擬這個業務場景,擴展 Marbles Server 端代碼。在每次事件發生時,將事件信息打包並經過函數計算的 HTTP 觸發器,由函數計算來對事件信息作相應處理。

1. 準備工做

開通阿里雲日誌服務、函數計算服務、區塊鏈服務

2. 在阿里雲區塊鏈服務中建立組織、建立聯盟

3. 在阿里雲區塊鏈服務中建立通道

  • 點擊相應組織
  • 點擊通道
  • 點擊添加通道,填寫名稱與組織,並建立
  • 點擊新建立的通道右側的待審批連接,贊成審批

4. 部署 Marbles 應用以及鏈碼

參考 阿里雲區塊鏈服務開發指南
注意事項:nodejs 版本爲 v8

5. 下載並配置阿里雲函數計算開發工具 fun

  • fun 是一個 Node.js 編寫的命令行工具,經過 npm 進行安裝:$ npm install @alicloud/fun -g
  • 經過在命令行輸入 fun config,根據提示依次配置 Account IDAccess Key IdAccess Key Secret 以及 Default Region Name。可參考:服務地址 、 建立 AccessKey
  • 配置 template.yml

在項目根目錄下建立一個 template.yml 文件:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  marblesFC: # 服務名稱
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: 'fc test'
      LogConfig:  # 日誌配置
        Project: test-log-project  # 日誌 Project
        Logstore: test-log-store   # 日誌 LogStore
    processEvent: # 函數名
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: httpTrigger.handler # 文件名.方法名
        Runtime: nodejs8
        CodeUri: './'
        Timeout: 60
      Events:
        http-test: # 觸發器名
          Type: HTTP # 觸發器類型
          Properties:
              AuthType: ANONYMOUS
              Methods: ['GET', 'POST', 'PUT']
  test-log-project:  #  LogProject 名稱
    Type: 'Aliyun::Serverless::Log'
    Properties:
      Description: 'just for test'
    test-log-store:    # LogStore 名稱
      Type: 'Aliyun::Serverless::Log::Logstore'
      Properties:
        TTL: 10
        ShardCount: 1

上述文件作了以下事項:

  1. 在函數計算中建立了 marblesFC 服務
  2. 爲 marblesFC 服務配置了 test-log-project 日誌 Project 以及 test-log-store 日誌 LogStore
  3. 在 marblesFC 服務中建立了 processEvent 函數,併爲其設置入口函數爲 httpTrigger.js 文件中的 handler 方法
  4. 爲 processEvent 函數配置了 HTTP 觸發器,觸發器名爲 http-test
  5. 建立了 test-log-project 日誌 Project 以及 test-log-store 日誌 LogStore
  • 在項目根目錄下建立 httpTrigger.js 文件

var getRawBody = require('raw-body')
module.exports.handler = function (request, response, context) {
  // get request info
  getRawBody(request, function (err, data) {
    var params = {
      path: request.path,
      queries: request.queries,
      headers: request.headers,
      method: request.method,
      body: data,
      url: request.url,
      clientIP: request.clientIP,
    }
    // you can deal with your own logic here
    console.log(JSON.stringify(params.queries))
    // set response
    var respBody = new Buffer.from(JSON.stringify(params));
    // var respBody = new Buffer( )
    response.setStatusCode(200)
    response.setHeader('content-type', 'application/json')
    response.send(respBody)
  })
};
  • 在項目根目錄下執行 fun deploy 進行部署
  • 在阿里雲函數計算控制檯中,進入到 marblesFC 服務下的 processEvent 函數,在代碼執行頁面記錄下調用 HTTP 觸發器的地址

6. 修改 Marbles Server 端代碼

  1. 打開 Marbles 源代碼根目錄文件夾下的 app.js 文件
  2. 添加 var https = require('https'); https模塊
  3. 修改 setupWebSocket 函數

function setupWebSocket() {
    console.log('------------------------------------------ Websocket Up ------------------------------------------');
    wss = new ws.Server({ server: server }); // start the websocket now
    wss.on('connection', function connection(ws) {

      // -- Process all websocket messages -- //
      ws.on('message', function incoming(message) {
        console.log(' ');
        console.log('-------------------------------- Incoming WS Msg --------------------------------');
        logger.debug('[ws] received ws msg:', message);
        var data = null;
        try {
          data = JSON.parse(message); // it better be json
        } catch (e) {
          logger.debug('[ws] message error', message, e.stack);
        }

        // --- [5] Process the ws message  --- //
        if (data && data.type == 'setup') { // its a setup request, enter the setup code
          logger.debug('[ws] setup message', data);
          startup_lib.setup_ws_steps(data); // <-- open startup_lib.js to view the rest of the start up code

        } else if (data) { // its a normal marble request, pass it to the lib for processing
          https.get("此處填寫觸發 HTTP 觸發器的 URL 地址?type="+data.type, function(res){
            console.log('test http trigger');
          });
          ws_server.process_msg(ws, data); // <-- the interesting "blockchainy" code is this way (websocket_server_side.js)
        }
      });

      // log web socket errors
      ws.on('error', function (e) { logger.debug('[ws] error', e); });

      // log web socket connection disconnects (typically client closed browser)
      ws.on('close', function () { logger.debug('[ws] closed'); });

      // whenever someone connects, tell them our app's state
      ws.send(JSON.stringify(ws_server.build_state_msg())); // tell client our app state
    });

    // --- Send a message to all connected clients --- //
    wss.broadcast = function broadcast(data) {
      var i = 0;
      wss.clients.forEach(function each(client) { // iter on each connection
        try {
          logger.debug('[ws] broadcasting to clients. ', (++i), data.msg);
          client.send(JSON.stringify(data)); // BAM, send the data
        } catch (e) {
          logger.debug('[ws] error broadcast ws', e);
        }
      });
    };

    ws_server.setup(wss, null);
  }

7. 啓動 Marbles

在控制檯中進入 Marbles 項目,經過 gulp marbles_baas 啓動 Marbles 應用

8. 建立彈珠或轉移彈珠

試着在瀏覽器中建立彈珠或者用鼠標拖拽轉移彈珠

9. 查看日誌

對 Marbles 應用作了相應操做後,進入阿里雲日誌服務 test-log-project Project 下的 test-log-store LogStore,查看日誌

咱們看到當 Marbles Server 接收到事件後,會觸發 HTTP 觸發器,由函數計算 FC 來對事件作相應處理。( 簡單起見,demo 的處理目前僅僅是記錄日誌,讀者們能夠自行擴展 )

區塊鏈應用與函數計算在業務上結合的場景與價值探討

經過製做上面的 demo,相信你們如今對於如何將區塊鏈應用與函數計算相結合有了必定的認識。接下來,就讓咱們一塊兒探討下,區塊鏈應用與函數計算在業務上有哪些結合的場景與價值。

下圖是最原始的 Fabric SDK 時序圖

爲了讓讀者方便理解,咱們仍舊使用 Marbles 應用的時序圖,讀者能夠將 Marbles 應用中的 Server 理解爲 Fabric SDK 時序圖中的 Application,

在筆者看來,函數計算能夠與區塊鏈應用相結合的場景主要有如下三點:

1. 處理事件

處理事件的場景剛剛在 demo 中各位讀者想必已經體驗過了。那麼,爲何筆者倡導用函數計算來處理事件呢?

經過函數計算能夠將每一次的事件進行相應的處理,處理完成後發送給日誌服務。同時,還能夠在函數計算中設定定時觸發器,在指定時間內,再次統計事件的信息,由此對區塊鏈狀態進行一個數據分析。

而關於這種方式的統計邏輯,頗有多是須要常常迭代的。所以,不適合將其邏輯放入區塊鏈應用中,而是更適合放在小巧易迭代的函數計算場景中。

2. 附加業務

考慮一個這樣的場景:如今 X 公司推出了一款新的支付 App,爲了鼓勵用戶使用該公司的 App,該公司對外宣傳當用戶用該公司的 App 成功完成交易後,該公司會送大量優惠券以及積分。若該 App 是一款區塊鏈應用,那麼把優惠活動的業務邏輯放在哪裏最合適呢?

筆者目前以爲是放在 Orderer 將交易打包成區塊並廣播的時候最合適,由於優惠活動的業務邏輯是常常會變化的,這類業務邏輯能夠統稱爲附加業務,將附加業務抽象爲一個個函數並放在函數計算中,容易更新迭代。

3. 驗證交易

Peer 節點在模擬提案時,如果有複雜多變的邏輯,能夠放入函數計算中,由 Peer 節點來負責調用。

以上三點就是筆者對於如何將區塊鏈服務與函數計算相結合的思考,有不許確的地方,歡迎你們指出。



本文做者:澤塵

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索