Created
September 20, 2021 00:52
-
-
Save Ericktz/bcefa529e24865af0a3982ad8faabf9c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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