Skip to content

Instantly share code, notes, and snippets.

@weserickson
Created September 10, 2021 20:50
Show Gist options
  • Save weserickson/82c4ade5872d0b9154fc58ad19eca9d2 to your computer and use it in GitHub Desktop.
Save weserickson/82c4ade5872d0b9154fc58ad19eca9d2 to your computer and use it in GitHub Desktop.
Simple contract allowing anyone to guess secret passwords. If they guess any right, they will be awarded an amount of Vite based on the amount funded to the contract.
//
// GuessToWin.solpp
//
// Simple contract allowing anyone to guess secret passwords. If they guess any right, they
// will be awarded an amount of Vite based on the amount funded to the contract.
//
// Contract initially has no rewards balances stored. Any user can create rewards for a guess
// by calling the Fund function and providing the appropriate hash of the secret guess they
// would like to award, along with a patment of the amount of Vite they want to fund the award with.
//
// The hash of the guesses can be generated via the shell command:
// echo -n YOURSECRETPASSWORD | b2sum -l 256
//
// Guesses are submitted by sending a string of the guess to the Guess function. Correct
// guessers are awarded the entire fund for that hash/guess pair
//
// Warning: If you send funds with a hash value of an unknown string, those funds will be
// permanently locked in the contract! Also be warned that all guesses/hashes are logged
// into the ledger, so testing a particular hash/guess combination permanently reveals it.
// It's good to test this with a known hash/guess and a small value first, before putting
// in a larger reward with a truly secret hash/guess.
//
// Example:
// Fund() with 10 Vite and the 32 byte hash "324dcf027dd4a30a932c441f365a25e86b173defa4b8e58948253471b81b72cf"
// Guess() with 0 Vite and the string "hello"
pragma soliditypp ^0.4.2;
contract GuessToWin {
// use Vite as token for funding and rewards, for ids see https://vitescan.io/tokens
tokenId token = tokenId("tti_5649544520544f4b454e6e40");
// mapping from hashes of correct guesses to the reward balance for that guess.
mapping(bytes32 => uint) public balances;
// events
event Funded(address indexed addr, uint256 amount, bytes32 hashval, string log);
event Awarded(address indexed addr, uint256 amount, string guess, string log);
event Failed(address indexed addr, uint256 amount, string guess, string log);
// function for creating and funding awards, must send Vite and provide hash of secret as argument.
onMessage Fund(bytes32 hashval) payable {
require(msg.tokenid == token, "Please send vite rewards only.");
require(msg.amount > 0, "Must send tokens to fund award.");
balances[hashval] += msg.amount;
emit Funded(msg.sender, msg.amount, hashval, "Thanks for funding!");
}
onMessage Guess(string calldata body) {
// here we encode and hash the input string and check if an award fund/balance
// exists for this hashed string.
bytes32 hashval = blake2b(abi.encodePacked(body));
if( balances[hashval] > 0 ) {
// Note: The following order of the transfer and the setting balances to zero
// would expose a Solidity contract to reentrancy attacks, but this NOT an
// issue in Solidity++ due to async design. Also easier to write this way.
msg.sender.transfer(token, balances[hashval]);
emit Awarded(msg.sender, balances[hashval], body, "Correct guess! Awarded!");
balances[hashval] = 0;
} else {
emit Failed(msg.sender, 0, body, "Failed guess, try again!");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment