From f9cac8cbbfb1450b06539d47cdc5dd5a97e8bceb Mon Sep 17 00:00:00 2001 From: willitscale Date: Wed, 11 Oct 2017 01:47:50 +0200 Subject: [PATCH] Added tutorial 18 --- README.md | 3 +- tutorial-18/Casino.sol | 94 ++++++++++++++++++++++++++++++++++++++++++ tutorial-18/Random.sol | 19 +++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 tutorial-18/Casino.sol create mode 100644 tutorial-18/Random.sol diff --git a/README.md b/README.md index b012176..bac6157 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,5 @@ The companion to the Youtube tutorials - [Learning Solidity : Tutorial 14 Transferring Ethereum between contracts](https://www.youtube.com/watch?v=ELWSKMcJfI8) - [Learning Solidity : Tutorial 15 Public vs External](https://www.youtube.com/watch?v=Ii4g38mPPlg) - [Learning Solidity : Tutorial 16 Time Based Events](https://www.youtube.com/watch?v=HGw-yalqdgs) -- [Learning Solidity : Tutorial 17 Polymorphism](https://www.youtube.com/watch?v=l_E5F5qnbtk) \ No newline at end of file +- [Learning Solidity : Tutorial 17 Polymorphism](https://www.youtube.com/watch?v=l_E5F5qnbtk) +- [Learning Solidity : Tutorial 18 Randomness and Gambling](https://www.youtube.com/watch?v=3wY5PRliphE) \ No newline at end of file diff --git a/tutorial-18/Casino.sol b/tutorial-18/Casino.sol new file mode 100644 index 0000000..0a0e005 --- /dev/null +++ b/tutorial-18/Casino.sol @@ -0,0 +1,94 @@ +pragma solidity ^0.4.0; + +contract Casino { + + uint private start; + + uint private buyPeriod = 1000; + uint private verifyPeriod = 100; + uint private checkPeriod = 100; + + mapping(address => uint) private _tickets; + mapping(address => uint) private _winnings; + + address[] _entries; + address[] _verified; + + uint private winnerSeed; + bool private hasWinner; + address private winner; + + function Casino() + public { + start = block.timestamp; + } + + /** + * This should NOT be part of the contract!! + */ + function unsafeEntry(uint number, uint salt) + public + payable + returns (bool) { + return buyTicket(generateHash(number, salt)); + } + + function generateHash(uint number, uint salt) + public + pure + returns (uint) { + return uint(keccak256(number + salt)); + } + + function buyTicket(uint hash) + public + payable + returns (bool) { + // Within the timeframe + require(block.timestamp < start+buyPeriod); + // Correct amount + require(1 ether == msg.value); + // 1 entry per address + require(_tickets[msg.sender] == 0); + _tickets[msg.sender] = hash; + _entries.push(msg.sender); + return true; + } + + function verifyTicket(uint number, uint salt) + public + returns (bool) { + // Within the timeframe + require(block.timestamp >= start+buyPeriod); + require(block.timestamp < start+buyPeriod+verifyPeriod); + // Has a valid entry + require(_tickets[msg.sender] > 0); + // Validate hash + require(salt > number); + require(generateHash(number, salt) == _tickets[msg.sender]); + winnerSeed = winnerSeed ^ salt ^ uint(msg.sender); + _verified.push(msg.sender); + } + + function checkWinner() + public + returns (bool) { + // Within the timeframe + require(block.timestamp >= start+buyPeriod+verifyPeriod); + require(block.timestamp < start+buyPeriod+verifyPeriod+checkPeriod); + if (!hasWinner) { + winner = _verified[winnerSeed % _verified.length]; + _winnings[winner] = _verified.length-10 ether; + hasWinner = true; + } + return msg.sender == winner; + } + + function claim() + public { + // Has winnings to claim + require(_winnings[msg.sender] > 0); + msg.sender.transfer(_winnings[msg.sender]); + _winnings[msg.sender] = 0; + } +} \ No newline at end of file diff --git a/tutorial-18/Random.sol b/tutorial-18/Random.sol new file mode 100644 index 0000000..a393756 --- /dev/null +++ b/tutorial-18/Random.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.4.0; + +contract Random { + + function unsafeBlockRandom() + public + returns (uint) { + return uint(block.blockhash(block.number-1)) % 100; + } + + uint private _baseIncrement; + + function unsafeIncrementRandom() + public + returns (uint) { + return uint(sha3(_baseIncrement++)) % 100; + } + +} \ No newline at end of file