Skip to content

Instantly share code, notes, and snippets.

@Zer0dot
Last active January 17, 2023 22:22
Show Gist options
  • Save Zer0dot/19428fcd5d80433166dcfe7e1050afc5 to your computer and use it in GitHub Desktop.
Save Zer0dot/19428fcd5d80433166dcfe7e1050afc5 to your computer and use it in GitHub Desktop.
A library with a custom type to introduce immutable strings of length less than 32 bytes.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title ImmutableStringLib
* @author Zer0dot
*
* @notice This library introduces an abstraction to store and decode immutable strings.
* This is necessary because simply casting a string to a bytes32 variable will lose the
* length, which will be hardcoded as 32 upon re-converting via abi.encode.
*
* @dev Immutable strings must be less than 32 bytes in length, as the last byte is used to
* store the length.
*/
library ImmutableStringLib {
type ImmutableString is uint256;
/**
* @dev Converts a standard string to an immutable string.
*/
function toImmutableString(string memory input) internal pure returns (ImmutableString) {
require(bytes(input).length < 32, "LENGTH_GTE_32");
return ImmutableString.wrap(uint256(bytes32(bytes(input)) | bytes32(bytes(input).length)));
}
/**
* @dev Converts an immutable string to a standard string.
*/
function toString(ImmutableString input) internal pure returns (string memory) {
uint256 unwrapped = ImmutableString.unwrap(input);
uint256 len = unwrapped & 255;
uint256 readNoLength = unwrapped >> 8 << 8;
string memory res = string(abi.encode(readNoLength));
assembly {
mstore(res, len) // "res" points to the length, not the offset.
}
return res;
}
}
/**
* @notice This is an example of how the ImmutableStringLib would be used.
*/
contract SomeContract {
using ImmutableStringLib for string;
using ImmutableStringLib for ImmutableStringLib.ImmutableString;
ImmutableStringLib.ImmutableString immutable someString;
constructor(string memory input) {
someString = input.toImmutableString();
}
function getSomeString() external view returns (string memory) {
return someString.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment