送書|5分鐘技術實操: 手把手教你開發以太坊錢包

編輯 | kou

本文節選自《區塊鏈項目開發指南》,閱讀時長大約10分鐘。 通過閱讀本文,你不僅可以學會如何開發一個以太坊錢包,還有機會免費獲得紙質書籍一本喲!

◆ ◆ ◆ ◆ ◆

創建錢包服務

錢包服務將允許用戶生成獨一無二的種子,顯示地址和相關餘額,最後將允許用戶發送以太幣給其他賬戶。所有操作都在客戶端上進行,這樣比較容易取得用戶的信任。用戶必須記住種子或者把它存儲在某個地方。

必要條件

在開始創建錢包服務之前,應確保運行geth開發實例(即挖礦),它已啓動了HTTP-RPC服務器,允許來自任何域名的客戶端請求,最後解鎖賬戶0。運行下面的代碼:

其中,--rpccorsdomain用於允許一些特定域與geth通信。需要提供一個以空格分隔的域名列表,例如“http://localhost:8080 https://mySite.com*”。它還支持*通配符。

--rpcaddr表示geth服務器可以到達哪個IP地址。默認的是127.0.0.1,所以如果它是一個託管服務器,就不能使用服務器的公共IP地址到達它。因此,將它的值改爲0.0.0.0,這表示該服務器可以使用任何IP地址到達。

項目結構

在本章的練習文件中,你將發現Final和Initial兩個目錄。Final包含項目的最終源代碼,而Initial 包含可以用於迅速創建應用的空的源代碼文件和庫。

爲了測試Final目錄,需要在其中運行npm install,然後使用Final目錄中的node app.js 命令運行該應用。

在Initial目錄中,你將發現一個public目錄和兩個文件(app.js和package.json)。package.json包含應用的後端相關內容,把後端源代碼放在app.js裏。

public目錄包含與前端相關的文件。在public/css中會發現bootstrap.min.css,它是bootstrap庫;在public/html中會發現index.html,把應用的HTML代碼放在這裏;在public/js目錄中將發現Hooked-Web3-Provider、web3js和LightWallet的.js文件。在public/js中還會發現一個main.js文件,把應用的前端JS代碼放在這裏。

創建後端

先來創建App後端。首先,在Initial目錄中運行npm install,爲後端安裝所需相關內容。

運行快捷服務並用於index.html文件和靜態文件的完整後端代碼如下:

創建前端

現在開始創建App前端。前端所包括的主要功能有生成種子、顯示種子地址和發送以太幣。

編寫應用的HTML代碼。把如下代碼放入index.html文件中:

上述代碼的執行過程如下:

1)把Bootstrap 4樣式表排入隊列。

2)顯示一個信息框,上面將顯示多個信息。

3)得到一個表單,上面有一個輸入框和兩個按鈕。輸入框用於輸入seed或者在生成新的seed時顯示seed。

4)Generate Details按鈕用於顯示地址,Generate NewSeed按鈕用於生成一個新的、獨一無二的seed。用戶單擊Generate Details按鈕就調用generate_Addresses()方法,單擊Generate New Seed按鈕就調用generate_seed()方法。

5)這時就有了一個空的有序列表。當用戶單擊Generate Details按鈕時,將動態顯示seed地址、餘額和相關私鑰。

6)最後有另外一張表單,其中有from地址、to地址和要轉賬的以太幣數量。from地址必須是當前未排序列表中顯示的地址之一。

現在編寫HTML代碼調用的每個函數的實現。首先編寫代碼,生成一個新的seed。將這段代碼放入main.js文件:

keystore命名空間的generateRandomSeed()方法用於生成一個隨機seed。它用接受一個可選參數,即一個表示額外的熵的字符串。

在一些算法中或者需要隨機數的地方會用到熵。熵通常來自於硬件源或者已經存在的硬件源,例如鼠標移動,或者特別提供的隨機數生成器。

生成一個獨特的seed需要非常高的熵。LightWallet內置了生成唯一seed的方法。LightWallet生成熵使用的算法取決於環境。但是如果能生成更好的熵,就可以把生成的熵傳送給generateRandomSeed(),它將在內部與generateRandomSeed()生成的熵進行拼接。

生成隨機seed之後,調用generate_Addresses方法。該方法以seed作爲參數,並在其中顯示地址。在生成地址之前,它會問用戶想要多少個地址。

generate_Addresses()方法的實現如下。把如下代碼放入main.js文件中:

上述代碼的執行過程如下:

1)首先有一個變量totalAddresses,它存儲用戶希望生成的地址總數。

2)檢查參數seed是否定義了。如果沒有定義,則從輸入欄抓取seed。這樣做,generate_Addressess()方法可以用於顯示信息 seed,如果用戶單擊Generate Details按鈕,還同時生成一個新的seed。

3)使用isSeedValid()方法驗證keystore命名空間的seed。

4)請用戶輸入想要生成和展示多少地址並進行驗證。

