Solidity
如何使用 Solidity 語言在創建乙太坊合約期間計算其地址?
現在我知道並閱讀了另一個執行緒,說合約的地址是通過 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