區塊鏈的開發與測試

在本文中,我們將介紹一些我們從區塊鏈的設計階段進入區塊鏈的實際開發時要牢記的基本概念。 在我們開發解決方案時,我們的開發團隊應該始終如一地評估這些要點,以確保我們沒有遵循不良模式或是有安全漏洞的解決方案。 在這裡有一些重要的和強烈推薦的事情要記住。

另外我們將介紹如何測試區塊鏈應用程式或解決方案。區塊鏈應用程式的測試應該像測試組織的任何其他企業專案一樣進行。區塊鏈應用程式的理念是測試不是費用,而是降低風險的策略。

測試人員應該是我們區塊鏈專案所有階段的一部分,因為讓測試人員成為專案整個生命週期(架構、設計和開發)的一部分將使他們更好地了解專案的願景,並且他們的測試將與我們的產品保持一致或是要應用的願景。這稱為“Shift-Left Testing”。

在專案的開發方面,鑑於區塊鏈的限制和持久特性,使用Test Driven Development(TDD) 對區塊鏈應用程式開發有很大幫助。 TDD 的核心是首先編寫test cases,然後開發人員編寫可以通過已經寫好的test cases函數。許多專案在開發完成或接近完成後進行測試,但測試應在開發期間進行。Test cases應該在每個軟體build時進行測試。

開發

1.謹慎使用外包的開發,用自己的開發團隊

如果在使用內部開發的智慧合約和第三方建立的智慧合約之間進行選擇,我們應該傾向於內部開發的。這是因為內部開發的任何智慧合約都將受到與我們整個區塊鍊解決方案的其餘部分有著相同的資安、稽核、測試和驗收標準 — — 換句話說,這些智慧將符合我們已經制定的相同品質和安全標準。

需要記住,新的智慧合約發佈時合約地址會發生變化,因此最好使用calling contract。

如果無法做到這一點,請務必為我們的團隊(包括資安專家)留出額外的時間來稽核和審查任何外包的智慧合約的source code。我們希望確保我們呼叫的任何智慧合約都符合我們為應用程式制定的標準。提供外部智慧合約功能的第三方可能從未想像過我們在應用程式中追求的use case,因此確保我們不會繼承任何由第三方建立的安全漏洞至關重要。牢記這句古老的格言 — — a chain is only as strong as its weakest link(鏈條的強度取決於其最薄弱的環節)

2.處理所有錯誤; 擷取外部呼叫中的所有異常

這種範例在任何類型的軟體開發場景中都很重要,當然不是區塊鏈獨有的。然而,在區塊鏈應用程式中,我們很可能要處理在平台上流動的金錢,這變得更加重要。智慧合約中的每個函數都應該包含在 try/catch 語法中,並且所有預期的異常都應該被明確地處理,無論我們認為它出現的機會有多小。任何我們沒有明確擷取和管理的異常都應該進行一般性的擷取和管理,並且不應允許任何異常上升到可以呼叫函數或合約。如果可能,合約應該能處理異常並嘗試在沒有用戶干預的情況下繼續進行。如果無法做到這一點,則應將錯誤回報給用戶,並就如何解決錯誤或以其他方式繼續向用戶提出建議。如果我們呼叫的合約不是內部建立的,永遠不要假設其他開發人員已經採取了同樣的預防措施,並準備好處理任何導致我們的合約的異常一直升高。了解呈現給最終用戶的任何異常或掩蓋錯誤都會導致他們將應用程式視為“損壞”。

3.用Pull Payments 而不是 Push Payments

在建立處理加密貨幣的智慧合約時,我們很可能會呼叫一個或多個函數來支付給用戶或將資金還給用戶。 在這種情況下,我們應該避免“push payment” — — 盡量避免直接將錢“push”到用戶的錢包中。 而應該設置一個“pull”支付系統。 pull payment將付款過程分為兩個不同的步驟。 第一步是通知用戶智慧合約中有錢,他們可以提取(withdraw or pull out)。 在第二步中,用戶根據此通知採取行動並將錢提取到他們指定的錢包地址。 將支付過程分為兩部分,可以讓我們的智慧合約在兩個不同的地方驗證正確的用戶正在提錢,如果原始錢包地址不再有效或已被盜了,它允許用戶指定新的錢包地址。 這樣的方式會有更安全和更強健的應用程式。

4.區塊鏈中的資料是公開的!它是被保護的嗎?

