Need a way to efficiently verify membership of a Loot Bag in some set X. For example, is Loot Bag 105 a member of the Library guild? In this case, it’s
getWeapon function returns
Book. We can verify that by calling the Solidity function and passing item ID 105, but we have to somehow understand that the
Book string implies membership in the Library guild.
The fact that Books mean membership in the Library guild is an additional piece of metadata that can be used in games, governance and other on-chain mechanism designs. Another example is group raids, where a developer might want to understand what is actually inside the bags in order to improve the game experience.
I’m assuming that comparing a lot of strings in Solidity is a pain for developers. If a developer were to check this on-chain, they would have to compare against all known permutations of Book, such as Book of the Twins and a hundred other variations. Furthermore, they would have to do this for each item name => guild association. Another example is mythical Loot items, which vary in name diversity to an extreme degree, where each name might be different in each Bag. Is there a solution which can scale to handle these degrees of diversity, while still being efficient for on-chain verification, and not being a huge pain for developers?
I propose using a Merkle tree structure where the leaf nodes consist of the items in the set. The root of the tree, the Merkle root, can then be used to cryptographically verify membership in the set. This verification can happen on-chain, efficiently and securely.
For example, we can take the names of all 4364 mythical items, and produce the Merkle root once, off-chain. Anyone could reproduce this Merkle root for themselves to verify its correctness. The Merkle root is then submitted to a smart contract
GuildMetadata.sol, which allows any developer in the Loot ecosystem to call a function such as
The item name and the guild name can be passed as arguments to the function, and the function would check for the membership of
hash(itemName) within the merkle root for
Using this technique, there can be a single contract that is used as a Guild metadata contract. Multiple items can be verified, within multiple guilds, so it’s scalable up to a large design space of item => guild combinations. For example:
- Any Divine items = Divine Lodge guild
- All Divine Robes = Divine Roles guild
- All Katanas = Katana guild
- All Mythical items = Mythical guild
- Any dragon item = Dragon guild
It also doesn’t matter how many Bags there are, 8000 or 2 million. They all could use the same technique to create the associations from a group of names to some metadata.
Using this technique, if a derivative or future project wanted to add names to the set, the Merkle root could just be recomputed and submitted without modifying the contracts that rely on these associations.
In this example, I used an item-to-guild association, but the technique works with associations to other kinds of data. The general problem of having to check many diverse names for membership in sets can be solved using this technique.
- For the divine items to Divine Lodge example, the attribute to check could be the
isItemMemberOfGuildalso require an argument for the attribute name to check, or
anyto check all of them?
- Are there any other ways to somehow improve this technique?
- Is it worth it, in terms of gas and compute, to perform the check this way?
I am a Solidity noob so I could be wrong in my thinking of this. I’m relying on second-hand knowledge of how other smart contract systems use Merkle roots, not first-hand experience. I’d love for someone with the Solidity expertise to take this idea, verify it could work and run with it for the benefit of the Loot community. If not, I could try to build myself, but it would take longer.