Truffle开发入门

一、Truffle框架入门

Truffle是一个功能强大的Dapp开发框架。使用Truffle在以太坊上开发应用程序变得更加简单。

Truffle官网:www.truffleframework.com

(1)安装Truffle

>> npm install -g truffle

安装结束后,可以执行如下命令测试是否安装成功。

>> truffle version

这时候如果可以看到以下输出,就代表安装成功。

(2)创建Truffle工程

第一步:在磁盘上新建一个空目录。

第二步:进入该目录后,执行下面命令。

>> truffle init

执行完成后,系统会自动生成以下目录结构:

contracts:存放合约文件

migrations:存放部署文件

test:存放测试文件

truffle-config.js:配置文件,描述不同网络

(3)编写合约

首先,在contracts目录下新建一个合约文件,代码如下所示:

pragma solidity ^0.4.24;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns(uint) {
        return storedData;
    }
}

然后,进入命令窗口,在项目根路径下执行以下命令编译合约:

>> truffle compile

执行该命令的时候,truffle框架会把contracts目录下的每一个合约都进行编译,并且在项目根路径下生成build文件夹。

Truffle开发入门_第1张图片

 

build文件夹下有一些json文件,这些json文件记录了合约的详细信息(比如abi、bytecode、network等等)。

(4)部署合约

第一步:在migrations目录下创建部署脚本,脚本文件的名称为“2_simplestorage_migration.js”。

const SimpleStorage = artifacts.require("./SimpleStorage.sol");

module.exports = function(deployer) {
  deployer.deploy(SimpleStorage);
};

第二步:打开truffle-config.js文件,在networks节点下添加以下配置网络。

ganacheNet: {
    host: "127.0.0.1",
    port: 7545,
    network_id: "*"
}

其中ganacheNet代表要部署合约的网络名,可以自己定义。

第三步:启动ganache客户端,并且在命令窗口中执行以下命令部署合约。

>> truffle migrate --network ganacheNet

执行完该命令后,networks会填充对应的网络和部署合约地址。

Truffle开发入门_第2张图片

(5)测试合约

第一步:打开remix,然后在browse菜单下新建一个合约,然后把上面的合约代码复制过来。从truffle-config.js文件中复制合约地址到remix上。

第二步:连接ganche本地网络,然后选择SimpleStorage合约后点击Deploy按钮部署合约。

第三步:测试网络。

Truffle开发入门_第3张图片

至此,合约的编译、部署、测试工作已经完成。接下来我们会更进一步地去看一下truffle框架的高级用法。

 

二、使用develop环境部署合约

truffle本身也内置了一个测试环境。

(1)启动truffle测试环境

>> truffle develop

启动后的控制台如下所示:

Truffle开发入门_第4张图片

truffle内置环境的网络地址为:http://127.0.0.1:9545,打开metamask,拷贝助记词后切换到该网络即可。

(2)truffle交互命令:

命令 说明
compile 编译合约
migrate 部署合约

使用truffle-contract库调用合约方法的步骤与使用web3调用合约方法有点类似,下面对比两种方法的区别:

对比项 web3 truffle-contract
创建合约实例 var instance = new web3.eth.Contract(abi, address) var contract = require("truffle-contract"); 
var myContract = contract(SimpleStorage.json)
设置web3 instance.setProvider(provider) myContract .setProvider(provider)
获取合约实例   var deployedInstance= await myContract.deployed()
调用send方法 instance.methods.setValue(10).send({from : xxx}).then(res) let res = await deployedInstance.setValue(5, {from:xxxx})
调用call方法 instance.methods.getValue().call({from : xxx}).then(res) deployedInstance.getValue.call(参数填这里, {from :xxx}).then(res)

上面第一个对比项的myContract 变量是一个使用truffle-contract包装的web3实例。它提供了一些调用合约的方法。

truffle控制台已经自带了web3的实例,但是该实例是使用truffle-contract库进行了包装。

关于truffle-contract的用法,可以参考:https://github.com/trufflesuite/truffle-contract

(3)truffle演示

>> compile
>> migrate
>> var deployedInstance;
>> SimpleStorage.deployed().then(instance => {deployedInstance = instance})
>> deployedInstance.get.call()

第1行:编译合约

第2行:部署合约

第3行:定义合约实例

第4行:初始化合约实例

