Search code examples
hashsolidity

Solidity method taking in bytes32 and hashing but values with previous hash don't match


Here's the code:

function playGame(bytes32 hashedMove) public returns (bool) {
        require(
            playerOne != address(0x0) && playerTwo != address(0x0),
            "Game needs more players to join first"
        );
        require(
            msg.sender == playerOne || msg.sender == playerTwo,
            "You did not join the game as a player"
        );

        if (msg.sender == playerOne && hashedPlayerOneMove == "") {
            hashedPlayerOneMove = hashedMove;
            emit PlayerMadeMove(playerOne);
        } else if (msg.sender == playerTwo && hashedPlayerTwoMove == "") {
            hashedPlayerTwoMove = hashedMove;
            emit PlayerMadeMove(playerTwo);
        } else {
            return false;
        }

        return true;
    }

The above method takes in a hashedMove argument which I am using the following site to get: https://emn178.github.io/online-tools/keccak_256.html

I send a value of 2test2 hashed which is 0x0698472c4668bddd0c694601ca101551bd7b5cfe6dc780ab37bccfc99ad22e4c

Now another method takes in the constituents of the hash which are 2 and test2 to compare it with the stored hash:

function revealPlayerChoice(uint256 move, bytes32 password)
        public
        returns (uint256)
    {
        require(
            hashedPlayerOneMove != bytes32(0x0) &&
                hashedPlayerTwoMove != bytes32(0x0),
            "The game is still running!"
        );

        bytes32 hashedAnswer = getSaltedHash(move, password);

        console.logBytes32(hashedAnswer);
        console.logBytes32(hashedPlayerOneMove);

        if (msg.sender == playerOne && hashedAnswer == hashedPlayerOneMove) {
            playerOneMove = move;
        } else if (
            msg.sender == playerTwo && hashedAnswer == hashedPlayerTwoMove
        ) {
            playerTwoMove = move;
        }

        if (playerOneMove != 0 && playerTwoMove != 0) {
            getGameOutcome();
        }
    }

I'm sending 2 as uint and 0x0000000000000000000000000000000000000000000000000000007465737432 (test2 in bytes) to the revealPlayerChoice method. However the values I'm getting from the console log are different. hashedAnswer is the hash I'm calculating in the method and hashedPlayerOneMove is the hash stored in playGame method.

for example, The console log outputs are

0x566d7dd4e9dc72e9beef887f2982703a0d0f9dd1b6505ee3ff5310c7383637bd
0x0698472c4668bddd0c694601ca101551bd7b5cfe6dc780ab37bccfc99ad22e4c

I would like to understand why the values are different? I'm using keccak256 to hash in solidity (pragma solidity ^0.8.0;) as well:

function getSaltedHash(uint answer, bytes32 salt) pure returns (bytes32) {
    return keccak256(abi.encodePacked(answer, salt));
}

Solution

  • The key to your problem might be what abi.encodePacked(answer, salt) is returning.

    When you pass the following arguments:

    uint256 answer = 2
    bytes32 salt = 0x0000000000000000000000000000000000000000000000000000007465737432
    

    abi.encodePacked(answer, salt) returns:

    0x00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000007465737432
    

    And then, if you run the keccak256(bytes) with the previous value, it returns:

    0x566d7dd4e9dc72e9beef887f2982703a0d0f9dd1b6505ee3ff5310c7383637bd