5)keystore命名空間中的私鑰總是加密存儲的。在生成密鑰時,需要進行加密;在簽署交易時,需要解密。衍生對稱加密密鑰的密碼可以由用戶輸入,或者提供一個隨機字符串作爲密碼。爲了使用戶體驗更好,生成一個隨機字符串,將它用作密碼。對稱加密密鑰沒有存儲在keystore命名空間裏,因此只要進行與私鑰相關的操作,例如生成密鑰、訪問密鑰等,就需要從密碼生成密鑰。

6)使用createVault方法創建keystore實例。

createVault用一個對象和一個回調函數作爲參數。對象可以有4種屬性:password、seedPharse、salt和hdPathString。

password是必選項,其他的都是可選項。如果不提供seedPharse,它會生成和使用一個隨機seed。拼接salt與password,以提高對稱密鑰加密技術的安全性,因爲攻擊者不僅要找到password還得找到salt。如果不提供salt,它就會隨機生成。keystore命名空間存儲未加密的salt。hdPathString用於爲keystore命名空間提供默認衍生路徑,即生成地址、簽署交易等。如果不提供衍生路徑,則使用該衍生路徑。

如果不提供hdPathString,則默認值爲m/0'/0'/0'。這個衍生路徑的默認目的是簽名。可以創建新的衍生路徑或者使用keystore實例的addHdDerivationPath()方法重寫當前衍生路徑的purpose。還可以使用keystore實例的setDefaultHdDerivationPath()方法改變默認衍生路徑。

最後,一旦keystore命名空間被創建,就通過回調函數返回實例。所以,這裏僅用keyword和seed創建了一個keystore。

7)生成用戶指定數量的地址及其相關密鑰。從一個seed中可以生成數百萬個地址,因爲keystore不知道用戶想生成多少個地址,所以在此之前不會生成任何地址。在創建keystore之後,使用keyFromPassword方法從密碼中生成對稱密鑰,然後調用generateNewAddress()方法生成地址及其相關密鑰。

8)generateNewAddress()有3個實參,即密碼衍生的密鑰、生成地址的數量和衍生路徑。因爲沒有提供衍生路徑,它使用keystore的默認衍生路徑。如果多次調用generateNewAddress(),它會從在最後一次調用中創建的地址重新開始。例如,如果調用該方法兩次,每次生成兩個地址,則將得到前四個地址。

9)使用getAddresses()獲取存儲在keystore上的全部地址。

10)使用exportPrivateKey方法解碼和檢索地址私鑰。

11)使用web3.eth.getBalance()獲取地址餘額。

12)在未排序的列表中顯示全部信息。

上面介紹了從seed生成地址及其私鑰的方法。現在編寫send_ether()方法的實現,該方法用於從一個由seed生成的地址發送以太幣。

相關代碼如下。將這段代碼放入main.js文件:

上述代碼直到由seed生成地址的部分都無須解釋。然後給ks的passwordProvider屬性分配一個回調函數。該回調函數在簽署交易時被調用,以獲取密碼解碼私鑰。如果不提供,LightWallet就會提示用戶輸入密碼。

此時,通過傳送keystore作爲交易簽署者創建一個HookedWeb3Provider實例。當自定義服務提供方想簽署交易時,它調用ks的hasAddress方法和signTransactions方法。

如果要簽署的地址不在生成的地址之中,ks將向自定義服務提供方返回錯誤。最後使用web3.eth.sendTransaction方法發送一些以太幣。

測試

錢包服務的創建已經完成了,讓我們測試一下,確保它像預想的那樣工作。

首先,在Initial目錄中運行node app.js,

然後在瀏覽器中訪問http://localhost:8080,運行界面如下圖。

單擊Generate New Seed按鈕,生成一個新的seed。提示輸入一個數字,代表要生成地址的數量。可以輸入任何數字,但是爲了實現測試目的,給出一個大於1的數。運行界面如下圖。

現在測試發送以太幣,需要發送一些以太幣到從coinbase賬戶中生成的地址之一。一旦發送一些以太幣到生成的地址之一,即單擊Generate Details按鈕更新用戶界面(UI),儘管並不需要測試使用錢包服務發送以太幣。確保再次生成同一個地址。此時的運行界面如下圖。

在From address欄中輸入列表中有餘額的賬戶的地址,然後在To address欄輸入另一個地址。爲了進行測試,可以輸入顯示的任意其他地址。

接着輸入一個以太幣數量,該值要小於等於地址賬戶中以太幣的餘額。運行界面如下圖。

單擊Send Ether按鈕,即可在信息框中看到交易哈希。等待挖出交易。同時在很短的時間內,可以單擊Generate Details按鈕查詢交易是否被挖出。如果交易被挖出,則運行界面如下圖。

如果每件事都和剛纔解釋的一樣,那麼錢包服務就已經就緒了。實際上,可以把該服務部署到一個自定義域名,讓公衆使用它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章