├── .gitattributes ├── 11_ERC721_usage └── DirtyToken.sol ├── 03_basic_random └── 03_basic_random.sol ├── 10_ERC20_usage └── PiotrexToken.sol ├── 08_basic_token └── 08_basic_token.sol ├── 01_greeter └── 01_say_hello.sol ├── helloWorld2.sol ├── 02_balance_address_checker └── 02_balance_address_checker.sol ├── 05_lottery_no_limit └── 05_lottery_no_limit.sol ├── 07_fundraising └── 07_fundraising.sol ├── 09_erc_20_token └── 09_erc_20_token.sol ├── 06_lottery_multiple_winners └── 06_lottery_multiple_winners.sol ├── 04_lottery_10_users ├── 04_lottery_10_users.sol └── 04_lottery_10_users_adamskrodzki.sol └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity -------------------------------------------------------------------------------- /11_ERC721_usage/DirtyToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | import "github.com/OpenZeppelin/zeppelin-solidity/contracts/token/ERC721/ERC721Token.sol"; 4 | 5 | contract DirtyToken is ERC721Token { 6 | string public constant name = "DirtyToken"; 7 | string public constant symbol = "DRT"; 8 | } -------------------------------------------------------------------------------- /03_basic_random/03_basic_random.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity ^0.8.0; 3 | 4 | contract BasicRandom { 5 | uint private randNonce = 0; 6 | 7 | function getRandomNumber() public returns (uint) { 8 | uint rand = uint(keccak256(abi.encodePacked(block.timestamp, msg.sender, randNonce))); 9 | randNonce++; 10 | return rand; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /10_ERC20_usage/PiotrexToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | import "zeppelin/contracts/token/StandardToken.sol"; 4 | 5 | contract PiotrexToken is StandardToken { 6 | string public constant name = "PiotrexToken"; 7 | string public constant symbol = "PTX"; 8 | uint8 public constant decimals = 18; 9 | uint256 public constant initialSupply = 1000 * (10 ** uint256(decimals)); 10 | 11 | constructor () public { 12 | balances[msg.sender] = initialSupply; 13 | totalSupply = initialSupply; 14 | } 15 | } -------------------------------------------------------------------------------- /08_basic_token/08_basic_token.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.22; 2 | 3 | contract BasicToken { 4 | uint public initialSupply; 5 | 6 | mapping(address=>uint) balances; 7 | 8 | constructor(uint _initialSupply) public { 9 | initialSupply = _initialSupply; 10 | balances[msg.sender] = _initialSupply; 11 | } 12 | 13 | function transfer(address _recipient, uint _amount) public { 14 | require(balances[msg.sender] >= _amount, "Not enough funds"); 15 | require(_recipient != msg.sender, "No need to send tokens to yourself"); 16 | require(balances[_recipient] + _amount > balances[_recipient]); //overflow check 17 | balances[msg.sender] -= _amount; 18 | balances[_recipient] += _amount; 19 | } 20 | 21 | function balanceOf(address _owner) public view returns (uint) { 22 | return balances[_owner]; 23 | } 24 | } -------------------------------------------------------------------------------- /01_greeter/01_say_hello.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | //https://github.com/pbrudny/learning-solidity-2018.git 3 | pragma solidity >=0.6.12 <0.9.0; 4 | 5 | contract Greeter { 6 | string public greeting; 7 | address public owner; 8 | 9 | modifier onlyOwner { 10 | require(isOwner(), "Only owner can do that!"); 11 | _; 12 | } 13 | 14 | constructor(string memory _greeting) { 15 | greeting = _greeting; 16 | owner = msg.sender; 17 | } 18 | 19 | function sayHello() public view returns(string memory) { 20 | if (isOwner()) { 21 | return "Hey daddy!"; 22 | } else { 23 | return greeting; 24 | } 25 | } 26 | 27 | function setGreeting(string memory _newGreeting) public onlyOwner { 28 | greeting = _newGreeting; 29 | } 30 | 31 | function isOwner() private view returns(bool) { 32 | return msg.sender == owner; 33 | } 34 | } 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /helloWorld2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | //https://github.com/pbrudny/learning-solidity-2018.git 3 | pragma solidity >=0.6.12 <0.9.0; 4 | 5 | contract Greeter { 6 | string public greeting; 7 | address public owner; 8 | 9 | modifier onlyOwner { 10 | require(isOwner(), "Only owner can do that!"); 11 | _; 12 | } 13 | 14 | constructor(string memory _greeting) { 15 | greeting = _greeting; 16 | owner = msg.sender; 17 | } 18 | 19 | function sayHello() public view returns(string memory) { 20 | if (isOwner()) { 21 | return "Hey daddy!"; 22 | } else { 23 | return greeting; 24 | } 25 | } 26 | 27 | function setGreeting(string memory _newGreeting) public onlyOwner { 28 | greeting = _newGreeting; 29 | } 30 | 31 | function isOwner() private view returns(bool) { 32 | return msg.sender == owner; 33 | } 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /02_balance_address_checker/02_balance_address_checker.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity ^0.8.0; 3 | 4 | contract Checker { 5 | address owner; 6 | 7 | constructor() { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier onlyOwner() { 12 | require(msg.sender == owner, "Not the contract owner"); 13 | _; 14 | } 15 | 16 | function getBalanceOfContract() public view returns(uint) { 17 | return address(this).balance; 18 | } 19 | 20 | function getBalanceOfOwner() public view onlyOwner returns(uint){ 21 | return owner.balance; 22 | } 23 | 24 | function getBalanceOfSender() public view returns(uint) { 25 | return msg.sender.balance; 26 | } 27 | 28 | function getAddressOfContract() public view returns(address) { 29 | return address(this); 30 | } 31 | 32 | function getAddressOfOwner() public view returns(address) { 33 | return owner; 34 | } 35 | 36 | function getAddressOfSender() public view returns(address) { 37 | return msg.sender; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /05_lottery_no_limit/05_lottery_no_limit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract LotteryNoLimit { 5 | address public owner; 6 | address[] public users; 7 | uint private randNonce = 0; 8 | 9 | 10 | modifier isOwner() { 11 | require(msg.sender == owner, "only owner can do that"); 12 | _; 13 | } 14 | 15 | constructor() { 16 | owner = msg.sender; 17 | } 18 | 19 | function join() external payable { 20 | require(msg.value == 0.1 ether, "Send 0.1 Ether"); 21 | users.push(msg.sender); 22 | } 23 | 24 | function selectWinner() external isOwner { 25 | require(users.length > 0, "No users in the lottery"); 26 | address winner = users[randomNumber(users.length)]; 27 | payable(winner).transfer(address(this).balance); 28 | delete users; 29 | } 30 | 31 | function randomNumber(uint _limit) private returns(uint) { 32 | randNonce++; 33 | return uint(keccak256(abi.encodePacked(block.timestamp, msg.sender, randNonce))) % _limit; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /07_fundraising/07_fundraising.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.22; 2 | 3 | contract FundRaising { 4 | address owner; 5 | uint public goal; 6 | uint public endTime; 7 | uint public total = 0; 8 | 9 | mapping(address=>uint) donations; 10 | 11 | constructor(uint _goal, uint _timeLimit) public { 12 | owner = msg.sender; 13 | goal = _goal; 14 | endTime = now + _timeLimit; 15 | } 16 | 17 | function add() payable public { 18 | require(now < endTime, "Fundraising is closed."); 19 | require(total < goal, "We reached a goal."); 20 | require(msg.value > 0, "You need to send some ether"); 21 | donations[msg.sender] += msg.value; 22 | total += msg.value; 23 | } 24 | 25 | function withdrawOwner() public { 26 | require(msg.sender == owner, "You must be owner"); 27 | require(total >= goal, "Fundraising not closed yet"); 28 | owner.transfer(address(this).balance); 29 | } 30 | 31 | function withdraw() public { 32 | require(now > endTime, "Fundraising not closed"); 33 | require(total < goal, "Can not withdraw when fundraising was successful"); 34 | uint amount = donations[msg.sender]; 35 | total -= amount; 36 | donations[msg.sender] = 0; 37 | address(msg.sender).transfer(amount); 38 | } 39 | } -------------------------------------------------------------------------------- /09_erc_20_token/09_erc_20_token.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.22; 2 | 3 | contract TokenErc20 { 4 | string public name; 5 | string public symbol; 6 | uint8 decimals; 7 | 8 | uint public totalSupply; 9 | 10 | event Transfer(address indexed _from, address indexed _to, uint value); 11 | event Approval(address indexed _owner, address indexed _spender, uint value); 12 | 13 | mapping(address=>uint) public balances; 14 | mapping(address => mapping(address => uint)) allowances; 15 | 16 | constructor( 17 | string _name, 18 | string _symbol, 19 | uint8 _decimals, 20 | uint _initialSupply 21 | ) public { 22 | name = _name; 23 | symbol = _symbol; 24 | decimals = _decimals; 25 | balances[msg.sender] = _initialSupply; 26 | } 27 | 28 | function balanceOf(address _owner) public view returns(uint balance) { 29 | return balances[_owner]; 30 | } 31 | 32 | function transfer(address _to, uint _value) public returns(bool success) { 33 | transferFrom(msg.sender, _to, _value); 34 | } 35 | 36 | function transferFrom(address _from, address _to, uint _value) public { 37 | require(balances[_from] >= _value); 38 | require(allowance(_from, _to) >= _value); 39 | balances[_from] -= _value; 40 | balances[_to] += _value; 41 | emit Transfer(_from, _to, _value); 42 | } 43 | 44 | function approve(address _spender, uint _value) public { 45 | allowances[msg.sender][_spender] = _value; 46 | } 47 | 48 | function allowance(address _owner, address _spender) public view returns(uint) { 49 | allowances[_owner][_spender]; 50 | } 51 | } -------------------------------------------------------------------------------- /06_lottery_multiple_winners/06_lottery_multiple_winners.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.23; 2 | 3 | contract LotteryMultipleWinners { 4 | address owner; 5 | uint randNonce = 0; 6 | address[] winners; 7 | uint prize; 8 | 9 | enum LotteryState { Accepting, Finished } 10 | LotteryState state; 11 | 12 | mapping (address => bool) gotReward; 13 | mapping (uint => address[]) choices; 14 | 15 | modifier isOwner { 16 | require(msg.sender == owner, "Must be owner"); 17 | _; 18 | } 19 | 20 | constructor() public { 21 | owner = msg.sender; 22 | state = LotteryState.Accepting; 23 | } 24 | 25 | function join(uint8 _chosenNumber) payable public { 26 | require(_chosenNumber > 0 && _chosenNumber <= 100, "Number must be in 1-100"); 27 | require(msg.value == 0.1 ether, "Transfer 0.1 Eth to join"); 28 | require(state == LotteryState.Accepting, "Lottery is closed"); 29 | choices[_chosenNumber].push(msg.sender); 30 | } 31 | 32 | function selectWinners() public isOwner returns(uint) { 33 | state = LotteryState.Finished; 34 | uint chosen = randomNumber(100) + 1; 35 | winners = choices[chosen]; 36 | prize = address(this).balance / winners.length; 37 | } 38 | 39 | function withdrawReward() public { 40 | require(isWinner(), "You must be a winner"); 41 | require(gotReward[msg.sender] != true, "You have got your reward"); 42 | gotReward[msg.sender] = true; 43 | msg.sender.transfer(prize); 44 | } 45 | 46 | function isWinner() public view returns(bool) { 47 | for(uint i = 0; i < winners.length; i++) { 48 | if (winners[i] == msg.sender) { 49 | return true; 50 | } else { 51 | return false; 52 | } 53 | } 54 | } 55 | 56 | function randomNumber(uint _limit) internal returns(uint) { 57 | uint rand = uint(keccak256(abi.encodePacked(now, msg.sender, randNonce))) % _limit; 58 | randNonce++; 59 | return rand; 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /04_lottery_10_users/04_lottery_10_users.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Lottery10Users { 5 | address[10] public participants; 6 | uint8 public participantsCount; 7 | uint private randNonce; 8 | uint public ticketPrice = 0.1 ether; 9 | //just added ticketPrice for this line also added public and private methods 10 | 11 | event LotteryWinner(address indexed winner, uint amount); 12 | //Events: Added an event LotteryWinner to log the winner and the prize amount. 13 | 14 | constructor() { 15 | participantsCount = 0; 16 | randNonce = 0; 17 | } 18 | 19 | function join() external payable { // changeced it with external 20 | require(msg.value == ticketPrice, "Must send 0.1 ether"); 21 | require(participantsCount < 10, "User limit reached"); 22 | require(!joinedAlready(msg.sender), "User already joined"); 23 | //Added "!" instead of use "== False" 24 | 25 | participants[participantsCount] = msg.sender; 26 | participantsCount++; 27 | 28 | if (participantsCount == 10) { 29 | selectWinner(); 30 | } 31 | } // added if block here for selectWinner 32 | 33 | function joinedAlready(address _participant) private view returns (bool) { 34 | for (uint i = 0; i < participantsCount; i++) { 35 | if (participants[i] == _participant) { 36 | return true; 37 | } 38 | } 39 | return false; 40 | } 41 | 42 | function selectWinner() private { 43 | require(participantsCount == 10, "Waiting for more users"); 44 | 45 | address winner = participants[randomNumber()]; 46 | uint prize = address(this).balance; 47 | (bool success, ) = winner.call{value: prize}(""); 48 | require(success, "Transfer failed"); 49 | 50 | emit LotteryWinner(winner, prize); 51 | 52 | // Reset lottery for the next round 53 | for (uint i = 0; i < 10; i++) { 54 | participants[i] = address(0); 55 | } 56 | participantsCount = 0; 57 | } 58 | 59 | function randomNumber() private returns (uint) { 60 | uint rand = uint(keccak256(abi.encodePacked(block.timestamp, msg.sender, randNonce))) % 10; 61 | randNonce++; 62 | return rand; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /04_lottery_10_users/04_lottery_10_users_adamskrodzki.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | 4 | /* 5 | Lottery is safe under the assumption that miners do not interfere, 6 | no smart contract can hack me (If You can prove me otherwise :D ) 7 | */ 8 | contract LotteryFor10{ 9 | 10 | address[] users; 11 | mapping(address => bool) participated; 12 | uint256 public constant WAIT_BLOCKS_LIMIT = 3 ; 13 | uint256 public registeredCount ; 14 | uint256 public _registeredLimit ; 15 | uint256 constant REGISTERING_PARTICIPANTS = 1; 16 | uint256 constant REGISTERING_FINISHED = 2; 17 | uint256 constant WAITING_FOR_RANDOMNESS = 3; 18 | uint256 constant SOLVING_LOTERRY = 4; 19 | uint256 constant LOTTERY_SOLVED = 5; 20 | uint256 public waitingStartBlockNumber; 21 | bool public lotterySolved; 22 | 23 | constructor(uint256 _limit) public{ 24 | waitingStartBlockNumber = 0; 25 | registeredCount = 0;//good habit not to rely on defaults if You do not have to 26 | _registeredLimit = _limit; 27 | } 28 | 29 | 30 | 31 | function () public payable{ 32 | 33 | if(getStage(block.number)==REGISTERING_PARTICIPANTS){ 34 | processAddingUser(msg.sender); 35 | } 36 | else{ // this else is crutial so we never enter two stages in same call 37 | if(getStage(block.number)==REGISTERING_FINISHED){ 38 | require(msg.value == 0,"no additional stake allowed"); 39 | waitingStartBlockNumber = block.number; 40 | emit ClosingList(waitingStartBlockNumber); 41 | } 42 | else{ 43 | if(getStage(block.number)==WAITING_FOR_RANDOMNESS){ 44 | require(msg.value == 0,"no additional stake allowed"); 45 | 46 | revert("To little time passed, wait at least WAIT_BLOCKS_LIMIT "); 47 | } 48 | else{ 49 | if(getStage(block.number)==SOLVING_LOTERRY){ 50 | require(msg.value == 0,"no additional stake allowed"); 51 | processSolvingLottery(block.number); 52 | } 53 | else{ 54 | revert("Lottery Closed "); 55 | } 56 | } 57 | } 58 | } 59 | } 60 | 61 | 62 | function getStage(uint256 blockNum) private view returns(uint256) { 63 | if(registeredCount<_registeredLimit){ 64 | return REGISTERING_PARTICIPANTS; 65 | } 66 | else{ 67 | if(waitingStartBlockNumber==0 //start waiting block has been never set 68 | || blockNum-waitingStartBlockNumber>=256 //start waiting block has been set long time ago 69 | ){ 70 | return REGISTERING_FINISHED; 71 | } 72 | else 73 | { 74 | if(blockNum-waitingStartBlockNumber