48

任何人都可以向我解释address(0)Solidity 中的内容吗?我在文档中找到了以下内容,但这对我来说真的没有意义:

如果目标账户是零账户(地址为0的账户),则交易创建一个新合约。如前所述,该合约的地址不是零地址,而是从发送者及其发送的交易数量(“nonce”)派生的地址。这种合约创建交易的有效负载被视为 EVM 字节码并被执行。此执行的输出作为合约代码永久存储。这意味着为了创建合约,您不需要发送合约的实际代码,而是发送返回该代码的实际代码。

http://solidity.readthedocs.io/en/develop/introduction-to-smart-contracts.html?highlight=address(0)#index-8

4

2 回答 2

42

在以太坊交易中,零账户只是一种特殊情况,用于指示正​​在部署新合约。to在原始事务中,它实际上设置为“0x0” 。

每个以太坊交易,无论是两个外部账户之间的转账、执行合约代码的请求,还是部署新合约的请求,都以相同的方式编码。原始交易对象看起来像这样:

transaction = {
  nonce: '0x0', 
  gasLimit: '0x6acfc0', // 7000000
  gasPrice: '0x4a817c800', // 20000000000
  to: '0x0',
  value: '0x0',
  data: '0xfffff'
};

如果to设置为 '0x0' 以外的值,此请求将导致将以太币传输到该地址(如果value非零),并执行该data字段中编码的函数。请记住,地址可以是合约或外部帐户。

to地址是零地址时,将通过执行其中的代码来创建一个新的合约data(这就是“返回代码的代码”的意思)。新创建的合约的地址在技术上是事先已知的,因为它基于发送者的地址并且是当前的随机数。该地址在挖矿后成为合约的官方地址。

想要很好地了解以太坊交易,请查看这篇文。

注意:还有实际的 Solidity 代码语句address(0),它是类型变量的初始值address。但是,您发布的文档专门指的to是交易中的帐户地址设置为“0x0”时。

于 2018-01-12T06:36:15.467 回答
4

合约创建交易的“to”字段设置为零地址(意思是 )实际上并不是真的0x00...000。这是一个容易犯的错误(我也犯过),因为在许多资源中都是这样描述的。

您从 Solidity 文档中引用的段落已更新以说明这一点:

如果没有设置目标账户(交易没有收款人或收款人设置为空),则交易创建一个新合约。如前所述,该合约的地址不是零地址,而是从发送者及其发送的交易数量(“nonce”)派生的地址。

所以你可以看到他们在某个时候意识到收件人字段应该是空的。我实际上已经查看了序列化的创建事务,并在0x80那里找到了而不是 RLP ed 零地址。

实际上,0x80 一个空字节数组的 RLP 编码,这就是黄皮书所说的合约创建的接收者:

地址哈希 $T_t$ 略有不同:它要么是 20 字节的地址哈希,要么在合约创建交易的情况下(因此正式等于∅),它是 RLP 空字节序列,因此$B_0$ 的成员

正如我所说,这是一个常见的混淆来源。在这种情况下,这个GitHub PR回滚一个错误地“固定”的测试很有趣。它有评论:

0的RLP编码是空字节数组的编码,所以0x80是正确的。

0x00 是长度为 1 的字节数组的编码,包含一个字节 0,而不是整数 0 的编码。

于 2021-07-26T16:24:51.583 回答