合约地址变量在solid中消耗多少状态字节?



我想知道如果你像下面这样在合约的状态变量中声明合约类型,会有多少字节。

contract ContractA {
// some code...
}
contract ContractB {
ContractA contractA; // how much bytes will this state take up?
constructor (address addr) {
contractA = ContractA(addr);
}
}

我对此很好奇,因为除了合约类型变量之外,solidity中单个存储槽中的32个字节可以将多个变量放入单个插槽中。

是否与地址类型相同,20字节?

在Solidity中,所有的存储槽都是32字节

这是正确的,但这并不意味着状态变量将消耗32字节。例如

uint8 public a=7 // 1 byte
uint16 public b=12 // 2 bytes
address public c=0xasdkhfk...... // 20 bytes
bool d=true //1 byte
uint64 public e=12 //8 bytes
uint256 public f=213 // 32 bytes

以太坊虚拟机将状态变量打包到插槽中。在上述状态变量中,将前5个变量abcde放在第一个槽位。正如你所看到的,物品的顺序关系到固体。

基于一个很棒的答案:https://ethereum.stackexchange.com/questions/115413/what-does-an-explicit-conversion-from-an-address-to-a-contract-type-actually-do

在Solidity中,合约变量实际上只是一个地址罩。

意味着它占用20个字节。答案的作者解释了addresscontract类型之间的差异。我们也可以用地址本身来调用契约:

您实际上可以与部署在特定地址的代码交互没有契约变量。Address有成员函数,比如例如.call()。这些函数是一种低级的EVM方法一个外部电话。在这个层次上,函数并不真正存在。你指定一些要发送到该代码并接收回的调用数据返回数据。

地址类型

的成员这里我们为什么使用contract类型:

Solidity的合约类型是一个抽象,使其成为外部的代码看起来更像您可能熟悉的其他类语言。类可以有方法,在Solidity中可以有编译器通过让字节码期望一个函数ID(选择器)来模拟这一点在前4个字节的呼叫数据和做不同的事情的基础上哪个ID被发送。特别是ID决定了如何解释它后面的数据(即参数)。

而不是在地址上手动使用低级的.call()构造正确的调用数据后,您可以只调用外部的函数,编译器会将其转换为它生成的字节码中的低级调用。然而,要做到这一点,它需要知道那份合同的地址。你可以这样做通过将地址强制转换为契约类型来获取信息。为方便,您可以将这种强制转换的结果存储在合约中变量,而不必每次都强制转换。

在Solidity中,所有的存储槽都是32字节,这是大多数变量声明将消耗的状态量。