当前位置: 代码网 > 科技>人工智能 > Truffle 开发入门

Truffle 开发入门

2024年08月01日 人工智能 我要评论
Truffle 是一个以太坊智能合约集成开发框架。Truffle 使用以太坊虚拟机(EVM)为区块链提供了世界级的开发环境、测试框架和资产管道,旨在让开发人员的工作更轻松。本文我们从一个 Truffle 官方示例入手,带你快速了解利用 Truffle 开发区块链项目的基础知识,包括 Truffle 项目的创建,智能合约的编译与部署,以及 Truffle 与智能合约进行交互实现区块链上的交易。

truffle 是一个以太坊智能合约集成开发框架。truffle 使用以太坊虚拟机(evm)为区块链提供了世界级的开发环境、测试框架和资产管道,旨在让开发人员的工作更轻松。本文我们从一个 truffle 官方示例入手,带你快速了解利用 truffle 开发区块链项目的基础知识,包括 truffle 项目的创建,智能合约的编译与部署,以及 truffle 与智能合约进行交互实现区块链上的交易。

项目依赖

安装

本文我们只介绍 truffle 的安装,其它依赖包的安装请参考对应的安装文档。

通过下面的命令安装 truffle:

npm install -g truffle

通过下面的命令确认是否已正确安装:

truffle version

控制台输出内容如下:

truffle v5.6.7 (core: 5.6.7)
ganache v7.5.0
solidity - 0.8.13 (solc-js)
node v16.15.0
web3.js v1.7.4

通过下面的命令查看 truffle 帮助:

truffle help

创建项目

首先,创建一个 truffle 项目。

本文我们使用 truffle 的官方示例 metacoin box 来创建i项目。

通过下面的命令创建项目:

mkdir metacoin
cd metacoin
truffle unbox metacoin

以上命令在 metacoin 目录下创建了这个 truffle 项目。

我们来看一下这个项目的目录结构:

  • contracts/:solidity 合约目录
  • migrations/:部署脚本目录
  • tests/:测试文件目录
  • truffle-config.js:truffle 配置文件

配置文件

配置文件位于项目根目录下,文件名为 truffle-config.js。

配置文件内容如下:

module.exports = {
  networks: {
    development: {
	  host: "127.0.0.1",     // localhost (default: none)
	  port: 7545,            // standard ethereum port (default: none)
	  network_id: "*",    	 // any network (default: none)
    }
  },

  compilers: {
    solc: {
      version: "0.8.13",      // fetch exact version from solc-bin
    }
  }
};

这个配置文件中,development 是我们要部署的区块链配置,这里指我们本地的 ganache 区块链节点。如果需要部署到其它区块链节点,请修改此配置文件。

智能合约

合约源码

我们来看一下合约的源码,文件名是 metacoin.sol。

pragma solidity ^0.8.13;
import "./convertlib.sol";

contract metacoin {
	mapping (address => uint) balances;

	event transfer(address indexed _from, address indexed _to, uint256 _value);

	constructor() {
		balances[tx.origin] = 10000;
	}

	function sendcoin(address receiver, uint amount) public returns(bool sufficient) {
		if (balances[msg.sender] < amount) return false;
		balances[msg.sender] -= amount;
		balances[receiver] += amount;
		emit transfer(msg.sender, receiver, amount);
		return true;
	}

	function getbalanceineth(address addr) public view returns(uint){
		return convertlib.convert(getbalance(addr),2);
	}

	function getbalance(address addr) public view returns(uint) {
		return balances[addr];
	}
}

这个合约包含一个构造函数、还定义了一个事件和三个函数。

  • constructor():合约的构造函数,在合约部署时自动存入一些 token 到发起者的账户。
  • event transfer(...):事件。转账交易时触发。
  • sendcoin(...):将 token 从一个账户转账到另一个账户。
  • getbalanceineth(...):取经转换后的账户余额(账户余额*2)。
  • getbalance(...):取账户余额(单位:1wei)。

测试合约

这个示例定义了两个测试文件,保存在 test 目录下:

  • metacoin.js 用 javascript 编写的测试脚本
  • testmetacoin.sol:用 solidity 编写的测试脚本

truffle 自带一个自动化测试框架,可以轻松测试合约,而不需要我们事先部署合约。

通过下面的命令运行所有测试:

truffle test

控制台输出如下:

compiling your contracts...
===========================
> compiling .\contracts\convertlib.sol
> compiling .\contracts\metacoin.sol
> compiling .\test\testmetacoin.sol
> compiling truffle\assert.sol
> compiling truffle\assertaddress.sol
> compiling truffle\assertaddressarray.sol
> compiling truffle\assertbalance.sol
> compiling truffle\assertbool.sol
> compiling truffle\assertbytes32.sol
> compiling truffle\assertbytes32array.sol
> compiling truffle\assertgeneral.sol
> compiling truffle\assertint.sol
> compiling truffle\assertintarray.sol
> compiling truffle\assertstring.sol
> compiling truffle\assertuint.sol
> compiling truffle\assertuintarray.sol
> compiling truffle\deployedaddresses.sol
> artifacts written to c:\users\zhang\appdata\local\temp\test--19216-dtwx8m04rlbn
> compiled successfully using:
   - solc: 0.8.13+commit.abaa5c0e.emscripten.clang

  testmetacoin
    √ testinitialbalanceusingdeployedcontract (93ms)
    √ testinitialbalancewithnewmetacoin (52ms)

  contract: metacoin
    √ should put 10000 metacoin in the first account (43ms)
    √ should call a function that depends on a linked library (49ms)
    √ should send coin correctly (100ms)

  5 passing (5s)

你也可以指定特定的文件进行测试,如:

truffle test .\test\metacoin.js
truffle test .\test\testmetacoin.sol

经测试无误后的合约,我们就可以将合约编译,然后部署到区块链中。

编译合约

通过下面的命令编译合约:

truffle compile

控制台输出信息如下:

compiling your contracts...
===========================
> compiling .\contracts\convertlib.sol-bin. attempt #1
> compiling .\contracts\metacoin.sol
> artifacts written to d:\work\blockchain\truffle-demo\metacoin\build\contracts
> compiled successfully using:
   - solc: 0.8.13+commit.abaa5c0e.emscripten.clang
_ fetching solc version list from solc-bin. attempt #1

编译后在根目录下自动生成 build\contracts 目录。编译后生成的 artifacts(我们翻译为"工件"或"构件")将被放置在该目录下,文件名后缀为 .json,对应于合约名称(非文件名称)。

部署合约

部署合约的脚本位于根目录下的 migrations 目录下。

文件名: 1_deploy_contracts.js

内容如下:

const convertlib = artifacts.require("convertlib");
const metacoin = artifacts.require("metacoin");

module.exports = function(deployer) {
  deployer.deploy(convertlib);
  deployer.link(convertlib, metacoin);
  deployer.deploy(metacoin);
};

在执行部署之前,确保已启动测试区块链,如 ganache 本地区块链。

接下来,我们运行下面的命令来部署合约:

truffle migrate

控制台输出信息如下:

starting migrations...
======================
> network name:    'development'
> network id:      5777
> block gas limit: 6721975 (0x6691b7)

1_deploy_contracts.js
=====================

   replacing 'convertlib'
   ----------------------
   > transaction hash:    0x626b0b2024f1de281a250f4c63d16cbaec056033235bc9f92e734ed42397787b
   > blocks: 0            seconds: 0
   > contract address:    0x9d97751e2091147e4dfe61d1384951ac89a3f886
   > block number:        7
   > block timestamp:     1669880418
   > account:             0x1665135c6681a43ee2f08b681a4bd8a9eb37fdc0
   > balance:             99.96252516
   > gas used:            157568 (0x26780)
   > gas price:           20 gwei
   > value sent:          0 eth
   > total cost:          0.00315136 eth

   linking
   -------
   * contract: metacoin <--> library: convertlib (at address: 0x9d97751e2091147e4dfe61d1384951ac89a3f886)

   replacing 'metacoin'
   --------------------
   > transaction hash:    0xfecbdb6d763a91d1cc909c14b2e778edc0c0fdad4c3e1b6a696ee33d2443785d
   > blocks: 0            seconds: 0
   > contract address:    0x3e330cbe1bc04766a8f83203277f349e58b243cd
   > block number:        8
   > block timestamp:     1669880419
   > account:             0x1665135c6681a43ee2f08b681a4bd8a9eb37fdc0
   > balance:             99.95423528
   > gas used:            414494 (0x6531e)
   > gas price:           20 gwei
   > value sent:          0 eth
   > total cost:          0.00828988 eth

   > saving artifacts
   -------------------------------------
   > total cost:          0.01144124 eth

summary
=======
> total deployments:   2
> final cost:          0.01144124 eth

合约交互

启动控制台

合约部署完成后,我们就可以通过 truffle 控制台与合约进行交互。

首先,我们启动 truffle 控制台。命令如下:

truffle console

此命令连接到您当前配置的区块链节点,连接成功后进入控制台命令模式,如下:

truffle(development)>

我们来验证一下连接是否成功。执行下面的 web3.js api 接口来获取区块链账户:

truffle(development)> web3.eth.getaccounts()

输出如下:

[
  '0x1665135c6681a43ee2f08b681a4bd8a9eb37fdc0',
  '0x28a71881645084c58ef7f82861b7ebd76bbaa75a',
  '0xed1c82d205570735582150d8ebcdc576b0a18039',
  '0xc81e32bae8f99b324593a18cd72f6fd6d6aeb780',
  '0x0fff006ae1d7d2b88e196d45a5026da6d7883ae5',
  '0x868d62f3813cf93d0654f87fb3a0dccb2da0ccab',
  '0x926f0ca47f625082d0920308c1979eceee9c4a20',
  '0x9b50cd8fbd95d9808762d398bd6923694a79b488',
  '0x68c23e5cc4b7d45ccd432f7d3e8e75bf4a0bdfaa',
  '0x00dd9aebf04c842ec7005b3d7bbf7f4bc7180d0b'
]

以上为 ganache 区块链中的测试账户。说明已经成功连接到 ganache。

与合约交互

根据合约源文件,我们知道该合约除了构造函数之外,还有三个方法(getbalancegetbalanceinethsendcoin。下面我们来看实际的交互过程。

1. 合约抽象

首先,在与合约交互之前,我们先获取合约抽象实例。代码如下:

truffle(development)> let instance = await metacoin.deployed()
truffle(development)> instance

2. 获取账户

通过下面的代码获取账户列表:

truffle(development)> let accounts = await web3.eth.getaccounts()
truffle(development)> accounts

3.获取余额

调用函数 getbalance 获取账户余额。代码如下:

truffle(development)> let balance = await instance.getbalance(accounts[0])
truffle(development)> balance.tonumber()
10000

4. 获取余额(经转换后)

调用函数 getbalanceineth 获取经转换后的账户余额。代码如下:

truffle(development)> let balance2 = await instance.getbalanceineth(accounts[0])
truffle(development)> balance2.tonumber()
20000

5. 转账交易

调用函数 sendcoin 发起转账交易。代码如下:

truffle(development)> let result = await instance.sendcoin(accounts[1], 10)
truffle(development)> result

以上转账从 accounts[0] 转账到 accounts[1],数量为 10 个 token。

result` 内容如下:

{
  tx: '0xb669c2bc68bf0c05d449b0acc85c50baa6a634744484b8cde507fd66f34dd337',
  receipt: {
    transactionhash: '0xb669c2bc68bf0c05d449b0acc85c50baa6a634744484b8cde507fd66f34dd337',
    transactionindex: 0,
    blockhash: '0x8f3d6d378a067a8c255d90779beaf0e9a8625311bf0a031b5983b0306f4429fc',
    blocknumber: 9,
    from: '0x1665135c6681a43ee2f08b681a4bd8a9eb37fdc0',
    to: '0x3e330cbe1bc04766a8f83203277f349e58b243cd',
    gasused: 52485,
    cumulativegasused: 52485,
    contractaddress: null,
    logs: [ [object] ],
    status: true,
    ......

我们来验证一下转账是否成功:

truffle(development)> let new_balance = await instance.getbalance(accounts[0])
truffle(development)> new_balance.tonumber()
9990
truffle(development)> let new_balance2 = await instance.getbalance(accounts[1])
truffle(development)> new_balance2.tonumber()
10

6. 捕获事件

转账的同时会触发事件,我们来看一下事件的日志内容:

truffle(development)> result.logs[0]

控制台输出内容如下:

{
  logindex: 0,
  transactionindex: 0,
  transactionhash: '0xb669c2bc68bf0c05d449b0acc85c50baa6a634744484b8cde507fd66f34dd337',
  blockhash: '0x8f3d6d378a067a8c255d90779beaf0e9a8625311bf0a031b5983b0306f4429fc',
  blocknumber: 9,
  address: '0x3e330cbe1bc04766a8f83203277f349e58b243cd',
  type: 'mined',
  id: 'log_ccd64ce1',
  event: 'transfer',
  args: result {
    '0': '0x1665135c6681a43ee2f08b681a4bd8a9eb37fdc0',
    '1': '0x28a71881645084c58ef7f82861b7ebd76bbaa75a',
    '2': bn { negative: 0, words: [array], length: 1, red: null },
    __length__: 3,
    _from: '0x1665135c6681a43ee2f08b681a4bd8a9eb37fdc0',
    _to: '0x28a71881645084c58ef7f82861b7ebd76bbaa75a',
    _value: bn { negative: 0, words: [array], length: 1, red: null }
  }
}
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com