前期準(zhǔn)備
- 編輯器
理論上講任何編輯器都可以編寫Solidity合約代碼,比如:WebStorm,VSCode盐欺,Sublime等。我選擇atom
autocomplete-solidity
代碼自動(dòng)補(bǔ)齊
linter-solium仅醇、linter-solidity
代碼錯(cuò)誤檢查
language-ethereum
支持Solidity代碼高亮以及Solidity代碼片段 - 環(huán)境
node.js
開發(fā)框架:truffle(用react box)
安裝truffle
$ npm install -g ethereumjs-testrpc truffle
創(chuàng)建項(xiàng)目
luoxuedeMacBook-Pro:~ luoxue$ cd desktop
luoxuedeMacBook-Pro:desktop luoxue$ mkdir voting
luoxuedeMacBook-Pro:desktop luoxue$ cd voting
luoxuedeMacBook-Pro:voting luoxue$ truffle unbox react-box
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!
Commands:
Compile: truffle compile
Migrate: truffle migrate
Test contracts: truffle test
Test dapp: npm test
Run dev server: npm run start
Build for production: npm run build
-
項(xiàng)目結(jié)構(gòu)
image.png - contracts:編寫智能合約的文件夾冗美,所有的智能合約文件都放置在這里
- migrations:部署合約配置的文件夾
- src:基于React的Web端源碼
- test:智能合約測試用例文件夾
編寫智能合約
- 在contracts文件夾下創(chuàng)建Voting.sol文件
- 編譯環(huán)境: remix-online (remix.ethereum.org)
- 創(chuàng)建合約對象Voting,存candidtae着憨,bytes23[]是可變的
contract Voting{
// luo
// xue
// ll
// xx
// mm
bytes32[] candidates = new bytes32[](5);
}
- 構(gòu)造函數(shù)
function Voting(bytes32[] _candidates) public{
for(uint i =0; i<_candidates.length;i++){
candidates[i] = _candidates[i];
}
}
- 創(chuàng)建一個(gè)字典:候選人-》票數(shù)
mapping(bytes32 => uint) candidatesVotingCount;
- 創(chuàng)建投票方法
function votingToPerson(bytes32 person) public {
candidatesVotingCount[person]+=1;
}
- 檢查是否是合法的候選人
function isValidPerson(bytes32 person) constant internal returns(bool){
for(uint i = 0; i<candidates.length; i++){
if(candidates[i] == person){
return true;
}
}
return false;
}
- 完整版
pragma solidity ^0.4.4;
contract Voting{
// luo
// xue
// ll
// xx
// mm
// ["luo","xue","ll","xx","mm"]
bytes32[] candidates = new bytes32[](5);
mapping(bytes32 => uint)candidatesVotingCount;
function Voting(bytes32[] _candidates) public {
for(uint i =0; i<_candidates.length;i++){
candidates[i] = _candidates[i];
}
}
function votingToPerson(bytes32 person) public {
assert(isValidPerson(person));
candidatesVotingCount[person]+=1;
}
function votingTotalToPerson(bytes32 person) constant public returns (uint) {
return candidatesVotingCount[person];
}
function isValidPerson(bytes32 person) constant internal returns(bool){
for(uint i = 0; i<candidates.length; i++){
if(candidates[i] == person){
return true;
}
}
return false;
}
}
-
remix 檢查調(diào)用情況
image.png
image.png -
復(fù)制粘貼并更換掉simple sample.sol 替換成voting
image.png -
在migration換掉部署文件中相應(yīng)部分
image.png 編譯Voting.sol
打開truffle控制臺
$ truffle develop
編譯合約
image.png
發(fā)現(xiàn)build文件夾里多了一個(gè) voting.json文件
image.png
-
App.js里面 改json的import
image.png 改this.state里面的狀態(tài)墩衙,存儲候選人相關(guān)信息
constructor(props) {
super(props)
this.state = {
canddidates:[
{
name:"luo",
count:0,
id:101
},
{
name:"xue",
count:0,
id:102
},
{
name:"ll",
count:0,
id:103
},
{
name:"xx",
count:0,
id:104
},
{
name:"mm",
count:0,
id:105
}
],
-
改路由
image.png -
與鏈上交互
通過get web3交互
注:
=>
是個(gè)js 的箭頭函數(shù)
this.instantiateContract() 初始化合約
image.png -
修改合約初始化,獲取合約實(shí)例
image.png -
取到候選人的票數(shù)
image.png
看控制臺輸出:
兩個(gè)1票3個(gè)0票
image.png
-
修改狀態(tài)機(jī), 讓網(wǎng)頁上顯示合約上的票數(shù)
image.png -
寫修改函數(shù)甲抖,注意參數(shù)不用var 定義變量
image.png - 在remix里投票漆改,看網(wǎng)頁上也有實(shí)時(shí)變化
-
加投票按鈕
image.png -
從input 里獲取資料,ref
image.png
從name里獲得了input的value
把contract變成全局變量
在點(diǎn)擊button里面調(diào)用
image.png
但要注意准谚,這里from 的要用web3來調(diào)用 -
然后刷新票數(shù)挫剑,直接復(fù)制上面即可
image.png