truffle 使用_使用Truffle CLI进行调试

truffle 使用

Debuggers have been crucial software development tools for over thirty years.

三十多年来,调试器一直是至关重要的软件开发工具。

A modern debugger enables us to:

现代调试器使我们能够:

  • run the code line-by-line

    逐行运行代码
  • set breakpoints in the code

    在代码中设置断点
  • put conditions on the breakpoints

    将条件置于断点上
  • evaluate expressions during runtime.

    在运行时评估表达式。

Most modern debuggers are also highly integrated into development environments of languages they are serving. They enable setting breakpoints by clicking on line numbers, evaluating expressions by hovering over variables, writing conditional breakpoints in the code comments … and so on.

大多数现代调试器还高度集成到它们所服务语言的开发环境中。 它们允许通过单击行号来设置断点,通过将鼠标悬停在变量上来评估表达式,在代码注释中编写条件断点……等等。

So what is the state of Solidity smart contract debugging and debuggers?

那么,Solidity智能合约调试和调试器的状态如何?

固态调试器 (Solidity Debugger)

As with most blockchain things, we’re still in the infancy stage. The basic debuggers are available (and advancing at a rapid pace), but no editor integrations are here yet, and the debugger heavily relies on the framework of choice.

与大多数区块链事物一样,我们仍处于起步阶段。 基本的调试器可用(并且正在快速发展),但是这里还没有编辑器集成, 并且调试器严重依赖于所选择的框架。

In this article, we’ll be exploring the Solidity debugger bundled with the Truffle Suite.

在本文中,我们将探索与Truffle Suite捆绑在一起的Solidity调试器。

入门 (Getting Started)

First, we’ll need to install all the required tools. Luckily for us, the Truffle framework is very well integrated, so we’ll just need to install it.

首先,我们需要安装所有必需的工具。 对我们来说幸运的是,Truffle框架已经很好地集成了,因此我们只需要安装它即可。

First, install Node.js and NPM. After you’ve installed Node, you can verify that it’s installed by checking the version of the tool like this:

首先,安装Node.js和NPM 。 安装Node之后,可以通过检查以下工具的版本来验证它是否已安装:

➜  ~ node -v
v10.2.1
➜  ~ npm -v
5.6.0

If your Node is up and running, let’s install the Truffle framework. This is made simple enough by the usage of npm, so just run this:

如果您的Node已启动并正在运行,请安装Truffle框架。 通过使用npm ,这已经足够简单了,因此只需运行以下命令:

npm install -g truffle

You can check whether the install was successful by checking the version:

您可以通过检查版本来检查安装是否成功:

truffle version
Truffle v4.1.11 (core: 4.1.11)
Solidity v0.4.24 (solc-js)

设置项目 (Setting Up the Project)

Now that you have Truffle all set up, let’s create a new (empty) Truffle project. Open your terminal, position yourself into a desired directory and run truffle init. The output should be similar to this:

现在已经完成了松露的全部设置,让我们创建一个新的(空)松露项目。 打开终端,将自己置于所需目录中,然后运行truffle init 。 输出应类似于以下内容:

truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test

After you’ve done this, you should have a contract structure similar to this:

完成此操作后,您应该具有类似于以下的合同结构:

.
├── contracts
│   └── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
├── test
├── truffle-config.js
└── truffle.js

Now open the truffle.js file and put the following data into it:

现在打开truffle.js文件,并将以下数据放入其中:

module.exports = {
  networks: {
      development: {
          port: 9545,
          host: "127.0.0.1",
          network_id: "*"
      }
  }
};

Save the file and run truffle develop. You should get an output similar to this:

保存文件并运行truffle develop 。 您应该得到类似于以下的输出:

truffle develop
Truffle Develop started at http://127.0.0.1:9545/

Accounts:
(0) 0x627306090abab3a6e1400e9345bc60c78a8bef57
(1) 0xf17f52151ebef6c7334fad080c5704d77216b732
(2) 0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef
(3) 0x821aea9a577a9b44299b9c15c88cf3087f3b5544
(4) 0x0d1d4e623d10f9fba5db95830f7d3839406c6af2
(5) 0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e
(6) 0x2191ef87e392377ec08e7c08eb105ef5448eced5
(7) 0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5
(8) 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc
(9) 0x5aeda56215b167893e80b4fe645ba6d5bab767de

