据我所知,实现permit函数是为了避免在调用transferFrom之前调用D2函数。这样,我们将只调用一个函数,而不是调用两个函数进行传输。从技术上讲,permit函数通过对事务进行签名调用approve函数,然后在链上验证该签名。但是在permit函数的末尾,它调用_approve函数。来自ERC721Permit.sol
function permit(
address spender,
uint256 tokenId,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external payable override {
require(_blockTimestamp() <= deadline, 'Permit expired');
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, spender, tokenId, _getAndIncrementNonce(tokenId), deadline))
)
);
address owner = ownerOf(tokenId);
require(spender != owner, 'ERC721Permit: approval to current owner');
if (Address.isContract(owner)) {
require(IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) == 0x1626ba7e, 'Unauthorized');
} else {
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0), 'Invalid signature');
require(recoveredAddress == owner, 'Unauthorized');
}
_approve(spender, tokenId);
}}
为什么_approve会被叫到permit?
发布于 2022-11-11 00:32:43
许可函数本质上是其他人为用户调用审批的一种方式,而不是用户必须启动两个事务的方式。然而,在erc20实现中,我们仍然需要更新该用户的批准存储数据。注意,我们调用内部助手函数_approve,而不是approve。_approve函数增加了用户的允许数据,无论用户调用审批本身,还是使用某个人的许可或某些合同来为用户设置批准,我们都需要这样做。
将许可看作是将带有签名的审批调用为允许控制,而不是将msg.sender视为允许。
就其使用许可的工作方式而言,我们仍然基本上是“为用户调用批准”,我们只是使用一个签名来验证用户是否想调用它,而不是要求用户从他们的钱包中发送交易。
对于使用许可证这样的事务,用户只需启动一个事务就可以进行交换,用户可以将许可证数据连同对交换的调用一起发送到合同,然后合同可以代表用户更新用户的批准。
这样可以避免用户启动两个事务,但也节省了整个事务,因为如果我没有记错的话,每个事务的基本成本约为21k气体,而回收成本约为3k气体。
https://ethereum.stackexchange.com/questions/139192
复制相似问题