zoukankan      html  css  js  c++  java
  • Solidity调试

    Solidity没有print或console.log方法可以用来打印变量,这会给我们调试程序增加难度。

    Solidity有event功能,可以在event中记录变量信息,通过调用event方法也可以实现打印功能,但不可能处处写event方法,麻烦。

    以下代码实现了可重用的log方法,只要调用log()方法就可以打印不同类型的变量值。

    使用方法为:log(string name, var value)

    pragma solidity ^0.4.21;
    
    //通过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.21;
    
    contract Console {
        event LogUint(string, var);
        function log(string s , var x) internal {
        emit LogUint(s, x);
        }
    }

    使用时只需要将Console.sol import进程序且继承Console就好(注意第3行和第41行):

      1 pragma solidity ^0.4.21;
      2 
      3 import "browser/Console.sol";
      4 
      5 contract SimpleAuction is Console {
      6     // Parameters of the auction. Times are either
      7     // absolute unix timestamps (seconds since 1970-01-01)
      8     // or time periods in seconds.
      9     address public beneficiary;  //受益人
     10     uint public auctionEnd; //竞拍终止时间
     11 
     12     // Current state of the auction.
     13     address public highestBidder; //最高竞拍者
     14     uint public highestBid; //最高竞拍
     15 
     16     // Allowed withdrawals of previous bids
     17     mapping(address => uint) pendingReturns;  //待退回的竞拍(不是最高出价都退回)
     18 
     19     // Set to true at the end, disallows any change
     20     bool ended; //一旦设置不允许再投标
     21 
     22     // Events that will be fired on changes.
     23     event HighestBidIncreased(address bidder, uint amount); //最高出价变动时调用事件
     24     event AuctionEnded(address winner, uint amount); // 拍卖结束时调用事件
     25 
     26     // The following is a so-called natspec comment,
     27     // recognizable by the three slashes.
     28     // It will be shown when the user is asked to
     29     // confirm a transaction.
     30 
     31     /// Create a simple auction with `_biddingTime`
     32     /// seconds bidding time on behalf of the
     33     /// beneficiary address `_beneficiary`.
     34     /// 初始化拍卖对象:受益人地址、拍卖持续时间
     35     function SimpleAuction(
     36         uint _biddingTime,
     37         address _beneficiary
     38     ) public {
     39         beneficiary = _beneficiary;
     40         auctionEnd = now + _biddingTime;
     41         log("time now", now);
     42     }
     43 
     44     /// Bid on the auction with the value sent
     45     /// together with this transaction.
     46     /// The value will only be refunded if the
     47     /// auction is not won.
     48     ///对竞拍投标,payable代表该交易可以获取ether,只有没有竞拍成功的交易款才会退回
     49     function bid() public payable {
     50         // No arguments are necessary, all
     51         // information is already part of
     52         // the transaction. The keyword payable
     53         // is required for the function to
     54         // be able to receive Ether.
     55 
     56         // Revert the call if the bidding
     57         // period is over.
     58         //输入检查,竞拍如果结束则终止
     59         require(now <= auctionEnd);
     60 
     61         // If the bid is not higher, send the
     62         // money back.
     63         //如果投标金额未超过当前最高金额,则终止
     64         require(msg.value > highestBid);
     65 
     66         if (highestBid != 0) {
     67             // Sending back the money by simply using
     68             // highestBidder.send(highestBid) is a security risk
     69             // because it could execute an untrusted contract.
     70             // It is always safer to let the recipients
     71             // withdraw their money themselves.
     72             pendingReturns[highestBidder] += highestBid; //原来的最高变次高出价,次高出价要退回
     73         }
     74         highestBidder = msg.sender; //新的最高出价者
     75         highestBid = msg.value; //新的最高出价
     76         emit HighestBidIncreased(msg.sender, msg.value); //触发最高出价增加事件
     77     }
     78 
     79     /// Withdraw a bid that was overbid.
     80     /// 取回被淘汰的竞拍
     81     function withdraw() public returns (bool) {
     82         uint amount = pendingReturns[msg.sender];
     83         if (amount > 0) {
     84             // It is important to set this to zero because the recipient
     85             // can call this function again as part of the receiving call
     86             // before `send` returns.
     87             pendingReturns[msg.sender] = 0; //在send方法被执行之前,将待退还的钱置为0 *这个很重要* 因为如果不置为0的话,可以重复发起withdraw交易,send需要时间,在交易没确认之前,重复发起可能就要退N倍的钱
     88 
     89             if (!msg.sender.send(amount)) { //用户自己取回退回的款项时,如果出错不用调用throw方法,而是将被置0的待退款金额恢复
     90                 // No need to call throw here, just reset the amount owing
     91                 pendingReturns[msg.sender] = amount;
     92                 return false;
     93             }
     94         }
     95         return true;
     96     }
     97 
     98     /// End the auction and send the highest bid
     99     /// to the beneficiary.
    100     function auctionEnd() public {
    101         // It is a good guideline to structure functions that interact
    102         // with other contracts (i.e. they call functions or send Ether)
    103         // into three phases:
    104         // 1. checking conditions
    105         // 2. performing actions (potentially changing conditions)
    106         // 3. interacting with other contracts
    107         // If these phases are mixed up, the other contract could call
    108         // back into the current contract and modify the state or cause
    109         // effects (ether payout) to be performed multiple times.
    110         // If functions called internally include interaction with external
    111         // contracts, they also have to be considered interaction with
    112         // external contracts.
    113 
    114         // 1. Conditions
    115         require(now >= auctionEnd); // auction did not yet end
    116         require(!ended); // this function has already been called
    117 
    118         // 2. Effects
    119         ended = true;
    120         emit AuctionEnded(highestBidder, highestBid);
    121 
    122         // 3. Interaction
    123         beneficiary.transfer(highestBid);
    124     }
    125 }

    log方法执行后可以在这里找到打印出的变量信息:

  • 相关阅读:
    Select2插件的隐藏、设置宽度
    远程登陆Linux服务器
    ECMAScript typeof用法
    Select2异步搜索数据
    ECMAScript 引用类型
    LeetCode 任务调度器-Python3<八>
    sort、sorted高级排序-Python3.7 And 算法<七>
    LeetCode算法笔记目录
    数据结构-Python3.7<三>
    【夯实PHP基础】php开发时遇到白页的调试方法
  • 原文地址:https://www.cnblogs.com/huahuayu/p/8593774.html
Copyright © 2011-2022 走看看