【本文目标】 本文目标是指导如何使用REMIX完成一次智能合约交易调试。 【前置条件】 学习过Solidity语言,需要进行调试。 【技术收获】 1). 使用REMIX进行单步调试 2). REMIX的Debugger界面介绍
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);
}
}
RUN运行环境选择JavaScript VM ,它用于模拟客户自定义环境,开始点击Create按钮执行智能合约:
智能合约创建
设置´value´的值为10,单位选择ether,点击Donate 表示从当前账号捐赠10个ETH给该智能合约。
交易转移
Remix显示交易相关的一些信息。在终端输出器,此次交易被记录,点击”Debug”按钮可开始调试。
在”Debugger”控制面板进入,在对应的编辑框输入transaction hash / block number、transaction index信息也可以开始会话。
面板进入
作为例子,运行“donate”函数后,点击终端输出器对应LOG的Detail按钮展开交易信息,复制hash信息值输入编辑框,点击PLAY按钮,即可进入Debug调试流程。 此效果等同于点击交易信息的“Debug”按钮。
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个面板用于显示执行的详细信息。
结果面板
本案例运行交易的Instructions信息
Instructions面板显示当前高亮显示的运行合约的汇编语言。 注意:当该面板隐藏时,滑动条的运行粒度是一个course的,即使在多EVM环境构建,也只会在语法边界停止;当该面板显示时,才可能逐步进入到构建函数内部,即使对应相同的语句。
Solidity Locals
Solidity Locals面板显示当前上下文环境的局部变量值。
Solidity State
Solidity State面板显示的是当前执行合约的状态变量。
其他低层级面板
以下面板显示本次执行的低层次信息: • Stack 堆栈 • Storages Changes 存储改变 • Memory 内存 • Call Data 调用数据 • Call Stack 调用堆栈 • Return Value 返回值,只有当运行到RETURN原语才显示 • Full Storages Changes 全存储改变,只有在执行末尾才显示所有改变的合约变化存储
交易回滚
一个交易合约可以回滚,例如因为GAS超限,程序抛出 throw语句或者低层次的异常。 在这种场景下,识别异常和定位异常的代码位置是非常重要的。 当执行抛出异常时,Remix将告警。warning 按钮将在异常发生前跳转到最后的执行原语。 需要说明的是,智能合约交易的执行是事件级别的,就是无法如C++一样在运行中改变变量值,只能一次执行完毕。调试器记录了执行的原语记录,所以可以前进和回滚。对于回滚,就像影片回滚放映一样,非常酷炫。
导航栏的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事件记录的参数信息。
执行结果
1),REMIX调试英文官网文档 2), SOLIDITY语言官网中文版
尊重知识输出,如需引用,敬请说明本文链接和作者-笔名辉哥。