6-2、3、4,truffle部署合约及测试(react+区块链实战)
- [6-2 truffle介绍安装(pet-shop下载编译)](#6-2 truffle介绍安装(pet-shop下载编译))
- [6-3 部署合约到本地私有链](#6-3 部署合约到本地私有链)
- [6-4 测试合约代码](#6-4 测试合约代码)
6-2 truffle介绍安装(pet-shop下载编译)
Truffle(以太坊的开发套件)
智能合约的编译和部署就会变得自动化
之前在remix中编译和部署都是在浏览器中自动进行的
自己编译的时候会生成API(是json可以部署),还有给web3做接口,整个过程
在已经安装好nodejs的电脑上
执行npm install -g truffle
安装成功后
在cmd输入truffle
如下
体验官方的学习demo宠物商店
直接使用truffle命令
下载失败
先在一个地方建立文件夹,然后输入
Truffle和ganache都是套件一个是开发用的,一个是部署私有链用的
在windows一直安装失败,原因链接不上github,可能需要翻墙
这直接在码云搜索看是否存在此项目
https://gitee.com/tongxiaojun/pet-shop-box
直接在码云上将此项目下载下来放到需要的文件夹下
Contract
是写合约的地方
Migrations
是部署的脚本
Node_modules
是npm的安装文件
Src
是源码目录(自带可以不用管,里面的图片可以拿出),自带了一个项目
Truffle.js
比较重要(可以配置开启的服务)
监听7545
Test测试目录
此时本地无编译器
故在remix进行合约编写,方便看
进行宠物领养需要输入宠物的id
在src文件下的pets.json下有id
pragma solidity ^0.4.24;
contract Adpotion{
//地址数组,公开变量
address[16] public adopters;
//宠物领养,参数宠物id
function adopt(uint petId) public returns(uint){
//断言,必须满足require的代码才能向下执行
require(petId>=0 && petId<16); //宠物的id必须在0-15,否则不会向下执行
//将当前宠物id对应用户地址获得
adopters[petId] = msg.sender; //msg.sender谁执行此合约,谁调用此领养函数,当前的地址就是谁
//只要值改变了,数据就存在数据库中
return petId;
}
//获取所有的领养者地址
//此函数无修改,即只需要使用VIEW修饰只读
function getAdopters() public view returns(address[16] ){
return adopters;
}
}
所有代码如上
在contract中的sol进行保存
并在windows进行编译使用truffle compile
发现编译失败,这是因为版本不对应的问题
在remix可以更换版本但下载的truffle是很高的版本0.5.16
所以对代码进行简单的更改
pragma solidity ^0.5.16;
//此函数无修改,即只需要使用VIEW修饰只读
function getAdopters() public view returns(address[16] memory){
return adopters;
}
版本及memory,具体可以看乐上至轻的合约讲解很细
在remix编译成功后再保存到如下
再编译就成功了
编译成功后会在build的contract下生成对应的json文件
此编译后的json在后续会有用
6-3 部署合约到本地私有链
合约如上
如何部署此合约
1,进入ganache,重启私有链
2,新建在migrations部署中如下
可以通过正确的匹配智能合约
3,编译及部署
部署报错,原因在合约下查看合约文件名及代码的合约名,找到错误更改
上方的函数忘记加入返回值了
重新编译部署(一定要重新reset)
Truffle migrate --reset --all
部署成功了
4,在ganache中查看,部署有消耗
5,查看区块有四个,上方只部署了adoption合约
部署合约已经成功了,但是发现没有什么效果,需要在前端进行体现
6-4 测试合约代码
写的智能合约非常简单
在test目录下,新建测试合约
pragma solidity ^0.5.16;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol"; //模拟部署的库
import "../contracts/Adoption.sol"; //写的合约
contract TestAdoption{
Adoption adoption = Adoption(DeployedAddresses.Adoption());//对合约进行部署
//测试部署合约中的函数
function testUserCanAdopt() public{
uint returnId = adoption.adopt(8); //执行之前编写的合约的adopt函数
uint expectId = 8;
Assert.equal(returnId,expectId,"返回领养id"); //希望返回的id和期望的id是相等的
}
}
在之前合约的编译部署了
上方的代码无问题
Truffle compile
Truffle migrate
这里的测试合约直接对之前写的合约部署,执行
Truffle test
测试成功了
加入第2个测试函数
pragma solidity ^0.5.16;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Adoption.sol";
contract TestAdoption{
Adoption adoption = Adoption(DeployedAddresses.Adoption());
function testUserCanAdopt() public{
uint returnId = adoption.adopt(8);
uint expectId = 8;
Assert.equal(returnId,expectId,"返回领养id");
}
//第二个测试函数
function testCanGetAdopters() public{
address expect = address(this); //this调用合约的地址值
address[16] memory adopters = adoption.getAdopters(); //调用合约中的函数
Assert.equal(adopters[8],expect,"领养后。我的地址是否会被记录下来"); //判断两者地址是否相同
}
}
再次测试
https://blog.csdn.net/sinyusin/article/details/88558519
编译合约报错:TypeError: Type contract TestAdoption is not implicitly convertible to expected type address.
测试成功了