当您将合约存储在映射中时,实际存储了啥?

Posted

技术标签:

【中文标题】当您将合约存储在映射中时,实际存储了啥?【英文标题】:What is actually stored when you store a contract in a mapping?当您将合约存储在映射中时,实际存储了什么? 【发布时间】:2021-10-29 15:58:18 【问题描述】:

如果我有一个叫做 Person 的合同,比如说,它包含一个名字和一个年龄,还有一个叫做 People 的合同,这个合同看起来像

 contract People 
      mapping(string => Person) myPeople;

      addPerson(string memory name, uint age) 
          Person person = new Person(name, age);
          myPeople[name] = person;
      
 

我想知道在这种情况下,区块链中实际发生了什么。我知道声明 Person person = new Person(name, age) 实际上会将新的 Person 合约部署到区块链上(我会为此付费)。但是当我通过myPeople[name] = person; 将其存储在映射中时,我是仅存储合约地址,还是再次存储其所有数据? (即在已部署合约的存储中,以及在 People 合约的存储中。如果是第二个,听起来只存储地址会便宜很多。我注意到我可以从映射,并且可以调用它的函数而不必实例化它,但也许在幕后从它的地址实例化合约有一些魔法,这使得我可以调用它的函数?

【问题讨论】:

这是一个很好的问题。我首先要说我不确定。但我很有信心猜测您的存储中没有合同数据的副本。只是因为这听起来不是一个好计划。考虑一下它的含义,您可能有两个指向相同数据的假定指针,并且可能不同。无论哪种方式,它仍然可能是这种情况,也许我可以编写一些测试并检查 gas 成本.. 【参考方案1】:

People 合约存储中存储的实际值(myPeople 映射的每个项下)是已部署的Person 合约的地址

Person 合约存储在People 合约中不重复

我可以从映射中检索 Person,并且可以调用它的函数而无需实例化它

People 合约与Person 实例交互时,它只使用Person 合约的接口。所以People 合约知道Person 有什么函数,期望的参数是什么,返回值等等。

当您从myPeople 映射分配一个变量时,Solidity 使用 local Person 接口。

所以是的,这就是魔法的来源。 :)

【讨论】:

以上是关于当您将合约存储在映射中时,实际存储了啥?的主要内容,如果未能解决你的问题,请参考以下文章

我如何存储合约地址

EOS智能合约授权限制和数据存储

调试智能合约

合约代码无法存储,请检查您的gas限制:以太坊智能合约部署失败:

区块链技术开发智能合约与图像存储在外部存储器IPFS(InterPlanetary File System)

币图网_教你必须了解的智能合约,共识机制,分布式存储以及密码学