Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String utilities #1795

Open
Arachnid opened this issue Jun 13, 2019 · 12 comments
Open

String utilities #1795

Arachnid opened this issue Jun 13, 2019 · 12 comments
Labels
contracts Smart contract code. feature New contracts, functions, or helpers.

Comments

@Arachnid
Copy link

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.

@Skyge
Copy link
Contributor

Skyge commented Jun 13, 2019

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

@nventuro nventuro added contracts Smart contract code. feature New contracts, functions, or helpers. labels Jun 13, 2019
@nventuro
Copy link
Contributor

Hi there @Arachnid, thank you very much for this! We've actually discussed your library a couple days ago in #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!

@crazyrabbitLTC
Copy link
Contributor

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!

@Arachnid
Copy link
Author

@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.

@abcoathup
Copy link
Contributor

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

@Skyge
Copy link
Contributor

Skyge commented Jun 17, 2019

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

@frangio
Copy link
Contributor

frangio commented Jun 24, 2019

Cool @Arachnid! We've always been reluctant to implement string utilities given that your library already existed 😄 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?

@Arachnid
Copy link
Author

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.

@jarednielsen
Copy link

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

@Arachnid
Copy link
Author

@jarednielsen You can use abi.encodePacked!

@jarednielsen
Copy link

Thanks! For future passerby, the code is

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

@0xCaso
Copy link
Contributor

0xCaso commented Oct 21, 2022

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 0xCaso mentioned this issue Oct 21, 2022
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contracts Smart contract code. feature New contracts, functions, or helpers.
Projects
None yet
Development

No branches or pull requests

8 participants