Ethereum Betting Integration for Casino

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Ethereum Betting Integration for Casino
Medium
~2-3 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1217
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1046
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Setting Up Ethereum Betting for Casino

Key problem of integrating Ethereum into online casino is not "how to accept ETH", it's "how to ensure fairness and instant response when blockchain is slow and public". Client clicks "bet" — can't wait 12 seconds confirmation. And using blockhash as randomness source — this invites miners to manipulate result.

Casino Architecture

Two fundamentally different approaches:

On-chain casino — smart contract manages all logic: accept bet, determine result, payout. Fully transparent and trustless. Problems: latency (12 sec per block), gas cost per action, randomness limitations. Suitable for poker/blackjack with slow pace or slot machines via VRF.

Hybrid casino — deposits/withdrawals on-chain, gaming sessions off-chain. Most common approach for casino: user deposits ETH/USDC in smart contract, gets internal credits, plays instantly off-chain, withdraws on-chain. Balance proven via Merkle proof or ZK proof.

Most practical implementations — hybrid.

Smart Contract for Deposits and Withdrawals

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract CasinoVault is ReentrancyGuard, Ownable {
    mapping(address => uint256) public ethBalances;
    mapping(address => mapping(address => uint256)) public tokenBalances;
    
    // Authorized operators for off-chain payouts
    mapping(address => bool) public operators;
    
    event Deposited(address indexed user, address indexed token, uint256 amount);
    event Withdrawn(address indexed user, address indexed token, uint256 amount);
    
    function depositETH() external payable {
        require(msg.value > 0, "Zero deposit");
        ethBalances[msg.sender] += msg.value;
        emit Deposited(msg.sender, address(0), msg.value);
    }
    
    function depositToken(address token, uint256 amount) external nonReentrant {
        IERC20(token).transferFrom(msg.sender, address(this), amount);
        tokenBalances[msg.sender][token] += amount;
        emit Deposited(msg.sender, token, amount);
    }
    
    // Withdrawal with operator signature (off-chain balance verified)
    function withdrawWithSignature(
        address token,
        uint256 amount,
        uint256 nonce,
        bytes calldata signature
    ) external nonReentrant {
        bytes32 hash = keccak256(abi.encodePacked(
            msg.sender, token, amount, nonce, address(this), block.chainid
        ));
        bytes32 ethHash = MessageHashUtils.toEthSignedMessageHash(hash);
        address signer = ECDSA.recover(ethHash, signature);
        require(operators[signer], "Invalid operator signature");
        require(!usedNonces[nonce], "Nonce used");
        
        usedNonces[nonce] = true;
        // payout...
    }
    
    mapping(uint256 => bool) public usedNonces;
}

Operator signature pattern allows off-chain system to authorize withdrawals. Operator signs "user X has right to withdraw Y tokens" — doesn't require on-chain transaction for each game move.

Verifiable Randomness: Chainlink VRF v2.5

For on-chain games (slots, dice, roulette) only reliable randomness source on EVM — Chainlink VRF. Using block.prevrandao (former blockhash) is unsafe: Ethereum validators can influence RANDAO value.

import "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";

contract DiceGame is VRFConsumerBaseV2Plus {
    uint256 s_subscriptionId;
    bytes32 s_keyHash = 0x787d74...; // VRF key hash for Ethereum mainnet
    
    mapping(uint256 => address) public requestIdToPlayer;
    mapping(uint256 => uint256) public requestIdToBet;
    
    function rollDice(uint256 betAmount) external payable returns (uint256 requestId) {
        require(msg.value >= betAmount, "Insufficient bet");
        
        requestId = s_vrfCoordinator.requestRandomWords(
            VRFV2PlusClient.RandomWordsRequest({
                keyHash: s_keyHash,
                subId: s_subscriptionId,
                requestConfirmations: 3,   // wait 3 blocks for safety
                callbackGasLimit: 100000,
                numWords: 1,
                extraArgs: VRFV2PlusClient._argsToBytes(
                    VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
                )
            })
        );
        
        requestIdToPlayer[requestId] = msg.sender;
        requestIdToBet[requestId] = betAmount;
    }
    
    function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) 
        internal override 
    {
        uint256 result = (randomWords[0] % 6) + 1; // 1-6
        address player = requestIdToPlayer[requestId];
        uint256 bet = requestIdToBet[requestId];
        
        if (result >= 4) {
            // payout 2x
            payable(player).transfer(bet * 2);
        }
        // otherwise bet stays in contract
    }
}

VRF has latency ~1-2 blocks (12-24 sec). For fast games unacceptable — need hybrid approach: game continues off-chain, VRF used only for seed initial session state.

Accepting USDC/USDT Instead of ETH

Most players prefer stablecoins — no volatility. Adding ERC-20 support to vault contract trivial (see depositToken above). Important nuances:

USDT has transfer fee (fee-on-transfer) in theory (though currently 0%), need check actually received amount. Pattern:

function depositToken(address token, uint256 amount) external {
    uint256 balanceBefore = IERC20(token).balanceOf(address(this));
    IERC20(token).transferFrom(msg.sender, address(this), amount);
    uint256 actualAmount = IERC20(token).balanceOf(address(this)) - balanceBefore;
    tokenBalances[msg.sender][token] += actualAmount; // account for actually received
}

Gas for ERC-20 transactions more expensive than ETH transfers (~65K gas vs ~21K). On Ethereum mainnet ~$1-3 at moderate gas. For casino with small bets better work on L2 (Base, Arbitrum) — gas 50-100x cheaper.

L2 Optimization

Optimal infrastructure for casino in 2024 — Base or Arbitrum One:

  • Gas for deposit/withdrawal: $0.01-0.10 (vs $2-10 on mainnet)
  • Confirmation speed: 1-2 sec (L2 finality sufficient for casino)
  • USDC from Circle natively available on Base and Arbitrum

Deploying contract on Base — same as on Ethereum mainnet, just change --rpc-url in foundry deploy script.

Regulatory Aspects

Casino smart contract must support: geoblocking at frontend level (IP filtering), ability to blacklist addresses (OFAC sanctions), pause mechanism (emergency stop). Contract audit mandatory before launch — vault vulnerability with liquidity means total loss of funds.