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调试 - 实现变量打印的更多相关文章

  1. Lua中如何实现类似gdb的断点调试--02通用变量打印

    在前一篇01最小实现中,我们实现了Lua断点调试的的一个最小实现.我们编写了一个模块,提供了两个基本的接口:设置断点和删除断点. 虽然我们已经支持在断点进行变量的打印,但是需要自己指定层数以及变量索引 ...

  2. Android Studio中JNI程序的单步调试和日志打印

    近日有个算法(检测碰撞)需要用C++实现,目的是IOS和ANDROID中共享同一段程序. 下面说说android调用这段程序过程中遇到的一些事情.(过程中网上搜索了一些相关文章,大部分说的是eclip ...

  3. 脚本编程中的test、bash调试、变量计算、参数

    脚本编程中的test.bash调试.变量计算.参数 1.文件测试 -e FILE:测试文件是否存在 -f FILE:测试文件是否为普通文件 -d FILE:测试路径是否为目录 -r FILE:测试当前 ...

  4. 冒泡排序 and 选择排序 变量打印斐波拉契数列 and 数组打印斐波拉契数列

    1 排序 1.1 冒泡排序 #include <stdio.h> int main() { ]; printf("input six int numbers:\n"); ...

  5. 使用whIle循环语句和变量打印九九乘法表

    -设置i变量declare @i int --设置j变量declare @j int --设置乘法表变量declare @chengfabiao varchar(1000)--给i,j,@chengf ...

  6. C#.Net集成Bartender条码打印,VS调试运行可以打印,发布到IIS运行打印报错

    C#.Net集成Bartender条码打印,VS调试运行可以打印,发布到IIS运行打印报错 问题原因: 问题出现在iis账户权限. 解决方法: iis默认是用network service这个账户去执 ...

  7. Tensorflow之调试(Debug)及打印变量

    参考资料:https://wookayin.github.io/tensorflow-talk-debugging 几种常用方法: 1.通过Session.run()获取变量的值 2.利用Tensor ...

  8. 增加p()函数,方便开发中对变量打印调试

    在开发的过程中,我们经常要输出一下变量看看得到的结果是什么,我们就要根据变量的类型选择使用echo,print_r或者var_dump,brophp框架中的p()函数会自动根据变量类型选择用什么方法为 ...

  9. GDB调试指南-变量查看

    前言 在启动调试以及设置断点之后,就到了我们非常关键的一步-查看变量.GDB调试最大的目的之一就是走查代码,查看运行结果是否符合预期.既然如此,我们就不得不了解一些查看各种类型变量的方法,以帮助我们进 ...

随机推荐

  1. bzoj 1188 [HNOI2007]分裂游戏 SG函数 SG定理

    [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1394  Solved: 847[Submit][Status][Dis ...

  2. 【转】磁盘I/O那些事

    背景 计算机硬件性能在过去十年间的发展普遍遵循摩尔定律,通用计算机的CPU主频早已超过3GHz,内存也进入了普及DDR4的时代.然而传统硬盘虽然在存储容量上增长迅速,但是在读写性能上并无明显提升,同时 ...

  3. 机器学习实战 之 KNN算法

    现在 机器学习 这么火,小编也忍不住想学习一把.注意,小编是零基础哦. 所以,第一步,推荐买一本机器学习的书,我选的是Peter harrigton 的<机器学习实战>.这本书是基于pyt ...

  4. PHP opcache扩展安装

    下面是我在PHP 5.4下的安装方法: https://pecl.php.net/get/zendopcache-7.0.5.tgz tar xzf zendopcache-7.0.5.tgz cd ...

  5. ios设备触发虚拟键盘输入后position:fixed 无效的一些简单另类的解决方法。

    首先看一下我要解决的问题,第一张图是正常的情况下,第二张图是点击了输入框之后的情况,就是要解决此问题~! 百度了一下解决方法,好像有以下的一些方法: 1. iscroll 2. Jquery Mobi ...

  6. nyoj137 取石子(三) 楼教主男人八题之一

    思路:一堆时,N态.两堆时,当两堆数量相同,P态,不同为N态.三堆时,先手可以变成两堆一样的,必胜N态. 此时可以总结规律:堆数为偶数可能且石子数都是两两相同的,为P态.分析四堆时,当四堆中两两数量一 ...

  7. java遍历的优化

    说明:这是在面试中面试官出的题.虽然是常见的优化问题,但这种经验的确很有用.感慨之余,分享出来,以此共勉. 场景:现有List<PersonA>,List<PersonB>,P ...

  8. linux下在用户空间访问I/O端口的ioperm和iopl函数

    1.ioperm函数      功能描述:为调用进程设置I/O端口访问权能.ioperm的使用需要具有超级用户的权限,只有低端的[0-0x3ff] I/O端口可被设置,要想指定更多端口的权能,可使用i ...

  9. 6.3 x86处理器如何处理MSI-X中断请求

    PCIe设备发出MSI-X中断请求的方法与发出MSI中断请求的方法类似,都是向Message Address所在的地址写Message Data字段包含的数据.只是MSI-X中断机制为了支持更多的中断 ...

  10. 集成电路883和883b有什么区别

    根据用途,元器件的质量等级可分为:用于元器件生产控制.选择和采购的质量等级和用于电子设备可靠性预计的质量等级两类,两者有所区别,又相互联系. 用于元器件生产控制.选择和采购的质量等级 元器件的质量等级 ...