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 program to convert // to a larger type pragma solidity ^0.8.0; contract Conversion {
uint8 public a = 100;
// Convert to larger type
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 program to convert // to a smaller type pragma solidity ^0.8.0; contract Conversion {
uint256 public a = 100;
// Convert to smaller type
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 program to covert to // higher bytes range adn smaller // bytes range pragma solidity ^0.8.0; contract Conversion {
// "hello" in ASCII
bytes16 public a = hex "68656c6c6f" ;
// Convert to smaller bytes range
bytes8 public b = bytes8(a);
// Convert to higher bytes range
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 program to convert // from uintM to bytesN pragma solidity ^0.8.0; contract Conversion {
uint256 public a = 12345;
// Convert to bytes2
bytes2 public b = bytes2(uint16(a));
// Convert to bytes4
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 program to convert // from bytesN to uintM pragma solidity ^0.8.0; contract Conversion {
bytes2 public a = hex "3039" ;
// Convert to uint16
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 program for Decimals // and Hex Literals Assignments uintN pragma solidity ^0.8.0; contract Conversion {
// Decimal literal assignment
uint8 public a = 42;
// Hexadecimal literal assignment
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 program to convert // from bytes to bytesN pragma solidity ^0.8.0; contract Conversion {
// "hello" in ASCII
bytes public a = hex "68656c6c6f" ;
// Convert to bytes2
bytes2 public b = bytes2(a);
// Convert to bytes4
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 program to convert // between bytes and strings pragma solidity ^0.8.0; contract Conversion {
// "hello" in ASCII
bytes public a = hex "68656c6c6f" ;
// Convert to string
string public b = string(a);
// Convert to bytes
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 program to convert from // hex literals to address 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 program to convert from // uint160 to address pragma solidity ^0.8.0; contract Conversion {
uint160 public num = 123;
// Convert uint160 to address
address public addr = address(num);
} |
Output:
3. Conversion from address to uint160
Below is the Solidity program to convert from address to uint160:
// Solidity program to convert from // address to uint160 pragma solidity ^0.8.0; contract Conversion {
address public addr = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
// Convert address to uint160
uint160 public num = uint160(addr);
} |
Output:
Conversion between address and address payable
Solidity requires explicit conversion from address to address payable.
// Solidity program to convert between // address and address payable pragma solidity ^0.8.0; contract Conversion {
address public addr = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
// Convert address to address payable
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 program to convert between // Contract and address types 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();
// get contract address
address public addr = myContract.getContractAddress();
function callContract() public view returns(uint256)
{
// call function from contract address
return MyContract(addr).value();
}
} |
Output: