Skip to content

Instantly share code, notes, and snippets.

@Ericktz
Created September 20, 2021 00:52
Show Gist options
  • Save Ericktz/bcefa529e24865af0a3982ad8faabf9c to your computer and use it in GitHub Desktop.
Save Ericktz/bcefa529e24865af0a3982ad8faabf9c to your computer and use it in GitHub Desktop.
//
// 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, "Funded!");
}
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, "Try again!");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment