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. Log4j2配置文件详解

    目录[-] 1 系列目录 2 默认配置 3 第一个配置例子 4 复杂一点的配置 4.1 Appender之Syslog配置 4.2 Syslog及Syslog-ng相关配置(Fedora) 5 Log ...

  2. ErrorKiller:Failed to decode response: zlib_decode(): data error

    先更新composer自己,composer self-update 然后再更新依赖关系 composer update

  3. Mysql取随机数据效率测试(400W条中读取100条)

    测试数据表的创建在文章:http://www.cnblogs.com/wt645631686/p/6868192.html 先看一下我的SQL方案 SELECT * FROM `emp` WHERE ...

  4. Docker系列二:Docker的基本结构

    Docker的基本结构 Docker 的三大基础组件 Docker有三个重要的概念:仓库 , 镜像 和 容器 ,它们是Docker的三大基出组件 Docker的组织结构 Docker处于操作系统和虚拟 ...

  5. OpenStack中memcached的使用和实现

    概述 主要分享下个人对Liberty版本openstack中cache使用的理解,由于作者水平有限,难免有所错误,疏漏,还望批评指正. openstack中可以使用cache层来缓存数据,Libert ...

  6. java编程思想第四版第六章习题

    (略) (略) 创建两个包:debug和debugoff,他们都包含一个相同的类,该类有一个debug()方法,第一个版本显示发送给控制台的String参数,而第二版本什么也不做,使用静态import ...

  7. 《实战Nginx》读书笔记

    最近今天读了一本书叫做<实战Nginx:取代Apache的高性能Web服务器>,看后对Nginx 了解了不少.但是还有很多地方不是很了解.不过此书可以作为一本参考手册来使用,里面的讲解很详 ...

  8. select(Linux 编程)

    select系统调用时用来让我们的程序监视多个文件句柄的状态变化的.程序会停在select这里等待,直到被监视的文件句柄有一个或多个发生了状态改变. 关于文件句柄,其实就是一个整数,通过socket函 ...

  9. JavaScript的几种常见的创建方式

    1.通过Object构造函数或者对象字面量创建单个对象 使用字面量方法创建对象:var stut = {name: "张三"}; 使用内置构造函数创建对象:var stu = ne ...

  10. 芝麻HTTP:Flask的安装

    Flask是一个轻量级的Web服务程序,它简单.易用.灵活,这里主要用来做一些API服务. 1. 相关链接 GitHub:https://github.com/pallets/flask 官方文档:h ...