部署时调用过 init,不代表它从此失去权限。DuskVM Reference 明确写出,init 在部署后仍是导出的入口。这个细节把一次性初始化从平台保证,推回了合约自己的访问控制。若代码没有留状态锁,部署时间只是一段经历,不是一张永久封条。
我把责任拆成两列。平台负责创建初始状态,并在部署时按参数调用 pub fn init。@Dusk 合约自己负责记录是否已经初始化,后续调用时拒绝重复执行,也要核对 caller 是否具备权限。前一列保证函数被调用,后一列才保证谁能再调用以及能调用几次,两列不能互相代签。
风险不在 init 这个名字,而在它可能写入什么。管理员地址、资产映射、费用参数或外部合约地址,只要允许第二次覆盖,第一次部署形成的信任条件就会被重置。这里不能凭函数名推断漏洞,事实说话,只有具体代码缺少状态位或调用者校验时,重复初始化才会变成真实攻击面。
$DUSK 上看一份合约的初始配置,我会追三处证据。持久状态里有没有 initialized 标记,第二次调用是否明确失败,修改关键字段前是否验证 caller。部署交易只能回答它当时执行过,回答不了后来谁还能执行。审计若只截图第一次成功回执,权限问题仍然空着一半。
这张两列表也给普通用户一个可用判断。项目方说参数已在部署时锁定,可以继续追问锁定由虚拟机完成,还是由合约代码完成。前者与文档不符,后者就应能在源码和重复调用测试里找到证据。init 是部署入口,也是部署后的公开入口。真正的一次性,不靠时间顺序,靠状态拒绝和调用者授权。#dusk
我把责任拆成两列。平台负责创建初始状态,并在部署时按参数调用 pub fn init。@Dusk 合约自己负责记录是否已经初始化,后续调用时拒绝重复执行,也要核对 caller 是否具备权限。前一列保证函数被调用,后一列才保证谁能再调用以及能调用几次,两列不能互相代签。
风险不在 init 这个名字,而在它可能写入什么。管理员地址、资产映射、费用参数或外部合约地址,只要允许第二次覆盖,第一次部署形成的信任条件就会被重置。这里不能凭函数名推断漏洞,事实说话,只有具体代码缺少状态位或调用者校验时,重复初始化才会变成真实攻击面。
$DUSK 上看一份合约的初始配置,我会追三处证据。持久状态里有没有 initialized 标记,第二次调用是否明确失败,修改关键字段前是否验证 caller。部署交易只能回答它当时执行过,回答不了后来谁还能执行。审计若只截图第一次成功回执,权限问题仍然空着一半。
这张两列表也给普通用户一个可用判断。项目方说参数已在部署时锁定,可以继续追问锁定由虚拟机完成,还是由合约代码完成。前者与文档不符,后者就应能在源码和重复调用测试里找到证据。init 是部署入口,也是部署后的公开入口。真正的一次性,不靠时间顺序,靠状态拒绝和调用者授权。#dusk