Open In App

Explicit Conversions in Solidity

Last Updated : 08 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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




// 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:

Converting to a larger type

 

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




// 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:

Converting to a smaller type

 

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




// 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:

Converting to higher range bytes and to smaller range bytes

 

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




// 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:

Convert from uintM to bytesN

 

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




// 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:

Convert from bytesN to uintM

 

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




// 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:

Decimals and Hex Literals Assignments uintN

 

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




// 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 from bytes to bytesN

 

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




// 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:

Conversion between bytes and strings

 

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




// Solidity program to convert from 
// hex literals to address
pragma solidity ^0.8.0;
  
contract Conversion {
  address public a = address(0x1234567890123456789012345678901234567890);
}


Output:

Conversion from hex literals to address

 

2. Conversion from uint160 to address

Below is the Solidity program to convert from uint160 to address:

Solidity




// 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:

Conversion from uint160 to address

 

3. Conversion from address to uint160

Below is the Solidity program to convert from address to uint160:

Solidity




// 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 from address to uint160

 

Conversion between address and address payable

Solidity requires explicit conversion from address to address payable. 

Solidity




// 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 address and address payable

 

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




// 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:

Conversion between Contract and address types

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads