本視頻課程面向初學者,介紹什么是區塊鏈,什么是智能合約,內容涵蓋以太坊開發相關的基本概念,Gregory(Dapp University 創始人,專注于講解在以太坊區塊鏈上構建DApp應用程序教程。Gregory大神的以太坊課程在youtube上超過五千位訂閱者,所有課程超過10萬人次觀看,深受區塊鏈技術開發用戶的喜愛 )大神在課程中手把手地教大家如何構建一個基于以太坊的完整去中心化應用 —— 區塊鏈投票系統。
課程介紹
本視頻課程面向初學者,介紹什么是區塊鏈,什么是智能合約,內容涵蓋以太坊開發相關的基本概念,Gregory大神在課程中手把手地教大家如何構建一個基于以太坊的完整去中心化應用 —— 區塊鏈投票系統。
通過本課程的學習,你將掌握:
1、以太坊區塊鏈開發的基本知識
2、開發和部署以太坊合約所需的軟件環境
3、使用高級語言(solidity)編寫以太坊智能合約
4、使用NodeJS編譯、部署合約并與之交互
5、使用Truffle框架開發分布式應用
6、使用控制臺或網頁與合約進行交互
課程內容
什么是區塊鏈?
我們用一個比喻來明白什么是區塊鏈,它的工作原理是怎樣?讓我們先看一下網頁應用程序。
當我們和網頁應用程序交互時,你使用網頁瀏覽器去連接我們的應用中心服務器。所有的網頁應用都基于中心服務器,所有的數據都在中心數據庫。任何時候在應用程序上交易,你都需要和網頁中心服務器溝通。
如果我們在網頁應用程序上投票選舉,投票選舉時我們會有以下問題:
1. 數據庫里的數據可能會被改變:或者重復投票:也可能投票數據全部被刪除。
2. 網頁服務器上的源代碼在任何時候都可能會被改變。
我們不愿意在網頁上創建應用程序。我們更愿意把它創建在大家能連接的區塊鏈上,確保一人投票一次,且不可篡改。讓我們看看在區塊鏈上怎么去實現它。
區塊鏈不是一個中央服務器和一個數據庫,而是一個網絡和一個數據庫。區塊鏈是計算機的對等網絡,稱為節點,共享網絡中的所有數據和代碼。因此,如果您是連接到區塊鏈的設備,則您是網絡中的一個節點,并且您可以與網絡中的所有其他計算機節點通話。您也擁有區塊鏈上所有數據和代碼的副本。區塊鏈上沒有中央服務器,只有不同設備之間在同屬性下的網絡點對點交流。
區塊鏈取代中心化數據庫,所有的交易都在區塊鏈上,所有包含的記錄稱之為區塊。所有連接起來的區塊叫區塊鏈,區塊鏈之間創建公共賬本,公共賬本代表區塊鏈里面的所有數據。
公共賬本的所有數據都通過加密技術哈希密碼進行保護,并通過共識算法進行驗證。網絡上節點的參與確保網絡上分散的所有數據副本都是一樣的。這就是我們為什么要在區塊鏈上構建投票應用程序,因為我們希望確保我們的投票都被計算在內,而且沒有被篡改。
如果我們的投票應用程序應用在區塊鏈上會怎么樣?
對于新用戶來講,新用戶需要一個帶錢包地址和有ETH的賬戶。ETH也就是以太坊的加密貨幣。一旦連接到區塊鏈網絡,投票會在區塊鏈上消耗一些ETH。
這些交易費用稱之為“燃氣”。當開始投票是,網絡上幫助完成這筆交易的礦工將獲得這筆交易費用的ETH。我投票的記錄就永遠被記錄下來了。
記住一點:投票是一種交易,交易會消耗ETH,但讀取數據是免費的。
什么是智能合約?
智能合約就是在以太坊虛擬機(EVM) 上執行我們代碼的過程。
智能合約的編程語言是Solidity,有點像Javascript,但有點不一樣。Solidity編程語言可以實現我們所有的商務交易邏輯。
如果說公共賬本代表網頁的數據庫,那么智能合約就是實現所有商務邏輯交易的地方。
現在讓我們快速的看看我們構建的DApp的結構。
傳統的前端應用程序用的是HTML, CSS, 和 Javascript.語言。
代替傳統的前端應用程序是后端服務器,客戶安裝連接本地以太坊區塊鏈,去用Solidity語言編譯去中心化選舉。部署智能合約到本地區塊鏈上進行投票選舉。
讓我們一起來看看區塊鏈的工作原理,為什么我們要用區塊鏈代替下當前的中心化應用程序。
我們要創建什么?
我們將構建一個客戶端應用程序,與我們在區塊鏈上的智能合約進行對話。這個客戶端應用程序將有一個候選人列表,列出每個候選人的ID,姓名和投票數。 它會有一個表格,我們可以為我們想要的候選人投一票。 它還顯示我們在“您的帳戶”下連接到區塊鏈的帳戶。
安裝依賴項
創建DApp之前, 首先需要安裝依賴項.
節點包管理器 (NPM)
我們需要的第一個依賴是Node Package Manager或NPM,它隨Node.js一起的。你可以看看你的節點是否已經安裝了,你可以去你的終端并輸入:
$ node -v
Truffle 框架
下一個依賴項是Truffle框架它可以使我們在以太坊區塊鏈上創建分布式應用,提供一套用solidity編譯的智能合約工具,也可以幫助我們測試智能合約部署區塊鏈,它也為我們開發客戶端應用程序提供了一個地方。在命令行中這樣安裝truffle和NPM:
$ npm install -g truffle
Ganache
下一個依賴項是Ganache,一個本地內存區塊鏈。你也可以在Truffle Framework 網址下載安裝Ganache。它將會提供以太坊外部賬戶,每個賬戶里都有100個假的ETH和它的錢包地址。
Metamask谷歌擴展插件
我們下一個要安裝的依賴項是:Metamask谷歌擴展插件。Metamask幫助我們用個人賬戶連接本地區塊鏈網絡進行交互。開始之前,記得安裝Metamask谷歌擴展插件哦。
語法高亮(Syntax Highlighting)
下一個依賴項是語法高亮,很多編輯器和IEDs沒有語法高亮,我建議在用solidity編程是安裝語法高亮。所以你要安裝一個這樣的安轉包,教程里用我用的是Sublime Text,我已經在“以太坊”包下載了這個語法高亮。
Smoke Test - 步驟一
好了,現在我們所以的依賴項都安裝好了,讓我們開始創建我們的DApp吧。
首先,下載Ganache并打開,確保你的本地區塊鏈正常運作。
Ganache給我們10個賬戶,每個賬戶100個假的ETH。
每個帳戶都有一個唯一的地址和一個私鑰。每個帳戶地址將作為我們選舉中每個選民的唯一標識符。現在讓我們創建一個Dapp的項目目錄:
$ mkdir election
$ cd election
現在我們進入項目內部了,Truffle box使其快速運行。這個教程我們使用PET Shop box.從您的項目目錄中, 像這樣從命令欄安裝 pet shop box:
$ truffle unbox petshop
看看 pet shop box給我們帶來什么:
· contracts 目錄:?this is where all smart contacts live. We already have a Migration contract that handles our migrations to the blockchain.
這就是智能合約所在的地方。在區塊鏈上我們已經有Migration(遷移)合約處理我們的遷移。
· migrations 目錄:這是所有migration文件所在地方。當在區塊鏈上更新區塊鏈狀態時就需要migration。就像網頁開發框架里面需要migration來更新數據狀態一樣。
· node_modules 目錄:?這是所有的節點依賴項的大本營。
· src 目錄:?這是我們開發客戶端應用程序的地方。
· test 目錄:?這是我們為智能合約編寫測試的地方。
· truffle.js?文件:這是 Truffle項目的主要配置文件.
讓我們一起來在合約目錄下創建新合約吧:
$ touch contracts/Election.sol
我們首先創建一個“煙霧測試”,以確保我們已經正確設置了項目,并成功地將合約部署到區塊鏈。打開文件并從下面的代碼開始:
pragma solidity 0.4.2;
contract Election {
// Read/write candidate
string public candidate;
// Constructor
function Election () public {
candidate = "Candidate 1";
}
}
現在我們已經為智能合約創建了基礎,讓我們看看是否可以將其部署到區塊鏈。因此,我們需要在migrations目錄中創建一個新文件。從您的項目根目錄中,像這樣從命令行中創建一個新文件:
$ touch migrations/2_deploy_contracts.js
請注意,我們使用數字為migrations目錄中的所有文件編號,以便Truffle知道執行它們的順序。讓我們創建一個這樣新的migration部署的合約:
var Election = artifacts.require("./Election.sol");
module.exports = function(deployer) {
deployer.deploy(Election);
};
首先,我們需要創建合約,并將其分配給名為“Election”的變量。 接下來,我們將其添加到已部署合同的清單中,以確保在我們運行migrations時將其部署。 現在讓我們像這樣從命令行中運行migrations
$ truffle migrate:
現在我們已經成功將我們的智能合約遷移到當地的以太坊區塊鏈, 讓我們打開控制臺與智能合約交互。 你可以像這樣從命令欄中打開truffle控制器:
$ truffle console
現在我們進入了控制臺,讓我們來看看我們部署的智能合約的一個實例,看看我們是否可以從合約中讀取候選人的名字。從控制臺運行此代碼:
Election.deployed().then(function(instance) { app = instance })
這里的Election 是我們在migration文件中創建的變量的名稱。我們在這個合約例子里檢索了一個部署deployed() 函數,分配給一個app變量在promise的回調函數中?,F在我們可以像這樣讀取候選變量的值:
app.candidate()
// => 'Candidate 1'
恭喜你!你剛剛編寫了第一份智能合約,并將其部署到區塊鏈中,并檢索了一些數據。
步驟二:候選人名單。
我們需要一種方法來存儲多個候選人,并存儲關于每個候選人的多個屬性。我們希望跟蹤候選人的ID,姓名和投票數。 以下是我們將如何對候選人進行模擬:
contract Election {
// Model a Candidate
struct Candidate {
uint id;
string name;
uint voteCount;
}
// ...
}
我們使用Solidity Struct為候選人建模,Solidity允許我們創建自己的結構類型,就像我們在這里為候選人所做的那樣。 我們指定這個結構有一個無符號整數類型的ID,字符串類型的名稱和無符號整數類型的voteCount。 簡單地聲明這個結構體實際上不會給我們一個候選人。 我們需要實例化它并在將它寫入存儲之前將其分配給一個變量。
接下來我們需要的是一個儲存候選人的地方。我們需要一個地方來存儲我們剛剛創建的一種結構類型。我們可以使用Solidity映射進行此操作。 Solidity中的映射類似于關聯數組或哈希,它將鍵 - 值對關聯起來。 我們可以像這樣創建這個映射:
contract Election {
// Model a Candidate
struct Candidate {
uint id;
string name;
uint voteCount;
}
// Read/write Candidates
mapping(uint => Candidate) public candidates;
// ...
}
在這種情況下,映射的關鍵是一個無符號整數,并且該值是我們剛剛定義的Candidate結構類型。 這基本上給了我們一個基于id的查找每個候選人。 由于該映射被分配給一個狀態變量,因此只要我們為其分配新的鍵值對,我們就會將數據寫入區塊鏈。 接下來,我們將該映射的可見性設置為public,以獲得getter函數,就像我們在煙霧測試中使用候選名稱一樣。
接下來,我們通過一個像這樣的計數器緩存狀態變量來跟蹤選舉中存在多少候選者:
contract Election {
// Model a Candidate
struct Candidate {
uint id;
string name;
uint voteCount;
}
// Read/write Candidates
mapping(uint => Candidate) public candidates;
// Store Candidates Count
uint public candidatesCount;
// ...
}
在Solidity中,無法確定映射的大小,也無法對它進行迭代。 這是因為尚未分配值的映射中的任何鍵都會返回默認值(在這種情況下為空候選)。 例如,如果我們在這次選舉中只有2名候選人,并且我們試圖查找候選人#99,那么映射將返回一個空的候選人結構。 這種行為使得不可能知道有多少候選者存在,因此我們必須使用計數器緩存
接下來,我們創建一個函數,將候選添加到我們創建的映射中:
contract Election {
// ...
function addCandidate (string _name) private {
candidatesCount ++;
candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
}
}
我們已經聲明了函數addCandidate,它接受一個表示候選人姓名的字符串類型參數。 在函數內部,我們遞增候選計數器緩存以表示添加了新的候選項。 然后我們用一個新的Candidate結構更新映射,使用當前的候選計數作為關鍵。 這個Candidate結構體使用來自當前候選計數的候選id,函數參數中的名稱以及初始投票計數初始化為0.請注意,此函數的可見性是私有的,因為我們只想在合同中調用它。
現在,我們可以通過在構造函數內兩次調用“addCandidate”函數來添加兩個候選人,如下所示:
contract Election {
// ...
function Election () public {
addCandidate("Candidate 1");
addCandidate("Candidate 2");
}
// ...
}
當我們將合同部署到區塊鏈時,這個遷移將會執行,并且會有兩名候選人參加我們的選舉。此時,您的完整合同代碼應如下所示:
pragma solidity ^0.4.2;
contract Election {
// Model a Candidate
struct Candidate {
uint id;
string name;
uint voteCount;
}
// Read/write candidates
mapping(uint => Candidate) public candidates;
// Store Candidates Count
uint public candidatesCount;
function Election () public {
addCandidate("Candidate 1");
addCandidate("Candidate 2");
}
function addCandidate (string _name) private {
candidatesCount ++;
candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
}
}
現在讓我們像這樣遷移我們的合同:
$ truffle migrate --reset
現在嘗試與控制臺內的候選人進行交互。
現在讓我們編寫一些測試來確保我們的智能合約正確初始化。首先,讓我解釋為什么在開發智能合同時測試如此重要。
Testing
現在我們來寫一些測試。確保你有Ganache第一次運行。 然后,從項目根目錄的命令行中創建一個新的測試文件,如下所示::
$ touch test/election.js
我們將用the Mocha testing framwork和the Chai assertion library在這個文件中使用Javascript編寫我們所有的測試。這些與Truffle框架捆綁在一起。 我們將使用Javascript編寫所有這些測試,以模擬客戶端與我們的智能合約的交互,就像我們在控制臺中所做的一樣。 這里是測試的所有代碼:
var Election = artifacts.require("./Election.sol");
contract("Election", function(accounts) {
var electionInstance;
it("initializes with two candidates", function() {
return Election.deployed().then(function(instance) {
return instance.candidatesCount();
}).then(function(count) {
assert.equal(count, 2);
});
});
it("it initializes the candidates with the correct values", function() {
return Election.deployed().then(function(instance) {
electionInstance = instance;
return electionInstance.candidates(1);
}).then(function(candidate) {
assert.equal(candidate[0], 1, "contains the correct id");
assert.equal(candidate[1], "Candidate 1", "contains the correct name");
assert.equal(candidate[2], 0, "contains the correct votes count");
return electionInstance.candidates(2);
}).then(function(candidate) {
assert.equal(candidate[0], 2, "contains the correct id");
assert.equal(candidate[1], "Candidate 2", "contains the correct name");
assert.equal(candidate[2], 0, "contains the correct votes count");
});
});
});
第一個測試通過檢查候選人數量是否等于2來檢查合同是否被初始化了正確的候選人數。
下一個考試考查每個候選人在選舉中的價值,確保每個候選人都有正確的ID,姓名和投票數。
現在讓我們像這樣從命令行運行測試:
$ truffle test
看,編譯通過。
關注蜜蜂區塊鏈學院,這里有最新最全的區塊鏈學習課程和資料。
課程合作聯系郵箱:bd@51bitbee.com