本文档定义了Starknet中作为账户的智能合约的标准API,为通过合约发送交易提供了基本功能,并为验证签名提供了支持账户、协议和dapp之间互操作性的功能。该标准账户接口支持不同的dapp、协议和标准合约,这些合约通常需要与账户进行可预测的交互。
账户的标准接口。
以下标准定义了在Starknet中作为账户的智能合约的标准API。它提供了通过合约发送交易的基本功能,以及支持账户、协议和dapp之间互操作性的验证签名的功能。
借助原生账户抽象,Starknet在账户管理方面具有很大的灵活性,而不是让它们的行为在协议层面确定。不同的用例正在并将继续为生态系统带来不同的账户实现。
拥有标准账户接口支持不同的dapp、协议和标准合约(如token),它们通常需要与账户进行可预测的交互,无论是通过识别它们,还是通过期望某些行为,否则这些行为可能无法实现。
本文档中的关键词“必须(MUST)”、“不得(MUST NOT)”、“必需(REQUIRED)”、“应(SHALL)”、“不应(SHALL NOT)”、“应该(SHOULD)”、“不应该(SHOULD NOT)”、“推荐(RECOMMENDED)”、“可以(MAY)”和“可选(OPTIONAL)”应按照RFC 2119中的描述进行解释。
每个符合SNIP-6的账户必须实现SRC6和SRC5接口(来自SNIP-5),并通过supports_interface发布这两个接口ID:
账户的接口ID被硬编码为0x2ceccef7f994940b3962a6c67e0ba4fcd37df7d131417c604f91e03caecc1cd,它与原始账户接口匹配。请注意,自第一个版本以来,某些方法已经更改,但接口ID不会更改以保持兼容性。
/// @title 表示对目标合约的调用
/// @param to 目标合约地址
/// @param selector 目标函数选择器
/// @param calldata 序列化的函数参数
struct Call {
to: ContractAddress,
selector: felt252,
calldata: Span<felt252>
}
/// @title SRC-6 标准账户
trait ISRC6 {
/// @notice 通过账户执行交易
/// @param calls 要执行的调用列表
fn __execute__(calls: Array<Call>);
/// @notice 断言交易是否有效以执行
/// @param calls 要执行的调用列表
/// @return 当有效时,表示为felt的字符串 'VALID'
fn __validate__(calls: Array<Call>) -> felt252;
/// @notice 断言给定hash的给定签名是否有效
/// @param hash 数据的hash
/// @param signature 要验证的签名
/// @return 当签名有效时,表示为felt的字符串 'VALID'
fn is_valid_signature(hash: felt252, signature: Array<felt252>) -> felt252;
}
/// @title SRC-5 标准接口检测
trait ISRC5 {
/// @notice 查询合约是否实现了接口
/// @param interface_id 接口标识符,如SRC-5中所述
/// @return 如果合约实现了`interface_id`,则为`true`,否则为`false`
fn supports_interface(interface_id: felt252) -> bool;
}
/// @title 表示对目标合约的调用
/// @param to 目标合约地址
/// @param selector 目标函数选择器
/// @param calldata 序列化的函数参数
struct Call {
to: ContractAddress,
selector: felt252,
calldata: Array<felt252>
}
/// @title SRC-6 标准账户
trait ISRC6 {
/// @notice 通过账户执行交易
/// @param calls 要执行的调用列表
/// @return 每个调用的序列化返回值列表
fn __execute__(calls: Array<Call>) -> Array<Span<felt252>>;
/// @notice 断言交易是否有效以执行
/// @param calls 要执行的调用列表
/// @return 当有效时,字符串 'VALID' 表示为 felt
fn __validate__(calls: Array<Call>) -> felt252;
/// @notice 断言给定hash的给定签名是否有效
/// @param hash 数据的hash
/// @param signature 要验证的签名
/// @return 当签名有效时,'VALID' 字符串表示为 felt
fn is_valid_signature(hash: felt252, signature: Array<felt252>) -> felt252;
}
请注意,如果签名有效,则is_valid_signature的返回值必须是短字符串字面量VALID。
为了保证签名不能在其他账户或其他链上重放,hash的数据必须对账户和链是唯一的。 对于starknet交易签名和SNIP-12签名来说,这是成立的。但是,值得注意的是,这可能不一定适用于其他类型的签名。 建议钱包不要签署任何数据,除非他们知道它包括账户地址和链ID。
本SNIP旨在标准化Starknet上的账户接口。虽然Starknet本身需要一些函数才能使账户发挥作用,但本标准包括增强账户与更广泛的Starknet生态系统互操作性的附加功能。
例如,is_valid_signature函数为dapp和协议提供了一种验证签名的标准方法,使账户与任何期望此功能的dapp或协议兼容。遵守SNIP-5也使账户更容易被发现和集成。
虽然Starknet上的账户可以在不遵守本标准的情况下运行,但这样做在互操作性、可发现性和用户体验方面提供了显著的好处。符合SNIP-6的账户可以期望与Starknet生态系统的其余部分有更好的兼容性和集成。 同时,该标准被设计为最小和灵活的,允许各种各样的账户实现。
如前所述,账户的接口ID仍然是0x2ceccef7f994940b3962a6c67e0ba4fcd37df7d131417c604f91e03caecc1cd**,它与原始账户接口匹配。
请注意,当前的接口ID和旧的接口ID在调用方式上是兼容的。
最新版本的__execute__方法不返回任何数据。但旧版本过去常常返回调用的结果。第三方不应依赖于返回的数据。
目前,多个账户使用bool作为is_valid_signature的返回值。虽然在未来我们希望大多数账户将迁移到这个标准,但在过渡期间,我们建议使用此功能的dapp和协议同时检查true或'VALID'。
版权及相关权利通过MIT放弃。
- 原文链接: github.com/starknet-io/S...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!