Ich habe eine Ausnahme an der Linie msg.sender.transfer(purchaseExcess);
in meinem Truffle Solidity Unit Test bekommen. Irgendeine Idee, der Grund?
mein Vertragscode:
function purchase(uint256 _tokenId) public payable {
address oldOwner = tokenOwner[_tokenId];
uint256 sellingPrice = emojiIndexToPrice[_tokenId];
address newOwner = msg.sender;
require(oldOwner != newOwner);
require(newOwner != address(0));
require(msg.value >= sellingPrice);
uint256 percentage = SafeMath.sub(100, ownerCut);
uint256 payment = uint256(SafeMath.div(SafeMath.mul(sellingPrice, percentage), 100));
uint256 purchaseExcess = SafeMath.sub(msg.value, sellingPrice);
emojiIndexToPrice[_tokenId] = SafeMath.div(SafeMath.mul(sellingPrice, 150), percentage);
_transfer(oldOwner, newOwner, _tokenId);
if (oldOwner != address(this)) {
oldOwner.transfer(payment);
}
msg.sender.transfer(purchaseExcess);
}
Unit-Tests-Code:
contract TestEmojiCoin {
uint public initialBalance = 1 ether;
function testPurchase() public {
address contractAddress = DeployedAddresses.EmojiCoin();
EmojiCoin emojiCoin = EmojiCoin(contractAddress);
// Emoji 0 is created in previous test.
emojiCoin.purchase.value(1 ether).gas(30000000000)(0);
}
}
Fehlermeldung
Error: VM Exception while processing transaction: revert
at Object.InvalidResponse (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/errors.js:38:1)
at /usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/requestmanager.js:86:1
at /usr/local/lib/node_modules/truffle/build/webpack:/~/truffle-provider/wrapper.js:134:1
at XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/httpprovider.js:128:1)
at XMLHttpRequestEventTarget.dispatchEvent (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:64:1)
at XMLHttpRequest._setReadyState (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:354:1)
at XMLHttpRequest._onHttpResponseEnd (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:509:1)
at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:469:1)
at endReadableNT (_stream_readable.js:1101:12)
at process._tickCallback (internal/process/next_tick.js:114:19)
Die Transaktion schlägt fehl, weil der Testvertrag keine kostenpflichtige Fallback-Funktion hat, um die überschüssigen Gelder „zu übertragen“.
pragma solidity ^0.4.17;
import "../contracts/EmojiCoin.sol";
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
contract TestEmojiCoin {
uint public initialBalance = 1 ether;
function testPurchase() public {
address contractAddress = DeployedAddresses.EmojiCoin();
EmojiCoin emojiCoin = EmojiCoin(contractAddress);
// Emoji 0 is created in previous test.
address owner_0 = emojiCoin.tokenOwner(0);
Assert.notEqual( owner_0, this, "owner for coin 0 is incorrect" );
emojiCoin.purchase.value(1 ether).gas(30000000000)(0);
owner_0 = emojiCoin.tokenOwner(0);
Assert.equal( owner_0, this, "owner for coin 0 is incorrect" );
}
// this new function IS REQUIRED for the test to work
function() public payable { }
}
Zwei Behauptungstests wurden hinzugefügt (einige könnten argumentieren, dass dies keine bewährte Methode ist, mehr als eine Behauptung im selben Test zu haben)
Außerdem musste ein sehr einfacher EmojiCoin-Vertrag implementiert werden, um zu überprüfen, ob dies das Problem war:
pragma solidity ^0.4.17;
import "zeppelin-solidity/contracts/math/SafeMath.sol";
contract EmojiCoin {
mapping(uint256 => address) public tokenOwner;
mapping(uint256 => uint256) public emojiIndexToPrice;
uint256 public ownerCut = 5;
function EmojiCoin() public {
// very simple constructor for the purpose of testing only
tokenOwner[0] = msg.sender;
emojiIndexToPrice[0] = 1 ether;
}
// simple _transfer implementation for the purpose of testing only
function _transfer(address oldOwner, address newOwner, uint256 _tokenId) internal {
require(tokenOwner[_tokenId] == oldOwner);
tokenOwner[_tokenId] = newOwner;
}
function purchase(uint256 _tokenId) public payable {
address oldOwner = tokenOwner[_tokenId];
uint256 sellingPrice = emojiIndexToPrice[_tokenId];
address newOwner = msg.sender;
require(oldOwner != newOwner);
require(newOwner != address(0));
require(msg.value >= sellingPrice);
uint256 percentage = SafeMath.sub(100, ownerCut);
uint256 payment = uint256(SafeMath.div(SafeMath.mul(sellingPrice, percentage), 100));
uint256 purchaseExcess = SafeMath.sub(msg.value, sellingPrice);
emojiIndexToPrice[_tokenId] = SafeMath.div(SafeMath.mul(sellingPrice, 150), percentage);
_transfer(oldOwner, newOwner, _tokenId);
if (oldOwner != address(this)) {
oldOwner.transfer(payment);
}
msg.sender.transfer(purchaseExcess);
}
}
mirg
mirg
uint public initialBalance = 2 ether;
könnte das Problem lösen.Wenjing