Error

Solidity 文件中的範例原始碼錯誤

  • November 1, 2018

新手來了 我正在嘗試將此處顯示在乙太坊網站上的範例購買契約部署到http://remix.ethereum.org/的線上 Remix Solidity 編譯器。

但是當我複制/粘貼編寫的範常式式碼時,我收到以下錯誤消息。

錯誤資訊

browser/purchase.sol:62:25:警告:不推薦使用從地址類型繼承的合約成員“餘額”。將合約轉換為“address”類型以訪問成員,例如使用“address(contract).balance”代替。

seller.transfer(this.balance);
                   ^----------^

任何人都可以幫助糾正我下面的程式碼嗎?我已經展示了我的工作和我已經嘗試過的兩件事,但都沒有成功。

購買.sol

pragma solidity ^0.4.22;

contract Purchase {
   uint public value;
   address public seller;
   address public buyer;
   enum State { Created, Locked, Inactive }
   State public state;

   // Ensure that `msg.value` is an even number.
   // Division will truncate if it is an odd number.
   // Check via multiplication that it wasn't an odd number.
   constructor() public payable {
       seller = msg.sender;
       value = msg.value / 2;
       require((2 * value) == msg.value, "Value has to be even.");
   }

   modifier condition(bool _condition) {
       require(_condition);
       _;
   }

   modifier onlyBuyer() {
       require(
           msg.sender == buyer,
           "Only buyer can call this."
       );
       _;
   }

   modifier onlySeller() {
       require(
           msg.sender == seller,
           "Only seller can call this."
       );
       _;
   }

   modifier inState(State _state) {
       require(
           state == _state,
           "Invalid state."
       );
       _;
   }

   event Aborted();
   event PurchaseConfirmed();
   event ItemReceived();

   /// Abort the purchase and reclaim the ether.
   /// Can only be called by the seller before
   /// the contract is locked.
   function abort()
       public
       onlySeller
       inState(State.Created)
   {
       emit Aborted();
       state = State.Inactive;
       seller.transfer(this.balance); // original attempt, yields below error
       // seller.transfer(address(contract).balance); // first unsuccessful attempt to correct
       // address(contract).balance; // second unsuccessful attempt to correct
   }

   /// Confirm the purchase as buyer.
   /// Transaction has to include `2 * value` ether.
   /// The ether will be locked until confirmReceived
   /// is called.
   function confirmPurchase()
       public
       inState(State.Created)
       condition(msg.value == (2 * value))
       payable
   {
       emit PurchaseConfirmed();
       buyer = msg.sender;
       state = State.Locked;
   }

   /// Confirm that you (the buyer) received the item.
   /// This will release the locked ether.
   function confirmReceived()
       public
       onlyBuyer
       inState(State.Locked)
   {
       emit ItemReceived();
       // It is important to change the state first because
       // otherwise, the contracts called using `send` below
       // can call in again here.
       state = State.Inactive;

       // NOTE: This actually allows both the buyer and the seller to
       // block the refund - the withdraw pattern should be used.

       buyer.transfer(value);
       seller.transfer(this.balance);
   }
}

評論摘要。

修正後的程式碼如下。

購買.sol

pragma solidity ^0.4.22;

contract Purchase {
   uint public value;
   address public seller;
   address public buyer;
   enum State { Created, Locked, Inactive }
   State public state;

   // Ensure that `msg.value` is an even number.
   // Division will truncate if it is an odd number.
   // Check via multiplication that it wasn't an odd number.
   constructor() public payable {
       seller = msg.sender;
       value = msg.value / 2;
       require((2 * value) == msg.value, "Value has to be even.");
   }

   modifier condition(bool _condition) {
       require(_condition);
       _;
   }

   modifier onlyBuyer() {
       require(
           msg.sender == buyer,
           "Only buyer can call this."
       );
       _;
   }

   modifier onlySeller() {
       require(
           msg.sender == seller,
           "Only seller can call this."
       );
       _;
   }

   modifier inState(State _state) {
       require(
           state == _state,
           "Invalid state."
       );
       _;
   }

   event Aborted();
   event PurchaseConfirmed();
   event ItemReceived();

   /// Abort the purchase and reclaim the ether.
   /// Can only be called by the seller before
   /// the contract is locked.
   function abort()
       public
       onlySeller
       inState(State.Created)
   {
       emit Aborted();
       state = State.Inactive;
       //seller.transfer(this.balance); // throws error
       seller.transfer(address(this).balance); // fixes error
   }

   /// Confirm the purchase as buyer.
   /// Transaction has to include `2 * value` ether.
   /// The ether will be locked until confirmReceived
   /// is called.
   function confirmPurchase()
       public
       inState(State.Created)
       condition(msg.value == (2 * value))
       payable
   {
       emit PurchaseConfirmed();
       buyer = msg.sender;
       state = State.Locked;
   }

   /// Confirm that you (the buyer) received the item.
   /// This will release the locked ether.
   function confirmReceived()
       public
       onlyBuyer
       inState(State.Locked)
   {
       emit ItemReceived();
       // It is important to change the state first because
       // otherwise, the contracts called using `send` below
       // can call in again here.
       state = State.Inactive;

       // NOTE: This actually allows both the buyer and the seller to
       // block the refund - the withdraw pattern should be used.

       buyer.transfer(value);
       //seller.transfer(this.balance); // throws error
       seller.transfer(address(this).balance); // fixes error
   }
}

屬性餘額與特定地址相關聯,而不是與合約本身相關聯。當你說 this.balance 時,它試圖呼叫合約的 balance 屬性,但它應該是 address(this).balance。這將使您能夠訪問合約地址的餘額。

引用自:https://ethereum.stackexchange.com/questions/47873