本文探討區塊鏈技術在無伺服器架構中的應用,並以智慧合約的實作案例說明整合流程。首先,我們會以 Solidity 語言撰寫一個用於管理手機號碼註冊資訊的智慧合約,並使用 Truffle 框架將其佈署至以太坊區塊鏈網路。接著,示範如何使用 WebHook 與已佈署的智慧合約進行互動,以查詢手機號碼的註冊資訊。此外,本文也介紹如何使用 Chromeless 自動化瀏覽器操作,將舊有的 UI 系統包裝成 OpenFaaS 函式,並與 WebHook 整合,實作更完整的應用場景。最後,我們將探討如何使用 Go 語言實作 Glue 功能,串接不同服務,並利用 Dockerfile 多階段建置最佳化佈署流程。
區塊鏈技術在無伺服器架構中的應用:以智慧合約為例
隨著區塊鏈技術的不斷發展,其在無伺服器架構中的應用也日益受到關注。本文將以智慧合約為例,探討區塊鏈技術在無伺服器架構中的應用,並深入分析相關技術細節。
智慧合約的基本概念
智慧合約是一種執行在區塊鏈上的程式碼,它能夠自動執行特定的任務。智慧合約的執行結果會被記錄在區塊鏈上,因此具有不可篡改的特性。
註冊智慧合約的實作
pragma solidity ^0.5.0;
contract RegistrationRepository {
event RegistrationFound(string telNo, string bank, string accNo);
event RegistrationNotFound(string telNo);
mapping(string => Registration) public registrations;
struct Registration {
string bank;
string accNo;
address owner;
}
function register(string memory telNo, string memory bank, string memory accNo) public {
registrations[telNo] = Registration(bank, accNo, msg.sender);
emit Registered(telNo, msg.sender);
}
function findByTelNo(string memory telNo) public view returns (address) {
Registration memory r = registrations[telNo];
require(r.owner != address(0), "Registration not found");
emit RegistrationFound(telNo, r.bank, r.accNo);
return r.owner;
}
}
內容解密:
此智慧合約用於管理手機號碼的註冊資訊。主要功能包括:
register函式:將手機號碼與銀行帳戶資訊進行繫結,並記錄擁有者地址。findByTelNo函式:根據手機號碼查詢相關的銀行和帳戶資訊。- 事件機制:當查詢到註冊資訊時觸發
RegistrationFound事件,否則觸發RegistrationNotFound事件。
使用 Truffle 框架佈署智慧合約
Truffle 是一個流行的以太坊開發框架,用於編譯、佈署和測試智慧合約。
佈署指令碼範例
var RegistrationRepository = artifacts.require("./RegistrationRepository.sol");
module.exports = function(deployer) {
deployer.deploy(RegistrationRepository).then(function() {
RegistrationRepository.deployed().then(function(repo) {
repo.register("+661234567", "faas", "55700").then();
repo.register("+661111111", "whisk", "A1234").then();
});
});
};
內容解密:
此指令碼用於佈署 RegistrationRepository 智慧合約,並註冊兩個手機號碼,分別對應不同的銀行和帳戶。
區塊鏈網路的設定
本文使用 Parity 客戶端建立以太坊區塊鏈網路。
Parity 客戶端啟動命令
docker run --rm --name=parity_dev -d -p 8545:8545 -p 8180:8180 \
--network=parse_net \
--network-alias=blockchain \
parity/parity:stable-release \
--geth --chain dev --force-ui \
--reseal-min-period 0 \
--jsonrpc-cors http://localhost \
--jsonrpc-apis all \
--jsonrpc-interface 0.0.0.0 \
--jsonrpc-hosts all
內容解密:
此命令啟動一個 Parity 客戶端容器,並組態相關引數以便與其他服務進行互動。
WebHook 如何與區塊鏈互動
WebHook 函式透過呼叫智慧合約來查詢手機號碼的註冊資訊。
Java 程式碼範例
public RegistrationResult lookup(String telNo) throws Exception {
val repo = ContractRegistry.registrationRepository();
val receipt = repo.findByTelNo(telNo).send();
val foundEvents = repo.getRegistrationFoundEvents(receipt);
if (!foundEvents.isEmpty()) {
val reg = foundEvents.get(0);
return new RegistrationResult(reg.bank, reg.accNo);
} else {
val notFoundEvents = repo.getRegistrationNotFoundEvents(receipt);
if (!notFoundEvents.isEmpty()) {
return null;
}
}
throw new Exception("Lookup does not find any event in receipt.");
}
內容解密:
此函式呼叫 findByTelNo 方法查詢手機號碼的註冊資訊,並根據事件結果傳回相關資訊或丟擲異常。
最佳化建議
- 最佳化事件處理:目前的實作中,智慧合約會觸發多個事件。可以考慮最佳化為只觸發一個事件,以提高效率。
- 錯誤處理:在 WebHook 函式中,可以增加更完善的錯誤處理機制,以應對各種可能的異常情況。
使用 Chromeless 包裝舊系統
Chromeless 是一個 Node.js 函式庫,用於實作瀏覽器自動化。
建立 hivectl 函式
$ faas new hivectl --lang node
內容解密:
此命令使用 FaaS CLI 建立一個名為 hivectl 的新函式,用於包裝舊有的 UI 系統。
隨著區塊鏈技術和無伺服器架構的不斷成熟,我們可以預見更多的企業將採用這些技術來構建更安全、更高效的應用系統。同時,開發者需要不斷學習和掌握相關技術,以應對日益複雜的技術挑戰。
附錄
系統架構圖
graph LR
A[WebHook] -->|呼叫智慧合約|> B[區塊鏈網路]
B -->|傳回結果|> A
C[舊系統] -->|被Chromeless包裝|> D[hivectl函式]
D -->|與WebHook互動|> A
圖表翻譯: 此圖表展示了系統的整體架構,包括 WebHook 如何與區塊鏈網路互動,以及如何使用 Chromeless 包裝舊系統並與 WebHook 進行互動。
程式碼最佳實踐
在開發過程中,應遵循最佳實踐來確保程式碼的品質和可維護性。例如,使用清晰的命名規則、新增必要的註解、以及進行充分的測試等。這些做法有助於提高程式碼的可讀性和可靠性。
使用 OpenFaaS 和 Chromeless 自動化頭部 Chrome 瀏覽器操作
簡介
本文將介紹如何利用 OpenFaaS 和 Chromeless 實作自動化頭部 Chrome 瀏覽器操作。我們將建立一個名為 hivectl 的 OpenFaaS 函式,該函式透過 Chromeless 控制頭部 Chrome 瀏覽器,以自動化 HiveMind ERP 系統中的財務帳戶調整操作。
建立 OpenFaaS 函式
首先,我們需要建立一個名為 hivectl 的 OpenFaaS 函式。執行以下命令:
$ faas new hivectl --lang node
該命令將在當前目錄下建立一個名為 hivectl 的資料夾,並包含 OpenFaaS 函式的描述檔案 hivectl.yml。
組態 OpenFaaS 函式
以下是 hivectl.yml 的內容:
provider:
name: faas
gateway: http://localhost:8080
functions:
hivectl:
lang: node
handler: ./hivectl
image: chanwit/hivectl:0.4
該組態檔案定義了一個名為 hivectl 的 OpenFaaS 函式,使用 Node.js 語言,處理器為 ./hivectl,並使用 chanwit/hivectl:0.4 映象。
編寫 Chromeless 指令碼
以下是 hivectl/handler.js 的內容:
const { Chromeless } = require('chromeless')
const url = 'http://hivemind/vapps/hmadmin/Accounting/FinancialAccount/FinancialAccountTrans?finAccountId='
module.exports = (content, callback) => {
async function run(accountId, amount) {
const chromeless = new Chromeless({
launchChrome: false,
cdp: { host: 'chrome', port: 9222, secure: false, closeTab: true }
})
const screenshot = await chromeless
.goto('http://hivemind/Login/logout')
.click('#TestLoginLink_button')
.wait('.btn-danger')
.goto(url + accountId)
.wait('#AdjustDialog-button')
.click('#AdjustDialog-button')
.type(amount, '#AdjustFinancialAccount_amount')
.mousedown('#select2-AdjustFinancialAccount_reasonEnumId-container')
.mouseup('#select2-AdjustFinancialAccount_reasonEnumId-container')
.press(40, 5)
.press(13)
.click('#AdjustFinancialAccount_submitButton')
.screenshot()
.catch(e => {
console.log('{"error":"' + e.message + '"}')
process.exit(1);
})
console.log('{"success": "ok", "screenshot":"' + screenshot + '"}')
await chromeless.end()
}
const opt = JSON.parse(content)
run(opt.accountId, opt.amount).catch(console.error.bind(console))
};
內容解密:
此指令碼使用 Chromeless 控制頭部 Chrome 瀏覽器,以自動化 HiveMind ERP 系統中的財務帳戶調整操作。首先,它導航到登出頁面並點選測試登入連結。然後,它導航到指定的財務帳戶頁面,點選調整按鈕,輸入調整金額,選擇調整原因,並點選提交按鈕。最後,它擷取螢幕並輸出結果。
建置和佈署 OpenFaaS 函式
執行以下命令建置 OpenFaaS 函式:
$ faas build -f ./hivectl.yml
建置完成後,將映象推播到 Docker Hub。
啟動頭部 Chrome 瀏覽器和 HiveMind ERP 系統
執行以下命令啟動頭部 Chrome 瀏覽器:
$ docker run -d --network=parse_net \
--network-alias=chrome \
--cap-add=SYS_ADMIN \
justinribeiro/chrome-headless
執行以下命令啟動 HiveMind ERP 系統:
$ docker run -p 10000:80 \
-d --network=parse_net \
--network-alias=hivemind \
moqui/hivemind
呼叫 OpenFaaS 函式
以下是 WebHook 程式碼,呼叫 hivectl 函式:
public boolean faasAdjust(String txId, String accountId, Double amount) throws Exception {
val env = System.getenv("FAAS_GATEWAY_SERVICE");
val faasGatewayService = (env == null ? "http://gateway:8080" : env);
val JSON = MediaType.parse("application/json; charset=utf-8");
val client = new OkHttpClient();
val json = new ObjectMapper().writeValueAsString(new HashMap<String, String>() {{
put("accountId", accountId);
put("amount", String.valueOf(amount));
}});
val body = RequestBody.create(JSON, json);
val request = new Request.Builder()
.url(faasGatewayService + "/function/hivectl")
.post(body)
.build();
val response = client.newCall(request).execute();
System.out.println(response);
if (response.code() == 200) {
val str = response.body().string();
return true;
}
throw new Exception(response.toString());
}
圖表翻譯:
此圖表呈現了整個系統的架構,包括 OpenFaaS、Chromeless、頭部 Chrome 瀏覽器和 HiveMind ERP 系統之間的互動流程。
graph LR;
A[OpenFaaS] -->|呼叫|> B(hivectl);
B -->|控制|> C(頭部 Chrome 瀏覽器);
C -->|操作|> D(HiveMind ERP 系統);
D -->|傳回|> C;
C -->|傳回|> B;
B -->|傳回|> A;
圖表翻譯: 此圖表呈現了 OpenFaaS 呼叫 hivectl 函式,hivectl 函式控制頭部 Chrome 瀏覽器,瀏覽器操作 HiveMind ERP 系統,並傳回結果的整個流程。
使用 Go 語言實作 Glue 功能
以下是使用 Go 語言實作的 Glue 功能程式碼:
func main() {
input := os.Args[1]
// OpenWhisk params are key/value pairs
params := map[string]interface{}{}
err := json.Unmarshal([]byte(input), ¶ms)
if err != nil {
fmt.Printf(`{"error":"%s", "input": "%s"}`, err.Error(), string(input))
os.Exit(-1)
}
entry := Entry{
Account: Account{
Id: params["accountId"].(string),
},
Amount: params["amount"].(float64),
}
jsonValue, err := json.Marshal(entry)
if err != nil {
fmt.Printf(`{"error":"%s"}`, err.Error())
os.Exit(-1)
}
accountService := os.Getenv("ACCOUNT_SERVICE")
if accountService == "" {
accountService = "http://accounting:8080/entries"
}
resp, err := http.Post(accountService, "application/json", bytes.NewBuffer(jsonValue))
if err != nil {
fmt.Printf(`{"error":"%s"}`, err.Error())
os.Exit(-1)
}
if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
fmt.Println(`{"success": "ok"}`)
os.Exit(0)
}
fmt.Printf(`{"error": "%s"}`, resp.Status)
}
Dockerfile 多階段建置
以下是 Dockerfile 的內容:
# Stage 0
FROM golang:1.8.5-alpine3.6
WORKDIR /go/src/app
COPY account_ctl.go .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo -ldflags '-extldflags "-static"' -o exec account_ctl.go
# Stage 1
FROM openwhisk/dockerskeleton
ENV FLASK_PROXY_PORT 8080
COPY --from=0 /go/src/app/exec /action/
RUN chmod +x /action/exec
CMD ["/bin/bash", "-c", "cd actionProxy python -u actionproxy.py"]
多階段建置流程
graph LR;
A[原始碼] -->|複製|> B(Stage 0);
B -->|建置|> C(靜態二進位制檔案);
C -->|複製|> D(Stage 1);
D -->|設定環境|> E(最終映象);
圖表翻譯: 此圖表呈現了多階段建置的流程,包括原始碼複製、靜態二進位制檔案建置、以及最終映象的建立。