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方法執行后可以在這里找到打印出的變量信息:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM