¿Es una buena práctica registrar un evento cada vez que lanzo Solidity?

En Solidity (0.3.2) soy consciente de que no hay forma de lanzar excepciones específicas. (Todo es un invalid JUMPerror). 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?

Respuestas (2)

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.


Alternativa posible

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_callantes de eth_sendTransaction (aquí se explica call vs sendTx).

El patrón eth_callanterior eth_sendTransactionse 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");
Con respecto a la alternativa posible , la desventaja de ese enfoque es: la persona que llama deberá pagar por la transacción fallida. Por supuesto, a veces sería deseable "cargar" a la persona que llama y devolver un estado significativo, por lo que sería una cuestión de elección.

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