在Solidity(0.3.2)中,我知道没有办法抛出特定的异常。 (一切都是invalid JUMP错误。)有一种记录特定错误的方法似乎是有益处的。 创建在任何异常之前会被触发的Error事件是否有意义呢? 有没有任何我没有想到的缺点吗?

event Error(string message);

...

if(msg.sender != owner) {
  Error("User not authorized");
  throw;
}

编注:如果交易失败,似乎根本没有记录事件。 有人可以证实吗?

原文地址

2 人回答 0

2 个回答
投票数
最旧发布
最近发布

回答发布于 2018-09-06 15:44:07

使用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_sendTransaction之前使用eth_call模式(此处说明call以及sendTx)。

eth_sendTransaction模式之前调用eth_call看起来就像这个前端Javascript代码:

// `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想要对遇到了多少错误,有多少是未经授权的错误等进行分析,那么错误事件可能就这么执行了。

编注:当实现https://github.com/ethereum/solidity/issues/1686 时, 问题中的示例会如下所示:

require(msg.sender == owner, "User not authorized");
||
||

回答发布于 2018-09-06 15:44:07

我注意到通过修饰符处理事件非常简单,而不需要在代码底部抛出异常了。示例如下:

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

回答发布于 2018-09-06 15:44:07

使用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_sendTransaction之前使用eth_call模式(此处说明call以及sendTx)。

eth_sendTransaction模式之前调用eth_call看起来就像这个前端Javascript代码:

// `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想要对遇到了多少错误,有多少是未经授权的错误等进行分析,那么错误事件可能就这么执行了。

编注:当实现https://github.com/ethereum/solidity/issues/1686 时, 问题中的示例会如下所示:

require(msg.sender == owner, "User not authorized");
||
||

回答发布于 2018-09-06 15:44:07

我注意到通过修饰符处理事件非常简单,而不需要在代码底部抛出异常了。示例如下:

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

回答发布于 2018-09-06 15:44:07

使用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_sendTransaction之前使用eth_call模式(此处说明call以及sendTx)。

eth_sendTransaction模式之前调用eth_call看起来就像这个前端Javascript代码:

// `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想要对遇到了多少错误,有多少是未经授权的错误等进行分析,那么错误事件可能就这么执行了。

编注:当实现https://github.com/ethereum/solidity/issues/1686 时, 问题中的示例会如下所示:

require(msg.sender == owner, "User not authorized");
||
||

回答发布于 2018-09-06 15:44:07

我注意到通过修饰符处理事件非常简单,而不需要在代码底部抛出异常了。示例如下:

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