In this challenge, you need to understand the complex inner workings of blocks to form some data with the same hash as a block.
The contract has two main functions:
preMintFlag(): Registers your intent to mint and stores the current block numbermintFlag(bytes memory rlpBytes): Verifies that keccak256(rlpBytes) is the same as a block hash before minting the flagmintFlag(bytes memory rlpBytes) requires keccak256(rlpBytes) to be the same as blockhash(registeredBlock). It's virtually impossible to find data that hashes to the same value. How else can you get some data that has the same hash?
blockhash() has a keccak256() operation. If we figure out the parameters to this hash, we can pass that into the mintFlag() function!
challenge12.preMintFlag();
uint256 targetBlock = block.number + challenge12.futureBlocks();
2. Get the block data for targetBlock. This can be obtained by an eth_getBlockByNumber call to an RPC.
3. After converting to a list (see hint #3), RLP encode it.
4. Submit the proof:
challenge12.mintFlag(rlpEncoded);
The contract will:
- Verify the block number matches
- Check that the RLP-encoded header matches the block hash
- Mint your flag if everything is correct
Congratulations! You've mastered block header verification and RLP encoding! 🎉