Private Keys:
(0) c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3
(1) ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f
(2) 0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1
(3) c88b703fb08cbea894b6aeff5a544fb92e78a18e19814cd85da83b71f772aa6c
(4) 388c684f0ba1ef5017716adb5d21a053ea8e90277d0868337519f97bede61418
(5) 659cbb0e2411a44db63778987b1e22153c086a95eb6b18bdf89de078917abc63
(6) 82d052c865f5763aad42add438569276c00d3d88a2d062d36b2bae914d58b8c8
(7) aa3680d5d48a8283413f7a108367c7299ca73f553735860a87b08f39395618b7
(8) 0f62d96d6675f32685bbdb8ac13cda7c23436f63efbb9d07700d8669ff12b7c4
(9) 8d5366123cb560bb606379f90a0bfd4769eecc0557f1b362dcae9012b548b1e5

Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

⚠️  Important ⚠️  : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.

This started an instance of the Truffle development blockchain backed by ganache-cli (former TestRPC).

这启动了由ganache-cli (以前的TestRPC )支持的Truffle开发区块链的实例。

编写和部署合同 (Writing and Deploying the Contract)

In the contracts directory, make a file called Storage.sol. In that file, put the following code:

在合同目录中,创建一个名为Storage.sol的文件。 在该文件中,输入以下代码:

pragma solidity ^0.4.23;


contract Storage {

    uint[] private _numberStorage;

    event AddedNewNumber(uint position);

    function addNumber(uint newNumber) public returns (uint) {
        _numberStorage.push(newNumber);

        uint numberPosition = _numberStorage.length;

        emit AddedNewNumber(numberPosition);
        return numberPosition;
    }

    function getNumber(uint position) public constant returns (uint) {
        return _numberStorage[position];
    }

}

After you’re done with this, your file structure should look like this:

完成此操作后,您的文件结构应如下所示:

├── contracts
│   ├── Migrations.sol
│   └── Storage.sol
├── migrations
│   └── 1_initial_migration.js
├── test
├── truffle-config.js
└── truffle.js

In the migrations directory, make a new file called 2_deploy_migrations.js and put the following code into it:

migrations目录中,创建一个名为2_deploy_migrations.js的新文件,并将以下代码放入其中:

var Storage = artifacts.require("./Storage.sol");

module.exports = function(deployer) {

    deployer.deploy(Storage);

}

This code defines how Truffle will migrate our project to the blockchain.

这段代码定义 Truffle 如何将我们的项目迁移到区块链。

Now open a new tab in the terminal (leaving the truffle develop running) and run truffle migrate. This will compile and migrate your contracts to the development blockchain. You should get an output like this:

现在在终端中打开一个新选项卡(让truffle develop运行)并运行truffle migrate 。 这将编译您的合同并将其迁移到开发区块链。 您应该得到如下输出:

Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x819678a9812313714a27b52c30f065544a331ec5c79ec6c251bc97cd09398d08
  Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0
Saving successful migration to network...
  ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts...

Now write truffle console. This will open up an interactive console for you to test out your contracts. In the console do the following:

现在编写truffle console 。 这将打开一个交互式控制台,供您测试合同。 在控制台中执行以下操作:

~> Storage.deployed().then((i) => { iStorage = i }) // Store the contract instance into the iStorage variable

~> iStorage.AddedNewNumber({}).watch((err, res) => { console.log("NUMBER POSITION: " + res.args.position.toNumber()) }) // Subscribe to the added new number event

Filter {
  requestManager:
   RequestManager {
     provider: Provider { provider: [HttpProvider] },
     polls: {},
     timeout: null },
  options:
   { topics:
      [ '0x197006a61de03a2f3b4de7f4c4fab6e30ebedef7c1a42d716b2140f184c718b7' ],
     from: undefined,
     to: undefined,
     address: '0xdda6327139485221633a1fcd65f4ac932e60a2e1',
     fromBlock: undefined,
     toBlock: undefined },
  implementation:
   { newFilter:
      { [Function: send] request: [Function: bound ], call: [Function: newFilterCall] },
     uninstallFilter:
      { [Function: send] request: [Function: bound ], call: 'eth_uninstallFilter' },
     getLogs:
      { [Function: send] request: [Function: bound ], call: 'eth_getFilterLogs' },
     poll:
      { [Function: send] request: [Function: bound ], call: 'eth_getFilterChanges' } },
  filterId: null,
  callbacks: [ [Function] ],
  getLogsCallbacks: [],
  pollFilters: [],
  formatter: [Function: bound ] }