第5行:调用合约的get方法

(4)测试合约

truffle提供了两种测试方式:JavaScript和Solidity。

官方文档:https://truffleframework.com/docs/truffle/testing/testing-your-contracts

使用solidity测试合约的具体步骤:

1)第一步:在test文件夹下创建测试合约。

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/SimpleStorage.sol";

contract TestSimpleStorage {

    function testSet() public {
        // 获取合约实例
        SimpleStorage ss = SimpleStorage(DeployedAddresses.SimpleStorage());
        // 调用set方法
        ss.set(1000);
        // 调用get方法
        uint res = ss.get();
        // 断言
        Assert.equal(res, 1000, "res should be 1000.");
    }

}

第1、2行的import命令是固定的,第3行import导入要测试的合约。

注意:1)合约名称必须Test开头,函数名也必须以test开头。2)合约名和文件名要相同。

2)第二步:执行test命令。

>> truffle test

如果断言正确,控制台会输出:

Truffle开发入门_第5张图片

如果断言失败,控制台输出:

Truffle开发入门_第6张图片

 

二、Truffle内置Inbox

truffle内置了一些项目(比如react),能够方便我们进行二次开发。如果要使用这些项目,就要先下载到本地。

(1)下载内置的react项目

第一步:在本地磁盘上创建一个空目录;

第二步:在命令行进入该目录,然后以下执行命令;

>> npm unbox react

由于下载时间很长,所以笔者直接到官网上下载项目。

下载地址:https://truffleframework.com/boxes/react

Truffle开发入门_第7张图片

下载完成后,把压缩文件家压缩到新建目录中。目录结构如下图所示:

Truffle开发入门_第8张图片

从图上可以看出,truffle-react项目的目录比之前truffle项目多了一个client目录。

在控制台进入client目录所在路径,然后执行命令下载依赖包。

>> npm install

(2)运行内置的react项目

第一步:打开控制台,启动develop环境,然后复制助记词;

>> truffle develop

2)在develop环境下编译和部署合约;

>> compile
>> migrate

3)在浏览器打开metamask插件,输入助记词,然后切换到本地网络(http://127.0.0.1:9545);

4)打开另外一个控制台,进入client目录所在路径,然后启动react项目:

>> npm start

 如果启动成功,在浏览器上输入localhost:3000,界面效果如下所示:

Truffle开发入门_第9张图片

(3)App.js源码分析

import React, { Component } from "react";
import SimpleStorageContract from "./contracts/SimpleStorage.json";
import getWeb3 from "./utils/getWeb3";

import "./App.css";

class App extends Component {
  // 初始化状态变量
  state = { 
      storageValue: 0,   // 调用合约实例get方法返回的结果
      web3: null,        // web3实例
      accounts: null,    // 合约帐号
      contract: null     // 合约实例
  };

  // 定义构造函数
  componentDidMount = async () => {
    try {
      // 获取web3实例
      const web3 = await getWeb3();

      // 获取所有用户
      const accounts = await web3.eth.getAccounts();

      // 获取合约实例
      const networkId = await web3.eth.net.getId();
      const deployedNetwork = SimpleStorageContract.networks[networkId];
      const instance = new web3.eth.Contract(
        SimpleStorageContract.abi,
        deployedNetwork && deployedNetwork.address,
      );

      // 把web3、accounts和contract设置到状态变量中
      // 然后运行runExample方法与合约进行交互
      this.setState({ web3, accounts, contract: instance }, this.runExample);
    } catch (error) {
      ...
    }
  };

  runExample = async () => {
    // 从state中把accounts和contract解构出来
    const { accounts, contract } = this.state;

    // 调用合约set方法
    await contract.methods.set(5).send({ from: accounts[0] });

    // 调用合约get方法
    const response = await contract.methods.get().call();

    // 把结果设置到状态变量storageValue中
    this.setState({ storageValue: response });
  };

  // 渲染页面
  render() {
    if (!this.state.web3) {
      return 
Loading Web3, accounts, and contract...
; } return (

Good to Go!

Your Truffle Box is installed and ready.

Smart Contract Example

If your contracts compiled and migrated successfully, below will show a stored value of 5 (by default).

Try changing the value stored on line 40 of App.js.

The stored value is: {this.state.storageValue}
); } } export default App;

 

你可能感兴趣的:(技术总结和分享)