I'm writing a contract in solidity (for practice) that is a guessing game that is played as such: 1) Users are given 100 MetaCoin (dummy currency) on sign up. 2) Users can pay 1 coin to play a guessing game, if they guess correctly they're given 5 coins, if not, they lose the coin.

However, I'm unsure on how to best implement this. Here's a pseudo implementation:

function takeGuess(int guess) returns (bool){
    uint balance = getBalance(msg.sender);
    if (balance>0){
        int actual = popNumber(); //Retrieves next "random" number
        if (guess == actual){
            coin.sendCoin(msg.sender, 4);
            return true;
        } else {
            coin.sendCoin(this, 1, {from: msg.sender}); //Not legal syntax
            return false;
    } else {
        return false;
    return false;

Now, this doesn't work because the third argument in the else statement is not a valid argument (it's JS abi notation), but it's a representation of what I want to do. Is there a way to take coins from users in-contract like this? Or does the user need to send coins, and then wait for the verification? How would I do that?

Here is the repo if you want to see the full source code: https://github.com/willikers19/GuessTheEth

Edit: This contract is mostly just for practice. It's not intended to have "good" random behavior.


2 Answers 2


I think you're looking for this:

ERC20 coin = ERC20(coin_address);
if (!coin.transfer(amount)) { throw; }

Where ERC20 is imported outside the contract definition (right under the pragma statement, import "./ERC20.sol";).

ERC20.sol only contains the function definitions, see: https://github.com/GridPlus/contracts/blob/master/ERC20.sol

If you want to transfer from an address that is not the contract, that user will need to approve the contract address to move those tokens (this approval is called from the coin contract in a separate transaction):

approve(contract_addr, amount)

And then use transferFrom:

ERC20 coin = ERC20(coin_address);
if (!coin.transferFrom(msg.sender, address(this), value)) { throw; }

Two things are certain on Ethereum (for now):

  1. You cannot keep anything private

  2. You cannot make anything happen on it's own - somebody needs to give the smartcontract "a push" with a transaction.

But there are also hashing functions. For the guessing, there would need to be something (a user / a contract [whereas it's almost impossible to make a contract generate randomnes] ) that generates a proposal for the number to be guessed, packed with some characters, > hashed, and then submitted < to the contract. in solidity, it's sha3() , since 0.4.12. keccak(), i think. A guessing user would have to submit his proposal, and somebody or something would reveal the correct answer by submitting the original proposal packed with characters, and it's hash would be compared with the originally submitted hash to prove that the revealed value corresponds to the previously submitted one. The reason why your submission needs to be the hash of "zdHfk 5 fjgfF" and not just "5" is simply because it's way harder for users to guess the answer them selves that way, and they are forced to guess.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.