Fn Project 結合區塊鏈技術,提供一個安全、可擴充套件的轉帳系統解決方案。透過 Fn Project 的 FaaS 平台,搭配 Ethereum 智慧合約及 WebHook 機制,實作了高效的交易處理流程。系統核心包含 Transfer 類別定義、WebHook 觸發器設定、Fn 函式撰寫與佈署,以及與 Ethereum 智慧合約的整合。文章詳細說明瞭 DTO 類別設計、Gradle 建置設定、Docker 容器化佈署、智慧合約程式碼範例,以及系統架構圖解,提供讀者清晰的實作。

透過 Parse 平台的 Webhook 功能,我們可以將 Transfer 類別的資料傳送到 Fn Project 進行處理。Fn 函式會解析請求中的資料,並與 Ethereum 區塊鏈互動,驗證交易資訊並更新區塊鏈上的狀態。這個機制確保了交易的安全性和可靠性,同時也提高了系統的效率。此外,文章也提到了如何使用 DTO 類別簡化資料傳輸,以及如何使用 Gradle 和 Docker 進行建置和佈署。

設計轉帳實體與WebHook整合應用

在Parse平台的左側導覽列中,我們可以看到「Core | Browser」選單,這裡顯示了所有在Parse平台上的資料。除了已經存在的內建類別外,我們需要定義一個新的類別來處理金錢轉帳的操作。

建立Transfer類別

首先,我們需要在「Core | Browser」選單中點選「Create a class」來建立一個新的類別。一個對話方塊會出現,提示我們為新的類別命名。我們將這個類別命名為「Transfer」,它將作為我們的主要實體,負責處理行動支付和金錢轉帳。

設定Transfer類別的欄位

我們為Transfer類別定義了以下欄位:

  • from:付款的手機號碼。
  • to:收款的手機號碼。
  • amount:要支付的金額。
  • sent:一個旗標,當我們準備開始處理交易時,需要將其設定為true。如果這個欄位是null或false,WebHook將只接收資料而不進行任何操作。
  • processed:一個旗標,當交易處理完成後,會自動被設定為true。

使用Transfer類別

透過Parse的儀錶板,我們可以為fromtoamount欄位設定手機號碼和金額。當我們準備好時,只需將sent欄位設定為true。如果交易處理過程中出現錯誤,sent旗標將被WebHook自動重置為null。

WebHook機制

Parse平台提供了一個可擴充套件的機制,允許我們在外部處理業務邏輯,這就是WebHook。我們可以將函式作為外部程式執行,並與Parse的WebHook結合使用,以執行複雜的業務邏輯。

建立WebHook

在我們的例子中,我們已經有了Transfer類別。接下來,我們為這個類別定義一個WebHook,在每次儲存Transfer實體之前呼叫一個外部函式。我們指定了一個URL給這個WebHook,它指向一個FaaS閘道。當儲存Transfer實體時,將會對指定的URL發起HTTP POST請求,請求體中包含了當前Transfer實體的資料。

WebHook觸發器

Parse中的WebHook可以透過「Core | Webhooks」建立。我們選擇使用觸發器(trigger)型別的WebHook,它可以在諸如beforeSave、afterSave、beforeDelete和afterDelete等多個地方被觸發。在我們的例子中,使用了beforeSave觸發器,並將Transfer類別作為目標類別。

在Fn中準備WebHook

Fn Project最適合用Java編寫函式。當呼叫一個函式時,框架能夠自動將請求體轉換為入口方法(entrypoint method)的引數。以下是一個範例,展示瞭如何將JSON請求轉換為字串,並傳遞給handleRequest方法:

public Object handleRequest(String body) {
    if (body == null || body.isEmpty()) {
        body = "{}";
    }
    Input input;
    try {
        val mapper = new ObjectMapper();
        input = mapper.readValue(body, Input.class);
    } catch (IOException e) {
        return new Error(e.getMessage());
    }
    if (input == null) {
        return new Error(body);
    }
    /* 處理剩下的業務邏輯 */
}

資料傳輸物件(DTO)類別

為了正確編碼和解碼Parse的WebHook訊息,我們定義了一系列DTO類別。藉助Project Lombok和Jackson,我們可以大幅減少程式碼的行數。

@Data
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Input {
    private Transfer object;
}

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Transfer {
    private String objectId;
    private String from;
    private String to;
    private Double amount;
    private Boolean sent;
    private Boolean processed;
}

@Data
@AllArgsConstructor
public static class Success {
    private Transfer success;
}

@Data
@AllArgsConstructor
public static class Error {
    private String error;
}

Gradle建置檔案

由於這是一個Java專案,我們無需在容器內建置它。以下是Gradle建置檔案的範例,可以使用gradle installDist命令進行建置:

plugins {
    id 'io.franzbecker.gradle-lombok' version '1.11'
    id 'java'
    id 'groovy'
    id 'application'
}
mainClassName = 'App'

測試WebHook

當我們建立一個新的Transfer實體並儲存時,WebHook將被觸發。如果手機號碼未註冊,WebHook將傳回錯誤訊息。我們可以在「Core | Logs」中檢視錯誤日誌。

回傳訊息規範

回傳訊息的規範為:{"success": object}用於更新資料回Parse平台,而{"error":"msg"}用於顯示錯誤訊息。

內容解密:

上述程式碼展示瞭如何在Fn Project中使用Java編寫FaaS函式,以處理Parse平台的WebHook請求。首先,我們定義了DTO類別來表示請求和回應資料。然後,在handleRequest方法中,我們將請求體解析為Input物件,並進行相應的業務邏輯處理。最後,我們傳回Success或Error物件,以更新資料或顯示錯誤訊息回Parse平台。

