3

Is it possible to slice variables in Solidity?

  • 1
    Thanks for posting that. – Rob Hitchens Dec 27 '19 at 21:53
5

Solidity 0.6.0 and Greater (Updated Jan 2020)

As of Solidity 0.6.0, there is array slice functionality built into Solidity. The syntax is similar to existing languages in that the array takes the following parameters x[start:end]. Here, start and end are ints that represent the starting and ending index to be sliced.

If start is greater than end or if end is greater than the length of the array, an exception is thrown.

As a note, either start or end (or both) can be excluded from the code. start defaults to 0 and end defaults to the length of the array. In the case where:

  • start is excluded, the returned value will be the sliced array from index 0 to the specified end
  • end is excluded, the returned value will be the sliced array from the specified start index to the end of the array
  • both are omitted, the returned array will be identical to input array

Examples

Simplified Example

bytes exampleBytes = '0xabcd'

exampleBytes[2:5];  # 'abc'
exampleBytes[:5];   # '0xabc'
exampleBytes[2:];   # 'abcd'
exampleBytes[:];    # '0xabcd'

Full Example (From Solidity Docs)

pragma solidity ^0.6.0;

contract Proxy {
    /// Address of the client contract managed by proxy i.e., this contract
    address client;

    constructor(address _client) public {
        client = _client;
    }

    /// Forward call to "setOwner(address)" that is implemented by client
    /// after doing basic validation on the address argument.
    function forward(bytes calldata _payload) external {
        bytes4 sig = abi.decode(_payload[:4], (bytes4));
        if (sig == bytes4(keccak256("setOwner(address)"))) {
            address owner = abi.decode(_payload[4:], (address));
            require(owner != address(0), "Address of owner cannot be zero.");
        }
        (bool status,) = client.delegatecall(_payload);
        require(status, "Forwarded call failed.");
    }
}

Note: As of Solidity 0.6.0, array slices are only implemented for calldata arrays.



Solidity < 0.6.0

For Solidity versions prior to 0.6.0, there was no slice functionality built into the language. There are, however, ways to perform similar functionality given the available language features at the time.

To slice a string, you can perform the following (from this answer):

pragma solidity 0.4.24;

contract test{

    function getSlice(uint256 begin, uint256 end, string text) public pure returns (string) {
        bytes memory a = new bytes(end-begin+1);
        for(uint i=0;i<=end-begin;i++){
            a[i] = bytes(text)[i+begin-1];
        }
        return string(a);    
    }
}

You can also use the stringutils library by Arachnid (Nick Johnson) to achieve the same goals.

| improve this answer | |
  • What will be its gas cost? @shane – alper Jan 8 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.