A maze hash function with blockhashes on Ethereum

in ethereum •  6 years ago  (edited)

The parts of the state that can be accessed from a smart contract is limited in Ethereum. What is available is that you can get the blockhash from any block within 256 blocks of the most recent one. That is a lot of random numbers there already, which can be recombined based on an input as a map.

With a map, lets call it uint treasureMap, generated first from block variables and entropy from the previous random number, the 256 blocks that can be accessed can be traversed as a labyrinth. The output of the maze hash function (mhf) will be a uint256.

uint treasureMap;
function mazeHashFunction() {
}
function getNthByte(uint _nth) returns (bytes1) {
    bytes memory ret = toBytes(treasureMap);
    return ret[_nth];
} 
function toBytes(uint256 x) internal returns (bytes b) {
    b = new bytes(32);
    assembly { mstore(add(b, 32), x) }
}

The first byte in treasureMap specifies a block, block.blockhash(block.number - ret[31]). The first byte in that blockhash, is xored with the first byte of the treasureMap, generating the mutated first byte for the random number, as well as the pointer that specifies the next block in the labyrinth. In the next block, the second byte of the blockhash is xored with the second byte of the treasureMap, generating the second byte in the random number as well as the pointer to the next block in the labyrinth. This continues once for each byte in the treasureMap, 32 times for a uint256.

bytes[32] memory randomNumber;
bytes treasureMapInBytes = toBytes(treasureMap);
uint nextByteInTreasureMap = uint8(treasureMapInBytes[31]);
uint8 pointerToNextPosition = nextByteInTreasureMap;

for(uint i = 31; i >0; i--) {
    uint nextHashInLabyrinth = uint(block.blockhash(block.number - pointerToNextPosition));
    bytes memory blockHashToBytes = toBytes(nextHashInLabyrinth);
    uint8 byteFromBlockhash = blockHashToBytes[i];
    nextByteInTreasureMap = uint8(treasureMapInBytes[i]);
    uint8 nextRandomNumber = nextByteInTreasureMap ^ byteFromBlockhash;
    randomNumber[i] = nextRandomNumber;
    pointerToNextPosition = randomNumber[i] ;
}

see proof-of-concept implementation on MazeHashFunction.sol, gas cost around 30000 gas

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!