Solidity调试 - 实现变量打印
Solidity没有print或console.log方法可以用来打印变量,这会给我们调试程序增加难度。
Solidity有event功能,可以在event中记录变量信息,通过调用event方法也可以实现打印功能,但不可能处处写event方法,麻烦。
以下代码实现了可重用的log方法,只要调用log()方法就可以打印不同类型的变量值。
使用方法为:log(string name, var value)
pragma solidity ^0.4.;
//通过log函数重载,对不同类型的变量trigger不同的event,实现solidity打印效果,使用方法为:log(string name, var value)
contract Console {
event LogUint(string, uint);
function log(string s , uint x) internal {
emit LogUint(s, x);
}
event LogInt(string, int);
function log(string s , int x) internal {
emit LogInt(s, x);
}
event LogBytes(string, bytes);
function log(string s , bytes x) internal {
emit LogBytes(s, x);
}
event LogBytes32(string, bytes32);
function log(string s , bytes32 x) internal {
emit LogBytes32(s, x);
}
event LogAddress(string, address);
function log(string s , address x) internal {
emit LogAddress(s, x);
}
event LogBool(string, bool);
function log(string s , bool x) internal {
emit LogBool(s, x);
}
}
我尝试过用var替代变量类型,但是编译不通过,应该是var不能做函数参数类型。
以下是编译不过的:
pragma solidity ^0.4.;
contract Console {
event LogUint(string, var);
function log(string s , var x) internal {
emit LogUint(s, x);
}
}
使用时只需要将Console.sol import进程序且继承Console就好(注意第3行和第41行):
pragma solidity ^0.4.;
import "browser/Console.sol";
contract SimpleAuction is Console {
// Parameters of the auction. Times are either
// absolute unix timestamps (seconds since 1970-01-01)
// or time periods in seconds.
address public beneficiary; //受益人
uint public auctionEnd; //竞拍终止时间
// Current state of the auction.
address public highestBidder; //最高竞拍者
uint public highestBid; //最高竞拍
// Allowed withdrawals of previous bids
mapping(address => uint) pendingReturns; //待退回的竞拍(不是最高出价都退回)
// Set to true at the end, disallows any change
bool ended; //一旦设置不允许再投标
// Events that will be fired on changes.
event HighestBidIncreased(address bidder, uint amount); //最高出价变动时调用事件
event AuctionEnded(address winner, uint amount); // 拍卖结束时调用事件
// The following is a so-called natspec comment,
// recognizable by the three slashes.
// It will be shown when the user is asked to
// confirm a transaction.
/// Create a simple auction with `_biddingTime`
/// seconds bidding time on behalf of the
/// beneficiary address `_beneficiary`.
/// 初始化拍卖对象:受益人地址、拍卖持续时间
function SimpleAuction(
uint _biddingTime,
address _beneficiary
) public {
beneficiary = _beneficiary;
auctionEnd = now + _biddingTime;
log("time now", now);
}
/// Bid on the auction with the value sent
/// together with this transaction.
/// The value will only be refunded if the
/// auction is not won.
///对竞拍投标,payable代表该交易可以获取ether,只有没有竞拍成功的交易款才会退回
function bid() public payable {
// No arguments are necessary, all
// information is already part of
// the transaction. The keyword payable
// is required for the function to
// be able to receive Ether.
// Revert the call if the bidding
// period is over.
//输入检查,竞拍如果结束则终止
require(now <= auctionEnd);
// If the bid is not higher, send the
// money back.
//如果投标金额未超过当前最高金额,则终止
require(msg.value > highestBid);
if (highestBid != ) {
// Sending back the money by simply using
// highestBidder.send(highestBid) is a security risk
// because it could execute an untrusted contract.
// It is always safer to let the recipients
// withdraw their money themselves.
pendingReturns[highestBidder] += highestBid; //原来的最高变次高出价,次高出价要退回
}
highestBidder = msg.sender; //新的最高出价者
highestBid = msg.value; //新的最高出价
emit HighestBidIncreased(msg.sender, msg.value); //触发最高出价增加事件
}
/// Withdraw a bid that was overbid.
/// 取回被淘汰的竞拍
function withdraw() public returns (bool) {
uint amount = pendingReturns[msg.sender];
if (amount > ) {
// It is important to set this to zero because the recipient
// can call this function again as part of the receiving call
// before `send` returns.
pendingReturns[msg.sender] = ; //在send方法被执行之前,将待退还的钱置为0 *这个很重要* 因为如果不置为0的话,可以重复发起withdraw交易,send需要时间,在交易没确认之前,重复发起可能就要退N倍的钱
if (!msg.sender.send(amount)) { //用户自己取回退回的款项时,如果出错不用调用throw方法,而是将被置0的待退款金额恢复
// No need to call throw here, just reset the amount owing
pendingReturns[msg.sender] = amount;
return false;
}
}
return true;
}
/// End the auction and send the highest bid
/// to the beneficiary.
function auctionEnd() public {
// It is a good guideline to structure functions that interact
// with other contracts (i.e. they call functions or send Ether)
// into three phases:
// 1. checking conditions
// 2. performing actions (potentially changing conditions)
// 3. interacting with other contracts
// If these phases are mixed up, the other contract could call
// back into the current contract and modify the state or cause
// effects (ether payout) to be performed multiple times.
// If functions called internally include interaction with external
// contracts, they also have to be considered interaction with
// external contracts.
// 1. Conditions
require(now >= auctionEnd); // auction did not yet end
require(!ended); // this function has already been called
// 2. Effects
ended = true;
emit AuctionEnded(highestBidder, highestBid);
// 3. Interaction
beneficiary.transfer(highestBid);
}
}
log方法执行后可以在这里找到打印出的变量信息:

