第十课 如何在Remix环境下进行Solidity代码单步调试

1,390 阅读5分钟

1. 文章摘要

【本文目标】 本文目标是指导如何使用REMIX完成一次智能合约交易调试。 【前置条件】 学习过Solidity语言,需要进行调试。 【技术收获】 1). 使用REMIX进行单步调试 2). REMIX的Debugger界面介绍

【实操课程列表】 第一课 如何在WINDOWS环境下搭建以太坊开发环境 第二课 如何实现以太坊最简智能合约“Hello World”的运行 第四课 以太坊开发框架Truffle从入门到实战 第六课 技术小白如何开发一个DAPP区块链应用(以宠物商店为例) 第七课 技术小白如何在45分钟内发行通证(TOKEN)并上线交易 第八课 如何调试以太坊官网的智能合约众筹案例 第九课 如何在Remix环境下进行Solidity代码单步调试 第十课 Solidity语言编辑器REMIX指导大全

【说明】未列出的课程为知识普及的非实操类课程,所有区块链文章参考“区块链入口”专栏。

2. 开始调试

REMIX有2种方式启动调试。 新建一个智能合约文件”Donation.sol”,复制以下代码:

contract Donation {
    address owner;
    event fundMoved(address _to, uint _amount);
    modifier onlyowner { if (msg.sender == owner) _; }
    address[] _giver;
    uint[] _values;

    function Donation() {
        owner = msg.sender;
    }

    function donate() payable {
        addGiver(msg.value);
    }

    function moveFund(address _to, uint _amount) onlyowner {
        uint balance = this.balance;
        uint amount = _amount;
        if (_amount <= this.balance) {
            if (_to.send(_amount)) {
                fundMoved(_to, _amount);
            } else {
                throw;
            }
        } else {
            throw;
        }
    }

    function addGiver(uint _amount) internal {
        _giver.push(msg.sender);
        _values.push(_amount);
    }
}

2.1 从用户界面开始

RUN运行环境选择JavaScript VM ,它用于模拟客户自定义环境,开始点击Create按钮执行智能合约:

智能合约创建

设置´value´的值为10,单位选择ether,点击Donate 表示从当前账号捐赠10个ETH给该智能合约。

交易转移

Remix显示交易相关的一些信息。在终端输出器,此次交易被记录,点击”Debug”按钮可开始调试。

2.2 从调试器开始

在”Debugger”控制面板进入,在对应的编辑框输入transaction hash / block number、transaction index信息也可以开始会话。

面板进入
作为例子,运行“donate”函数后,点击终端输出器对应LOG的Detail按钮展开交易信息,复制hash信息值输入编辑框,点击PLAY按钮,即可进入Debug调试流程。 此效果等同于点击交易信息的“Debug”按钮。

3. 使用调试器

Transation信息
调试器允许查看交易合约执行的详细信息。它使用左侧的编辑器显示执行时源码的位置。 交易控制面板显示当前交易合约的基础信息。导航栏包括7个按钮用于交易的单步调试。
调试器按钮
从左到右的按钮名称: 1,step over back 2,step back 3, step into 4,step over forward 5,jump to the previous breakpoint 6,jump out 7, jump to the next breakpoint 下面有11个面板用于显示执行的详细信息。
结果面板

3.1 Instructions面板

本案例运行交易的Instructions信息

Instructions面板显示当前高亮显示的运行合约的汇编语言。 注意:当该面板隐藏时,滑动条的运行粒度是一个course的,即使在多EVM环境构建,也只会在语法边界停止;当该面板显示时,才可能逐步进入到构建函数内部,即使对应相同的语句。

3.2 Solidity Locals面板

Solidity Locals
Solidity Locals面板显示当前上下文环境的局部变量值。

3.3 Solidity State面板

Solidity State
Solidity State面板显示的是当前执行合约的状态变量。

3.4 Low level面板

其他低层级面板
以下面板显示本次执行的低层次信息: • Stack 堆栈 • Storages Changes 存储改变 • Memory 内存 • Call Data 调用数据 • Call Stack 调用堆栈 • Return Value 返回值,只有当运行到RETURN原语才显示 • Full Storages Changes 全存储改变,只有在执行末尾才显示所有改变的合约变化存储

3.5 交易回滚(Reverted Transaction)

交易回滚
一个交易合约可以回滚,例如因为GAS超限,程序抛出 throw语句或者低层次的异常。 在这种场景下,识别异常和定位异常的代码位置是非常重要的。 当执行抛出异常时,Remix将告警。warning 按钮将在异常发生前跳转到最后的执行原语。 需要说明的是,智能合约交易的执行是事件级别的,就是无法如C++一样在运行中改变变量值,只能一次执行完毕。调试器记录了执行的原语记录,所以可以前进和回滚。对于回滚,就像影片回滚放映一样,非常酷炫。

3.6 Breakpoints断点和单步调试

导航栏的5,7按钮按钮用于回滚到前一个断点和执行到下一个断点。 在左侧编辑框的行数处单击即可增加和删除断点。 作为样例,在18行和20行双击,设置2个断点,在Run面板的moveFund输入框内输入参数,给第二个账号转移0.0005个ETH。点击”MoveFund”执行该交易函数。

"0x14723a09acff6d2a60dcdf7aa4aff308fddc160c",500000000000000

合约交易执行成功后,点击终端输出器中的Debug按钮,点击调试面板的“Jump to the next breakpoint”程序会运行到第一个断点处。

执行到第一个断点

再点击“Jump to the next breakpoint”按钮一次,直接运行到20行第二个断点处。 点击”Jump out”函数跳出该函数,运行完成后可以看到第二个账号余额发生了改变,增加了0.0005个ETH。 点击展开Detail,可以看到EVENT事件记录的参数信息。

执行结果

3.7 切换账号调用存量合约

REMIX在“Environment”采用“Injected WEB3”的方式下,切换账号会导致智能合约呈现消失。 此时可以通过调用合约地址的方式把合约和命令复原回来。 例如我有一个部署在ropsten的智能合约,地址为"0xbb7695fe978176cbe86d27b9e2b4e9eff1a04f82",恢复方法如下图所示:记得输入合约地址框不要加"" 哦。

4.参考文档

1),REMIX调试英文官网文档 2), SOLIDITY语言官网中文版

尊重知识输出,如需引用,敬请说明本文链接和作者-笔名辉哥。