Warum schlägt dieser Test mit einem ungültigen Opcode-Fehler beim Aufruf von transferFrom() fehl?

Ich bekomme folgenden Fehler:

1) Contract: Bencoin should send Bencoin correctly via transferFrom(address, address, uint256):                                       
     Uncaught Error: VM Exception while processing transaction: invalid opcode                                                          
      at Object.InvalidResponse (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:36886:16)                                     
      at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:206712:36                                                             
      at XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:205491:13)                 
      at XMLHttpRequestEventTarget.dispatchEvent (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:207364:18)                   
      at XMLHttpRequest._setReadyState (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:207654:12)                             
      at XMLHttpRequest._onHttpResponseEnd (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:207809:12)                         
      at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:207769:24)                               
      at endReadableNT (_stream_readable.js:1047:12)                                                                                    

Wenn ich den folgenden Test mit Trüffeltest durchführe:

  it("should send Bencoin correctly via transferFrom(address, address, uint256)", function() {
    var bencoin;

    var amount = 5;

    // Get initial balances of first and second account.
    var account_one = accounts[0]; // should be 9;
    var account_two = accounts[1]; // should be 8;

    var account_one_starting_balance;
    var account_two_starting_balance;
    var account_one_running_balance;
    var account_two_running_balance;

    return Bencoin.deployed().then(function(instance) {
      bencoin = instance;
    })

    .then(function() {
      return bencoin.balanceOf.call(account_one);
    }).then(function(balance) {
      account_one_starting_balance = balance.toNumber();
      return bencoin.balanceOf.call(account_two);
    }).then(function(balance) {
      account_two_starting_balance = balance.toNumber();
    }).then(function() {
      // the balance of account one should start off equal to 9
      assert.equal(
        account_one_starting_balance,
        9,
        "Account one did not start with a balance of 9 Bencoin"
      );
      // the balance of account two should start off equal to 8
      assert.equal(
        account_two_starting_balance,
        8,
        "Account two did not start with a balance of 8 Bencoin"
      );
    })

    // approve the transfer of 5 Bencoin from account_one to account_two
    .then(function() {
      bencoin.approve(account_two, amount);
    }).then(function() {
      return bencoin.allowance.call(account_one, account_two);
    }).then(function(allowance) {
      assert.equal(
        allowance,
        amount,
        "account_two was not successfully approved to transferFrom() 5 Bencoin from account_one"
      );
    })

    // execute the transfer of 5 Bencoin from account_one to account_two (code fails here)   
    .then(function() {
      bencoin.transferFrom(account_one, account_two, amount);
    }).then(function() {
      return bencoin.balanceOf.call(account_one);
    }).then(function(balance) {
      account_one_running_balance = balance.toNumber();
    }).then(function(balance) {
      return bencoin.balanceOf.call(account_two);
    }).then(function(balance) {
      account_two_running_balance = balance.toNumber();
    }).then(function() {
      // 5 was taken from 9, so the balance of account one should be 4
      assert.equal(
        account_one_running_balance,
        account_one_starting_balance - amount,
        "5 Bencoin were not correctly taken from the sender"
      );
      // 5 was added to 8, so the balance of account two should be 13
      assert.equal(
        account_two_running_balance,
        account_two_starting_balance + amount,
        "5 Bencoin were not correctly sent to the receiver"
      );
    });
  });

Ich truffle testverwende testrpc und mein Token ist ein ERC20-Token, das die OpenZeppelin StandardToken.sol erweitert.

EDIT: Hier ist mein Vertragscode:

pragma solidity ^0.4.4;
import "zeppelin-solidity/contracts/token/StandardToken.sol";

contract Bencoin is StandardToken {
  string public name = "Bencoin"; 
  string public symbol = "BEN";
  uint public decimals = 18;
  uint public INITIAL_SUPPLY = 0;

  function Bencoin() {
    totalSupply = INITIAL_SUPPLY;
  }

  function mintCoin(address _to, uint256 _value) {
    balances[_to] = balances[_to].add(_value);
    totalSupply = totalSupply.add(_value); 
  }
}

Die Werte 9 für account_one und 8 für account_two wurden in vorherigen Tests gesetzt. Diese Werte werden zu Beginn des transferFrom()-Tests durch „asser()“ bestätigt, und sie bestehen immer „asser()“, also liegt es nicht daran, dass ich kein Guthaben auf Konto 1 habe. (9 ist natürlich > 5 )

Wirklich schwer zu wissen ohne Ihren Vertragscode. Aber normalerweise werden ungültige Opcodes durch eine throwInsolidität verursacht. Möglicherweise verfügt Ihr Konto nicht über genügend Guthaben oder der Test verwendet ein anderes Konto.
Bitte poste deinen Vertragscode. Sehen Sie sich auch async/ an, awaitwenn Sie möchten, dass Ihre Tests nicht überall Promise-Verkettungen haben.
Danke @0xcaff, Ismael, ich habe meinen Vertragscode oben hinzugefügt. Ich werde async auschecken und auch warten. Ich sollte als account_one anrufen (ich bin mir nicht sicher, wie ich das Konto ändern soll, das ich beim Testen verwende, wenn das möglich ist ...)

Antworten (1)

Das Problem ist, dass Sie Konto_zwei genehmigen, Geld von Konto_eins zu überweisen, aber Sie führen die Überweisung mit Konto_eins aus

Der Test sollte in etwa so sein

  bencoin.transferFrom(account_one, account_two, amount, { from: account_two });