Solidity

如何使用 Solidity 語言在創建乙太坊合約期間計算其地址?

  • March 25, 2021

現在我知道並閱讀了另一個執行緒,說合約的地址是通過 RLP 對創建者的地址和他的 nonce 進行編碼確定性地創建的,然後使用 Keccak-256 進行雜湊處理,但問題是解決方案是在 Python 中提供的。

我目前正在使用 Solidity 進行編碼,儘管我已嘗試將解決方案移植到 Solidity,但據我所知,Solidity 不支持 rlp_encoder 函式所需的多類型數組。任何有關如何在 Solidity 中實現此目的的幫助或提示將不勝感激!(nonce 將在契約創建期間作為輸入給出)

最優化版本:

function addressFrom(address _origin, uint _nonce) public pure returns (address) {
   bytes memory data;
   if (_nonce == 0x00)          data = abi.encodePacked(byte(0xd6), byte(0x94), _origin, byte(0x80));
   else if (_nonce <= 0x7f)     data = abi.encodePacked(byte(0xd6), byte(0x94), _origin, byte(_nonce));
   else if (_nonce <= 0xff)     data = abi.encodePacked(byte(0xd7), byte(0x94), _origin, byte(0x81), uint8(_nonce));
   else if (_nonce <= 0xffff)   data = abi.encodePacked(byte(0xd8), byte(0x94), _origin, byte(0x82), uint16(_nonce));
   else if (_nonce <= 0xffffff) data = abi.encodePacked(byte(0xd9), byte(0x94), _origin, byte(0x83), uint24(_nonce));
   else                         data = abi.encodePacked(byte(0xda), byte(0x94), _origin, byte(0x84), uint32(_nonce));
   return address(keccak256(data));
}

Solidity 0.6.x 更新:

function addressFrom(address _origin, uint _nonce) public pure returns (address) {
   bytes memory data;
   if (_nonce == 0x00)          data = abi.encodePacked(byte(0xd6), byte(0x94), _origin, byte(0x80));
   else if (_nonce <= 0x7f)     data = abi.encodePacked(byte(0xd6), byte(0x94), _origin, uint8(_nonce));
   else if (_nonce <= 0xff)     data = abi.encodePacked(byte(0xd7), byte(0x94), _origin, byte(0x81), uint8(_nonce));
   else if (_nonce <= 0xffff)   data = abi.encodePacked(byte(0xd8), byte(0x94), _origin, byte(0x82), uint16(_nonce));
   else if (_nonce <= 0xffffff) data = abi.encodePacked(byte(0xd9), byte(0x94), _origin, byte(0x83), uint24(_nonce));
   else                         data = abi.encodePacked(byte(0xda), byte(0x94), _origin, byte(0x84), uint32(_nonce));
   return address(uint256(keccak256(data)));
}

我碰巧實現了一個。

我的第一個版本是可靠的,但它的執行成本超過 6000 氣體,所以我花了一些時間用純彙編程式碼建構另一個版本。這個效率要高得多。

https://github.com/yanche/eth_contract_addr_calc/blob/master/contract_addr.sol

引用自:https://ethereum.stackexchange.com/questions/24248