欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

游戏的区块链代码  

程序员文章站 2022-06-06 10:15:50
...
pragma solidity >=0.4.21 <0.6.0;
contract Casino {
    address payable public owner;

    event Play(address payable indexed player, uint256 betSize, uint8 betNumber, uint8 winningNumber);
    event Payout(address payable winner, uint256 payout);

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

    function kill() external {
        require(msg.sender == owner, "Only the owner can kill this contract");
        selfdestruct(owner);
    }

    function fund() external payable {}

    function bet(uint8 number) external payable {
        require(msg.value <= getMaxBet(), "Bet amount can not exceed max bet size");
        require(msg.value > 0, "A bet should be placed");

        uint8 winningNumber = generateWinningNumber();
        emit Play(msg.sender, msg.value, number, winningNumber);

        if (number == winningNumber) {
            payout(msg.sender, msg.value * 10);
        }
    }

    function getMaxBet() public view returns (uint256) {
        return address(this).balance / 100;
    }

    function generateWinningNumber() internal view returns (uint8) {
        return uint8(block.number % 10 + 1); // Don't do this in production
    }

    function payout(address payable winner, uint256 amount) internal {
        assert(amount > 0);
        assert(amount <= address(this).balance);

        winner.transfer(amount);
        emit Payout(winner, amount);
    }
}

 

 

测试代码:

const Casino = artifacts.require('Casino');
const assert = require("chai").assert;
const truffleAssert = require('truffle-assertions');

contract('Casino', (accounts) => {
    let casino;
    const fundingAccount = accounts[0];
    const bettingAccount = accounts[1];
    const fundingSize = 100;

    // build up and tear down a new Casino contract before each test
    beforeEach(async () => {
        casino = await Casino.new({ from: fundingAccount });
        await casino.fund({ from: fundingAccount, value: fundingSize });
        assert.equal(await web3.eth.getBalance(casino.address), fundingSize);
    });

    afterEach(async () => {
        await casino.kill({ from: fundingAccount });
    });

    it("should lose when bet on the wrong number", async () => {
        let betSize = 1;
        // we know what the winning number will be since we know the algorithm
        let betNumber = (await web3.eth.getBlock("latest")).number % 10 + 1;

        let tx = await casino.bet(betNumber, { from: bettingAccount, value: betSize });

        // player should be the same as the betting account, and the betted number should not equal the winning number
        truffleAssert.eventEmitted(tx, 'Play', (ev) => {
            return ev.player === bettingAccount && !ev.betNumber.eq(ev.winningNumber);
        });
        // there should be no payouts
        truffleAssert.eventNotEmitted(tx, 'Payout');
        // check the contract's balance
        assert.equal(await web3.eth.getBalance(casino.address), fundingSize + betSize);
    });

    it("should win when bet on the right number", async () => {
        let betSize = 1;
        // we know what the winning number will be since we know the algorithm
        let betNumber = ((await web3.eth.getBlock("latest")).number + 1) % 10 + 1;

        let tx = await casino.bet(betNumber, { from: bettingAccount, value: betSize });

        // player should be the same as the betting account, and the betted number should equal the winning number
        truffleAssert.eventEmitted(tx, 'Play', (ev) => {
            return ev.player === bettingAccount && ev.betNumber.eq(ev.winningNumber);
        });
        // player should be the same as the betting account, and the payout should be 10 times the bet size
        truffleAssert.eventEmitted(tx, 'Payout', (ev) => {
            return ev.winner === bettingAccount && ev.payout.toNumber() === 10 * betSize;
        });
        // check the contract's balance
        assert.equal(await web3.eth.getBalance(casino.address), fundingSize + betSize - betSize * 10);
    });
});