如何用 Swift 打造你的第一個區塊鏈 App


區塊鏈 (Blockchain) 是一種突破性技術 (Disruptive Technologies),近年漸獲關注。為什麼呢?因為區塊鏈是許多加密貨幣 (Cryptocurrencies) 如比特幣 (Bitcoin)、以太坊 (Ethereum)、萊特幣 (Litecoin) 的創始技術。那區塊鏈是如何運作的呢?在本次的教學裡,我將會談到所有關於區塊鏈技術的知識,以及如何用 Swift 來製作自己的「區塊鏈」。那麼,讓我們開始吧!

區塊鏈的運作

顧名思義,區塊鏈就是一個由不同的區塊串連在一起的「鏈」,每個區塊包含三則資訊:資料 (Data)、雜湊值 (Hash)、和前一個區塊的雜湊值。

  1. 資料 ── 依據使用情境,儲存在區塊的資料會因區塊鏈的類型而不同。例如,在比特幣區塊鏈中,儲存資料就是與交易有關的資訊,即是轉帳的金額、以及參與交易二人的資訊。
  2. 雜湊值 ── 你可以把雜湊想成是一種數位指紋,它是用來識別一個區塊及其資料。雜湊最重要的地方,就是它是一個獨一無二的字母數字 (Alphanumeric) 程式碼,通常會由 64 個字元組成。當一個區塊被創造時,雜湊值也同時產生。當一個區塊被更動時,雜湊值也會同時被更動。透過這種方式,當你想要查看區塊上的任何變動時,雜湊值就非常重要。
  3. 前一個區塊的雜湊值 ── 每個區塊就是藉由儲存前個區塊的雜湊來鏈結在一起,組成一個區塊鏈!這就是讓區塊鏈如此安全的原因。

看看這張圖片:

blockchain-explained

如你所見,每個區塊由資料(未顯示)、雜湊值、和前一個區塊雜湊值所組成。舉個例子,黃色區塊包含了自己的雜湊值 H7S6、和紅色區塊的雜湊值 8SD9。以這種方式,它們組成了一個鏈結,並以此連結在一起。現在,假設有個駭客入侵並嘗試更動紅色區塊。請記住,每次一個區塊以任何方式被更動時,區塊的雜值湊也會被更動!因此,當下一個區塊執行確認、並看到前一個區塊的雜湊值並不吻合時,它會有效地將自己從「鏈」中分離出來,而不會被駭客讀取。

這就是區塊練會如此安全的原因,你幾乎不可能嘗試回溯並更改任何資料。雜湊值提供了不錯的保密及隱私,但還有兩個安全機制來讓區塊鏈更加安全:驗證 (Proof-of-work) 及智慧合約 (Smart Contract)。雖然我不會詳述,但你可以在這裡了解更多。

區塊鏈最後一個保全方式就是基於它的位置。與大多儲存在伺服器或是資料庫內的資料不同,區塊鏈使用點對點網路 (Peer-To-Peer, P2P),它是一種網路型態,允許任何人加入並將該網路上的資料分發給每位接收者。

每當有人加入這個網路時,他們就會得到區塊鏈的完整拷貝;每當有人建立一個新區塊時,就會傳送到網路內的所有人。然後,透過一些複雜的程式,讓節點 (Node) 在加入這個區塊到區塊鏈之前,先確認該區塊有否被竄改。就這樣,任何地方的任何人都可以取得這些資訊。如果你是 HBO 矽谷群瞎傳 (Silicon Valley) 的忠實粉絲,這聽起來可能有點熟悉,因為在這齣美劇裡,主角就是用了類似的技術來建立一個全新網路。

因為每個人或節點都有一份區塊鏈的拷貝,他們可以有共識並確認哪些區塊是合法的。因此,如果你想要駭入一個區塊,你必須駭入網路上超過 50% 的區塊來通過你的資訊。這就是為什麼區塊鏈或許是過去十年以來最安全的技術之一。

