rt,有些合约不希望有多个实例,需要全局唯一,有什么好的方案吗?
我个人想到的是在 constructor 中写个 require 校验,指定只能由某个固定的 msg.sender 地址来创建。期待探讨更好的方式。
有没有单例模式的最佳实践?
没有明白你这里所有的单例指的是什么?
是指一个合约只部署一次,然后让所有的其它合约来调用吗?
如果是这样,与谁来创建这个合约又有何关系呢?
singleton
设计模式的单例是 用于 全局共享数据,您说的单例具体要干什么? 有什么场景说一下吗?
因为区块链不可篡改的特性,我们想设计一个变通的方案来支持合约升级(修改)。参考了有个叫 r egistry pattern 的方案,即有个类似索引的全局唯一合约,用于记录合约的别名、地址、版本、是否生效,同时我们再扩展一些统计分析的功能(当然这些功能会限定使用者),所以单例模式是比较适合的。
如上所述,还是有点关系,因为该单例合约在功能上的有限制,不是完全开放给所有人。
Okay, 我理解你的意思并想了如下思路,你看行不行:
Step 1: 部署 global 合约
这个合约是调用其它合约的总入口,这个合约对你的客户提供服务,一旦部署,将不会改变。也就是这个合约部署后的地址不变,我暂记为 GlobalAddress
。
这个合约至少包括了注册子合约的接口:
register(SubContractsInfo)
SubContractsInfo 中至少包括了子合约的地址。
Step 2: 部署子合约
子合约可能有很多个,为了控制子合约接口的访问权限。在每个方法上添加 onlyGlobalAdress 的限制:
modifier onlyGlobalAdress () {
require(msg.sendder == GlobalAddress, "Not the global address!")
_
}
function xxxx onlyGlobalAdress {
}
部署子合约将会获得合约地址, 暂记为 SubAddress
。
Step 3: 在 Global 合约中注册 SubAddress
调用 Global 合约中的注册接口 register
注册子合约 SubAddress 。
Step 4: 子合约升级
- 子合约更改,重新部署,获得新的地址,暂记为 SubAddressNew ;
- 调用Global 合约中的注册接口
register
重新注册子合约 SubAddressNew。 - 完成合约升级。
不知道这样描述是不是你所想?