Solidity
應付函式錯誤:如果您發送值並且您發送的值應該小於您目前的餘額,則呼叫的函式應該是應付的
我想創建簡單的拍賣契約(見下面的程式碼)。但是**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。調試器可能會幫助您放大實際問題。如果您單步執行程式碼直到它崩潰,您可能會看到問題。
希望能幫助到你。