關於範例應用

現在你了解區塊鏈是如何運作了,那麼開始來製作我們的範例 App 吧!請先下載初始專案

如你所見,我們有兩個比特幣錢包。第一個帳號 Account 1065 擁有 500 BTC,而第二個帳號 0217 則甚麼都沒有。我們利用傳送按鈕來傳送比特幣到其他帳號。為了賺取 BTC,我們按下 Mine 按鈕就可以獲得 50 BTC 為獎勵。基本來說,我們做的是當 App 執行時,利用控制台來觀察兩個比特幣帳號間的交易情況。

Blockchain demo storyboard

你會注意到,側邊欄裡有兩個重要的類別:BlockBlockchain。打開這些檔案,你會看到檔案是空的,那是因為我將會引導你寫出這些類別的邏輯。那我們開始吧!

在 Swift 定義 Block

前往 Block.swift 並添加程式碼以定義一個區塊。首先,讓我們了解一下區塊是什麼。我們先前定義了一個區塊由三個部分組成: 雜湊值、記錄的實際資料、以及前一個區塊的雜湊值。當我們想建立自己的區塊鏈時,必須要知道區塊的排序,這一點可以很容易地在 Swift 中定義。添加以下程式碼到類別裡:

現在,我們需要添加最後一個重要的程式碼。我之前提到每次一個區塊被更動,雜湊就會改變;這就是區塊鏈如此安全的特色之一。所以我們必須建立一個函式來產生一個隨機字母數字的雜湊。這個函式只需要幾行程式碼:

NSUUID 是一個物件,代表橋接 UUID 的通用唯一值。它內置於 Swift 中,而且非常適合用來產生 32 字元的字串。這個函式產生一個 UUID,消除所有連字符 (-),然後回傳 String,即區塊的雜湊。Block.swift 現在應該看起來像這樣:

blockchain-4

我們已經定義了 Block 類別,接著讓我們定義 Blockchain 類別吧。切換到 Blockchain.swift

在 Swift 定義 Blockchain

如前文所說,讓我們嘗試從基本面來了解區塊鏈。在基本的術語裡,區塊鏈只是區塊串在一起組成的鏈;換句話說,它是一個包含所有項目的列表。聽起來是不是有點熟悉呢?因為這就是陣列的定義,而這個陣列就是由區塊所組成!讓我們把下列的程式碼加進去吧:

小提示:這幾乎可以應用在電腦科學世界的所有事上。如果你曾遇過大問題,試著將它拆解成小組件,然後以自己的方法來解決問題;就像我們弄清楚如何在 Swift 中加入區塊及區塊鏈一樣!

你會注意到在陣列裡面包含了先前定義的 Block 類別,那是我們在區塊鏈中需要的所有變數。加入兩個函式到類別裡,我們就完成了。試著用我前文所教的來回答這個問題:

在一個區塊鏈中,兩個主要的函式是什麼?

希望你能夠回答這個問題!這兩個區塊鏈擁有的主要函式,是用來建立初始區塊,以及在後面新增新的區塊。當然,現在我不會下放這個鏈並加入智慧合約,但是這些是基本函式!加入以下程式碼到 Blockchain.swift

  1. 我們加入的第一個函式是用來建立初始區塊。為此,我們建立了一個函式來把區塊的資料作為 Input。然後,我們定義一個名為genesisBlock 的變數,並將它設為 Block 型別。因為它是 Block 型別,所以它有我們之前在 Block.swift 定義的所有變數及函式。我們設定 generateHash() 為雜湊、 Input data 為資料 。因為這是第一個區塊,所以我們將前一個區塊的雜湊設定為 000,好讓我們知道這是初始區塊。我們將它的索引值設為 0 ,然後放到區塊鏈 chain
  2. 我們建立的下一個函式則適用於所有 genesisBlock 後的區塊,而它會建立剩下的所有區塊。你會注意到它跟之前的函式非常相似,唯一的不同的是我們將 previousHash 設定為前一個區塊的雜湊,並將 index 設為它在區塊練的位置。

