This code is nearly identical to my answer here: Zero knowledge contingent payment on etherum?. The changes mostly involved renaming variables, but the core concept is the same:
- ether is escrowed
- if the preimage is revealed before the deadline, the funds go to one account
- if the preimage is not revealed before the deadline, the funds go to a different account
pragma solidity 0.5.2;
contract TimedCommitment {
address payable revealer;
address payable fineRecipient;
bytes32 public hash;
uint256 public deadline;
constructor(address payable _fineRecipient, bytes32 _hash, uint256 timeout) public payable {
revealer = msg.sender;
fineRecipient = _fineRecipient;
hash = _hash;
deadline = now + timeout;
}
// If this is called with the correct preimage, the revealer gets their funds back.
function providePreimage(bytes calldata preimage) external {
require(keccak256(preimage) == hash);
revealer.transfer(address(this).balance);
}
// Pay the fine to the fineRecipient if the timeout has expired.
function refund() external {
require(msg.sender == fineRecipient);
require(now >= deadline);
msg.sender.transfer(address(this).balance);
}
}