Truffle: ¿Por qué mi modificador "onlyOwner" no se ejecuta en truffle?

Estoy usando una versión simplificada de un contrato proporcionado por el sitio web de Solidity. Mi contrato es el siguiente:

pragma solidity ^0.4.4;

import "./ConvertLib.sol";
contract MetaCoin {
   address owner;
   uint val;    

   function MetaCoin() {
       owner= msg.sender;
  }

    modifier onlyOwner {
    require (msg.sender==owner);
    _;
  }
  function change() onlyOwner{
  val=55;
 }
 function get_owner() returns (address){
 return owner;
 }
}

Y mi contrato de prueba es el siguiente:

pragma solidity ^0.4.2;

 import "truffle/Assert.sol";
 import "truffle/DeployedAddresses.sol";
 import "../contracts/MetaCoin.sol";

 contract TestMetacoin {

 function test1(){
 MetaCoin meta = MetaCoin(DeployedAddresses.MetaCoin());
 meta.change();
 }

 function test2(){
 MetaCoin meta = MetaCoin(DeployedAddresses.MetaCoin());
 Assert.equal(meta.get_owner(), msg.sender, "I must be the owner");
}
}

Estoy usando testrpc. Entonces, primero implemento el primer contrato: "despliegue de trufas" y luego ejecuto la prueba uno: "prueba de trufas".

Problema : test2 pasa pero test1 no. Si elimino "onlyOwner" de change(), entonces test1 puede pasar.

Pregunta : ¿Por qué no se puede pasar test1 y cuál es la solución?


Tenga en cuenta que ambos contratos se compilan sin ningún error.

Hay algo mal con su ejemplo ya MetaCoinque no tiene un testmétodo, siempre debería fallar. ¿Quiso decir changeen lugar de test? En tal caso, ¿puedes poner el mensaje de error exacto de truffle?
@Ismael gracias por tu comentario. Well truffle te permite "implementar" y "probar" tu contrato usando los comandos: truffle deployment y truffle test. No necesita tener ningún "método" de prueba en su código. Ver aquí: truffleframework.com/docs/getting_started/testing
Quiero decir que meta.test();es incorrecto porque Metacoin no tiene un test()método.

Respuestas (1)

Falla porque la llamada está dentro TestMetacoin.test1()y cuando un contrato A hace una llamada a otro contrato B, entonces msg.sender dentro de B es la dirección de A.

  1. El propietario llama a TestMetacoin.test1()
  2. Dentro de TestMetacoin.test1() msg.sender es igual a la dirección del propietario
  3. test1() llama a MetaCoin.change()
  4. Dentro de MetaCoin.change() msg.sender es la dirección de TestMetacoin

No puede cambiar el remitente desde un contrato de solidez, por lo que le sugiero que haga esa prueba desde el lado de javascript, que puede cambiar fácilmente el remitente que se agrega {from: "0x...." }a la transacción.

Gracias por la respuesta clara! No puedo votarte porque todavía no tengo suficiente "reputación".