type-conversiontypeerrorsoliditycontractremix

Explicit Type Conversion in Remix


This function:

  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))
            ^^^^^^^^^^^^^^^^^^^
        ));
}

Is kicking back this error:

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

What am I doing wrong? pragma solidity ^0.8.4;


Solution

  • Starting with Solidity 0.8.0 you can no longer convert address directly to bytes32. You have to perform two separate conversions: first to bytes20, which changes the type from address to fixed bytes and only then to bytes32 which extends the length.

    See 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.

    So the correct conversion in your case would be bytes32(bytes20(address(this))).

    But abi.encodePacked() does not require the argument to be of a bytes type and in fact you do not need a conversion here at all:

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