Collision

Here is some code to check for block hash collisions

Marvin


pragma solidity ^0.8.13; contract V3 { function checkCollision(bytes[] calldata preImage) external view returns (bool){ bytes32 hashValue = blockhash(block.number - 1); for (uint256 ii; ii < preImage.length; ii++) { // check that all inputs are a pre image and therefore we have a hash collision if (keccak256(abi.encodePacked(preImage[ii])) != hashValue){ revert("Not a correct pre image"); } } // win the prize you found collisions return true; } }

The following test will fail since the inputs are not collisions for the block hash.

function testCollision() public { bytes [] memory preImages = new bytes[](3); preImages[0] = bytes('0xdb337542cb34f29f365ba199ace89e847f3734de5c16b30c17874e618ed99f5d'); preImages[1] = bytes('0xdea4797f0cd66325a4c946b4a4427a7e4fb6c24e311359435a185a9037149d99'); preImages[2] = bytes('0xcfba164542b27aa14af7b01e10a239c6a7cc844d309305ee2b47ff79fab5a5fb'); bool result = v3.checkCollision(preImages); assert (result); }

Can you rewrite the test to find an input to the function that will not revert ?

Solution and discussion

Click here bytecode

OK I confess, there was some sleight of hand here, I tried to distract you.

The hash collision part isn't really the point of this, it is all about the way that the function is written, in particular the loop.

There is an assumption that will loop through the input, but what if the input array is empty ?.

In that case we don't process the loop body, don't do any tests, and end up with the default return value which is true.