介紹
Truffle 是一個在以太坊進行 DApp 開發的世界級開發環境、測驗框架,
安裝truffle
在安裝truffle之前需要安裝nodejs,安裝后通過如下命令安裝truffle:
sudo npm install -g truffle
安裝程序中可能會報錯,如果報錯則執行如下命令升級nodejs:
sudo npm install -g n
sudo n stable
truffle安裝完成后用如下命令檢查:
truffle -v
寫合約
我們寫一個簡單的投票合約,如下:
pragma solidity >=0.4.22 <0.6.0;
contract Voting {
bytes32[] public candidateList;
mapping(bytes32 => uint8) public votesReceived;
constructor(bytes32[] memory candidateListName) public {
candidateList = candidateListName;
}
function validateCanditate(bytes32 candidateName)internal view returns(bool) {
for (uint8 i =0; i < candidateList.length; i++) {
if (candidateName == candidateList[i])
return true;
}
return false;
}
function voteForCandidate(bytes32 candidateName) public {
require(validateCanditate(candidateName));
votesReceived[candidateName] += 1;
}
function totalVotesFor(bytes32 candidateName) view public returns(uint8) {
require(validateCanditate(candidateName));
return votesReceived[candidateName];
}
}
先將上述合約在remix中除錯通過,
創建工程
使用如下命令創建工程:
mkdir Vote
cd Vote
truffle unbox webpack
創建合約:
cd contracts
rm meta.sol
rm Lib.sol
vim Voting.sol
將上面的合約代碼拷貝到Voting.sol中,
修改migrations/_deploy_contracts.js如下:
//const ConvertLib = artifacts.require("ConvertLib");
//const MetaCoin = artifacts.require("MetaCoin");
const Voting = artifacts.require("Voting.sol");
module.exports = function(deployer) {
//deployer.deploy(ConvertLib);
//deployer.link(ConvertLib, MetaCoin);
//deployer.deploy(MetaCoin);
//deployer.deploy(Voting, ['A', 'B']);//error,注意,要使用16進制 bytes32
deployer.deploy(Voting,
["0x4100000000000000000000000000000000000000000000000000000000000000",
"0x4200000000000000000000000000000000000000000000000000000000000000"]);
};
編譯合約
truffle compile
部署合約
啟動ganache-cli:
ganache-cli//如果報錯則重新安裝下npm install -g ganache-cli
修改truffle-config.js如下:
module.exports = {
/**
* Networks define how you connect to your ethereum client and let you set the
* defaults web3 uses to send transactions. If you don't specify one truffle
* will spin up a development blockchain for you on port 9545 when you
* run `develop` or `test`. You can ask a truffle command to use a specific
* network from the command line, e.g
*
* $ truffle test --network <network-name>
*/
networks: {
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 8545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},
...
}
部署:
truffle migrate
部署完后可以用truffle console進行測驗:
truffle console//打開truffle控制臺
let instance = await Voting.deployed()
instance
修改前端的頁面
修改app/src/index.html如下:
<!DOCTYPE html>
<html>
<head>
<title>Vote Demo</title>
</head>
<body>
<h1>Voting App</h1>
<p>Alice: <strong id="alice">loading...</strong> votes </p>
<p>Bob: <strong id="bob">loading...</strong> votes </p>
<label for="vote">VoteFor:</label>
<input type="text" id="candidate"/>
<button onclick="App.voteForCandidate()">vote</button>
<script src="index.js"></script>
</body>
</html>
修改app/src/index.js如下:
import Web3 from 'web3';
import votingArtifact from '../../build/contracts/Voting.json'
const aInBytes32 = "0x4100000000000000000000000000000000000000000000000000000000000000";
const bInBytes32 = "0x4200000000000000000000000000000000000000000000000000000000000000";
const App = {
web3: null,
account: null,
voting: null,
start: async function() {
const { web3 } = this;
try {
// get contract instance
const networkId = await web3.eth.net.getId();
const deployedNetwork = votingArtifact.networks[networkId];
this.voting = new web3.eth.Contract(
votingArtifact.abi,
deployedNetwork.address,
);
// get accounts
const accounts = await web3.eth.getAccounts();
this.account = accounts[0];
// console.log("will ready +++++++ ");
this.ready();
} catch (error) {
console.error("Could not connect to contract or chain.");
}
},
refresh: async function(id, nameInBytes32) {
const { totalVotesFor } = this.voting.methods;
const tickets = await totalVotesFor(nameInBytes32).call();
const element = document.getElementById(id);
element.innerHTML = tickets.toString();
},
ready: async function() {
try {
this.refresh("alice", aInBytes32);
this.refresh("bob", bInBytes32);
} catch (err) {
console.log(err);
}
},
voteForCandidate: async function() {
try {
const { voteForCandidate } = this.voting.methods;
const candidateName = document.getElementById("candidate").value;
if (candidateName == "Alice") {
await voteForCandidate(aInBytes32).send({ from: this.account });;
this.refresh("alice", aInBytes32);
} else if (candidateName == "Bob") {
await voteForCandidate(bInBytes32).send({ from: this.account });;
this.refresh("bob", bInBytes32);
}
} catch (err) {
console.log(err);
}
},
}
window.App = App;
window.addEventListener("load", function() {
// console.log("load+++++");
if (window.ethereum) {
// use MetaMask's provider
App.web3 = new Web3(window.ethereum);
window.ethereum.enable(); // get permission to access accounts
} else {
console.warn(
"No web3 detected. Falling back to http://127.0.0.1:8545. You should remove this fallback when you deploy live",
);
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
App.web3 = new Web3(
new Web3.providers.HttpProvider("http://127.0.0.1:8545"),
);
}
App.start();
});
運行
npm run dev
打開瀏覽器,輸入127.0.0.1:8080
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/237703.html
標籤:區塊鏈
上一篇:composer require(install.update) Failed to execute git clone --mirror ;remote: HTTP Basic: Access。
