console 调试合约

本章学习如何使用 console 调试智能合约。

推特@Hita_DAO    DiscordHitaDAO

Foundry 项目中,我们除了使用 forge 命令对合约进行测试外,还经常插入 console.log 语句来输出信息。

console.log 语句既能应用于测试用例合约,又能应用于被测试合约。

1. 测试合约使用 console

Foundry  的标准合约 forge-std 中提供了一个 console 库合约,可以通过 import 语句引入使用。

使用这个 console 库合约,我们就可以在 solidity 代码中直接调用函数 console.log,用来打印日志信息和合约变量。

我们拿 test 目录下 Counter.t.sol 文件中的 CounterTest 合约为例:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Test, console} from "forge-std/Test.sol";
import {Counter} from "../src/Counter.sol";

contract CounterTest is Test {
    Counter public counter;

    function setUp() public {
        counter = new Counter(); // 创建被测试合约 counter
        counter.setNumber(0);  // 调用被测试合约的函数 setNumber,设置初值
    }

    function test_Increment() public {
        counter.increment(); // 调用被测试合约的函数 increment
        console.log("number is = ", counter.number());
        assertEq(counter.number(), 1); // 判断被测试合约中 number 的值是否等于 1
    }

    function test_SetNumber(uint256 x) public {
        counter.setNumber(x); // 调用被测试合约的函数 setNumber
        assertEq(counter.number(), x); // 判断被测试合约中 number 的值是否等于 1
    }
}

在命令行中输入测试命令:

forge test -vvv

输出测试结果:

[⠢] Compiling...
[⠰] Compiling 1 files with 0.8.21
[⠔] Solc 0.8.21 finished in 2.11s
Compiler run successful!

Ran 2 tests for test/Counter.t.sol:CounterTest
[PASS] test_Increment() (gas: 35348)
Logs:
  number is =  1

[PASS] test_SetNumber(uint256) (runs: 256, μ: 30176, ~: 31265)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 15.26ms (14.62ms CPU time)

Ran 1 test suite in 326.53ms (15.26ms CPU time): 2 tests passed, 0 failed, 0 skipped (2 total tests)

我们在输出测试结果的 Logs 中,可以看到:number is = 1。

2. 被测试合约使用 console

Foundry  的标准合约 forge-std 中提供了一个 console 库合约,还可以在被测试合约中使用。

我们拿 src 目录下 Counter.sol 文件中的 Counter 合约为例:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {console} from "forge-std/console.sol";

contract Counter {
    uint256 public number;

    function setNumber(uint256 newNumber) public {
        number = newNumber;
        console.log("number in contract Counter =", number);
    }

    function increment() public {
        number++;
    }
}

在命令行中输入测试命令:

forge test -vvv

输出测试结果:

[⠆] Compiling...
[⠆] Compiling 2 files with 0.8.21
[⠰] Solc 0.8.21 finished in 1.89s
Compiler run successful!

Ran 2 tests for test/Counter.t.sol:CounterTest
[PASS] test_Increment() (gas: 31337)
Logs:
  number in contract Counter =  0

[PASS] test_SetNumber(uint256) (runs: 256, μ: 33509, ~: 34442)
Logs:
  number in contract Counter = 0

Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 29.25ms (19.41ms CPU time)

Ran 1 test suite in 324.13ms (29.25ms CPU time): 2 tests passed, 0 failed, 0 skipped (2 total tests)

我们在输出测试结果的 Logs 中,可以看到:number in contract Counter = 0。