Explicit Conversions in Solidity
Last Updated :
08 May, 2023
Converting data types in Solidity requires explicit conversions. When working with incompatible data formats, this is beneficial. Solidity explicitly converts values via casting operations. To maintain compatibility or execute a particular action, Solidity data types might have distinct sizes and representations.Â
What is Explicit Conversion?
Explicit conversions may convert simple kinds like integers and floating-point numbers or complicated types like arrays and structs. Solidity supports typecasting, type conversion via a function Object() { [native code] }, and conversion using built-in conversion methods like address(uint160(addr)) or string(addr) (data).Â
- If utilized improperly, explicit conversions might cause data loss or unexpected behavior.Â
- Always explicitly convert types that are compatible.
- Explicit conversions are performed using built-in functions such as bytes().
Explicit Conversion vs Implicit Conversion
- Implicit conversion happens when a value of one type is given to a variable of another type, unlike explicit conversion.Â
- Implicit conversions in Solidity are restricted to converting an unsigned integer to a bigger unsigned integer or a string literal to a bytes type. Explicit conversions may convert more types.
Unsigned integer conversion
Solidity supports uint8, uint16, uint32, uint64, uint128, and uint256. These types may be converted explicitly.
1. Converting to a Larger Type
When converting to a larger type, such as uint256 to uint128, the value is simply padded with zeroes to fill the extra space.
Solidity
pragma solidity ^0.8.0;
contract Conversion {
uint8 public a = 100;
uint256 public b = uint256(a);
}
|
Output:
Â
2. Converting to a Smaller Type
When converting to a smaller type, such as uint32 to uint16, the value is truncated to fit the smaller size. This can result in data loss if the value being converted is too large to fit in the smaller type.
Solidity
pragma solidity ^0.8.0;
contract Conversion {
uint256 public a = 100;
uint8 public b = uint8(a);
}
|
Output:
Â
Conversion between bytesN
Solidity also supports fixed-size byte arrays, such as bytes8, bytes16, bytes32, and so on. Explicit conversions can be used to convert between these types when necessary.
Converting to a Higher Bytes Range and  to a Smaller bytes range
When converting to a smaller bytes range, such as bytes16 to bytes8, the value is truncated to fit the smaller size. This can result in data loss if the value being converted is too large to fit in the smaller type.
Solidity
pragma solidity ^0.8.0;
contract Conversion {
bytes16 public a = hex "68656c6c6f" ;
bytes8 public b = bytes8(a);
bytes32 public c = bytes32(a);
}
|
Output:
Â
Conversions from uintM to bytesNÂ
Solidity supports converting unsigned integers to bytesN types with explicit conversion, where N is a multiple of 8 between 1 and 32.
Solidity
pragma solidity ^0.8.0;
contract Conversion {
uint256 public a = 12345;
bytes2 public b = bytes2(uint16(a));
bytes4 public c = bytes4(uint32(a));
}
|
Output:
Â
Conversion from bytesN to uintM
Solidity supports converting bytesN types to unsigned integers with explicit conversion, where N is a multiple of 8 between 1 and 32.
Solidity
pragma solidity ^0.8.0;
contract Conversion {
bytes2 public a = hex "3039" ;
uint16 public b = uint16(a);
}
|
Output:
Â
Decimals and Hex Literals Assignments uintN
In Solidity, we can assign values using decimal and hexadecimal literals to uintN types. These assignments require explicit conversion when assigning to smaller uint types.
Solidity
pragma solidity ^0.8.0;
contract Conversion {
uint8 public a = 42;
uint256 public b = 0x123456789ABCDEF;
}
|
Output:
Â
Conversion from bytes to bytesN
We can also perform explicit conversions between different bytesN types. Here, the source bytes must be of a larger size than the destination type, and an error will occur if the source bytes are of a smaller size than the destination type.
Solidity
pragma solidity ^0.8.0;
contract Conversion {
bytes public a = hex "68656c6c6f" ;
bytes2 public b = bytes2(a);
bytes4 public c = bytes4(a);
}
|
Output:
Â
Conversion between bytes and strings
Solidity provides built-in functions to convert bytes to strings and vice versa. The conversion from bytes to a string requires that the bytes are in UTF-8 format.Â
Solidity
pragma solidity ^0.8.0;
contract Conversion {
bytes public a = hex "68656c6c6f" ;
string public b = string(a);
bytes public c = bytes(b);
}
|
Output:
Â
Conversions to address Type
In Solidity, there are several ways to convert to the address type. Here are some examples:
1. Conversion from hex literals to address
Below is the Solidity program to convert from hex literals to address:
Solidity
pragma solidity ^0.8.0;
contract Conversion {
address public a = address(0x1234567890123456789012345678901234567890);
}
|
Output:
Â
2. Conversion from uint160 to address
Below is the Solidity program to convert from uint160 to address:
Solidity
pragma solidity ^0.8.0;
contract Conversion {
uint160 public num = 123;
address public addr = address(num);
}
|
Output:
Â
3. Conversion from address to uint160
Below is the Solidity program to convert from address to uint160:
Solidity
pragma solidity ^0.8.0;
contract Conversion {
address public addr = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
uint160 public num = uint160(addr);
}
|
Output:
Â
Conversion between address and address payable
Solidity requires explicit conversion from address to address payable.Â
Solidity
pragma solidity ^0.8.0;
contract Conversion {
address public addr = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
address payable public payAddr = payable(addr);
}
|
Output:
Â
Conversion between Contract and address types
A Solidity contract is essentially an address with code associated with it. Therefore, it is possible to convert between the address and contract types.Â
Solidity
pragma solidity ^0.8.0;
contract MyContract {
uint256 public value = 123;
function getContractAddress() public view returns(address)
{
return address( this );
}
}
contract Conversion {
MyContract public myContract = new MyContract();
address public addr = myContract.getContractAddress();
function callContract() public view returns(uint256)
{
return MyContract(addr).value();
}
}
|
Output:
Â
Share your thoughts in the comments
Please Login to comment...