环境:win7
安装
- 安装nodejs:官网
- 安装truffle框架:
npm install truffle
编译
- 初始化项目文件夹
truffle init
初始文件夹
- contracts/: Solidity合约目录(Migrations.sol)
- migrations/: 部署文件目录(1_initial_migration.js)
- test/: 测试文件目录
- truffle-config.js: windows下Truffle 配置文件(MAC和Linux是truffle.js)
遇到的问题:truffle init时报错
RequestError: Error: getaddrinfo ENOENT raw.githubusercontent.com
解决:https://github.com/trufflesuite/truffle/issues/2692
将本地C:\Windows\System32\drivers\etc\hosts文件替换为https://github.com/googlehosts/hosts中的host文件
cmd执行ipconfig/flushdns即可
- 编写合约
truffle create contract InfoConteact
contracts/InfoConteact.sol
pragma solidity ^0.5.16;
contract InfoContract{
string name;
uint age;
event Instructor(string name,uint age);
function setInfo(string memory _name, uint _age)public{
name=_name;
age=_age;
emit Instructor(name, age);
}
function getInfo()public view returns(string memory,uint){
return (name,age);
}
}
- 编译合约
truffle compile
若报错试试truffle.cmd compile
(Windows下)
首次将编译所有合约,再次编译时只编译有更改的合约。若想全部编译使用truffle compile --compile-all
编译后生成文件夹:
- build/contracts:json文件(包含合约ABI和bytecode)
部署
- 打开ganache,启动节点
- 修改配置文件
truffle-config.js
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 7545, //ganache
network_id: "*"
}
}
}
- 创建迁移脚本
truffle create migration HelloWorld
文件名改为2_deploy_Info.js
var info = artifacts.require("InfoContract");
module.exports = function(deployer) {
deployer.deploy(info);
};
- 部署合约
truffle migrate
每次只运行新建的迁移,使用–reset将从头开始迁移。
加–network可指定网络。
UI
创建文件夹:
- src:存放前端文件
- src/js
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Info truffle DAPP</title>
<link rel="stylesheet" href="./main.css">
</head>
<body>
<div id="container">
<h1 id="title">Info DAPP</h1>
<h2 id="info"></h2><!--显示读取到的内容-->
<div id="loader"><img src="load.png"></div>
<div>
<div>
<label for="name">姓名:</label>
<input type="text" id="name">
</div>
<div>
<label for="age">年龄:</label>
<input type="text" id="age">
</div>
<button id="button">更新</button>
</div>
</div>
</body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="js/web3.min.js"></script>
<script src="js/truffle-contract.js"></script>
<script src="js/app.js"></script>
</html>
交互
truffle-contract
目前只支持web3 0.2x
npm init //根目录下,先转换为npm项目(提示时都使用默认值即可)
完成后出现package.json
npm install truffle-contract
//安装truffle框架提供的contract,对web3进行了封装,方便与合约进行交互
将包中的truffle-contract.js复制到src/js文件夹下
app.js
App={
web3Provider:null,
contracts:{},
init:function(){
return App.initWeb3();
},
//初始化web3
initWeb3:function () {
if (typeof web3 !== 'undefined') {
App.web3Provider = web3.currentProvider;
} else {
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
App.initContrct();
},
//初始化合约
initContrct:function () {
$.getJSON('InfoContract.json',function (data) {
App.contracts.InfoContract = TruffleContract(data);
App.contracts.InfoContract.setProvider(App.web3Provider);
return App.getInfo();
});
App.bindEvents();
App.watchChanged();
},
//调用get方法
getInfo:function () {
App.contracts.InfoContract.deployed().then(function (instance) {
//return instance.methods.getInfo().call(); //没有return后面then就拿不到
return instance.getInfo.call();
}).then(function (result) {
$("#loader").hide();
$("#info").html(result[0]+'(' + result[1] + ' years old )');
}).catch(function (error) {
console.log(error);
});
},
//绑定事件
bindEvents:function () {
$("#button").click(function () {
$("#loader").show();
var message = {
from: '0x2670A910a0Ba3d1faDf6E82EC74087e540d663C9'
};
App.contracts.InfoContract.deployed().then(function (instance) {
return instance.setInfo($("#name").val(),$("#age").val(),message);
}).then(function (result) {
//return App.getInfo(); //重新调用get方法
return App.watchChanged(); //事件监听
}).catch(function (error) {
console.log(error);
});
});
},
//事件监听
watchChanged:function(){
App.contracts.InfoContract.deployed().then(function (instance) {
var infoEvent = instance.Instructor();
infoEvent.watch(function(error,result){
$("#loader").hide();
$("#info").html(result.args.name+'(' + result.args.age + ' years old )');
});
});
}
}
$(function () {
$(window).load(function () {
App.init();
});
});
其中需要使用web3 0.2x的API。
将web3 0.2x的web3.min.js放到src/js下。
lite-server
npm install -g lite-server //安装项目服务器
根目录下创建bs-config.json,写入配置
{
"server": {"baseDir": ["./src", "./build/contracts"] }
}
配置./src,直接localhost:3000 即可打开index.html
配置./build/contracts,index.js里$.getJSON第一个参数路径就可以省略,直接写InfoContract.json即可
修改package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "lite-server" //新增脚本
},
根目录下输入npm run dev
,localhost:3000定位到index.html。
输入姓名和年龄,点击提交,界面上方会自动刷新数据。
测试
truffle test //执行所有测试文件
truffle test ./test/TestInfoContract.sol //测试指定文件
solidity测试用例
文档
pragma solidity ^0.5.16;
import "truffle/Assert.sol";
import "truffle/DeployedAddress.sol"; //动测试时态生成
import "../contracts/InfoContract.sol";
contract TestInfoContract{
//拿到合约实例
InfoContract info = InfoContract(DeployedAddress.InfoContract());
//测试方法
function testInfo(){
info.setInfo("muse",24);
(name,age) = info.getInfo();
Assert.equal(name,"muse","设置名字出错");
Assert.equal(age,24,"设置年龄出错");
}
}