Remix 中的显式类型转换

Explicit Type Conversion in Remix

这个函数:

  function initializeDomainSeparator() public {
    // hash the name context with the contract address
    EIP712_DOMAIN_HASH = keccak256(abi.encodePacked(// solium-disable-line
            EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
            keccak256(bytes(name)),
            bytes32(address(this))
            ^^^^^^^^^^^^^^^^^^^
        ));
}

正在解决这个错误:

TypeError: Explicit type conversion not allowed from "address" to "bytes32".

我做错了什么?编译指示 solidity ^0.8.4;

从 Solidity 0.8.0 开始,您无法再将 address 直接转换为 bytes32。您必须执行两个单独的转换:首先转换为 bytes20,它将类型从 address 更改为固定字节,然后才转换为扩展长度的 bytes32

Solidity v0.8.0 Breaking Changes > New Restrictions

There are new restrictions on explicit type conversions. The conversion is only allowed when there is at most one change in sign, width or type-category (int, address, bytesNN, etc.). To perform multiple changes, use multiple conversions.

  • address(uint) and uint(address): converting both type-category and width. Replace this by address(uint160(uint)) and uint(uint160(address)) respectively.

所以在你的情况下正确的转换是 bytes32(bytes20(address(this)))

但是abi.encodePacked()不要求参数是字节类型,事实上你根本不需要在这里进行转换:

EIP712_DOMAIN_HASH = keccak256(abi.encodePacked(// solium-disable-line
    EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
    keccak256(bytes(name)),
    this
));