ブロックチェーンはじめました
あらすじ
スマートコントラクトからマネーのオイニーがしてきたので素振りしておきました。
やってみた
以下を参考にやってみた
Full Stack Hello World Voting Ethereum Dapp Tutorial — Part 1 | by Mahesh Murthy | Medium
mkdir practice-dapp && cd $_ yarn init -y yarn add solc --save yarn add web3@0.20.6 --save mkdir contracts script touch contracts/Voting.sol script/vote.js
create contracts/Voting.sol
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; } }
create script/vote.js
const fs = require('fs'); const solc = require('solc'); const Web3 = require("web3"); main(); function sleep(ms = 0) { return new Promise(r => setTimeout(r, ms)); } async function main(err, blockchain) { // ganeche を起動しておく const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545")); // 登録済みのアカウントを確認 const accounts = web3.eth.accounts; console.log(accounts); // compile 開始 const code = fs.readFileSync('./contracts/Voting.sol').toString(); const compiledCode = solc.compile(code); const abiDefinition = JSON.parse(compiledCode.contracts[':Voting'].interface); const byteCode = compiledCode.contracts[':Voting'].bytecode; // deploy 開始 const VotingContract = web3.eth.contract(abiDefinition); const deployedContract = VotingContract.new( ['Rama','Nick','Jose'], { data: byteCode, from: web3.eth.accounts[0], gas: 4700000 } ) // deploy 中 while (!deployedContract.address) { console.log("wait a minute..."); await sleep(1000); } // deploy 完了 console.log(deployedContract.address); // 投票開始 const contractInstance = VotingContract.at(deployedContract.address) // 投票数を見る view なので gas を消費しない(transaction が発生しない) let result = contractInstance.totalVotesFor.call('Rama'); console.log(result); // transaction が発生する contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]}); contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]}); contractInstance.voteForCandidate('Rama', {from: web3.eth.accounts[0]}); result = contractInstance.totalVotesFor.call('Rama').toLocaleString(); console.log(result); }
感想
version 指定しないで yarn add web3
すると 1.0
の version をインストールするけどこれは不安定なのでお気をつけ下さい。
そして web3 の 0.2.x 系のドキュメントはここ