调试智能合约终极指南:Web3 开发人员的提示和工具

作者:Olubisi Idris Ayinde来源:DeveloperDAO2023-05-22

智能合约开发对于在区块链上构建去中心化应用程序至关重要。然而,与任何软件开发一样,调试智能合约可能具有挑战性,但可以使用用于调试 Solidity 智能合约的高级工具快速确定单个交易或合约执行失败的原因。

一旦我们确定了导致特定问题的错误并深入了解错误的性质,我们就可以实施合适的解决方案。

本指南将提供调试智能合约的提示和工具,以帮助 Web3 开发人员确保他们的合约按预期工作。

调试智能合约

智能合约调试是识别和修复智能合约中的错误。它在开发任何去中心化应用程序时至关重要,因为它确保合约按预期运行。

合约开发可能会遇到几个问题,包括不可预测的行为、编码错误和安全漏洞。调试可以帮助解决这些问题,并防止以后出现更严重的问题。

实施、测试和部署只是开发智能合约的几个过程。每个步骤中的一个关键阶段是调试。部署协定后,调试有助于查找和更正编写阶段引入的代码中的缺陷。

调试有助于查找和更正在测试阶段的写入阶段可能未被注意到的问题。调试还可确保合约正确部署,并在部署期间按预期与区块链交互。

调试提示

编写易于调试的智能合约是开发中的关键一步。以下是编写易于调试的智能合约的一些技巧:

  • 为您的变量和函数使用简单、令人舒适的名称,以便任何人都可以快速掌握每个变量和函数的作用并发现错误。
  • 利用内置的Solidity函数叫做"require"来确保在合约继续执行之前满足特定条件。它是一个有价值的调试工具,因为当需要未满足时会停止合约执行,使程序员能够快速定位问题。
  • Truffle 调试器是一个功能强大的工具,可用于在测试阶段调试合约。它允许开发人员查看代码、检查变量值并恢复到以前的状态。

web3

  • Remix IDE 是 Solidity 流行的在线代码编辑器。它包含一个集成的调试功能,使程序员能够浏览代码并检查变量的值

web3

错误类别

在编写或运行Solidity合约的代码时,语法、运行时和逻辑错误是工程师们经常遇到的问题。

语法错误

智能合约中的语法错误是代码中的错误,它阻止了计算机理解代码。简单的错误,比如漏掉一个分号或错误使用术语,都可能构成语法错误。

逻辑错误

智能合约中的逻辑错误指的是代码中的错误,这些错误不会阻止其执行,但会导致它产生预期之外或错误的结果。

例如,当从一个账户向另一个账户发送资金时,合约将资金转移到了错误的地址。

智能合约的审计可以发现逻辑问题,因为有时从开发者的视角来看,一切都按计划进行。即使代码中可能没有漏洞,审计员仍然可以执行智能合约以寻找安全漏洞、检查业务逻辑并找出漏洞。

运行时错误

合约在执行过程中的任何错误都称为运行时错误。如果合约无法正确处理意外输入或条件,或者试图执行底层区块链禁止的操作,则可能会出现此类错误。

例如,试图将超出账户允许金额的资金转移的合约会导致运行时错误。

与语法错误相比,运行时问题更难诊断,因为它们在部署到区块链之前并不会被发现,并且只能在智能合约的状态发生变化时才会发生。

常见的运行时错误

让我们看看为以太坊网络开发智能合约时最常见的运行时错误。

堆栈溢出

在Solidity中,栈只能容纳1024个框架,这意味着一个函数只能调用自身1024次,否则将会发生栈溢出。如果尝试递归执行一个函数而没有停止递归的条件,就会发生栈溢出。

pragma solidity ^0.8.0;

contract Overflow { function count(uint256 num) public returns (uint256) { return count(num + 1); }}

Overflow o = new Overflow();o.count(1); // This will cause a Stack Overflow error as the function keeps calling itself infinitely.

web3

堆栈下溢

在汇编语言中尝试弹出一个不存在的变量时,将会发生堆栈下溢。

