I am writing a simple betting application that will return double the ether deposited by the player, provided they guess correctly the random number generated by the virtual slot machine.

it works like this:

  1. Player inputs their Ethereum Address, a guess and amount they are willing to deposit in the user interface.
  2. if the users guess is the same as the randomly generated number then they receive 2x what they credited to the slot machine. If their guess is incorrect they simply lose their deposit.

Like any slot machine in the real world in order to play you must first credit the machine with some money. Similarly, I am scripting my virtual machine to work in this way except to keep the transaction fees low the ether must be sent to the contract along with the data payload:

here is my solidity code:

   contract Slot_Machine is Mortal{

  // A struct type that defines state variables of a player.
  //Every player has a wallet, amount they are willing to
  //deposit and a guess.

  struct Player{
      address payable wallet;
      uint deposit;
      uint guess;

  address payable slotMachine;

  mapping (address => Player) public player;

  //The random number returned from the generator.
  uint randomNumber;

  constructor() public{
    randomNumber = 5;

  fallback () external payable{}

  receive () external payable{
    require(msg.sender.balance >= msg.value,
          "Insufficient balance to complete transaction.");

  function main(uint pdeposit, uint pguess) public{

    player[msg.sender] = Player(msg.sender, pdeposit, pguess);

    if(player[msg.sender].guess != randomNumber){
      emit Message("Unlucky this time! try again when you are feeling lucky!");

    } else {
          player[msg.sender].wallet.transfer(player[msg.sender].deposit*2 ether);
          emit Message("You Win!");


The main function is the method called when the player hits the 'Play' object.

My my issue is that when I call this function using web3 via node, there is no ether credited to the contract.

here is my web3 script:

contract.methods.main(amount, guess).send({from: Hannah, value: amountWei, gas: 3000000}, (error, result) => {console.log(error)})

on making this call I met with this error:

Error: Returned error: VM Exception while processing transaction: revert

However, calling this method without the value option in the send function:

contract.methods.main(amount, guess).send({from: Hannah,gas: 3000000}, (error, result) => {console.log(error)})

returns a Tx number.

So is the former the incorrect way to send ether to a contract while simultaneously calling a method?

  • Does your contract have sufficient funds for the transfer operation? – goodvibration Jul 8 '20 at 16:59
  • In other words, does the expression address(this).balance >= player[msg.sender].deposit*2 ether evaluate to true? – goodvibration Jul 8 '20 at 17:00
  • @goodvibration yes the contract has a balance of 60 ether. Also the contract returns winnings to the player if they guess right but Ether is never transferred from the player to the contract when the main function is called. – oBlox Jul 8 '20 at 17:37
  • @goodvibration maybe my main function needs to a 'payable' function? – oBlox Jul 8 '20 at 17:56
  • Yes, that's exactly what I've just explained in my answer. – goodvibration Jul 8 '20 at 17:59

Since you are passing value > 0 in:

contract.methods.main(amount, guess).send({value: amountWei, ...}, ...)

You need to declare function main as payable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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