完成了!我們已經成功定義自己的 Blockchain!你的程式碼應該如下圖所示!

blockchain-5

接著,我們將所有的部分連接到 ViewController.swift 檔案,並看看執行成果吧!

錢包後台 (Wallet Backend)

切換到 ViewController.swift,我們可以看到所有的 UI 元件都已經連結完畢。我們所需要做的就是處理交易,並將交易列印到控制台上。

然而在開始之前,我們應該稍微探討一下比特幣區塊鏈。比特幣來自一個總帳號,假設這個帳號的編號是 000。當你挖掘一顆比特幣時,就表示你解答了數學問題,並獲得一定數量的比特幣作為獎勵。這是發行貨幣一個很聰明的方法,同時也創造了讓更多人去挖掘的動機。在我們的 App 裡,我們將 100 BTC 作為獎勵。首先,讓我們在 ViewController 添加需要的變數:

我們定義兩個帳號:一個編號為 1065,另一個編號為 0217。我們同時新增一個 bitcoinChain 變數來作為我們的區塊鏈,並將 reward 設定為 100。我們需要一個作為比特幣來源的主帳號:這是我們的初始帳號,編號為 0000,它擁有一千萬個比特幣。你可以把這個帳號當成銀行,在每一次的獎勵中,就會從中取出 100 個比特幣,並轉至合法的帳號裡。我們也定義一個警告,在每次交易無法完成時顯示。

現在,讓我們來寫些將會執行的泛用函式。你可以猜到這些函式是什麼嗎?

  1. 第一個函式是用來處理交易的。我們要確認傳送者及接收者的帳號中,接收或扣除的金額是正確的,而且這個資訊會被記錄在我們的區塊鏈上。
  2. 下一個函式是要在控制台裡印出完整的紀錄,它會顯示每個區塊及每個區塊內的資料。
  3. 最後一個函式是用來驗證區塊鏈是否合法,方法為確認前個區塊的雜湊是否符合下一個區塊的資訊。因為我們不會示範任何駭客方法,所以範例中的鏈永遠都是合法的。

Transaction 函式

以下是我們的泛用交易函式。在定義變數之下輸入以下程式碼:

看起來程式碼很多,但是它的核心只是為每次的交易定義一些規則。在開頭的地方,我們有四個參數:tofromamount 以及 type。To、From、及 Amount 的含義一目了然,而 Type 基本上就是定義交易的類型。這裡有兩種 Type:Normal 和 Genesis。一個 Normal 的交易類型會是在帳號 10650217 之間進行,而 Genesis 交易類型則會涉及到帳號 0000

  1. 第一個 if-else 條件式是關於來源帳號。如果來源帳號不存在或金額不足,我們會顯示交易無效的警告,然後結束函式。而如果通過的話,我們會更新數值
  2. 第二個 if-else 條件式是關於接收帳號。如果接收帳號不存在,那麼我們隨它而去,然後結束函式。要不然,我們就會傳送正確的比特幣數量到帳號。
  3. 第三個 if-else 條件式處理交易的類型。如果一個交易涉及初始區塊,我們就建立一個新的初始區塊;反之我們建立一個新區塊來儲存資料。

Printing 函式

在每次交易的最後,我們想要看到一個清單列出所有交易,來確保我們知道所有發生的事情。以下是我們在 transaction 函式下輸入的程式碼:

這是一個簡單的 for 迴圈,包含 bitcoinChain 的每個區塊。我們印出區塊的編號、雜湊值、前個區塊的雜湊、以及儲存的資料,再更新 UILabel 來顯示每個帳號內正確的 BTC 數目。最後,印出一個列出每個帳號的清單(應該會有三個),並驗證鏈的合法性。

現在,你應該會在函式最後一行中發生錯誤。這是因為我們還沒定義 chainValidity() 函式,那麼就來開始吧!

Validity 函式

