Solidity

應付函式錯誤:如果您發送值並且您發送的值應該小於您目前的餘額,則呼叫的函式應該是應付的

  • March 10, 2021

我想創建簡單的拍賣契約(見下面的程式碼)。但是**newBid()**函式不起作用。

要執行此合約,您必須首先創建一個項目 newItem(name, price, time),然後執行 newBid(itemId) - 檢查程式碼。

在此處輸入圖像描述

有2個文件`

拍賣.sol

pragma solidity ^0.7.0;
import "./Item.sol";

contract Auction {

   uint256 lastId = 0;
   mapping (uint256 => Item) idToItem;

   address admin;

constructor () {
   admin = msg.sender;
}

function newItem(string memory _name, uint256 _price, uint256 _time) public {
   lastId += 1;
   idToItem[lastId] = new Item(_name, _price, msg.sender, _time);
}

function newBid(uint256 itemId) public payable {
   Item item = idToItem[itemId];
   
   item.newBid(msg.sender, msg.value);
}

function timeLeft(uint256 itemId) public view returns(uint256){
   return idToItem[itemId].timeLeft();
}

function getMaxBid(uint256 itemId) public view returns(uint256) {
   return idToItem[itemId].getMaxBid();
}

}

項目.sol

pragma solidity ^0.7.0;

contract Item {
   // Global fee is 14% of item price  
   uint256 fee;

   // Main Parameters of item
   string name;
   uint256 price;
   address payable public owner;
   uint256 time;
   bool sold; 

   uint256 maxBid;

   struct Bid {
       address payable bider;
       uint256 amount;
   }

   Bid[] Bids;

   constructor(string memory _itemName, uint256 _price, address payable _owner, uint256 _time) {
       name = _itemName;
       price = _price;
       owner = _owner;
       time = block.timestamp + _time;
       sold = false;
   }

// Returns item ramaining time (in seconds)
function timeLeft() public view returns(uint256) {
   return time - block.timestamp;
   
}

// Registers new bid for this item.
function newBid (address payable _bider, uint256 _amount) public payable {
   if (block.timestamp + time > time) {
       sellItem();
       require(block.timestamp < time, "Sorry, time is up");
   }else {
       require(_amount > maxBid, "The bid must be higher than the current maximum bid");
       Bids.push(Bid( _bider, _amount ));
       
       fee = (_amount / 100) * 14;
   }
}

// Sells item and refunds money
function sellItem () private {
   address _maxAmountAddress;
   uint256 _maxAmount = 0;
   
   for (uint i = 0; i <= Bids.length; i++) {
       if (Bids[i].amount > _maxAmount) {
           _maxAmountAddress = Bids[i].bider;
           _maxAmount = Bids[i].amount;
       }
   }
   
   for (uint j = 0; j <= Bids.length; j++) {
       if (_maxAmountAddress != Bids[j].bider) {
           Bids[j].bider.transfer(Bids[j].amount);
       }
   }
   
   
   owner.transfer(_maxAmount - fee);
   sold = true;
} 

// Returns max bid for the item
function getMaxBid () public view returns(uint256) {
   return maxBid;
}
}

“被呼叫的函式應該是應付的”是對暗示的瘋狂猜測,通常是錯誤的。由於各種原因,該契約已恢復。您將不得不使用調試技術將實際原因歸零,這可能是數組索引超出範圍、除以零、要求之一不滿意等。

我做到了 Item.sellItem()。作為一般觀察,在這一交易中發生了太多事情。您應該嘗試簡化和消除 for 循環。

看起來您正在使用 Remix。調試器可能會幫助您放大實際問題。如果您單步執行程式碼直到它崩潰,您可能會看到問題。

希望能幫助到你。

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