Я знаю, что в Solidity (0.3.2) нет возможности создавать определенные исключения. (Все является invalid JUMP
ошибкой.) Представляется полезным иметь способ регистрации определенных ошибок. Имеет ли смысл создавать событие Error, которое будет запускаться перед любым исключением? Есть ли недостатки, о которых я не думаю?
event Error(string message);
...
if(msg.sender != owner) {
Error("User not authorized");
throw;
}
РЕДАКТИРОВАТЬ: похоже, что событие вообще не регистрируется, если транзакция не удалась. Кто-нибудь может подтвердить?
За исключением, как и в случае throw
, все эффекты (включая события) транзакции отменяются, кроме выплаты майнеру. Таким образом, было бы бесполезно запускать событие перед throw
.
Если полный реверс через исключение не требуется , можно использовать код ошибки.
Пример:
contract C {
function foo() returns(int) {
if(msg.sender != owner) {
Error("User not authorized")
return -1111; // some error code
}
// sender is authorized so do stuff
}
}
Контракты не могут получить доступ к событиям, поэтому сообщение об ошибке больше для внешнего интерфейса. Если сообщение предназначено только для внешнего интерфейса, рассмотрите возможность использования шаблона eth_call
перед eth_sendTransaction
(здесь объясняется call vs sendTx).
Шаблон « eth_call
до eth_sendTransaction
» будет выглядеть следующим образом:
// `contract` is an instance, from web3.eth.contract(...).at(...)
if (contract.foo.call({from: eth.accounts[0]...) === -1111) {
// example only of how error could be dealt with
alert("User not authorized");
return;
}
// user should now be authorized (though it is possible another transaction may have changed `owner` in contract `C` after above eth_call and before this upcoming eth_sendTransaction)
contract.foo.sendTransaction({from: eth.accounts[0]......)
Тем не менее, могут быть случаи, когда желательно создать событие Error. Например, если вашему DApp требуется аналитика о том, сколько ошибок было обнаружено, сколько несанкционированных ошибок и т. д., может подойти событие Error.
EDIT: когда https://github.com/ethereum/solidity/issues/1686 реализован, пример в вопросе будет выглядеть так:
require(msg.sender == owner, "User not authorized");
Я заметил, что обработка событий с помощью модификатора работает довольно просто без броска в нижнем примере.
modifier Modifier_Name() {
if (Some_Check == Bool) {
Event(Event_Arg_Type);
Function_Access_Bool = Bool;
}
_;
}
function Function_Name(Function_Args) public
Modifier_Name()
returns bool (success)
{
if (Function_Access_Bool == false) {
return false;
}
else
{
...Desired_Code...;
return true;
}
}
Лукаш Зуховски