OpenZeppelin 实现ERC20 的transferFrom 时,为什么先调用_transfer(),然后再检查withdrawer allowance
In OpenZeppelin's implementation of ERC20's transferFrom, why is _transfer() called before withdrawer allowance is checked
这取自 OpenZeppelin 的 ERC20 transferFrom
实现:
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), currentAllowance - amount);
return true;
}
在检查取款人 (msg.sender
) 津贴之前调用 _transfer
是否有原因?
如果先进行津贴 require
检查,transferFrom
还能正常工作吗?
我在 OpenZeppelin GitHub Issues 上发现了关于同一主题的讨论,代码的作者确认该顺序在 ERC-20 的上下文中是不相关的。
In the case of ERC20, the order is irrelevant because _transfer and _approve are independent and never call any other contract: they are executed atomically.
此外,他指出,在有人想要覆盖功能的情况下,保持顺序稳定很重要。
However, this is very relevant for users that intent to override _transfer or _approve with their own implementations: we should be clear about the order in which these things happen.
来源:https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2030#issuecomment-568487500
所以假设您没有在重写的 _transfer()
和 _approve()
内部函数中使用自定义逻辑,如果您切换顺序,transferFrom()
仍然可以正常工作。
其实我也在找同样的东西,然后我发现了这个讨论
[https://forum.openzeppelin.com/t/in-erc20-tranferfrom-why-transfer-before-checking-allowance/5312/3] 它提供了更多细节并阐明了其背后的原因。
这取自 OpenZeppelin 的 ERC20 transferFrom
实现:
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), currentAllowance - amount);
return true;
}
在检查取款人 (msg.sender
) 津贴之前调用 _transfer
是否有原因?
如果先进行津贴 require
检查,transferFrom
还能正常工作吗?
我在 OpenZeppelin GitHub Issues 上发现了关于同一主题的讨论,代码的作者确认该顺序在 ERC-20 的上下文中是不相关的。
In the case of ERC20, the order is irrelevant because _transfer and _approve are independent and never call any other contract: they are executed atomically.
此外,他指出,在有人想要覆盖功能的情况下,保持顺序稳定很重要。
However, this is very relevant for users that intent to override _transfer or _approve with their own implementations: we should be clear about the order in which these things happen.
来源:https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2030#issuecomment-568487500
所以假设您没有在重写的 _transfer()
和 _approve()
内部函数中使用自定义逻辑,如果您切换顺序,transferFrom()
仍然可以正常工作。
其实我也在找同样的东西,然后我发现了这个讨论 [https://forum.openzeppelin.com/t/in-erc20-tranferfrom-why-transfer-before-checking-allowance/5312/3] 它提供了更多细节并阐明了其背后的原因。