Трюфель: почему мой модификатор onlyOwner не работает в трюфеле?

Я использую упрощенную версию контракта, предоставленную веб-сайтом Solidity. Мой контракт выглядит следующим образом:

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

И мой тестовый контракт выглядит следующим образом:

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

Я использую testrpc. Итак, сначала я развертываю 1-й контракт: «truffle deploy», а затем запускаю тестовый: «truffle test».

Проблема : test2 проходит, а test1 нет. Если я удалю «onlyOwner» из change (), тогда test1 может пройти.

Вопрос : Почему test1 не проходит и какое решение?


Обратите внимание, что оба контракта составлены без ошибок.

Что-то не так с вашим примером, поскольку MetaCoinу него нет testметода, он всегда должен давать сбой. Вы имели в виду changeвместо test? В таком случае вы можете указать точное сообщение об ошибке от трюфеля?
@Исмаэль, спасибо за ваш комментарий. Что ж, truffle позволяет вам «развернуть» и «проверить» ваш контракт с помощью команд: truffle deploy и truffle test. Вам не нужно иметь какой-либо тестовый «метод» в вашем коде. См. здесь: truffleframework.com/docs/getting_started/testing
Я имею в виду, что meta.test();это неправильно, потому что у Metacoin нет test()метода.

Ответы (1)

Это не удается, потому что вызов находится внутри, TestMetacoin.test1()и когда контракт A вызывает другой контракт B, тогда msg.sender внутри B является адресом A.

  1. Владелец вызывает TestMetacoin.test1()
  2. Внутри TestMetacoin.test1() msg.sender равен адресу владельца
  3. test1() вызывает MetaCoin.change()
  4. Внутри MetaCoin.change() msg.sender находится адрес TestMetacoin.

Вы не можете изменить отправителя из контракта на солидность, поэтому я предлагаю сделать этот тест со стороны javascript, который может легко изменить отправителя, добавляя {from: "0x...." }к транзакции.

Спасибо за четкий ответ! Я не могу проголосовать за вас, так как у меня еще недостаточно «репутации».