以太坊智能合約及應(yīng)用開發(fā)簡介

在這個入門教程中我們將建立以太坊應(yīng)用開發(fā)環(huán)境并學(xué)習(xí)編寫一個投票智能合約。

在這個教程中,讓我們構(gòu)建一個簡單的"Hello World!" 應(yīng)用程序, 這是一個投票應(yīng)用程序。

該應(yīng)用程序非常簡單,它所做的只是初始化一組候選人,讓任何人投票給候選人,并顯示每個候選人收到的總票數(shù)。

我有意避免使用任何DAPP框架構(gòu)建這個應(yīng)用程序,因為框架抽象掉很多細(xì)節(jié),你不了解系統(tǒng)的內(nèi)部。此外,當(dāng)你使用框架時,將對框架所做的繁重工作有更多的體會!

## 1. 設(shè)置開發(fā)環(huán)境

我們使用一個模擬的內(nèi)存區(qū)塊鏈(ganache)代替真實的區(qū)塊鏈在進(jìn)行開發(fā)。在本教程的2章,我們將與真實的區(qū)塊鏈交互。下面是安裝ganache、web3js的步驟,然后在linux上啟動一個測試鏈。在macOS上安裝過程也是一樣的。

![以太坊開發(fā)教程](http://blog.hubwiz.com/2018/04/11/ethereum-dapp-intro/ganache-test-accounts.jpg)

你可以看到ganache-cli自動創(chuàng)建了10個測試賬號,每個賬號預(yù)分配了100(虛構(gòu)的)ethers

如果需要更詳細(xì)的開發(fā)環(huán)境安裝教程,可以參考如下文章:

- [windows以太坊開發(fā)環(huán)境搭建](http://blog.hubwiz.com/2018/03/08/windows-ethereum-dev-env/)

- [linux/ubuntu以太坊開發(fā)環(huán)境搭建](http://blog.hubwiz.com/2018/03/09/linux-ethereum-dev-env/)

## 2.簡單的投票合約

我們將使用solidity編程語言來編寫我們的合約。如果您熟悉面向?qū)ο缶幊蹋瑢W(xué)習(xí)編寫solidity合約應(yīng)該是輕而易舉的事。我們將編寫一個合約對象,含有一個構(gòu)造函數(shù)初始化候選人數(shù)組。合約對象有2個方法:

1. 返回候選人獲得的總票數(shù)

2. 增加候選人的投票數(shù)。

> 注意:構(gòu)造函數(shù)只被調(diào)用一次,當(dāng)您部署合約到區(qū)塊鏈。不像在網(wǎng)絡(luò)世界里的每一個部署你的代碼覆蓋舊的代碼,部署后的代碼在區(qū)塊鏈上是不變的。例如,如果你更新你的合約并且再次部署,舊合約仍然會在區(qū)塊鏈上, 它所存儲的數(shù)據(jù)不受影響,新的部署將創(chuàng)建一個新實例的合約。

下面是投票合約的代碼:

```

pragma solidity ^0.4.18;?

? ? // We have to specify what version of compiler this code will compile with?


? ? contract Voting {?

? ? ? /* mapping field below is equivalent to an associative array or hash.?

? ? ? The key of the mapping is candidate name stored as type bytes32 and value is?

? ? ? an unsigned integer to store the vote count?

? ? ? */?


? ? ? mapping (bytes32 => uint8) public votesReceived;?


? ? ? /* Solidity doesn't let you pass in an array of strings in the constructor (yet).?

? ? ? We will use an array of bytes32 instead to store the list of candidates?

? ? ? */?


? ? ? bytes32[] public candidateList;?


? ? ? /* This is the constructor which will be called once when you?

? ? ? deploy the contract to the blockchain. When we deploy the contract,?

? ? ? we will pass an array of candidates who will be contesting in the election?

? ? ? */?

? ? ? function Voting(bytes32[] candidateNames) public {?

? ? ? ? candidateList = candidateNames;?

? ? ? }?


? ? ? // This function returns the total votes a candidate has received so far?

? ? ? function totalVotesFor(bytes32 candidate) view public returns (uint8) {?

? ? ? ? require(validCandidate(candidate));?

? ? ? ? return votesReceived[candidate];?

? ? ? }?


? ? ? // This function increments the vote count for the specified candidate. This?

? ? ? // is equivalent to casting a vote?

? ? ? function voteForCandidate(bytes32 candidate) public {?

? ? ? ? require(validCandidate(candidate));?

? ? ? ? votesReceived[candidate] += 1;?

? ? ? }?


? ? ? function validCandidate(bytes32 candidate) view public returns (bool) {?

? ? ? ? for(uint i = 0; i < candidateList.length; i++) {?

? ? ? ? ? if (candidateList[i] == candidate) {?

? ? ? ? ? ? return true;?

? ? ? ? ? }?

? ? ? ? }?

? ? ? ? return false;?

? ? ? }?

? ? }?

```

復(fù)制上面的代碼,在hello_world_voting目錄下創(chuàng)建一個Voting.sol文件?,F(xiàn)在讓我們來編譯代碼并將其部署到ganache的區(qū)塊鏈上.

為了編譯solidity代碼,我們需要安裝名字為solc的npm模塊

```

~/hello_world_voting$ npm install solc?

```

我們將在node控制臺中使用這個庫來編譯我們的合約。在上一篇文章中我們提到,web3js是一個讓我們可以通過rpc訪問區(qū)塊鏈的庫。我們將使用該庫來部署我們的應(yīng)用程序并與之交互。

首先,在命令行中斷運(yùn)行`node`命令進(jìn)入node控制臺,初始化solc和文本對象。下面的所有代碼片段都需要在node控制臺中鍵入

```

~/hello_world_voting$ node?

> Web3 = require('web3')?

> web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));?

```

為了確保web3對象已經(jīng)初始化、區(qū)塊鏈能夠訪問,讓我們試一下查詢區(qū)塊鏈上的所有賬戶。您應(yīng)該看到如下的結(jié)果:

```

> web3.eth.accounts?

? ? ['0x9c02f5c68e02390a3ab81f63341edc1ba5dbb39e',?

? ? '0x7d920be073e92a590dc47e4ccea2f28db3f218cc',?

? ? '0xf8a9c7c65c4d1c0c21b06c06ee5da80bd8f074a9',?

? ? '0x9d8ee8c3d4f8b1e08803da274bdaff80c2204fc6',?

? ? '0x26bb5d139aa7bdb1380af0e1e8f98147ef4c406a',?

? ? '0x622e557aad13c36459fac83240f25ae91882127c',?

? ? '0xbf8b1630d5640e272f33653e83092ce33d302fd2',?

? ? '0xe37a3157cb3081ea7a96ba9f9e942c72cf7ad87b',?

? ? '0x175dae81345f36775db285d368f0b1d49f61b2f8',?

? ? '0xc26bda5f3370bdd46e7c84bdb909aead4d8f35f3']?

```

從voting.sol加載代碼,保存在一個字符串變量中,然后開始編譯

```

> code = fs.readFileSync('Voting.sol').toString()?

> solc = require('solc')?

> compiledCode = solc.compile(code)?

```

當(dāng)你的代碼編譯成功并打印了合約對象的內(nèi)容(在node控制臺中輸出的內(nèi)容),有2個字段很重要,需要理解它們:

- `compiledCode.contracts[‘:Voting’].bytecode`: Voting.sol源代碼編譯后得到的字節(jié)碼。這是將被部署到blockchain的代碼。

- `compiledCode.contracts[‘:Voting’].interface`: 合約接口或模板(稱為ABI)告訴用戶合約含有哪些方法。您需要這些ABI的定義,因為將來你總是需要與合約交互的。更多ABI信息請參考[這里](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI)。

> 如果你希望馬上開始學(xué)習(xí)以太坊DApp開發(fā),可以訪問匯智網(wǎng)提供的出色的在線互動開發(fā)教程:

>

> - [java以太坊開發(fā)教程](http://xc.hubwiz.com/course/5b2b6e82c02e6b6a59171de2?affid=cdldy),主要是針對java和android程序員進(jìn)行區(qū)塊鏈以太坊開發(fā)的web3j詳解。

> - [python以太坊](http://xc.hubwiz.com/course/5b40462cc02e6b6a59171de4?affid=cdldy),主要是針對python工程師使用web3.py進(jìn)行區(qū)塊鏈以太坊開發(fā)的詳解。

> - [php以太坊](http://xc.hubwiz.com/course/5b36629bc02e6b6a59171de3?affid=cdldy),主要是介紹使用php進(jìn)行智能合約開發(fā)交互,進(jìn)行賬號創(chuàng)建、交易、轉(zhuǎn)賬、代幣開發(fā)以及過濾器和交易等內(nèi)容。

> - [以太坊入門教程](http://xc.hubwiz.com/course/5a952991adb3847553d205d1?affid=cdldy),主要介紹智能合約與dapp應(yīng)用開發(fā),適合入門。

> - [以太坊開發(fā)進(jìn)階教程](http://xc.hubwiz.com/course/5abbb7acc02e6b6a59171dd6?affid=cdldy),主要是介紹使用node.js、mongodb、區(qū)塊鏈、ipfs實現(xiàn)去中心化電商DApp實戰(zhàn),適合進(jìn)階。

> - [ERC721以太坊通證實戰(zhàn)](http://xc.hubwiz.com/course/5c6ed395070c379b559a813a?affid=cdldy),課程以一個數(shù)字藝術(shù)品創(chuàng)作與分享DApp的實戰(zhàn)開發(fā)為主線,深入講解以太坊非同質(zhì)化通證的概念、標(biāo)準(zhǔn)與開發(fā)方案。內(nèi)容包含ERC-721標(biāo)準(zhǔn)的自主實現(xiàn),講解OpenZeppelin合約代碼庫二次開發(fā),實戰(zhàn)項目采用Truffle,IPFS,實現(xiàn)了通證以及去中心化的通證交易所。

> - [C#以太坊](http://xc.hubwiz.com/course/5b6048c3c02e6b6a59171dee?affid=cdldy),主要講解如何使用C#開發(fā)基于.Net的以太坊應(yīng)用,包括賬戶管理、狀態(tài)與交易、智能合約開發(fā)與交互、過濾器和交易等。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容