Types

  • Yul has only one type - the 32-bit word, or the 256 bits that we’re used to seeing in Solidity.

// Usual Solidity representation

    function getNumberSol() external pure returns (uint256) {
        return 42;
    }

// Yul representation 

    function getNumberYul() external pure returns (uint256) {
        uint256 x;

        assembly {
            x := 42
        }
        return x;
    }
  • Yul can also take in hex values, but will output them as decimals, since we are casting them as uint256

function getHex() external pure returns (uint256) {
        uint256 x;

        assembly {
            x := 0xa
        }

        return x; // returns decimal 10 
    }
  • Strings are not naturally a bytes32, so we cannot assign values to a string in memory in Yul.

  • Calling this function will return an out of gas error, since you’re essentially trying to assign “hello world” to the pointer storing the location of the string in memory

// wrong example
 
function getString() external pure returns (string memory) {
        string memory myString;

        assembly {
            myString := "hello world"
        }

        return myString;
    }
  • We have to change the string’s data type to bytes32, in order for it to be stored in the stack so that Yul can access it. (bytes32 is always stored on the stack)

  • To make the output a readable string, we have to cast it using: string(abi.encode(myString))

function demoString() external pure returns (string memory) {
        bytes32 myString = "";

        assembly {
            myString := "hello world"
        }
				
        return string(abi.encode(myString));
				// return myString; -> will return a bytes32 representation of hello world 
				// 0x68656c6c6f20776f726c64000000000000000000000000000000000000000000 
    }
  • The max size of the string you can assign to a variable in Yul is 32 bytes, anything larger will return a compiler error

  • 32 bytes is the only type in Yul, and Solidity will just enforce an interpretation based on the value type its being assigned to.

// the following returns true, 
// since a boolean in solidity is essentially 32 bytes where the last bit is 1 
// Example: often seen in calldata 
function representation() external pure returns (bool) {
        bool x;

        assembly {
            x := 1
        }

        return x;
    }
  • If we change the variable to an address, it will return 0x0....001 = address(1)

Last updated