-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
Set types #2075
Set types #2075
Conversation
FYI, I've been working on something similar, expec my version used a templated file to generate sets/maps with arbitrary types. This reduces code duplication. |
Hello @rob-Hitchens and @Amxx, thank you for contributing! The proposed contracts have the same API and implementation as our new I'd like to wait a little bit before adding full-fledged support for all primitive types: we've only just included That said, your comment about |
Hi @nventuro, Thanks for that. I'll just clarify a bit of my original post you mention here:
The idea is to make it completely discoverable. The contract might generate keys somehow, but a client needs to bootstrap from nothing and retrieve everything. Here's a typical usage:
It's handy if the contract is generating keys with a hash function. Generally, if that happens, then it's a good idea for the contract to I usually incline to completely discoverable states, so it would be typical to include:
That habit gives a client a second way to unfold the keys. That means the In any case, devs struggle with sets because a CRUD pattern isn't easy to work out. Something reliable helps keep the focus on what the contract is supposed to do instead of problematic implementation details. One can go nuts with it, like in this layout for a graph:
|
Hi all! |
Hm, yes, I can see how that could work, but that'd be straying a bit too far away from the original I still think that we could add more types to it, but for the moment I'd rather not pollute the library with too many of these yet, and would rather start out with just the ones we're using internally. |
Hi all! |
Closing for the reasons explained by @nventuro above. |
Fixes #2061
Implementation of an address Enumerable Set
There are use-cases for enumerable sets of most scalar types.
address
is appropriate user-oriented cases such as memberships, followers, privileges, etc.bytes32
is appropriate for any sort of contract-generated UID such as a hash generated on the fly. While almost anything can be converted to abytes32
for a uniqueness test, in practice I found the caller code is ugly (e.g.toBytes32(whatever)
) and it's usually best to tweak the basic idea to accommodate keys that are natural from the caller's perspective. I added astring
variant to show how a hash can be used internally to make it work.Implementations are libraries that create Set types. Operations are O(1). Enumeration is done by the caller, one row at a time as I'm not comfortable with returning lists of unbounded size in one move. (
count()
andkeyAtIndex(uint row)
). In my opinion, calling for the entire list is wasteful and risky in most use-cases.E.g.
Get started:
Typical usage:
Insert
addressSet.insert(msg.sender);
Remove
addressSet.remove(msg.sender);
Check
if(addressSet.exists(msg.sender)) { ... }
Enumerate (Count)
uint count = addressSet.count();
Enumerate (Fetch)
address user = addressSet.keyAtIndex(row);
I realize there is a merged candidate implementation, so this is a little late to the party. I will go ahead and create unit tests and address other feedback if there is interest in this approach. I'm not sure where you would want to put it but a little folder of SetTypes (4 given) seemed intuitive to me.