記住,如果前一個區塊的雜湊值符合目前區塊所描述的內容,那麼這一個鏈就是合法的。我們可以輕易地用另一個 for 迴圈來重複驗證每個區塊。

跟之前有點相似,我們在 bitcoinChain 中重複驗證每個區塊,來確認前一個區塊的雜湊值是否與目前區塊所描述的內容符合。

這樣就完成了!我們已經定義了函式,並將會每次都用到它們!你的 ViewController.swift 現在應該看起來像這樣:

blockchain-6

現在我們只需要將按鈕連接到函式就完成了,來開始最後的篇章吧!

將所有東西連結在一起

當我們的 App 首次啟動時,我們想讓初始帳號 0000 傳送 50 BTC 到我們的第一個帳號。然後,我們將讓第一個帳號傳送 10 BTC 到第二個帳號。這個步驟僅需三行程式碼就可以完成。如此更改你的 viewDidLoad 函式:

我們使用先前定義好的函式,並在最後呼叫 chainState()。同時,我們新增一個 OK 按鈕到交易無效的警告中。

現在讓我們來看看剩下的四個函式裡要加入什麼:redMine()blueMine()redSend()blueSend()

挖礦函式

挖礦函式非常地簡單,只要三行程式碼就行了。這就是我們要添加的程式碼:

在第一個挖礦函式中,我們使用 transaction 函式從初始帳號傳送 100 BTC 到第一個帳號,先印出一個區塊被挖出,再印出 chainState。同樣地,我們在 blueMine 函式裡將 100 BTC 傳送到第二個帳號。

傳送函式

傳送函式與先前的函式也稍微相似。

首先,我們確認 redAmountblueAmount 中的文字欄位是否為空值。如果是,我們會顯示一個交易無效的警告。如果不是,我們就可以繼續。我們使用 transaction 函式輸入金額,並把交易設為 normal 型態,以將第一個帳號的金額傳送到第二個帳號(或相反)。我們印出被傳送的金額,然後呼叫 chainState() 函式。最後,把文字欄位清空。

這樣我們就完成囉!確認一下你的程式碼是否符合下圖所示。

執行 App 試試看!從前端來說,它看起來就如一個普通的交易 App,但你會知道它後台的運作。試試使用 App 將 BTC 從一個帳號交易給另一個帳號、並試著欺騙 App 吧!

結論

在這次的教學中,你學到了如何使用 Swift 來建立一個區塊鏈,並建立自己的比特幣交易。請注意在真實的加密貨幣後台裡,實作部分是跟上文是完全不一樣的東西,因為它需要藉由智慧合約來分散,但是上面的示範內容用來學習的。

在這個範例中,我們運用了比特幣來當加密貨幣,但你能想到區塊鏈還的其他用途嗎?歡迎在下面留言分享你的看法!希望你在此學到新的東西!

你可以在 Github 下載完整專案作參考。

譯者簡介:楊敦凱-目前於科技公司擔任 iOS Developer,工作之餘開發自有 iOS App同時關注網路上有趣的新玩意、話題及科技資訊。平時的興趣則是與自身專業無關的歷史、地理、棒球。來信請寄到:[email protected]

原文Building Your First Blockchain App in Swift


Sai Kambampati 是程式開發員,生活於美國加州薩克拉門托,於2017獲得Apple's WWDC獎學金。精於 Swift及Python語言,渴望自家開發人工智能產品。閒時喜歡觀看Netflix、做健身或是遛漣圖書館中。請到推特追蹤 @Sai_K1065 。

blog comments powered by Disqus
訂閲電子報

訂閲電子報

AppCoda致力於發佈優質iOS程式教學,你不必每天上站,輸入你的電子郵件地址訂閱網站的最新教學文章。每當有新文章發佈,我們會使用電子郵件通知你。

已收你的指示。請你檢查你的電郵,我們已寄出一封認證信,點擊信中鏈結才算完成訂閱。

Shares
Share This