How to Bury and Find a Treasure in Solidity

I’ll start with a description of a case where we needed a solution to a similar problem. We have completed the project TheWall Global, within which we created a two-dimensional space or wall, which is divided into equal areas, each of which represents an NFT token. Anyone can buy a piece of our virtual space to place there any information that he considers interesting and useful for others – a kind of non-moderated space of everything that is significant for humanity and man. The basic idea was carefully borrowed by us from a wonderful and well-known project TheMillionDollarHomepagebut we have endowed this story with a wonderful secondary economy. In fact, I will not go into the details of the project and polemicize on the topic of whether it is interesting, whether it is monetized, whether it will work over a long distance – I will only say that in three weeks we sold regions for almost half a million dollars and held negotiations with dozens of galleries and artists who are eager to place their expositions in our space, therefore, I think it will be interesting. But now we are not talking about that.

At some point, we came up with a great idea to gamify the domain buying process, making it more interesting for buyers. We decided to start with a simple mechanic, which, with my light hand, got the name – Treasure Hunters. The essence of the mechanics is extremely simple, at some point in time we “guess” happy areas by simply choosing them from the currently available areas, give buyers, say, a week to buy one or more areas, and then tell everyone what it was the areas that we wondered, and if someone purchased any of them, then he receives a prize in the form of a certain number of tokens (for example, USDT tokens or other ERC20 tokens). Everything would be fine, but we really wanted to implement this mechanic in a decentralized way. What for? Well, at least, to exclude accusations against us that we changed the hidden areas so as not to part with the prize.

The decentralized implementation required a separate smart contract, which we called Treasure. But then a snag arose. To exclude the manipulation, we had to somehow inform the smart contract of the coordinates of the happy areas before the start of the game, but that would mean that we would have to tell everyone the correct answer. The solution we applied turned out to be very simple. We decided to load into the smart contract not the coordinates of the happy areas, but the hash function calculated from them, i.e. We hide the treasure with a simple function call:

    function hideTreasure(bytes32 hash) onlyOwner public
    {
        _hash = hash;
        emit TreasureHidden(hash);
    }

We used the keccak256 hash function because its call is available directly from the smart contract, and, therefore, the smart contract can make sure that the coordinates of the happy areas loaded later by us (the organizers) exactly correspond to those that were predicted before the start of the game. Well, as you can see, the call to the hideTreasure () function does not reveal the secret, which is a set of area coordinates specified as an int256 array [] coords, which is a sequence (x1, y1, x2, y2,…., xN, yN).

It seems that everything looks good, but in fact, not very much. Our wall has a limited size – 1000×1000 areas, i.e. only 1 million accommodation options, and even after deducting the already occupied areas. Agree, it’s not such a difficult task for a complete enumeration of coordinates and calculating their hash. Of course, for not very large N. Therefore, we decided not to risk it and “salt” the coordinate vector a little by adding one more term to its end – SALT – a very large and very random number. The result is a sequence (x1, y1, x2, y2,…., XN, yN, SALT), for which we have already calculated the hash.

Summing up the results of the game round also looks very compact and simple:

    function findTreasure(int256 [] memory coords, uint256 salt) onlyOwner public
    {
        bytes32 hash = keccak256(abi.encodePacked(keccak256(abi.encodePacked(coords)), salt));
        require(hash == _hash, "Treasure: Invalid data");
        emit TreasureFound(coords);
        delete _hash;

        for(uint i = 0; i < coords.length;)
        {
            int256 x = coords[i++];
            int256 y = coords[i++];
            uint256 tokenId = _thewallcore._areaOnTheWall(x, y);
            if (tokenId != 0)
            {
                address user = _thewall.ownerOf(tokenId);
                if (_treasureContract.transfer(user, _treasuredAmount))
                {
                    emit Rewarded(user, tokenId, _treasuredAmount);
                }
            }
        }
    }

Actually, the most interesting thing in the above code is in the first line of the function, which describes how to calculate the value of the keccak256 hash function from almost any parameters. In our case, we read the hash from the array of coordinates abi.encodePacked (coords), but, in principle, at this place there could be a secret of absolutely any type and format. You can read more about abi.encodePacked in the Solidity documentation or see illustrative examples here in this article

Well, then, making sure that the loaded coordinates correspond to those that were predicted at the time of the start of the game, i.e. the hash from them corresponds to the previously loaded one, which means that the organizer did not change the conditions of the problem, the smart contract runs through all the specified coordinates, checks if the corresponding areas have an owner, and, if so, gives him a well-deserved reward, which should be prudently placed on the address of the Treasure smart contract itself.

Our project works on the basis of the Polygon blockchain (MATIC), but everything I described above can be perfectly executed on Ethereum and many others made on the basis of the Ethereum blockchain code. Why we stopped at Polygon is a topic for a separate story, like many other life hacks that we used when creating our project. Perhaps I will talk about them in future posts. But it is not exactly 🙂

The full text of the Treasure smart contract is available here… You may be interested in taking a look at other contracts of our project that are called from the above as example code, namely smart contracts TheWall and TheWallCore

The project itself is available at https://thewall.global, and the accompanying information on the sites https://thewall.cptpoint.global and https://about.thewall.global

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *