ERC20Permit

EIP-2612 标准,通常被称为 ERC20Permit,旨在支持无 Gas 代币授权。这是通过遵循 SNIP12 标准而不是链上交易的链下签名实现的。 如果签名有效,permit 函数会验证签名并设置 spender 的 allowance。此方法改善了用户体验并降低了 Gas 成本。

与 Solidity 的区别

尽管此扩展在很大程度上与 EIP-2612Solidity 实现 相似,但 permit 函数的参数存在一些显着差异:

  • deadline 参数由 u64 表示,而不是 u256

  • signature 参数由 felts 的 span 表示,而不是 vrs 值。

与 Solidity 不同,Starknet 上没有强制执行的签名格式。签名由 felts 的数组或 span 表示,并且没有用于验证未知格式签名的通用方法。 因此会通过对 owner 地址的合约进行外部 is_valid_signature 调用来验证提供给 permit 函数的签名。

用法

该功能作为 ERC20Component 的可嵌入 ERC20Permit trait 提供。

#[abi(embed_v0)]
impl ERC20PermitImpl = ERC20Component::ERC20PermitImpl<ContractState>;

合约必须满足以下要求才能使用 ERC20Permit trait:

类型化消息

为了防止重放攻击并确保通过 permit 的每次授权的唯一性,签名的数据包括:

  • owner 的地址。

  • approve 函数中指定的参数(spenderamount

  • token 合约本身的地址。

  • nonce,对于每个操作必须是唯一的。

  • chain_id,可防止跨链重放攻击。

签名许可消息中 Permit 结构的格式如下:

struct Permit {
    token: ContractAddress,
    spender: ContractAddress,
    amount: u256,
    nonce: felt252,
    deadline: u64,
}
代币的所有者也是签名消息的一部分。它在 get_message_hash 调用中用作 signer 参数。

有关准备和签署类型化消息的更多详细信息,请参见 SNIP12 指南