擲骰子DApp的實現

 

前言:
​   DApp前些日子比較火, 這段時間有些低迷. 我也是後知後覺, 如今才接觸一些, 這篇博文就當作DApp的初次印象吧.
​   本文要寫的是基於智能合約的博彩遊戲DApp—骰子游戲, 來看看它是怎麼實現的, 以及它背後的一些考量.算法

 

遊戲介紹:
​   骰子游戲比較簡單, 就是選擇0~99之間一個數N, 而後擲骰子, 若小於該數N, 則勝, 並相應的賠率, 若大於等於則輸.後端

數字N在[1, 99]的範圍內

P(勝率) = N / 100;
O(賠率) = 1 / P(勝率) = 100 / N;

  好比選擇N=1, 則只有系統出0才能贏, 則勝率P爲1%, 賠率爲100x.
​  能夠參考stake, 不熟悉該遊戲規則的人, 能夠體驗一下該遊戲.
  
​   骰子游戲這個遊戲堪稱幣圈的傳奇, 它極致簡單卻創造了暴富神話.dom

 

智能合約:
​   DApp本質是去中心化的App, 它但願去掉中心化的後端服務, 取而代之的運行於區塊鏈虛擬機上的服務. 而這個服務就是由智能合約所定義和描述的, 它是公開和透明的.函數

pragma solidity ^0.4.0;

contract MyDice {

    // 合約建立者
    address private owner;

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    constructor() public {
        owner = msg.sender;
    }

    // 房主給合約錢包裏充錢
    function recharge() onlyOwner payable public {
    }

    // 房主主動從合約錢包中提現
    function withdraw(uint32 _amount) onlyOwner public {
        owner.transfer(_amount);
    }

    // solidity不能返回結構, 但能夠返回元組
    // @param _num                 爲選擇的數字 [1, 99]之間
    // @return (玩家選擇數字, 籌碼, 生成的數字, 賠付籌碼)
    function play(uint8 _num) payable public
            returns (uint8, uint256, uint8, uint256) {

        require(_num >= 1 && _num <= 99);

        // 生成[0, 99]的隨機數
        uint8 tval = randomInt(0, 99);

        if ( tval < _num ) {
            // 計算賠付的值
            uint256 payout = uint256(msg.value * 100 / _num);
            msg.sender.transfer(payout);
            return (_num, msg.value, tval, payout);
        } else {
            return (_num, msg.value, tval, 0);
        }

    }

    // 生成[min, max]之間的一個隨機數
    function randomInt(uint8 min, uint8 max) private
            view returns(uint8) {

        require(max > min);

        bytes32 hash = keccak256(
            abi.encodePacked(now, msg.sender, block.difficulty)
        );

        return uint8(uint256(hash) % (max - min + 1)) + min;

    }

}

  合約即代碼, 玩家不再用懼怕被傳統中心化的遊戲服務做弊坑錢, 由於代碼邏輯清清楚楚. 區塊鏈

 

缺陷:
  這其實也是通病, 就是智能合約對隨機算法支持比較弱, 純粹是一些加密函數+隨機變量種子來實現, 好比區塊鏈block的信息, 時間戳, 以及調用方信息. 而公鏈上數據是公開的, 黑客可經過控制這些隨機變量, 從而來預測結果, 這樣就大大破壞遊戲自己的公平性.
​  所以通常不建議, 合約現有機制來實現隨機數的產生, 而是藉助第三方(Oraclize)來實現. ui


總結:
  關於合約對隨機算法不友好的問題, 有不少服務採用混合模型, 好比Dice2win 就採用的hash-commit-reveal機制, 很是完美地解決該類問題, 有空咱們再聊聊.加密

相關文章
相關標籤/搜索