Solidity并没有像其他一些编程语言(如C语言)那样使用基于堆栈的执行模型,因此无法以与这些语言相同的方式在Solidity中引发堆栈下溢错误。

但是,如果一个合约用尽了gas,Solidity确实会抛出一些异常,可以将其视为类似于堆栈下溢的概念。以下是可能导致gas不足错误的Solidity代码示例:

pragma solidity ^0.8.0;

contract Underflow { function loop(uint256 num) public returns (uint256) { for (uint256 i = 0; i < num; i--) { // Do some operation } return num; }}

Underflow u = new Underflow();u.loop(1); // This code may run out of gas as the for loop condition will always be true and the loop will continue indefinitely, potentially causing an Out of Gas error.

web3

执行被回滚

当一个合约停止执行偏离其业务逻辑的交易时,会发生回滚错误。合约通常包括对各种必需条件的检查。如果交易不符合所有要求,合约将认为交易无效并停止执行。

重要的是要记住,只有在尝试完成交易但无法根据智能合约的逻辑执行交易时,交易才会被回滚;在这种情况下,EVM将返回错误,并且交易将被回滚。

pragma solidity ^0.8.0;

contract Revert { function transfer(address payable recipient, uint256 amount) public { require(amount > 0, "Amount must be greater than zero"); recipient.transfer(amount); }}

Revert r = new Revert();r.transfer(address(0), 0); // This code will cause an Execution Reverted error as the `require` statement will fail since the amount is zero, causing the function to revert its execution.

gas 耗尽

当您没有提供足够的 gas 来执行交易或 gas 不足以完成交易时,就会发生 gas 不足错误。

pragma solidity ^0.8.0;

contract OutOfGas { function consumeGas() public { while (true) { // Do some computation that consumes gas } }}

OutOfGas o = new OutOfGas();o.consumeGas(); // This code may run out of gas as the while loop runs indefinitely, consuming all available gas.

web3

无效操作码

当EVM与合约存在不兼容时,就会发生无效操作码错误。例如,当合约使用不受支持的编译器编译时。

跳转错误

当您尝试调用一个不存在的函数时,例如在通过不存在的另一个合约调用一个合约的函数时,就会发生无效操作错误。当您使用汇编语言并指向错误的内存时,也可能出现类似的问题。

pragma solidity ^0.8.0;

contract JumpError { function jump() public returns (uint256) { uint256 x = 1; if (x == 1) { return 1; } else { return 2; } return 3; // This code is unreachable and can cause a "JUMP" error. }}

JumpError j = new JumpError();j.jump(); // This code may cause a "JUMP" error as the final return statement is unreachable.

web3

调试工具

上一节向我们介绍了构建和部署智能合约时的常见错误。现在,我们将查看用于调试智能合约的工具。

Hardhat & Truffle

Hardhat是用于以太坊的开源开发环境,包括用于开发、测试和部署智能合约的工具。Hardhat还具有内置调试器,允许开发人员查看代码并检查变量值。

Truffle是以太坊的流行开发框架,包括一组用于开发、测试和部署智能合约的工具。Truffle还包括Truffle Debugger,这是一个在测试阶段调试合约的强大工具。

web3

web3

Remix

Remix是Solidity的流行在线代码编辑器,它具有内置的调试功能,允许开发人员扫描代码并检查变量值。

web3

EtherScan

Etherscan是用于以太坊的区块链浏览器,它允许开发人员检查和调试在以太坊区块链上部署的合约。

web3

开发阶段和项目特定需求将决定用于调试合约的最佳工具。

Remix和EtherScan更适合部署阶段,而Truffle和Hardhat更适合测试。Truffle和Hardhat提供更复杂的调试工具,如逐步执行代码和返回到先前状态。另一方面,Remix和Etherscan为部署的合约提供了更多的可见性和透明性。

测试各种工具以确定哪种最适合项目的需求至关重要。

总结

在创建区块链的去中心化应用程序时,调试智能合约是一个关键阶段。Web3开发人员可以通过遵循本指南中描述的建议和使用资源来确保其合约按预期运行。

随着技术和最佳实践的不断进步,保持学习和尝试新的调试合约工具和策略至关重要。