Solidity调试 - 实现变量打印的更多相关文章
- Lua中如何实现类似gdb的断点调试--02通用变量打印
在前一篇01最小实现中,我们实现了Lua断点调试的的一个最小实现.我们编写了一个模块,提供了两个基本的接口:设置断点和删除断点. 虽然我们已经支持在断点进行变量的打印,但是需要自己指定层数以及变量索引 ...
- Android Studio中JNI程序的单步调试和日志打印
近日有个算法(检测碰撞)需要用C++实现,目的是IOS和ANDROID中共享同一段程序. 下面说说android调用这段程序过程中遇到的一些事情.(过程中网上搜索了一些相关文章,大部分说的是eclip ...
- 脚本编程中的test、bash调试、变量计算、参数
脚本编程中的test.bash调试.变量计算.参数 1.文件测试 -e FILE:测试文件是否存在 -f FILE:测试文件是否为普通文件 -d FILE:测试路径是否为目录 -r FILE:测试当前 ...
- 冒泡排序 and 选择排序 变量打印斐波拉契数列 and 数组打印斐波拉契数列
1 排序 1.1 冒泡排序 #include <stdio.h> int main() { ]; printf("input six int numbers:\n"); ...
- 使用whIle循环语句和变量打印九九乘法表
-设置i变量declare @i int --设置j变量declare @j int --设置乘法表变量declare @chengfabiao varchar(1000)--给i,j,@chengf ...
- C#.Net集成Bartender条码打印,VS调试运行可以打印,发布到IIS运行打印报错
C#.Net集成Bartender条码打印,VS调试运行可以打印,发布到IIS运行打印报错 问题原因: 问题出现在iis账户权限. 解决方法: iis默认是用network service这个账户去执 ...
- Tensorflow之调试(Debug)及打印变量
参考资料:https://wookayin.github.io/tensorflow-talk-debugging 几种常用方法: 1.通过Session.run()获取变量的值 2.利用Tensor ...
- 增加p()函数,方便开发中对变量打印调试
在开发的过程中,我们经常要输出一下变量看看得到的结果是什么,我们就要根据变量的类型选择使用echo,print_r或者var_dump,brophp框架中的p()函数会自动根据变量类型选择用什么方法为 ...
- GDB调试指南-变量查看
前言 在启动调试以及设置断点之后,就到了我们非常关键的一步-查看变量.GDB调试最大的目的之一就是走查代码,查看运行结果是否符合预期.既然如此,我们就不得不了解一些查看各种类型变量的方法,以帮助我们进 ...
随机推荐
- Sublime Text编辑远程Linux服务器上的文件
sublime有个叫sftp的插件,可以通过它直接打开远程机器上的文件进行编辑,并在保存后直接同步到远程linux服务器上. 用Package Control安装插件 按下Ctrl+Shift+P调出 ...
- ZOJ - 3261 逆向并查集
思路:很巧妙的解法.如果按照常规一边读入,一边合并并查集,删边实在没办法做. 首先读入所有的操作,把所有不会被删除的边加入并查集,然后从最后一个操作开始逆向操作,当遇到删边操作,就直接把这条边加入并查 ...
- Java 多线程入门
进程与线程 在学习Java多线程之前,先简单复习一下进程与线程的知识. 进程:进程是系统进行资源分配和调度的基本单位,可以将进程理解为一个正在执行的程序,比如一款游戏. 线程:线程是程序执行的最小单位 ...
- Hdfs读取文件到本地总结
总结了一下三个方法:hdfs自带 按字节复制 按行复制 (在java io里还有字符复制,暂且不提) 因为hdfs自带的,不知道为什么有些场合不能用,每次能下载的个数还不一定,所以就考虑自己按照jav ...
- Jmeter_beanshell实现字符串加密
Jmeter内置的没有MD5加密方法,所以需要写一些java代码实现加密功能,以下是具体操作: 1:用eclipse建个工程(包名.类名.方法名自己起) package com.wjika.test; ...
- Eviews 9.0新版本新功能——预测(Auto-ARIMA预测、VAR预测)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 9.预测功能 新增需要方法的预测功能:Auto ...
- Css中路径data:image/png;base64的用法详解
今天查看一些网站的css中发现了 background-image:url(data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAAB ...
- freemarker之include指令
freemarker之include指令 1.父页面ftl <html> <head> <meta http-equiv="content-type" ...
- hi3531 SDK已编译文件系统制作jffs2文件系统镜像并解决问题 .
一, 安装SDK 1.Hi3531 SDK包位置 在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx. ...
- java.sql.SQLException:No suitable driver found for http://localhost:3306/school
1.错误描述 java.sql.SQLException:No suitable driver found for http://localhost:3306/school 2.错误原因 Class. ...