Hashing
Crypto.keccak256 hashes bytes or string. To hash several values, encode them first.
hashing.lithe
(* A commit-reveal guessing game. `Crypto.keccak256` hashes `bytes` or `string`;
encode several values with `Abi.encode` first, since `encodePacked` of
adjacent dynamic values can collide. *)
import "std/abi";
import "std/crypto";
import "std/evm";
error WrongGuess;
error AlreadySolved;
event Solved of record {
indexed by : address;
}
storage is record {
answerHash : bytes32;
solved : bool;
}
external function setPuzzle(const answerHash : bytes32) is {
storage.answerHash := answerHash;
storage.solved := false;
}
external pure function hashAnswer(const answer : string; const salt : bytes32) : bytes32 is
Crypto.keccak256(Abi.encode(answer, salt))
external function solve(const answer : string; const salt : bytes32)
raises WrongGuess | AlreadySolved
is {
assert(not storage.solved, AlreadySolved);
assert(Crypto.keccak256(Abi.encode(answer, salt)) = storage.answerHash, WrongGuess);
storage.solved := true;
emit Solved { by = Evm.sender(); };
}Prefer Abi.encode over Abi.encodePacked when hashing several values. With packed encoding, ("ab", "c") and ("a", "bc") produce the same bytes.