圖表翻譯:

此圖示展示了Parse平台與Fn Project之間的互動流程。首先,使用者在Parse平台上建立Transfer實體並儲存。然後,Parse平台透過WebHook機制,將請求傳送到Fn Project中的FaaS函式。FaaS函式處理請求後,回傳結果給Parse平台,完成整個流程。

圖表翻譯: 此圖表展示了使用者在Parse平台上建立Transfer實體並儲存後,Parse平台如何透過WebHook機制與Fn Project中的FaaS函式互動,最終完成業務邏輯處理並回傳結果的過程。

建構根據 Fn Project 的區塊鏈轉帳系統

在現代金融科技(FinTech)領域中,區塊鏈技術與無伺服器架構的結合為開發高效、安全且可擴充套件的支付系統提供了新的可能性。本篇文章將探討如何利用 Fn Project 構建一個根據區塊鏈的轉帳系統,並詳細解析其技術實作細節。

技術背景與系統架構

Fn Project 簡介

Fn Project 是一個開源的無伺服器框架,支援多種程式語言和執行環境。它提供了高度的可移植性和靈活性,使得開發者能夠在不同的雲端和本地環境中佈署函式。

系統架構設計

我們的轉帳系統將採用以下架構:

  1. Fn Project 作為函式服務平台
  2. Ethereum 區塊鏈作為事件狀態機
  3. 智慧合約管理轉帳狀態和註冊資訊

建構 Fn Project 函式

依賴管理

首先,我們需要在 build.gradle 檔案中定義專案依賴:

dependencies {
    // Fn Project
    compile 'com.fnproject.fn:api:1.0.56'
    // JSON 編碼
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.9.4'
    // REST 使用者端
    compile 'com.squareup.okhttp3:okhttp:3.9.1'
    // 簡化 Java 語法
    compile group: 'org.projectlombok', name: 'lombok-maven', version: '1.16.20.0', ext: 'pom'
    // Ethereum 使用者端
    compile 'org.web3j:core:3.2.0'
    // 測試框架
    testCompile 'com.fnproject.fn:testing:1.0.56'
    testCompile 'junit:junit:4.12'
    testCompile 'org.codehaus.groovy:groovy-all:2.4.12'
    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
}

Dockerfile 組態

接下來,我們需要建立 Dockerfile 以建構函式的 Docker 映像:

FROM fnproject/fn-java-fdk:jdk9-1.0.56
WORKDIR /function
COPY ./build/install/routing_fn/lib/*.jar /function/app/
CMD ["com.example.fn.TransferFunction::handleRequest"]

建構與佈署指令碼

我們建立一個名為 buildAndPush 的指令碼來自動化建構和佈署過程:

#!/bin/bash
./gradlew installDist
VERSION=$1
docker build -t chanwit/routing_fn:$VERSION .
docker push chanwit/routing_fn:$VERSION
fn routes delete demo /routing_fn
fn routes create /routing_fn -i chanwit/routing_fn:$VERSION demo

執行指令碼:./buildAndPush v1

區塊鏈事件狀態機實作

Ethereum 智慧合約開發

我們使用 Truffle 框架來開發 Ethereum 智慧合約。以下是 TransferState.sol 合約的實作:

pragma solidity ^0.4.24;

contract TransferState {
    enum State { NONE, STARTED, PENDING, COMPLETED }
    string txId;
    State state;

    constructor(string _txId) public {
        state = State.NONE;
        txId = _txId;
    }

    function start() public {
        require(state == State.NONE);
        state = State.STARTED;
    }

    function pending() public {
        require(state == State.STARTED);
        state = State.PENDING;
    }

    function complete() public {
        require(state == State.PENDING);
        state = State.COMPLETED;
    }

    function currentState() public constant returns (uint8) {
        return uint8(state);
    }
}

儲存函式庫模式實作

TransferStateRepository 合約實作了儲存函式庫模式,用於管理轉帳狀態:

contract TransferStateRepository {
    event TransferStarted(string txId);
    event TransferPending(string txId);
    event TransferCompleted(string txId);

    mapping(bytes32 => address) states;

    function start(string txId) public {
        // 註冊狀態並設為 STARTED
        emit TransferStarted(txId);
    }

    function pending(string txId) public {
        // 檢查狀態並設為 PENDING
        emit TransferPending(txId);
    }

    function complete(string txId) public {
        // 檢查狀態並設為 COMPLETED
        emit TransferCompleted(txId);
    }

    function getStateOf(string txId) public constant returns (string) {
        // 傳回當前狀態
    }
}

系統整合與測試

Fn 函式與區塊鏈整合

我們的 Fn 函式將與 Ethereum 區塊鏈進行互動,以查詢帳戶資料和追蹤轉帳交易狀態。

事件驅動架構

系統採用事件驅動架構,當智慧合約狀態變更時,會發出事件通知 Fn 函式進行後續處理。

系統架構圖
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title FnProject區塊鏈轉帳系統設計

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

圖表翻譯: 此圖示呈現了系統的整體架構,包括 Fn Project 如何與 Ethereum 區塊鏈互動,以及智慧合約在其中的角色。其中,TransferState 合約負責管理轉帳狀態,而 RegistrationRepository 合約則處理註冊資訊的儲存與查詢。

  1. 效能最佳化:研究如何最佳化智慧合約的執行效率和降低 Gas 費用。
  2. 安全性增強:實施更嚴格的安全稽核和漏洞測試,確保系統的健壯性。
  3. 功能擴充套件:增加更多金融服務功能,如跨鏈交易支援等。

透過不斷最佳化和擴充套件,我們的根據區塊鏈的轉帳系統將能夠更好地服務於現代金融科技的需求。