~> iStorage.addNumber(13) // Add a new number

{ tx:
   '0xad3f82a6a6cec39dff802f2f16e73bbbc8eff3b68c2ac4da4c371a4c84345a4f',
  receipt:
   { transactionHash:
      '0xad3f82a6a6cec39dff802f2f16e73bbbc8eff3b68c2ac4da4c371a4c84345a4f',
     transactionIndex: 0,
     blockHash:
      '0x464bc0075036cf95484dec165f0248fb0a7db929d14068a312076be14d43d1fe',
     blockNumber: 5,
     gasUsed: 63362,
     cumulativeGasUsed: 63362,
     contractAddress: null,
     logs: [ [Object] ],
     status: '0x01',
     logsBloom:
      '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000010000000000000' },
  logs:
   [ { logIndex: 0,
       transactionIndex: 0,
       transactionHash:
        '0xad3f82a6a6cec39dff802f2f16e73bbbc8eff3b68c2ac4da4c371a4c84345a4f',
       blockHash:
        '0x464bc0075036cf95484dec165f0248fb0a7db929d14068a312076be14d43d1fe',
       blockNumber: 5,
       address: '0x345ca3e014aaf5dca488057592ee47305d9b3e10',
       type: 'mined',
       event: 'AddedNewNumber',
       args: [Object] } ] }

After you’ve run the iStorage.addNumber(...) function, the event we subscribed to should have been fired. If this is the case, the output should contain something like this:

在运行iStorage.addNumber(...)函数之后,应该已触发我们订阅的事件。 在这种情况下,输出应包含以下内容:

truffle(development)> NUMBER POSITION: 1

Now let’s try fetching the number from the position to which we stored it:

现在,让我们尝试从存储位置提取数字:

~> iStorage.getNumber(1)
iStorage.getNumber(1)
Error: VM Exception while processing transaction: invalid opcode
    at XMLHttpRequest._onHttpResponseEnd (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:509:1)
    at XMLHttpRequest._setReadyState (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:354:1)
    at XMLHttpRequestEventTarget.dispatchEvent (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:64:1)
    at XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/httpprovider.js:128:1)
    at /usr/local/lib/node_modules/truffle/build/webpack:/~/truffle-provider/wrapper.js:134:1
    at /usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/requestmanager.js:86:1
    at Object.InvalidResponse (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/errors.js:38:1)

We get an error! How convenient: it seems we can now use the debugger. It’s almost as if it was planned!

我们得到一个错误! 多么方便:看来我们现在可以使用调试器了。 这几乎就像是计划中的!

使用调试器 (Using the Debugger)

In order to debug the transactions, you need to find the transaction hash of the transaction you wish to debug. Copy the transaction hash and, in the terminal, input it in the form:

为了调试事务,您需要找到要调试的事务的事务哈希。 复制交易哈希,并在终端中以以下形式输入:

truffle debug tx_hash

We’ll debug the function which adds the number to the storage. The tx hash will be different for you, but the overall form will be similar to this. And the output should be the same:

我们将调试将数字添加到存储的功能。 对于您来说,tx哈希将有所不同,但是总体形式与此类似。 并且输出应该是相同的:

truffle debug 0x34d26b8bcf01f23dfbef0de28384623ca3ed3e3e7fe28f1a0968d363cf38765f
Compiling ./contracts/Migrations.sol...
Compiling ./contracts/Storage.sol...

Gathering transaction data...

Addresses affected:
 0x345ca3e014aaf5dca488057592ee47305d9b3e10 - Storage

Commands:
(enter) last command entered (step next)
(o) step over, (i) step into, (u) step out, (n) step next
(;) step instruction, (p) print instruction, (h) print this help, (q) quit
(b) toggle breakpoint, (c) continue until breakpoint
(+) add watch expression (`+:<expr>`), (-) remove watch expression (-:<expr>)
(?) list existing watch expressions
(v) print variables and values, (:) evaluate expression - see `v`


Storage.sol:

