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");