任何人都可以通過使用 Etherscan.io 等區塊鏈瀏覽器查看公有區塊鏈(如以太坊)上的所有資料。 以太坊上的用戶必須擁有智慧合約的公共地址才能與區塊鏈的網路交互。 寫入公有區塊鏈的所有交易資料都以十六進制編碼的plain text或十進制格式存儲,除非我們的contract layer或middle layer(或兩者)對其執行加密和解密服務。 如果您將敏感資料寫入公有區塊鏈,或者不希望所有人都能看到我們的交易詳細資訊,請確保在將資料寫入區塊鏈之前加密或以其他方式保護資料。 或者,考慮區塊鏈是否是存儲此類資料的最佳位置,或者資料是可以存放在RDBMS等傳統資料庫。

5.始終從本地測試轉移到測試網路,然後再轉移到生產環境

在開發和測試智能合約時,我們要先在本地開發環境中執行廣泛的測試。之後再到以太坊公有區塊鏈上,使用 Ganache (TestRPC) 等工具,然後再推送到測試或生產環境的區塊鏈。 由於區塊鏈上的所有記錄都是永久性的所以智慧合約也會像是交易紀錄般的存在於區塊鏈,舊合約永遠不會消失。 在本地執行大部分測試可以讓我們成為測試資源好的的管理者,而不是不必要地使用 Rinkeby 或 Ropsten 等測試網路。 只有當我們確信我們的智慧合約已準備好用於生產環境時,我們才應將它們部署到測試網路以進行漏洞尋找和最終驗證。 需要記住,一旦部署到生產環境的區塊鏈,成本(費用)就成為現實,因此請確保我們首先進行了大量測試以避免不必要的成本。

6.使用敏捷方法預先發布很好,但在發佈到生產環境後效果不佳。

在開發區塊鏈解決方案時,許多人想知道是否仍然可以採用敏捷方法。 答案在於智慧合約和區塊鏈的本質。 每個智慧合約都是區塊鏈上的永久記錄,一旦部署就無法刪除。 Killing或呼叫合約的self-destruct需要想清楚,因此一旦合約投入生產環境中,"不建議繼續進行持續發布和開發的敏捷循環"。 在pre-production版本中,仍然可以採用敏捷,但團隊應該計劃更長的測試週期,以確保在第一次投入生產後發布後盡可能有太多的更版。

7. 在設計和開發過程中,要非常小心與注意指導原則到任務的一致性

  • 指導原則驅動人物角色 — — 確保人物角色與指導原則保持一致
  • 人物角色驅動User stories— — 確保User stories符合指導原則
  • User stories驅動功能需求 — — 確保功能需求符合指導原則
  • 功能需求驅動技術需求 — — 確保技術需求與指導原則保持一致
  • 技術要求驅動開發作業 — — 確保作業符合指導原則

8.最後才做出技術決策

許多設計和開發專案在花時間討論和定義指導原則、角色、用戶故事和要求之前,都會犯選擇技術平台的常見錯誤。 永遠不建議提前做出技術決策,因為哪會讓我們想要設計的平台或解決方案去符合哪一個技術平台,而不是設計符合最終用戶需求的解決方案。 為避免這個陷阱,請確保推遲決定使用哪些技術,直到設計決策已經確定、記錄並被專案中的主要的厲害關係人充分理解。

9.小心只呼叫我們寫的智慧合約,或是可以直接信任

在將合約連接到share functions時,呼叫非內部開發的智慧合約時要格外小心。 我們應該審核所有第三方的智慧合約,以確保它們符合與我們自己的內部開發的智慧合約有著相同的品質和安全標準。 我們不希望解決方案的品質或安全性因繼承的缺陷和漏洞而受到影響。

10.單體式或模組化

在確定是否使用一系列相互呼叫的合約(模組化),或者是否將所有代碼和邏輯保存在一個且只有一個智慧合約中時,通常建議採用模組化方法。 但是,"當安全性是最重要的問題時",單體式架構可能是最好的選擇。 需要記住以下幾點:

  • 模組化的方式是有效率的
  • 模組化的方式讓我們的code可以reuse
  • 模組化的方式會引入額外的安全性問題
  • 模組化的方式通常是優先考慮用的,但不會永遠都是
  • 單體式=潛在的更高的安全性

11.三明治複雜模型

在設計三層式的去中心化應用程式時,盡量將業務邏輯和複雜性集中在middle layer。 把我們的應用程式想像成一個三明治; UI(頂層麵包層)和智慧合約層(底層麵包層)應保持盡可能簡單,複雜性和業務邏輯應位於中間層(三明治的肉)。

測試

在設計和架構區塊鏈應用程式,人物角色(personas)應該是我們的test cases的起始點,我們可以在其中為每個人物角色建立一組test cases。 從一開始就製作好的test case可以讓開發更快。