2:
3:
4: contract Storage {
   ^^^^^^^^^^^^^^^^^^

debug(development:0x34d26b8b...)>

Here we can see the debug console. It’s much more primitive than the modern debuggers most of the developers are used to, but it has all the required functionality. Let’s explore the functionality.

在这里我们可以看到调试控制台。 它比大多数开发人员所习惯的现代调试器原始得多,但是它具有所有必需的功能。 让我们探索一下功能。

In the console, run the following series of commands:

在控制台中,运行以下一系列命令:

debug(development:0x34d26b8b...)> o

Storage.sol:

 8:     event AddedNewNumber(uint position);
 9:
10:     function addNumber(uint newNumber) public returns (uint) {
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

By typing o, we’ve stepped over the function line — meaning we didn’t enter the body of the function we called.

通过输入o ,我们跨过了函数行-这意味着我们没有输入所调用函数的主体。

Now we’re positioned at line 10 — or the header of the function for adding a number. Let’s go further. Type o again.

现在我们位于第10行-或用于添加数字的函数的标题。 让我们走得更远。 再次键入o

Storage.sol:

 9:
10:     function addNumber(uint newNumber) public returns (uint) {
11:         _numberStorage.push(newNumber);
            ^^^^^^^^^^^^^^

Now we’re pushing the number to the array. Type o again.

现在,我们将数字推送到数组。 再次键入o

Storage.sol:

11:         _numberStorage.push(newNumber);
12:
13:         uint numberPosition = _numberStorage.length;

We’ve pushed the number and are getting the position of the number in the array. Press o again.

我们已经推送了数字,并且正在获取数字在数组中的位置。 再次按o

Storage.sol:

13:         uint numberPosition = _numberStorage.length;
14:
15:         emit AddedNewNumber(numberPosition);
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

We’re at the line emitting the position. Now instead of pressing o, let’s inspect our variables and try getting the number back from the array. We can use one of two ways. The first, more generic one is just typing v and inspecting all variables available from the function context.

我们在发出位置的线上。 现在,不用按o ,而是检查变量并尝试从数组中取回数字。 我们可以使用以下两种方法之一。 第一个更通用的方法是键入v并检查函数上下文中可用的所有变量。

Do it by typing v. The output should be this:

输入v 。 输出应该是这样的:

numberPosition: 1
     newNumber: 12
              : 189
_numberStorage: [ 12 ]

The other way to do it is more specific, and we can do it by typing :<variable_name>. Do it by typing :numberPosition. You should get 1 as output.

另一种方法是更具体,我们可以通过输入:<variable_name> 。 通过输入:numberPosition 。 您应该得到1作为输出。

Now let’s try evaluating an expression. You can do this with the : construct also.

现在,让我们尝试评估一个表达式。 您也可以使用:构造。

Let’s try getting our number back with the :_numberStorage[numberPosition]:

让我们尝试使用:_numberStorage[numberPosition]找回我们的电话号码:

debug(development:0x34d26b8b...)> :_numberStorage[numberPosition]
undefined

By running it, we get the output undefined. This means that there is no number there.

通过运行它,我们得到输出undefined 。 这意味着那里没有数字。

To all developers, the error should be reasonably self-evident. We’ve tried accessing the first element at the position one. Since in Solidity, as in most languages, the arrays are zero indexed, we need to access it with the number zero.

对于所有开发人员,该错误应该是不言而喻的。 我们尝试访问位置1的第一个元素。 与大多数语言一样,由于在Solidity中,数组的索引为零,因此我们需要使用数字零对其进行访问。

Press q to exit the debugger and let’s fix the code. In your Storage.sol change this:

q退出调试器,让我们修复代码。 在您的Storage.sol更改以下内容:

uint numberPosition = _numberStorage.length;

to this:

对此:

uint numberPosition = _numberStorage.length - 1;

Now run truffle migrate again, and after it’s finished, run truffle console. In the console, run the commands again:

现在再次运行truffle migrate ,完成后,运行truffle console 。 在控制台中,再次运行命令:

~> Storage.deployed().then((i) => { iStorage = i})
~> iStorage.AddedNewNumber({}).watch((err, res) => { console.log("NUMBER POSITION: " + res.args.position.toNumber()) });
~> iStorage.addNumber(12);
~> output: "NUMBER POSITION: 0"
~> iStorage.getNumber(0)
~> iStorage.getNumber(0).then((res) => { console.log(res.toNumber()) } )
~> output: 12

You’ve successfully deployed and debugged the smart contract!

您已经成功部署和调试了智能合约!

翻译自: https://www.sitepoint.com/debugging-with-truffle-cli/

truffle 使用

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值