1

I want to generate tokenIDs based on the properties generated in the contract.

         uint256[5] memory tokenID;
    
         for (uint i = 0; i < 5; i++) {
             tokenID[i] =  1 + item[i] + property[i] + level[i];
         }

So if the item is 14, the property is 4, and the level is 51, then the combined uint would 114451.

As I see it now I need to convert every uint to a bytes32, convert bytes32 to a string, and then I'm not even sure if there is a simple way to converts string to a uint. Is there a way to do this without much gas, or do I need to look at a more complicated naming convention?

Edit: Forgot to add the current solution which doesn't allow for scaling:

tokenID[i] = (((item[i]+1) * 10**5) + (property[i] * 10**4)) + level[i]

Item goes up to 1000, property goes up to 100, and level is always under 10.

2

Try this:

for (uint256 i = 0; i < tokenID.length; i++) {
    uint256 levelLen    = numOfDigits(level[i]);
    uint256 propertyLen = numOfDigits(property[i]);
    uint256 itemLen     = numOfDigits(item[i]);
    tokenID[i] =
        level[i] +
        property[i] * 10 ** levelLen +
        item[i] * 10 ** (propertyLen + levelLen) +
        10 ** (itemLen + propertyLen + levelLen);
}

Where a simple implementation of function numOfDigits can be:

function numOfDigits(uint256 _x) private pure returns (uint256) {
    uint256 y = 0;
    for (uint256 x = _x; x > 0; x /= 10) {
        y++;
    }
    return y;
}

Note that this method can map several different inputs to the same output.

For example, both [14, 4, 51] and [14, 45, 1] are mapped to 114451.

In that sense, the correct way is to do what you've mentioned as "doesn't allow for scaling".

So I would recommend you to reconsider exactly what scaling issue you're concerned with.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.