本篇文章適合對區塊鏈應用感興趣或是想要經過函數計算服務進一步開發區塊鏈應用的新人。本文將結合阿里雲區塊鏈服務、阿里雲函數計算服務、阿里雲日誌服務 以及社區應用 Marbles,手把手教你們如何將阿里雲區塊鏈服務與阿里雲函數計算服務相結合,並進一步提供業務上的結合場景,供你們開拓思路。html
本文分爲如下幾部分:node
函數計算git
函數計算是事件驅動的全託管計算服務。使用函數計算,無需採購與管理服務器等基礎設施,只需編寫並上傳代碼。函數計算爲用戶準備好計算資源,彈性地可靠地運行任務,並提供日誌查詢、性能監控和報警等功能。藉助函數計算,能夠快速構建任何類型的應用和服務,而且只需爲任務實際消耗的資源付費。github
下圖爲函數計算工做流程:web
區塊鏈npm
區塊鏈能夠理解爲去中心的分佈式記帳系統,其是一種 分佈式、去中心化的計算與存儲架構 。區塊鏈經過某種方式來記錄數據,使用戶能夠信任區塊鏈系統記錄的數據。區塊鏈中的記帳節點會按照一致性協議記帳。記帳節點願意按照一致性協議記帳,是由於在一致性協議的設計中,誠實的記帳節點會獲得相應的獎賞,且誠實的記錄比惡意篡改記錄的收益更大。json
依託於區塊鏈網絡的可信度,衍生出了智能合約的概念。什麼是智能合約呢?現實生活中,買家與賣家要進行一筆交易,爲了保證交易的順利進行,雙方會簽定一份合約,合約中會聲明雙方各自的身份、權利以及義務。當交易出現糾紛時,買家與賣家根據當時簽定的合約經過法律的手段解決糾紛。這種方式的不足之處在於解決糾紛的過程須要第三方權威來仲裁以及須要大量時間。那麼,假使咱們如今有一位可信公正的交易代理人。賣家將商品交給代理人,買家與代理人雙方之間一手交錢一手交貨。若買家拒絕購買,代理人會將商品歸還給買家。買家也不會付了錢拿不到商品。智能合約就能夠充當這樣的代理人,其爲區塊鏈上一個包含合約代碼和存儲空間的虛擬帳戶,合約的代碼控制智能合約的行爲,合約的帳戶存儲合約的狀態。gulp
因爲有了智能合約,DApp (Decentralized Application 即去中心化應用)也應運而生。DApp 是運行在區塊鏈網絡上的應用軟件,其上運行的代碼咱們稱之爲智能合約。瀏覽器
Marbles 區塊鏈應用是一個 資產轉移 應用演示。在 Marbles 區塊鏈應用中多個用戶能夠建立並相互轉移彈珠。 ( 即彈珠就是資產轉移中的資產 )服務器
上圖中:
Marbles 區塊鏈應用代碼分紅三部分:
在 Marbles 應用中,當客戶端發送消息給服務端,服務端與區塊鏈網絡通訊的時序圖大致上以下圖所示:( 讀者對詳細過程感興趣,能夠閱讀 Github IBM-Blockchain/marbles )
其中,Peer 節點(對等節點) 存在於區塊鏈網絡中,擁有帳本而且可安裝鏈碼。Orderer 節點負責接收包含簽名的交易,對未打包的交易進行排序生成區塊,廣播給 Peer 節點。
上圖中:Client 以及 Server 是上文中所說的客戶端以及服務端。
假設說,如今有這麼一個業務場景,須要在每次 Marbles 應用有事件發生時,要對事件進行相應處理,且這部分的處理代碼會 常常迭代 。那麼,在區塊鏈應用更新須要較多時間的狀況下,經過函數計算來處理是較爲方便的。( 具體原因在下一節將會繼續探討 )
接下來,筆者將帶着你們模擬這個業務場景,擴展 Marbles Server 端代碼。在每次事件發生時,將事件信息打包並經過函數計算的 HTTP 觸發器,由函數計算來對事件信息作相應處理。
1. 準備工做
開通阿里雲日誌服務、函數計算服務、區塊鏈服務
2. 在阿里雲區塊鏈服務中建立組織、建立聯盟
3. 在阿里雲區塊鏈服務中建立通道
4. 部署 Marbles 應用以及鏈碼
參考 阿里雲區塊鏈服務開發指南
注意事項:nodejs 版本爲 v8
5. 下載並配置阿里雲函數計算開發工具 fun
$ npm install @alicloud/fun -g
fun config
,根據提示依次配置 Account ID
、Access Key Id
、Access Key Secret
以及 Default Region Name
。可參考:服務地址 、 建立 AccessKey 在項目根目錄下建立一個 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
上述文件作了以下事項:
marblesFC
服務marblesFC
服務配置了 test-log-project
日誌 Project 以及 test-log-store
日誌 LogStoremarblesFC
服務中建立了 processEvent
函數,併爲其設置入口函數爲 httpTrigger.js
文件中的 handler
方法processEvent
函數配置了 HTTP 觸發器,觸發器名爲 http-test
test-log-project
日誌 Project 以及 test-log-store
日誌 LogStorevar 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 端代碼
app.js
文件var https = require('https');
https模塊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 節點來負責調用。
以上三點就是筆者對於如何將區塊鏈服務與函數計算相結合的思考,有不許確的地方,歡迎你們指出。
本文爲雲棲社區原創內容,未經容許不得轉載。