У меня есть контракт с именем AccessControl, в котором владелец контракта устанавливается при его развертывании.
Я хочу проверить setCEO
правильность обновления метода на нем, но для этого запрос должен исходить от владельца контракта.
contract AccessControl {
address public ceoAddress;
modifier onlyCEO() {
require(msg.sender == ceoAddress);
_;
}
function setCEO(address _newCEO) external onlyCEO {
require(_newCEO != address(0));
ceoAddress = _newCEO;
}
}
Когда я запускаю console.log в тестах, текущий ceoAddress выглядит так:
const paymentPipe = await PaymentPipe.deployed();
console.log(await paymentPipe.ceoAddress());
Я вижу, что адрес 0x000000000000000000000000000000000000000000.
Когда я пытаюсь вызвать setCEO в своих тестах из этой учетной записи, например:
await paymentPipe.setCEO(bob, {from: contractAddress});
Трюфель жалуется:
Ошибка: учетная запись отправителя не распознана
Если я попытаюсь использовать любую другую учетную запись из набора тестов трюфеля (например, учетные записи [x]), я получу:
Ошибка: исключение виртуальной машины при обработке транзакции: возврат
Подразумевается, что метод не передал оператор require, потому что адрес вызова не был установлен в качестве генерального директора.
С какого адреса развернуты контракты в наборе тестов truffle? И почему, если я вижу в своем контракте адрес как 0x000000000000000000000000000000000000000000, я не могу использовать этот адрес для вызова функций?
Я думаю, что ваша проблема возникает из -за ceoAddress
неправильной инициализации, и она будет иметь значение 0x0000000000000000000000000000000000000000
.
Теперь изменить его требует контракт msg.sender == ceoAddress
, из этого следует, что msg.sender
должно быть 0x0000000000000000000000000000000000000000
. Эта операция не может быть выполнена, потому что у вас нет закрытого ключа, который генерирует такой адрес.
Один из вариантов - инициализировать вашу переменную в конструкторе с учетной записью отправителя.
contract AccessControl {
address public ceoAddress;
modifier onlyCEO() {
require(msg.sender == ceoAddress);
_;
}
constructor() {
// ---- Initialize ceoAddress ----
ceoAddress = msg.sender;
}
function setCEO(address _newCEO) external onlyCEO {
require(_newCEO != address(0));
ceoAddress = _newCEO;
}
}
Truffle использует первый адрес, возвращенный eth.accounts
для развертывания контрактов.
module.exports = function(deployer, network, accounts) {
// You can pass other parameters like gas or change the from
deployer.deploy(AccessControl, { from: accounts[2] });
}
Проверьте документацию Truffle , чтобы узнать о дополнительных возможностях использования.
Ричард Хоррокс
ceoAddress
какmsg.sender
?СовместныйУченик