ethereum solidity require 和 revert + error 之间有什么区别
ethereum solidity what's the difference between require and revert + error
我想知道和
有什么区别
contract TestToken {
mapping(address => uint) balance;
error InsufficientBalance(uint256 available, uint256 required);
function transfer(address to, uint256 amount) public {
if (amount > balance[msg.sender])
// Error call using named parameters. Equivalent to
// revert InsufficientBalance(balance[msg.sender], amount);
revert InsufficientBalance({
available: balance[msg.sender],
required: amount
});
balance[msg.sender] -= amount;
balance[to] += amount;
}
// ...
}
和
contract TestToken {
mapping(address => uint) balance;
error InsufficientBalance(uint256 available, uint256 required);
function transfer(address to, uint256 amount) public {
require(balance[msg.sender]<amount, "Insufficient Balance");
balance[msg.sender] -= amount;
balance[to] += amount;
}
// ...
}
处理 solidity 中的错误
在 require 中,我们指定一个条件,如果为假,它将恢复。
Revert and error 是 require 的更复杂版本,您可以在其中指定条件以依赖于上下文并创建自定义错误。
例如
error InvalidAmount (uint256 sent, uint256 minRequired);
contract TestToken {
mapping(address => uint) balances;
uint minRequired;
constructor (uint256 _minRequired) {
minRequired = _minRequired;
}
function list() public payable {
uint256 amount = msg.value;
if (amount < minRequired) {
revert InvalidAmount({
sent: amount,
minRequired: minRequired
});
}
balances[msg.sender] += amount;
}
}
在该代码中,需要一个名为“无效金额”的错误,它取决于输入构造函数的最小金额。如果金额小于最小金额,交易将恢复并显示自定义错误,该错误将指定用户输入的金额和输入构造函数的最小金额。
从 low-level 的角度来看,这两种方法是相同的。两者都以字节数组作为异常数据抛出异常。
您可以 catch
low-level catch (bytes memory)
块中的两个错误
function foo() public {
try this.transfer(address(0x123), 2) {
// ok
} catch (bytes memory data) {
// returns either the encoded object or the encoded string
}
}
但是您只能 catch
使用“常规”catch Error(string memory)
块
的 string-encoded 错误
function foo() public {
try this.transfer(address(0x123), 2) {
// ok
} catch Error (string memory reason) {
// returns the string message
// fails to catch if an object is returned
}
}
文档:https://docs.soliditylang.org/en/v0.8.13/control-structures.html#try-catch
请注意,第二个片段中存在逻辑错误。
// `balance` needs to be lower than `amount`
// otherwise fail
require(balance[msg.sender]<amount, "Insufficient Balance");
应该是
// `balance` needs to be larger or equal than `amount`
// otherwise fail
require(balance[msg.sender] => amount, "Insufficient Balance");
我想知道和
有什么区别contract TestToken {
mapping(address => uint) balance;
error InsufficientBalance(uint256 available, uint256 required);
function transfer(address to, uint256 amount) public {
if (amount > balance[msg.sender])
// Error call using named parameters. Equivalent to
// revert InsufficientBalance(balance[msg.sender], amount);
revert InsufficientBalance({
available: balance[msg.sender],
required: amount
});
balance[msg.sender] -= amount;
balance[to] += amount;
}
// ...
}
和
contract TestToken {
mapping(address => uint) balance;
error InsufficientBalance(uint256 available, uint256 required);
function transfer(address to, uint256 amount) public {
require(balance[msg.sender]<amount, "Insufficient Balance");
balance[msg.sender] -= amount;
balance[to] += amount;
}
// ...
}
处理 solidity 中的错误
在 require 中,我们指定一个条件,如果为假,它将恢复。
Revert and error 是 require 的更复杂版本,您可以在其中指定条件以依赖于上下文并创建自定义错误。
例如
error InvalidAmount (uint256 sent, uint256 minRequired);
contract TestToken {
mapping(address => uint) balances;
uint minRequired;
constructor (uint256 _minRequired) {
minRequired = _minRequired;
}
function list() public payable {
uint256 amount = msg.value;
if (amount < minRequired) {
revert InvalidAmount({
sent: amount,
minRequired: minRequired
});
}
balances[msg.sender] += amount;
}
}
在该代码中,需要一个名为“无效金额”的错误,它取决于输入构造函数的最小金额。如果金额小于最小金额,交易将恢复并显示自定义错误,该错误将指定用户输入的金额和输入构造函数的最小金额。
从 low-level 的角度来看,这两种方法是相同的。两者都以字节数组作为异常数据抛出异常。
您可以 catch
low-level catch (bytes memory)
块中的两个错误
function foo() public {
try this.transfer(address(0x123), 2) {
// ok
} catch (bytes memory data) {
// returns either the encoded object or the encoded string
}
}
但是您只能 catch
使用“常规”catch Error(string memory)
块
function foo() public {
try this.transfer(address(0x123), 2) {
// ok
} catch Error (string memory reason) {
// returns the string message
// fails to catch if an object is returned
}
}
文档:https://docs.soliditylang.org/en/v0.8.13/control-structures.html#try-catch
请注意,第二个片段中存在逻辑错误。
// `balance` needs to be lower than `amount`
// otherwise fail
require(balance[msg.sender]<amount, "Insufficient Balance");
应该是
// `balance` needs to be larger or equal than `amount`
// otherwise fail
require(balance[msg.sender] => amount, "Insufficient Balance");