Last active
January 17, 2023 22:22
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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