【发布时间】:2022-08-23 02:39:31
【问题描述】:
我正在尝试开发一个应用程序来跟踪供应链,但由于该链有多个参与者,主合同的功能已经超出了 25kb 的限制。
所以我将合约的功能拆分为几个合约,我有一个问题,是否可以从其他合约访问存储类型变量。如果可能的话,你能给我一个线索吗,因为我还没有找到关于它的信息?
标签: blockchain ethereum solidity smartcontracts
我正在尝试开发一个应用程序来跟踪供应链,但由于该链有多个参与者,主合同的功能已经超出了 25kb 的限制。
所以我将合约的功能拆分为几个合约,我有一个问题,是否可以从其他合约访问存储类型变量。如果可能的话,你能给我一个线索吗,因为我还没有找到关于它的信息?
标签: blockchain ethereum solidity smartcontracts
你可以读存储属性,如果它们有 public visibility modifier。
您还可以创建相应的 setter 函数。请注意,此示例实现允许任何人设置数字,因此您应该添加一个授权机制,以便只有一些发件人可以设置值。
// deployed on 0x123
contract A {
uint256 public number;
function setNumber(uint256 _number) external {
number = _number;
}
}
// deployed on 0x456
contract B {
function getNumberInA() external view returns (uint256) {
return A(0x123).number();
}
}
如果您对实验性功能持开放态度,您还可以使用 Diamond 模式(EIP-2535,目前尚未批准)来利用代理合约的公共存储,以及部署在多个地址上的实现。
【讨论】:
return A(0x123).number(); 行上复制了您的示例,我复制了 tx 哈希但是我没有和合同A中相同的数字。它获取全局范围的数字值,但我需要本地范围,即函数传递后的数字值。
public存储属性,而无法访问部署在不同地址的其他合约的函数变量。
看起来您想要一个基本合同,然后创建分包合同。所以你的基础合约将访问子合约的函数和变量。你必须实现inheritance。假设您有 Base 和 Sub 合同;
// with this import you will have access to contract Name inside Sub.sol file
import "./Sub.sol"
contract Base is Sub{
// here you can just refence storage variables inside Sub.sol
// BUT storage variables inside Sub.sol has to be "public"
}
【讨论】:
是的,EIP2535 Diamonds 解决了 24kb 的大小限制。它不是通过访问来自其他合约的状态变量来做到这一点,而是通过将所有状态变量存储在一个合约中,而是利用来自其他合约的代码。一篇关于它的文章在这里:https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard
EIP2535 Diamonds 超越了实验技术。在 Ethereum 和 Polygon 上部署了持有数百万美元资产的钻石。超过30个项目正在使用它作为这一点。
【讨论】:
智能合约不能直接相互访问存储。相反,它们通过函数调用交换数据。但是,正如您所提到的,可以部署到区块链的代码量(24 kB)是有限制的。
Nick Mudge 在EIP-2535 上建议的一种可能的解决方案是拥有一个名为“diamond”的代理合约,它将函数调用委托给他们适当的实现合约,称为“facets”。 24 kB 大小限制问题已解决,因为您可以拥有任意数量的方面。此外,钻石的所有方面共享相同的存储上下文,这消除了它们之间调用函数的需要。
该规范非常健壮和强大。特别是Cartesi 一直在使用 Diamonds 将智能合约的功能扩展到通常的限制之外,并利用共享存储上下文来降低函数调用的 gas 成本。如果您想了解更多关于 EIP-2535 及其对代码和存储可升级性的影响,请随时阅读我在 Medium 上的 article。
【讨论】: