msg.sender.transfer (KaufÜberschuss); Versagen im Festigkeitstest

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)
welchen Fehler bekommst du?
Ich bin mir nicht ganz sicher, aber Sie müssen möglicherweise das Vertragsguthaben erhöhen, falls die Transaktion Gas erfordert, um ausgeführt zu werden. uint public initialBalance = 2 ether;könnte das Problem lösen.
@mirg leider hat es das Problem nicht gelöst :-(

Antworten (1)

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);
    }


}
Vielen Dank! Können Sie etwas näher darauf eingehen, dass "jede der Übertragungen fehlschlagen und Ether im Vertrag stranden kann"?
Mein letzter Kommentar war unbegründet und wurde entfernt; es war spät, und ich dachte über einen unmöglichen Codepfad nach.