游戏的区块链代码
程序员文章站
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); }); });
上一篇: 回顾JAVA值传递和引用传递
下一篇: 数据库逻辑层优化策略