En Solidity (0.3.2) soy consciente de que no hay forma de lanzar excepciones específicas. (Todo es un invalid JUMP
error). Parece beneficioso tener una forma de registrar errores específicos. ¿Tiene sentido crear un evento de error para que se dispare antes de cualquier excepción? ¿Hay alguna desventaja en la que no estoy pensando?
event Error(string message);
...
if(msg.sender != owner) {
Error("User not authorized");
throw;
}
EDITAR: parece que el evento no se registra en absoluto si la transacción falla. ¿Alguien puede confirmar?
Con una excepción, como con throw
, todos los efectos (incluidos los eventos) de una transacción se revierten, excepto el pago al minero. Por lo tanto, no habría ningún beneficio en activar un evento antes de un throw
.
Si no se requiere una reversión completa a través de una excepción , se puede usar un código de error.
Ejemplo:
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
}
}
No se puede acceder a los eventos mediante contratos , por lo que el mensaje de error es más para la interfaz. Si el mensaje es solo para la interfaz, considere usar un patrón de eth_call
antes de eth_sendTransaction
(aquí se explica call vs sendTx).
El patrón eth_call
anterior eth_sendTransaction
se vería como este código Javascript frontend:
// `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]......)
Dicho esto, puede haber casos en los que se desee crear un evento de error. Por ejemplo, si su DApp quiere análisis sobre cuántos errores se han encontrado, cuántos son errores no autorizados, etc., un evento de error podría ser el camino a seguir.
EDITAR: cuando se implementa https://github.com/ethereum/solidity/issues/1686 , el ejemplo en la pregunta se vería así:
require(msg.sender == owner, "User not authorized");
He notado que el manejo de eventos a través de un modificador funciona bastante simple sin tirar con el ejemplo inferior.
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;
}
}
lukasz zuchowski