¿Por qué falla esta prueba con un error de código de operación no válido en la llamada transferFrom()?

Obtuve el siguiente error:

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)                                                                                    

Cuando ejecuto la siguiente prueba con la prueba de trufa:

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

Estoy ejecutando truffle testtestrpc y mi token es un token ERC20 que extiende OpenZeppelin StandardToken.sol.

EDITAR: Aquí está mi código de contrato:

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

Los valores 9 para cuenta_uno y 8 para cuenta_dos se establecieron en pruebas anteriores. Estos valores se afirman () al comienzo de la prueba transferFrom (), y siempre pasan esa afirmación (), por lo que no es que no tenga los fondos en la cuenta 1. (9 es> 5, por supuesto )

Realmente difícil de saber sin su código de contrato. Pero, por lo general, los códigos de operación no válidos son causados ​​​​por una throwsolidez. Tal vez su cuenta no tenga fondos suficientes o la prueba esté usando una cuenta diferente.
Por favor, publique su código de contrato. Consulte también async/ awaitsi desea que sus pruebas no tengan encadenamientos de Promise por todas partes.
Gracias @0xcaff, Ismael, agregué mi código de contrato arriba. Revisaré async y esperaré también. Debería estar llamando como account_one (no estoy seguro de cómo cambiar la cuenta que estoy usando durante la prueba, si eso es posible...)

Respuestas (1)

El problema es que está aprobando cuenta_dos para transferir fondos de cuenta_uno, pero está ejecutando la transferencia con cuenta_uno

La prueba debe ser algo como esto.

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