對於測試區塊鏈應用程式,通常要有 5 到 10 倍的傳統應用程式的測試時間。 我們將測試是很多的firmware,而不只有software的功能,因為一旦它在區塊鏈上就無法更改。 應用程式的 100% 測試覆蓋率的目標通常是不切實際的,但卻是理想的標準。

我們需要在測試區塊鏈應用程式時使用測試工具。注意,測試工具不會改良我們的test cases,它們只會幫忙我們管理它們。 "自動化測試工具可以讓您測試更快但不是更好"

不同類型的測試包括:

• Unit Testing

• Developer level testing

• Configuration & Environment Testing — 在不同的環境(Test, Staging, Production)下測試代碼

• Load & Performance Testing

• Volume/Stress testing

  • Regression Testing — 已經部署的所有ocde的測試,即使之前的code沒有變。 這可以防止重新引入舊錯誤並擷取從新的code引入的任何新錯誤

由於區塊鏈變化的速度,經常會發現新的漏洞。 我們一定要聘請網路安全專家進行解決方案審查。 提供給能在我們的code中發現缺陷、安全漏洞的開發人員(內部和外部)提供獎金有助於提高測試覆蓋率和速度。

在區塊鏈測試中該做與不該做的

該做的

  1. 在一組預定義的條件下測試您的解決方案,例如:

• 我們的解決方案能否處理100 個concurrent user,平均每10 秒一個事務?

• 我們的解決方案能否在有250 個concurrent user時能處理一個transaction平均每0.5 秒處理一個?

• 更新密碼複雜性規則時,是否會通知密碼較弱的現有用戶應該更新?

• 測試“Happy Path” — — 我們期望大多數用戶大部分時間都會做的事情

  • 然後離開“Happy Path” — — 我們的用戶會不會做?

2. 應該要有開發和測試環境

3. 測試您的文件和支援材料 — 如果用戶無法找到有關我們的解決方案的支援或訊息可能將其視為“無法使用”

4. 從多個用戶的 POV 進行多次測試一個函數

5. 在我們的用戶將使用的每種設備上進行測試

6. 明確聲明不支援任何未經測試的平台

不應該做的

  • 不要讓開發人員測試自己的code — — 開發人員會下意識地根據他們用來建立code的心智模型來測試code
  • 不要讓開發人員接觸測試環境 — — 開發人員會忘記記錄config step和其他需求。 不讓他們接觸測試環境會顯示出這些miss掉的部分。
  • 不要在最新型號的智慧手機上測試,應該盡可能在所有型號上測試!!

Bug的分類

對錯誤進行分類很重要。 不同類型的錯誤包括:

  • 業務邏輯 — — 根據業務要求,有些事情就是不對的
  • 安全性 — — code容易受到一些安全漏洞的攻擊
  • 回歸 (Regression)— — 一些code更新後導致現有功能中斷
  • 效能 — — code很慢,或者某些動作執行了額外的功能
  • 可訪問性 (Accessibility)— code不符合可訪問性規範(例如:美國殘疾人法案)
  • UI 錯誤 — — 用戶界面不符合設計規範
  • 整合 — — 兩個或多個組件不能按預期協同工作

在記錄錯誤時,它們應該與人物角色和業務價值相關聯。 訓練我們的測試人員使用多媒體記錄錯誤 — 圖片或影片值一千或百萬字的文字紀錄。

負載測試

在測試應用程式的負載時,請務必同時考慮預期的concurrent user數量和每個用戶預期的平均transaction數量。 確保我們的應用程式可以擴展到超出這些預期,並且不會成為其業務大量成長的受害者。

主要區塊鏈架構測試問題

區塊鏈架構師會就測試提出的一些關鍵問題包括:

  • 該應用程式是否適合當前的用戶需求?
  • 該應用程式是否能滿足用戶明天或未來的需求?
  • 我們計劃測試多少應用程式?
  • 我們會使用任何測試工具嗎?
  • 會有自動化測試嗎?
  • 我們將如何追蹤和管理我們的測試?
  • 我們會讓最終用戶參與測試嗎?

--

--

運用"雲端服務"加速企業的數位轉型願景
運用"雲端服務"加速企業的數位轉型願景

Written by 運用"雲端服務"加速企業的數位轉型願景

我們協助您駕馭名為"雲端運算"的怪獸,馴服它為您所用。諮詢請來信jason.kao@suros.com.tw. https://facebook.com/jason.kao.for.cloud

No responses yet