openzeppelin-contracts icon indicating copy to clipboard operation
openzeppelin-contracts copied to clipboard

String utilities

Open Arachnid opened this issue 6 years ago • 12 comments

Does Open Zeppelin have any interest in integrating a library for string manipulation? I created the most widely used one here nearly three years ago, but lack the time to maintain it as a separate library. If there's interest, I'm happy to license and contribute it in any way that works for the OZ team.

Arachnid avatar Jun 13 '19 02:06 Arachnid

Could you please give me an example of such an operation, or why do not I do this offline?

Skyge avatar Jun 13 '19 06:06 Skyge

Hi there @Arachnid, thank you very much for this! We've actually discussed your library a couple days ago in https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1746, and started work on a Strings library (rather barebones so far). I think it'd be great to have your work here!

We'd have to migrate the test cases from Solidity to JavaScript (to bring them in line with the rest of our test suite), and update the code so that we can target solc v0.5.0, but I don't see any major blockers in this regard.

Also, note that openzeppelin-solidity is licensed under MIT, whereas stringutils uses Apache v2: would you be okay with re-licensing it under MIT for this?

We'll take a look at the API to analyse if we want to bring the whole library over, or just a portion of it to start with, and figure out the best way to make this happen while bothering you as little as possible (e.g. we won't ask you to rewrite the tests in JavaScript for us).

Once again, thanks a lot!

nventuro avatar Jun 13 '19 06:06 nventuro

That would be fantastic! I've used your string library before @Arachnid and I think it's great. (Maybe I messaged you about it once). I think it would also be a great EVM package! Let see if they can incorporate it!

crazyrabbitLTC avatar Jun 13 '19 16:06 crazyrabbitLTC

@nventuro Sounds good! I'm happy to relicense my contributions under any license you see fit - MIT is absolutely fine. Please let me know if you need anything else from me.

Arachnid avatar Jun 13 '19 21:06 Arachnid

That is so awesome @Arachnid.

@Skyge for your background, in two contracts this year, to reduce gas costs when minting ERC721 tokens with metadata, I used string concatenation and uint to string from a different implementation (I only found Nick's library later). I proposed this as an addition in the forum

abcoathup avatar Jun 14 '19 04:06 abcoathup

@abcoathup Ohhh, I see, I seldom use ERC721.

Skyge avatar Jun 17 '19 00:06 Skyge

Cool @Arachnid! We've always been reluctant to implement string utilities given that your library already existed :smile: so we're happy to see that you'd like to contribute it.

There are several functions for which we haven't seen concrete use cases before. For example, do you know of situations where a smart contract needed to use find?

Do you know what are the most common functions that people tend to use? We're really interested in this because it will inform what things we prioritize.

I also have some concerns regarding the heavy use of loops in the library. Although it makes complete sense for a string manipulation library, OpenZeppelin generally tends to avoid loops as much as possible, to protect our users from running into issues where an attacker could control the loop bound. What are your thoughts on this?

frangio avatar Jun 24 '19 23:06 frangio

There are several functions for which we haven't seen concrete use cases before. For example, do you know of situations where a smart contract needed to use find?

I'm not aware of any concrete examples of that in use, no.

Do you know what are the most common functions that people tend to use? We're really interested in this because it will inform what things we prioritize.

In my own subjective experience, read-only operations I've seen used in the wild:

  • UTF8 string length (we use it in ENS, but our use-case could be quite specific).
  • Converting between null-terminated bytes32 short strings and variable length strings and back.
  • Comparing strings for equality or for sort order.
  • Checking a string prefix.
  • Getting a slice.

As far as string mutations go, concatenating strings is the main thing I've seen done - for example, in constructing a URL for an oracle service. I do think a separate 'Buffer' library makes sense for this, to avoid O(n^2) copying.

I also have some concerns regarding the heavy use of loops in the library. Although it makes complete sense for a string manipulation library, OpenZeppelin generally tends to avoid loops as much as possible, to protect our users from running into issues where an attacker could control the loop bound. What are your thoughts on this?

I don't think there's much avoiding this, while keeping the library generally useful. I think we simply need to warn users that string operations are expensive and generally bounded by their length, and that they should perform input sanitisation any time an attacker could affect someone else's operations with a large string.

Arachnid avatar Jun 25 '19 00:06 Arachnid

I'd be quite interested in a strConcat function that works in Solidity ^0.8.0. Can anyone point me to a good library?

jarednielsen avatar Mar 24 '21 23:03 jarednielsen

@jarednielsen You can use abi.encodePacked!

Arachnid avatar Mar 24 '21 23:03 Arachnid

Thanks! For future passerby, the code is

string(abi.encodePacked(partOne, Strings.toString(numberTwo)));

jarednielsen avatar Mar 24 '21 23:03 jarednielsen

Hi there! I'd join this (old) discussion and propose the new method compare(string memory a, string memory b) returns (bool), as the (most popular) solution keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)) could be repetitive, and such a method would make things more elegant imo.

0xCaso avatar Oct 21 '22 09:10 0xCaso