跳转到正文
Lishude's Web Note
返回

solidity: bytes 强制类型转化为地址注意点

当 bytes32 转换为 address 时候,需要进行强制转换,通常有两种方式

第一种,转换为 bytes20 然后再转换为 address

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Parser {
    function parse(bytes32 code) public pure returns (address) {
        return address(bytes20(code));
    }
}   

第二种,转化为 uint160 再转换为 address

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Parser {
    function parse(bytes32 code) public pure returns (address) {
        return address(uint160(uint256(code)));
    }
}   

这两种方式看起来差不多,其实输出是不一样的。第一种会取前 20 字节,也就是后面数据截断;第二种是取后 20 字节,也就是溢出的形式。

例如使用 0xe69b9548081a52fc6972902887aa83079e169569f88c911b052464a25460a5fa 进行计算。

Screen Shot 2022-04-24 at 23 59 22

这一点尤其重要,尤其是在 create2 下计算地址时比较容易犯错,因为 create2 是需要取最后的 20 字节。

// CreateAddress2 creates an ethereum address given the address bytes, initial
// contract code hash and a salt.
func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
	return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
}

原文:GitHub Issue #253



上一篇
selfdestruct 的两点重要的容易被忽视的逻辑
下一篇
golang generic nil check 泛型空指针检查