├── .gitignore ├── 001-pragma-solidity.sol ├── 002-variable-and-types.sol ├── 003-functions-in-solidity.sol ├── 004-decision-making.sol ├── 005-variables-and-scope.sol ├── 006-arithmetic-operators.sol ├── 007-comparison-operators.sol ├── 008-logical-operators.sol ├── 009-loops-in-solidity.sol ├── 010-strings-in-solidity.sol ├── 011-constructors.sol ├── 012-arrays-in-solidity.sol ├── 013-enums-in-solidity.sol ├── 014-struct-in-solidity.sol ├── 015-mappings-in-solidity.sol ├── 016-maps-and-stucts.sol ├── 017-nested-maps.sol ├── 018-conversions-solidity.sol ├── 019-ether-units-and-domination-in-solidity.sol ├── 020-global-variables.sol ├── 021-function-modifiers-in-solidity.sol ├── 022-view-and-pure-keywords.sol ├── 023-fallback-functions.sol ├── 024-function-overloading.sol ├── 025-cryptographic-functions.sol ├── 026-subcurrency-crypto-tokens.sol ├── 027-security-when-writing-contracts.sol ├── 028-handling-threats.sol ├── 029-restricted-access.sol ├── 030-entrance-exam.sol ├── 031-docstrings-in-solidity.sol ├── 032-advanced-inheritance.sol ├── 033-more-on-events.sol ├── 034-abstract-contracts.sol ├── 035-interfaces-in-solidity.sol ├── 036-uniswap-protocol.sol ├── 037-libraries-in-solidity.sol ├── 038-library-assignment.sol ├── 039-assembly-in-solidity.sol ├── 040-error-handling-in-solidity.sol ├── 041-auction-app-project.sol ├── README.md └── notes ├── blockchain.txt ├── dApps.txt └── ethereum_virtual_machine.txt /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ -------------------------------------------------------------------------------- /001-pragma-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | // specify the solidity version you code is currently being written in 4 | // pragma is generally the first line in a solidity file and it is a 5 | // directive that specifies the compiler version to be used for 6 | // the solidity file 7 | 8 | // single version 9 | // pragma solidity 0.8.0; 10 | 11 | // range version 12 | pragma solidity >= 0.7.0 < 0.9.0; 13 | 14 | // reference for solidity version releases 15 | // Link: https://github.com/ethereum/solidity/releases 16 | -------------------------------------------------------------------------------- /002-variable-and-types.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | // variables are used to store information to be referenced 6 | // or manipulated by our program 7 | 8 | // Mostly used and three main variable types: 9 | 10 | // Boolean - keyword: bool - Example values: true, false 11 | // Integer - keyword: uint - Example values: signed and unsigned integers with varying sizes 12 | // String - keyword: string - Example values: data values that are made up of a sequence of characters 13 | 14 | // isAdmin = boolean - checks if a user is an admin 15 | // walletAmount = integer, total amount in users wallet 16 | // errorMessage = a string containing a description of what went wrong 17 | 18 | contract LearnVariables { 19 | // our solidity code 20 | 21 | // declaring an integer variable 22 | uint256 chocolateBar = 100; 23 | 24 | // string variables 25 | string storeOwner = "Prince Junior"; 26 | string errorMessage = "Not an Admin"; 27 | 28 | // boolean variable 29 | bool isAdmin = true; 30 | 31 | // exercise 32 | uint256 wallet = 300; 33 | bool spent = false; 34 | string notififySpend = "You spent an amount of money"; 35 | } 36 | -------------------------------------------------------------------------------- /003-functions-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Learn about functions in solidity 7 | * Manipulating and calling functions to execute 8 | */ 9 | 10 | // A function is a group of code that can be called anywhere within your program 11 | // Eliminating the possibility of writing thesame block of code many times 12 | 13 | contract LearnFunctions { 14 | // syntax 15 | // function functionName(parameter list) scope returns(return type) { statements } 16 | 17 | // examples 18 | function remoteControlOpen(bool closedDoor) public returns (bool) {} 19 | 20 | // state variables 21 | // uint defaultValue = 5; 22 | 23 | function addValues() public pure returns (uint256) { 24 | // local variables - scope: only valid or accessible within the this function 25 | uint256 a = 2; 26 | uint256 b = 3; 27 | uint256 result = a + b; 28 | 29 | return result; 30 | } 31 | 32 | // function with parameters 33 | function multiplyValues(uint256 a, uint256 b) 34 | public 35 | pure 36 | returns (uint256) 37 | { 38 | uint256 result = a * b; 39 | return result; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /004-decision-making.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Learn about decision making in solidity 7 | * conditional statements, switching execution paths 8 | * based on certain conditions or decision made 9 | */ 10 | 11 | contract LearnDecisionMaking { 12 | // orange variable 13 | uint256 oranges = 5; 14 | 15 | // validate oranges function 16 | function validateOranges() public view returns (bool) { 17 | // if...else condition 18 | if (oranges == 5) // evaluates trueness of the expression in parenthesis 19 | { 20 | // then 21 | return true; 22 | } else { 23 | return false; 24 | } 25 | } 26 | 27 | // exercise 28 | uint256 stakingWallet = 10; 29 | 30 | // stake more and ge more, stake less you get less 31 | function airDrop() public view returns (uint256) { 32 | if (stakingWallet == 10) { 33 | return stakingWallet + 10; 34 | } else { 35 | return stakingWallet + 1; 36 | } 37 | } 38 | 39 | function airDropTwo() public view returns (uint256) { 40 | if (stakingWallet == 10) return stakingWallet + 10; 41 | 42 | return stakingWallet + 1; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /005-variables-and-scope.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Learn about variables and scope 7 | */ 8 | 9 | contract LearnVariableAndScope { 10 | // state variable 11 | uint256 public data = 10; 12 | 13 | // private variable - can't be accessed out of the contract 14 | uint256 private dataTwo = 50; 15 | 16 | // internal variable - can be accessed within this contract and 17 | // contracts that inherit this contract 18 | // private with a lesser restriction power 19 | uint256 internal dataThree = 50; 20 | 21 | // do not do this for variables; as this removes or contradicts 22 | // the purpose of having a state variable 23 | // uint256 external dataFour = 50; 24 | 25 | function x() public returns (uint256) { 26 | // modifying the state variable 27 | data = 25; 28 | return data; 29 | } 30 | 31 | function y() public view returns (uint256) { 32 | // returns 10 if function x is not ran 33 | // but returns 25 after function x runs 34 | return data; 35 | } 36 | 37 | // private function, cannot be accessed out of the contract 38 | function z() private returns (uint256) { 39 | data = 35; 40 | return data; 41 | } 42 | 43 | // this function can only be called out of the contract 44 | // will produce a compilation error when called 45 | // function b() external returns (uint256) { 46 | // data = 45; 47 | // return data; 48 | // } 49 | 50 | function m() public returns (uint256) { 51 | // calls function z to execution 52 | return z(); 53 | 54 | // test execution for function b 55 | // return b(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /006-arithmetic-operators.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Learn about arithmetic operators in solidity 7 | * Intro - Operators tell the compiler to perform specific 8 | * mathematical operation, logical or relational 9 | * operation and produce a suitable response 10 | */ 11 | 12 | contract LearnArithmeticOperators { 13 | uint256 public a = 5; 14 | uint256 public b = 10; 15 | 16 | function calculatorAdd() public view returns (uint256) { 17 | uint256 result; 18 | result = a + b; 19 | return result; 20 | } 21 | 22 | function calculatorMultiply() public view returns (uint256) { 23 | uint256 result; 24 | result = a * b; 25 | return result; 26 | } 27 | 28 | function calculatorSubtract() public view returns (uint256) { 29 | uint256 result; 30 | result = a - b; 31 | return result; 32 | } 33 | 34 | function calculatorDivide() public view returns (uint256) { 35 | uint256 result; 36 | 37 | // division by ZERO 38 | if (b != 0) { 39 | result = a / b; 40 | } else { 41 | result = 0; 42 | } 43 | return result; 44 | } 45 | 46 | function calculatorGetRemainder() public view returns (uint256) { 47 | uint256 result; 48 | result = a % b; 49 | return result; 50 | } 51 | 52 | // modulo trick 53 | // the goal is to find the remainder 54 | /* 55 | 12 % 23 56 | 1. divident = 12, divisor = 23 57 | 2. q = 12 / 23, q = 0 58 | 3. 0 * 23 = 0, newResult = 0 59 | 4. 12 - 0, remainder = 0 60 | */ 61 | 62 | function calculatorIncrement() public returns (uint256) { 63 | return a++; 64 | } 65 | 66 | function calculatorExpression() public view returns (uint256) { 67 | return (a + b) * 3 - 10; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /007-comparison-operators.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Comparison operators 7 | */ 8 | 9 | contract ComparisonOperators { 10 | uint256 public a = 5; 11 | uint256 public b = 10; 12 | 13 | function compareEquality() public view returns (bool) { 14 | return a == b; // evaluates to a boolean: true or false 15 | // return a != b; // not equal to 16 | } 17 | 18 | function compareValues() public view returns (bool) { 19 | if (a > b) { 20 | return true; 21 | } 22 | return false; 23 | } 24 | 25 | // require function 26 | function compareValuesUsingRequire() public view { 27 | require(a > b, "This is false."); 28 | } 29 | 30 | function compareGreaterOrEqual() public view { 31 | require(a >= b, "This is false."); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /008-logical-operators.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Logical operators 7 | */ 8 | 9 | contract LogicalOperators { 10 | uint256 public a = 5; 11 | uint256 public b = 10; 12 | 13 | // logical not 14 | function logicalNot() public view returns (bool) { 15 | if (!(a > b)) { 16 | return true; 17 | } 18 | return false; 19 | } 20 | 21 | // AND: && 22 | function logicAND() public view returns (bool) { 23 | // both conditions must be fulfilled 24 | if ((a > b) && (a == b)) { 25 | return true; 26 | } 27 | return false; 28 | } 29 | 30 | // OR: && 31 | function logicOR() public view returns (bool) { 32 | // atleast one condition should be fulfilled 33 | if ((a > b) || (a == b)) { 34 | return true; 35 | } 36 | return false; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /009-loops-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Working with loops 7 | */ 8 | 9 | contract LoopsInSolidity { 10 | // a list of numbers ranging from 1 to 10 11 | uint256[] public numbersList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 12 | 13 | function countMultiples(uint256 _number) public view returns (uint256) { 14 | // three part statement for a for loop 15 | // 1. Initialize start of loop 16 | // 2. Determine the length of the run time 17 | // 3. iterate or update the index after each turn 18 | // depending on the case - in our case we want to 19 | // increment the index after each run. 20 | 21 | uint256 count = 0; 22 | for (uint256 index = 0; index < numbersList.length; index++) { 23 | // logic for the loop 24 | if (checkIfMultiple(numbersList[index], _number)) { 25 | count++; 26 | } else { 27 | continue; 28 | } 29 | } 30 | 31 | return count; 32 | } 33 | 34 | function checkIfMultiple(uint256 _num, uint256 _num2) 35 | public 36 | pure 37 | returns (bool) 38 | { 39 | // we will make use of modulo operator 40 | if (_num % _num2 == 0) { 41 | return true; 42 | } else { 43 | return false; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /010-strings-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Working with strings 7 | */ 8 | 9 | contract LearnStrings { 10 | // string literals 11 | string greetings = "Hello World!"; 12 | string firstName = "Njoh Noh"; 13 | string lastName = "Prince Junior"; 14 | 15 | // To create functions to work with our strings, 16 | // we need to specify where the string will be stored 17 | // memory is a temporal storage location in solidity 18 | // while storage holds the data between function calls 19 | 20 | /** 21 | A solidity contract can use any amount of memory during execution, 22 | but once the execution stops, the memory is wiped off completely 23 | for the next execution. 24 | */ 25 | 26 | // function to get the first name 27 | function getFirstName() public view returns (string memory) { 28 | return firstName; 29 | } 30 | 31 | // function to get the last name 32 | function getLastName() public view returns (string memory) { 33 | return firstName; 34 | } 35 | 36 | // function to say hello 37 | function sayHello() public view returns (string memory) { 38 | return greetings; 39 | } 40 | 41 | // function to change greeting 42 | function changeGreeting(string memory _change) public { 43 | greetings = _change; 44 | } 45 | 46 | // strings in solidity are computationally expensive 47 | // getting the length or manipulating strings is a bit 48 | // different from other programming languages. 49 | 50 | // as a result we convert our strings to bytes 51 | function getCharFromGreeting() public view returns (bytes1) { 52 | bytes memory greetingsInBytes = bytes(greetings); 53 | return greetingsInBytes[0]; 54 | } 55 | 56 | function getLengthGreeting() public view returns (uint256) { 57 | bytes memory greetingsInBytes = bytes(greetings); 58 | return greetingsInBytes.length; 59 | } 60 | 61 | // using special characters in strings 62 | // can be created or escaped using '\' 63 | // example: 'Hello, you\'re smart' 64 | 65 | // another possible way 66 | string text = "You're very smart!"; 67 | } 68 | -------------------------------------------------------------------------------- /011-constructors.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Constructors in solidity 7 | * 8 | * Constructors are special function created using 9 | * the constructor keyword. 10 | * It initializes state variables of a contract. 11 | */ 12 | 13 | /** 14 | A constructor has the following key characteristics 15 | 16 | 1. A contract can have only one constructor 17 | 2. A constructor code is executed once when a contract 18 | is created and it is used to initialize the contract 19 | state. 20 | 3. After a constructor is executed, the final code is 21 | deployed to the blockchain. 22 | This code include the public functions and code 23 | reachabke through public functions. 24 | Constructors code or any internal method used by 25 | constructor are not included in final code 26 | 27 | A constructor can either be public or internal. 28 | 29 | An internal constructor marks the contract as abstract. 30 | 31 | In case, no constructor is defined, a default constructor 32 | is present in the contract. 33 | */ 34 | 35 | contract Member { 36 | string name; 37 | uint256 age; 38 | 39 | // constructor 40 | // initialize name and age 41 | constructor(string memory _name, uint256 _age) { 42 | name = _name; 43 | age = _age; 44 | } 45 | } 46 | 47 | // demonstrating inheritance 48 | contract Teacher is Member("Tom", 28) { 49 | function getName() public view returns (string memory) { 50 | // returns Tom 51 | return name; 52 | } 53 | } 54 | 55 | // students 56 | contract Student is Member { 57 | constructor(string memory name, uint256 age) Member(name, age) {} 58 | 59 | function getName() public view returns (string memory) { 60 | // return the value stored within the state variable name 61 | return name; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /012-arrays-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Working with arrays in solidity 7 | * 8 | * An array is used to store a fixed size, sequential collection. 9 | * of elements of the same type. 10 | * An array is used to store a collection of data. 11 | */ 12 | 13 | contract LearnArrays { 14 | uint256[] public myArray; 15 | uint256[] public myArray2; 16 | uint256[200] myFixedSizedArray; 17 | 18 | // addding elements to the array: 19 | // the push method adds one or more elemens to the end of an array 20 | // and returns the new length of the array. 21 | 22 | // function to push an element into the array 23 | function push(uint256 number) public { 24 | // using the push method 25 | myArray.push(number); 26 | } 27 | 28 | // function to pop/remove the last element from an array 29 | function pop() public { 30 | // using the pop() method 31 | myArray.pop(); 32 | } 33 | 34 | // function to get the length of an array 35 | function getArrayLength() public view returns (uint256) { 36 | // using the length property to get the length of the array 37 | return myArray.length; 38 | } 39 | 40 | // get array element at a particular index 41 | function getElementAtIndex(uint256 index) public view returns (uint256) { 42 | return myArray[index]; 43 | } 44 | 45 | // remove a element at a particular index 46 | function remove(uint256 index) public { 47 | // using the delete keyword 48 | // length of the array remains thesame 49 | // deleted number will be replaced with a zero 50 | delete myArray[index]; 51 | } 52 | 53 | // trick to remove an element completely from an array 54 | // but changes the positions of the elements in the array 55 | 56 | // swap the element and the element at the last position 57 | function trickyRemove(uint256 index) public { 58 | // assign the last element within the array unto a temp variable 59 | uint256 temp = myArray[myArray.length - 1]; 60 | 61 | // send the element to be deleted to the end of the array 62 | myArray[myArray.length - 1] = myArray[index]; 63 | 64 | // assign the last element to the element to be deleted position 65 | myArray[index] = temp; 66 | 67 | // pop the last element within the array 68 | myArray.pop(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /013-enums-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Working with enums in solidity 7 | * 8 | * Enums restrict a variable to have only a few 9 | * predefined values. Tha values enumeraed in the 10 | * list are called enums. 11 | * 12 | * With the use of enums it is possible to reduce 13 | * he number of bugs in your code. 14 | */ 15 | 16 | contract LearnEnums { 17 | // create an enum list of french fries sizes 18 | enum frenchFriesSize { 19 | LARGE, 20 | MEDIUM, 21 | SMALL 22 | } 23 | 24 | // create a variable choice with datatype frenchFriesSize 25 | // frenchFriesSizes now acts as a datatype for creating new 26 | // variables 27 | frenchFriesSize choice; 28 | 29 | // setting a default choice 30 | frenchFriesSize constant defaultChoice = frenchFriesSize.MEDIUM; 31 | 32 | // switch choice to small 33 | function setSmall() public { 34 | choice = frenchFriesSize.SMALL; 35 | } 36 | 37 | // switch choice to large 38 | function setLarge() public { 39 | choice = frenchFriesSize.LARGE; 40 | } 41 | 42 | // funcion to get the choice 43 | function getChoice() public view returns (frenchFriesSize) { 44 | return choice; 45 | } 46 | 47 | // funcion to get the choice 48 | function getDefaultChoice() public pure returns (uint256) { 49 | return uint256(defaultChoice); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /014-struct-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Working with structs in solidity 7 | * 8 | * Structs are types that are used to represent a record. 9 | * Supposed you want to keep track of movies in a library 10 | * You might want to keep track of the following 11 | * properties about each movie: 12 | * 13 | * title, director, movieID 14 | */ 15 | 16 | contract LearnStructs { 17 | // Defining a movie structure 18 | struct Movie { 19 | string title; 20 | string director; 21 | uint256 movieID; 22 | } 23 | 24 | // we can create many variables of type Movie 25 | Movie movie; 26 | Movie horrorMovies; 27 | Movie scienceFictionMovies; 28 | Movie commedyMovies; 29 | 30 | // set a movie 31 | function setMovie() public { 32 | movie = Movie("The Contrast Pair", "TheUnicornDev", 1); 33 | horrorMovies = Movie("Targetting TheTarget", "AbstractDev", 1); 34 | } 35 | 36 | // get the movie 37 | function getMovieID() public view returns (uint256) { 38 | return movie.movieID; 39 | } 40 | 41 | // wanna watch horror movie --lets get you what you want 42 | function getHorrorMovieID() public view returns (uint256) { 43 | return horrorMovies.movieID; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /015-mappings-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Mapping in solidity 7 | * 8 | * Mapping is a reference type as arrays and structs. 9 | * Mapping allows one to store data in key value pairs 10 | * for easier retrieval later on the the course of the program 11 | * 12 | * In solidity you can't iterate through a map - you need to store 13 | * the keys in an array and you can't give them sizes 14 | */ 15 | 16 | contract LearnMapping { 17 | // syntax to declare a mapping type 18 | // address could be of any daatype 19 | mapping(address => uint256) public myMap; 20 | 21 | // create a specific address 22 | // NOTE: Keys in a map have to be unique 23 | function setAddress(address _addr, uint256 _i) public { 24 | myMap[_addr] = _i; 25 | } 26 | 27 | // get data stores in a certain key - addr 28 | function getAddress(address _addr) public view returns (uint256) { 29 | return myMap[_addr]; 30 | } 31 | 32 | // remove an address 33 | function removeAddress(address _addr) public { 34 | // replaces the value of the corresponding key to zero 35 | // as when we were working with arrays 36 | delete myMap[_addr]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /016-maps-and-stucts.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Working with Maps and Structs 7 | */ 8 | 9 | contract LearnMappingAndStruct { 10 | // movie map 11 | mapping(uint256 => Movie) movie; 12 | 13 | // movie structure 14 | struct Movie { 15 | string title; 16 | string director; 17 | } 18 | 19 | // create and add a movie to the map 20 | function addMovie( 21 | uint256 movieID, 22 | string memory title, 23 | string memory director 24 | ) public { 25 | movie[movieID] = Movie(title, director); 26 | } 27 | 28 | // get a particular movie from the map 29 | function getMovieFromMap(uint256 movieID) 30 | public 31 | view 32 | returns (Movie memory) 33 | { 34 | return movie[movieID]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /017-nested-maps.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Working with nested maps in solidity 7 | */ 8 | 9 | contract LearnNestedMapping { 10 | // movie map 11 | mapping(uint256 => Movie) movie; 12 | 13 | // creating a nested map 14 | mapping(address => mapping(uint256 => Movie)) public myMovie; 15 | 16 | // movie structure 17 | struct Movie { 18 | string title; 19 | string director; 20 | } 21 | 22 | // create and add a movie to the map 23 | function addMovie( 24 | uint256 movieID, 25 | string memory title, 26 | string memory director 27 | ) public { 28 | movie[movieID] = Movie(title, director); 29 | } 30 | 31 | // adding a movie to the nested map 32 | function addMyMovie( 33 | uint256 movieID, 34 | string memory title, 35 | string memory director 36 | ) public { 37 | // NOTE: msg.sender is a global variable, which is accessible 38 | // throughout solidity which captures the address that is calling 39 | // the contract. 40 | 41 | // store this movie unto a particular address 42 | myMovie[msg.sender][movieID] = Movie(title, director); 43 | } 44 | 45 | // get a particular movie from the map 46 | function getMovieFromMap(uint256 movieID) 47 | public 48 | view 49 | returns (Movie memory) 50 | { 51 | return movie[movieID]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /018-conversions-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Conversions - datatypes 7 | */ 8 | 9 | contract LearnConversions { 10 | // uint defaults to 256; 11 | // uint cannot take negative numbers 12 | // it is represents an unsigned integer 13 | // has a maximum value of 2^256 - 1 14 | // minimum value of 0 15 | uint256 data; 16 | 17 | // how to be specific to reduce gas rates in solidity 18 | // when working with smart contracts 19 | 20 | // converting to a lower type costs higher order bits 21 | uint32 a = 0x12345678; 22 | uint256 b = uint16(a); // b = 0x5678 23 | 24 | // converting yo higher type adds padding bits to the left 25 | uint16 c = 0x1234; 26 | uint32 d = uint32(c); 27 | 28 | // working with bytes 29 | bytes2 e = 0x1234; 30 | bytes1 f = bytes1(e); // f = 0x12 31 | 32 | // converting to a larger bytes adds padding bits to the right 33 | bytes2 g = 0x1234; 34 | bytes4 h = bytes4(g); // h = 0x12340000 35 | } 36 | -------------------------------------------------------------------------------- /019-ether-units-and-domination-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Ether units 7 | * Etherium is the blockchain and Ether is the 8 | * currency for the Etherium blockchain. 9 | */ 10 | 11 | contract LearnEtherUnits { 12 | // assert is a special function that test for the trueness of expressions 13 | // it breaks the code of function when the expression evaluates to false 14 | function testEtherUnits() public pure { 15 | // wei is the smallest domination of ether 16 | assert(1000000000000000000 wei == 1 ether); // 10^18 = 1 ether 17 | assert(1 wei == 1); // 1 wei = 1 18 | 19 | assert(1 ether == 1e18); 20 | 21 | // assertion for the equivalent of 2 ethers in weis 22 | assert(2 ether == 2000000000000000000 wei); 23 | } 24 | 25 | // working with time 26 | function timeAssertion() public pure { 27 | assert(1 minutes == 60 seconds); 28 | assert(24 hours == 1440 minutes); 29 | assert(1 days == 24 hours); 30 | assert(1 weeks == 7 days); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /020-global-variables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Global variables(special variables) in solidity 7 | * These are variables that provide information about the blockchain 8 | * 9 | * As examples we have: 10 | * msg.sender - sender of the message (current call), 11 | * msg.value (uint) - number of wei sent with the message, 12 | * block.timestamp - current block timestamp as seconds since unix epoch, 13 | * block.number - current block number 14 | */ 15 | 16 | // helpful link to learn more about global variables and a lot of examples, 17 | // their uses and warnings. 18 | // https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html 19 | 20 | contract LedgerBalance { 21 | mapping(address => uint256) balance; 22 | 23 | // update the balance of the current sender, initiator of the transaction 24 | function updateBalance(uint256 newBalance) public { 25 | balance[msg.sender] = newBalance; 26 | } 27 | } 28 | 29 | // update the balance from another contract 30 | // interaction between two contracts 31 | contract Updated { 32 | function updateBalance() public { 33 | // creating an instance of the LedgerBalance contract 34 | LedgerBalance ledgerBalance = new LedgerBalance(); 35 | 36 | // updating the balance 37 | ledgerBalance.updateBalance(40); 38 | } 39 | } 40 | 41 | // Other global variables 42 | contract SimpleStorage { 43 | uint256 storeData; 44 | uint256 difficulty; 45 | uint256 timestamp; 46 | uint256 number; 47 | 48 | function set(uint256 x) public { 49 | storeData = x; 50 | 51 | // diffculty of the current block 52 | difficulty = block.difficulty; 53 | 54 | // time of interaction with the blockchain 55 | timestamp = block.timestamp; 56 | 57 | // block number 58 | number = block.number; 59 | } 60 | 61 | function get() public view returns (uint256) { 62 | return storeData; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /021-function-modifiers-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Function Modifiers in solidity 7 | * a function modifier is used to modify the behaviour of a function 8 | * they are customizable 9 | */ 10 | 11 | contract Owner { 12 | address owner; 13 | 14 | // when we deploy this contract we want to set the address to the owner (msg.sender) 15 | constructor() { 16 | owner = msg.sender; 17 | } 18 | 19 | // writing our function modifier 20 | modifier onlyOwner() { 21 | // customizable logic 22 | 23 | // required checks for the trueness 24 | // or throws an error 25 | require(msg.sender == owner); 26 | _; 27 | // the underscore continues with the function that has the 28 | // modifier attached unto it 29 | } 30 | 31 | modifier costPriceCheck(uint256 price) { 32 | // msg.value: amount in wei being sent with a message to the contract 33 | require(msg.value >= price); 34 | _; 35 | } 36 | } 37 | 38 | // inherits Owner --variables and functions 39 | contract FunctionModifiers is Owner { 40 | mapping(address => bool) registeredAddresses; 41 | uint256 price; 42 | 43 | // constructor 44 | constructor(uint256 initialPrice) { 45 | price = initialPrice; 46 | } 47 | 48 | // function to register an address 49 | // the public keyword changes the vivibility of our function 50 | // hence the scope whereby which our function can be 51 | //called or accessed(but it is fixed in behaviour in what it does) 52 | function registerAddress() public payable { 53 | registeredAddresses[msg.sender] = true; 54 | } 55 | 56 | // function to modify price 57 | // onlyOwner is our function modifier 58 | // which says only he owner can modify the price 59 | function changePrice(uint256 _price) public onlyOwner { 60 | price = _price; 61 | } 62 | 63 | function changePriceUsingSecondModifier(uint256 _price) 64 | public 65 | payable 66 | costPriceCheck(price) 67 | { 68 | price = _price; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /022-view-and-pure-keywords.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * View Keyword in solidity 7 | * view functions ensure that they will not modify the state (return values) 8 | * while pure functions ensure that they not read or modify the state (returns calculations) 9 | */ 10 | 11 | contract ViewAndPureKeyword { 12 | uint256 value; 13 | 14 | // this function modifies the state 15 | function setValue(uint256 _value) external { 16 | // here we are using an eth send transaction 17 | value = _value; 18 | } 19 | 20 | // does not modifies the state --read-only function 21 | // that returns a value 22 | function getValue() external view returns (uint256) { 23 | // this is an eth call 24 | return value; 25 | } 26 | 27 | // does not reads or modify the state 28 | function aPureFunc() public pure returns (uint256) { 29 | return 4 + 5; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /023-fallback-functions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Fallback functions 7 | * 8 | * Define a fallback function: 9 | * 1. Cannot have a name 10 | * 2. Does not take any inputs 11 | * 3. Does not return any outputs 12 | * 4. Must be declared as external 13 | */ 14 | 15 | // USAGE - Why Use It 16 | /** 17 | * When you call a function that does not exists 18 | * when transfering ethers; send and transfer receives 2300 gas 19 | * bu call method receives more(all of the gas). 20 | */ 21 | 22 | contract FallBack { 23 | event Log(uint256 gas); 24 | 25 | fallback() external payable { 26 | // not recommended to write to much code - because the function will fail 27 | 28 | // invoke the send or transfer method: we get 2300 gas which is enough to emit a log 29 | // invoke the call method: we get all the gas 30 | 31 | // special solidity function gasleft returns how many gas is left 32 | emit Log(gasleft()); 33 | } 34 | 35 | function getBalance() public view returns (uint256) { 36 | // return the stored balance of the contract 37 | return address(this).balance; 38 | } 39 | } 40 | 41 | // new contract will send ether to the FallBack contract 42 | contract SendToFallBack { 43 | function transferToFallBack(address payable _to) public payable { 44 | // send ether with transfer method 45 | // automatically transfer will transfer 2300 gas amount 46 | 47 | _to.transfer(msg.value); 48 | } 49 | 50 | function callFallBack(address payable _to) public payable { 51 | // send ether with call 52 | (bool sent, ) = _to.call{value: msg.value}(""); 53 | require(sent, "Failed to send!"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /024-function-overloading.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Function overloading in solidity 7 | * You can have multiple definitions for the same function name in the same scope 8 | * 9 | * The function definition of the function must differ from each other by types and/or 10 | * the number of arguments in the argument list 11 | * Also, the type of the arguments can be different. 12 | * 13 | * NOTE: You cannot overload function declarations that differ only by return type 14 | */ 15 | 16 | contract LearnFunctionOverLoading { 17 | // calculateSum function with two arguments --calculates the sum of two numbers 18 | function calculateSum(uint256 numberOne, uint256 numberTwo) 19 | public 20 | pure 21 | returns (uint256) 22 | { 23 | return numberOne + numberTwo; 24 | } 25 | 26 | // calculateSum function with three arguments --calculates the sum of three numbers 27 | function calculateSum( 28 | uint256 numberOne, 29 | uint256 numberTwo, 30 | uint256 numberThree 31 | ) public pure returns (uint256) { 32 | return numberOne + numberTwo + numberThree; 33 | } 34 | 35 | // 😅 Sum two strings --concatenation of two strings 36 | function calculateSum(string memory first, string memory second) 37 | public 38 | pure 39 | returns (string memory) 40 | { 41 | // return the concatenation of both strings 42 | return string.concat(first, second); 43 | } 44 | 45 | // concatenate two names 46 | function concatenateTwoString() public pure returns (string memory) { 47 | string memory fullName = calculateSum("Njoh Noh", "Prince Junior"); 48 | return fullName; 49 | } 50 | 51 | // call the function to add two numbers and return the result 52 | // of the computation. 53 | function calculateSumTwoArgs() public pure returns (uint256) { 54 | // assign the result of the computation to a variable 55 | uint256 result = calculateSum(3, 4); 56 | return result; 57 | } 58 | 59 | // call the function to add three numbers and return the result 60 | // of the computation. 61 | function calculateSumThreeArgs() public pure returns (uint256) { 62 | // assign the result of the computation to a variable 63 | uint256 result = calculateSum(3, 4, 1); 64 | return result; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /025-cryptographic-functions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Cryptographic Functions 7 | * A cryptographic has function(CHF) is a mathematical algorithm that maps data of arbitrary size 8 | * (often called the "message") to a bit array of a fixed size (called the "hash" or "hash value" or "message digest") 9 | * It is a one way function, that is, a function which is practically infeasible to invert or reverse the computation. 10 | * 11 | * Solidity provides inbuilt cryptographic functions as well. Below are some of the important methods it provides: 12 | * 13 | * keccak256(bytes memory) returns (byte32) 14 | * sha256(bytes memory) returns (bytes 32) 15 | * ripemd160(bytes memory) returns (bytes 20) 16 | */ 17 | 18 | // Keccak is a leading hashing function, designed by non-NSA designers. Keccak won NIST competition to become the official SHA3 19 | // Keccak is a family of cryptographic sponge functions and is designed as an alternative to SHA-256 20 | 21 | // Oracle dynamic feeds 22 | // A database management system is not only used for storing the data but to effectively manage 23 | // it and provides high performance, authorized access and failure recovery features. 24 | 25 | contract Oracle { 26 | address admin; 27 | uint256 public rand; 28 | 29 | constructor() { 30 | admin = msg.sender; 31 | } 32 | 33 | // seed the rand variable 34 | function seedRandom(uint256 _rand) external { 35 | require(msg.sender == admin); 36 | rand = _rand; 37 | } 38 | } 39 | 40 | contract LearnCryptoGraphicFunctions { 41 | // we will leaverage this module on two things 42 | // 1. Modulo operator 43 | // 2. Cryptographic hashing 44 | 45 | Oracle oracle; 46 | 47 | constructor(address oracleAddress) { 48 | oracle = Oracle(oracleAddress); 49 | } 50 | 51 | function randMod(uint256 range) external view returns (uint256) { 52 | // grab information from the blockchain to randomly generate numbers 53 | // abi.encodePacked concatenates arguments nicely 54 | return 55 | uint256( 56 | keccak256( 57 | abi.encodePacked( 58 | oracle.rand, 59 | block.timestamp, 60 | block.difficulty, 61 | msg.sender 62 | ) 63 | ) 64 | ) % range; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /026-subcurrency-crypto-tokens.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Crypto Tokens 7 | * 8 | * The contract allows only its creator to create new coins(different issuance schemes are possible) 9 | * 10 | * Anyone can send coins to each other without the need for regictering 11 | * with username and password, all you need is an Etherium keypair 12 | * 13 | */ 14 | 15 | contract CryptoTokensAndMinting { 16 | // REMINDER: The keyword public is used in 17 | // making the variables accessible from other contracts 18 | 19 | address public minter; 20 | 21 | // bonus rate only configurable by the contract owner 22 | // set to an initial value of 0 23 | uint256 bonusRate = 0; 24 | 25 | // account balances 26 | mapping(address => uint256) public balances; 27 | 28 | // bonuses --each client account will be entitled to a bonus 29 | // depending on hopw they work. 30 | mapping(address => uint256) public bonuses; 31 | 32 | // our clients can react to specific 33 | // contract changes you declare 34 | 35 | // Event is an inheritable member of a contract. An event is emmited 36 | // it stores the arguments passed in the transaction logs. 37 | 38 | // These logs are stored on the blockchain and are accessible using the 39 | // address of the contract untill the contract is present on the blockchain. 40 | event Sent(address from, address to, uint256 amount); 41 | 42 | // create a constructor 43 | // REMINDER: The constructor only runs when we deploy the contract 44 | constructor() { 45 | minter = msg.sender; 46 | } 47 | 48 | // want to make new coins and send to an address 49 | // only the owner can do this 50 | function mint(address receiver, uint256 amount) public { 51 | // make sure its the minter 52 | require(msg.sender == minter, "Access Denied"); 53 | 54 | // add amount to the receiver's previous balance 55 | balances[receiver] += amount; 56 | } 57 | 58 | // set a bonus rate 59 | // only by the contract owner 60 | function setBonusRate(uint256 bonus) public { 61 | require(msg.sender == minter, "Access Denied"); 62 | 63 | // set a bonus rate 64 | bonusRate = bonus; 65 | } 66 | 67 | // check set bonus rate 68 | function checkBonusRate() public view returns (uint256) { 69 | return bonusRate; 70 | } 71 | 72 | // add eligible clients to benefit from bonus rate 73 | function setEligibility(address _addr) public { 74 | require(msg.sender == minter, "Access Denied"); 75 | 76 | // add client to map of eligible clients 77 | bonuses[_addr] = bonusRate; 78 | } 79 | 80 | // error function to handle error in transactions 81 | error insufficientBalance(uint256 requested, uint256 available); 82 | 83 | // send any amount of coins to an existing address 84 | function send(address receiver, uint256 amount) public { 85 | // require the senders balance to be greater that or equal to the amount to be sent 86 | if (balances[msg.sender] < amount) { 87 | // revert keyword will cancel the transaction 88 | revert insufficientBalance({ 89 | requested: amount, 90 | available: balances[msg.sender] 91 | }); 92 | } 93 | 94 | // the sender has a reduction in amount of coins in possession 95 | // while the receiver has an increase in amount of coins in posesssion 96 | balances[msg.sender] -= amount; 97 | balances[receiver] += amount; 98 | 99 | // emit the event with the required details 100 | emit Sent(msg.sender, receiver, amount); 101 | } 102 | 103 | // check availability of a bonus for current account 104 | function requestMyBonus() public view returns (uint256) { 105 | if (bonusRate > 0) return bonuses[msg.sender]; 106 | return 0; 107 | } 108 | 109 | // request transfer of the current account's bonus to balances account 110 | function requestToTransferMyBonus() public returns (string memory) { 111 | if (bonuses[msg.sender] > 0) { 112 | // add bonus to the requested account 113 | balances[msg.sender] += bonusRate; 114 | 115 | // reset account bonus to zero 116 | bonuses[msg.sender] = 0; 117 | return "Coins successfully transfered!"; 118 | } 119 | 120 | return 121 | "Transfer could not be established! Please check you bonus value and try again."; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /027-security-when-writing-contracts.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Cyber Security in Solidity - against bad actors, accidential occurences 7 | * 8 | * Withdrawal patterns ensures that direct transfer call is bot made which 9 | * poses a security threat 10 | * 11 | * Transfers are atomic(meaning all or nothing) 12 | */ 13 | 14 | contract SecurityInSolidity { 15 | // some constant variables for testing 16 | // and getting rid of warnings or errors. 17 | uint256 contributedAmount = 100; 18 | address payable[20] public funders; 19 | 20 | // specific addresses 21 | address payable tatiana; 22 | address payable john; 23 | 24 | // modifier 25 | modifier onlyOwner() { 26 | require(true); 27 | _; 28 | } 29 | 30 | // function to return funds 31 | function returnFunds() public payable onlyOwner returns (bool success) { 32 | for (uint256 i = 0; i < funders.length; i++) { 33 | funders[i].transfer(contributedAmount); 34 | } 35 | return true; 36 | } 37 | 38 | // From the above function: 39 | // 1. What if the owner chickens out and does not return the funds 40 | // 2. The loop is unbound considering that the total funders is unknown 41 | // it could run out of gas before allocaing all the funds, what an attacker could 42 | // just do is to make a small bunch of contributions .0000284289 43 | 44 | // function transfer funds between two addresses 45 | function returnFundsTwoAddresses() 46 | public 47 | payable 48 | onlyOwner 49 | returns (bool success) 50 | { 51 | tatiana.transfer(contributedAmount); 52 | john.transfer(contributedAmount); 53 | 54 | return true; 55 | } 56 | 57 | // What could go wrong in this case? 58 | // 1. What if tatiana rejects the transfer 59 | // - The function is going to break or fail and john is not going to get paid 60 | 61 | // Thinking that all contracts and accounts would want to receive or accept 62 | // funds automatically is intuitive at first; but it is infact very naive and dangerous 63 | // to build your code like this. 64 | 65 | // If it is in their interest to reject the funds they will 66 | 67 | } 68 | -------------------------------------------------------------------------------- /028-handling-threats.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Handling threats 7 | * Cyber Security in Solidity - against bad actors, accidential occurences 8 | * 9 | * Withdrawal patterns ensures that direct transfer call is bot made which 10 | * poses a security threat 11 | * 12 | * Transfers are atomic(meaning all or nothing) 13 | */ 14 | 15 | contract SecurityInSolidity { 16 | uint256 contributedAmount = 100; 17 | address payable[20] public funders; 18 | mapping(address => uint256) public balances; 19 | 20 | // specific addresses 21 | address payable tatiana; 22 | address payable john; 23 | 24 | // modifier 25 | modifier onlyOwner() { 26 | require(true); 27 | _; 28 | } 29 | 30 | // from the previous module --instead of using the transfer method 31 | // which reverts the code; we can use the send method which returns 32 | // a boolean 33 | function sendRefund() public payable onlyOwner returns (bool success) { 34 | // though not the best but considerately solves a problem 35 | if (!tatiana.send(contributedAmount)) { 36 | // do something 37 | } else { 38 | // we might also wanna do something at this point 39 | } 40 | 41 | return true; 42 | } 43 | 44 | // a more better way of tackling this problem is to let the investor 45 | // withdraw their funds themselves. 46 | // A global method which comes on handy here is the: msg.sender 47 | 48 | // function to claim refunds 49 | // this eliminates outside interference very greatly 50 | function claimRefund() public payable { 51 | require(balances[msg.sender] > 0); 52 | 53 | // we make the address payable before initiating the send transaction 54 | address payable convertedPayableAddress = payable(msg.sender); 55 | convertedPayableAddress.transfer(balances[msg.sender]); 56 | } 57 | 58 | // BY MAKING OUR TRANSACTIONS ONE AT A TIME we greatly reduce danger to our executions 59 | } 60 | 61 | contract withDrawal { 62 | mapping(address => uint256) public balances; 63 | 64 | function withDraw(uint256 amount) public payable returns (bool success) { 65 | require(balances[msg.sender] >= amount); // guards upfront 66 | 67 | balances[msg.sender] -= amount; // optimistic accounting 68 | address payable convertedPayableAddress = payable(msg.sender); 69 | 70 | convertedPayableAddress.transfer(amount); // transfer 71 | return true; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /029-restricted-access.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Restricted Access 7 | * 8 | * By Default a contract is made readonly unless it is made public 9 | * We can restrict who can modify a contract's state or call a 10 | * function using modifiers. 11 | */ 12 | 13 | contract RestrictedAccess { 14 | address public owner = msg.sender; 15 | uint256 public creationTime = block.timestamp; 16 | 17 | modifier onlyBy(address _account) { 18 | // check if the current sender is the owner 19 | // require(msg.sender == owner); 20 | require(msg.sender == _account, "Access Restricted to Owners Only!"); 21 | _; 22 | } 23 | 24 | modifier onlyAfter(uint256 _time) { 25 | require(block.timestamp >= _time, "Function called to early!"); 26 | _; 27 | } 28 | 29 | // function that changes the owner address 30 | // restrict this access only to the owner of the contract 31 | function changeOwnerAddress(address newAddres) public onlyBy(owner) { 32 | owner = newAddres; 33 | } 34 | 35 | // function to disown the current owner 36 | // only run the contract after three weeks of creation 37 | function disownOwner() 38 | public 39 | onlyBy(owner) 40 | onlyAfter(creationTime + 3 weeks) 41 | { 42 | delete owner; 43 | } 44 | 45 | // add more ethers to the owner 46 | // not the best way but this will do 47 | // for this case. 48 | uint256 balance = msg.value + 200 ether; 49 | 50 | // cost restriction 51 | modifier costs(uint256 _amount) { 52 | require(balance > _amount, "Not enough Ether provided!"); 53 | _; 54 | } 55 | 56 | function forceOwnerChange(address _newOwner) 57 | public 58 | payable 59 | costs(200 ether) 60 | { 61 | owner = _newOwner; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /030-entrance-exam.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Entrance exam into Advanced Solidity Concepts 7 | * @author Njoh Noh Prince Junior 8 | */ 9 | 10 | // contract C 11 | contract C { 12 | uint256 private data; 13 | uint256 public info; 14 | 15 | // constructor --runs only once the contract is deployed 16 | // sets the initial value of info to 10 17 | constructor() { 18 | info = 10; 19 | } 20 | 21 | // increment a given number by 1 and return the result 22 | function increment(uint256 a) private pure returns (uint256) { 23 | return a + 1; 24 | } 25 | 26 | // assign a given value to data 27 | function updateData(uint256 a) public { 28 | data = a; 29 | } 30 | 31 | // get the value stored in data 32 | function getData() public view returns (uint256) { 33 | return data; 34 | } 35 | 36 | // compute the sum between two numbers 37 | // and it returns the sum of the two numbers 38 | function compute(uint256 a, uint256 b) internal pure returns (uint256) { 39 | return a + b; 40 | } 41 | } 42 | 43 | // contract D 44 | contract D { 45 | // creating an instance of contract C 46 | C c = new C(); 47 | 48 | // read the data saved in info variable in contract C 49 | function readInfo() public view returns (uint256) { 50 | return c.info(); 51 | } 52 | } 53 | 54 | // contract E 55 | // inheriting contract C using the special keyword is 56 | contract E is C { 57 | uint256 private result; 58 | C private c; 59 | 60 | // instantiate variable c to an instance of contract C 61 | constructor() { 62 | c = new C(); 63 | } 64 | 65 | // run the compute function from contract C 66 | function getComputedResult() public { 67 | result = compute(23, 5); 68 | } 69 | 70 | // get the value store in result 71 | function getResult() public view returns (uint256) { 72 | return result; 73 | } 74 | 75 | // read the data saved in info variable in contract C 76 | function readInfo() public view returns (uint256) { 77 | return info; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /031-docstrings-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Docstrings 7 | * 8 | * @title Docstrings => a title that describes the contract 9 | * context of use: contracts and interfaces 10 | * 11 | * @notice => explanation of some functionality 12 | * context of use: contracts, interfaces and functions 13 | * 14 | * @author Njoh Noh Prince Junior => author's name 15 | * context of use: contracts, interfaces and functions 16 | * 17 | * @dev => extra details 18 | * context of use: contracts, interfaces and functions 19 | */ 20 | 21 | // contract C 22 | contract DocStrings { 23 | /** 24 | * @param _addr: address => parameter of the function 25 | * context of use: functions 26 | * 27 | * @return address => return value of the function 28 | * context of use: functions 29 | */ 30 | function someRandomFunction(address _addr) public pure returns (address) { 31 | return _addr; 32 | } 33 | 34 | address storedStateAddress; 35 | 36 | /** 37 | * @param _addr: address 38 | * @dev changes the state variable storedStateAddress to a new one 39 | */ 40 | function storeNewAddress(address _addr) public { 41 | storedStateAddress = _addr; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /032-advanced-inheritance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * Advanced Inheritance 7 | * 8 | * @title Advances Inheritance 9 | * @notice Inheritance is a way to extend functionality of a contract 10 | * Solidity supports single as well as multiple inheritance 11 | * 12 | * @dev A contract in solidity is similar to a class in C++ --which ia a blueprint for an object 13 | * Classes can inherit other classes, so can contracts inherit other contracts! 14 | * 15 | * REMINDER: A constructor is a special function declared with the constructor keyword which will be 16 | * executed once per contract and is invoked when a contract is created. 17 | */ 18 | 19 | // contract C 20 | contract AdvancedInheritance { 21 | 22 | } 23 | 24 | contract FirstContract {} 25 | 26 | // second contract inheriting the first contract 27 | contract secondContract is FirstContract { 28 | 29 | } 30 | 31 | // Exercise 32 | contract A { 33 | uint256 public innerVal = 100; 34 | 35 | function innerAddTen(uint256 value) public pure returns (uint256) { 36 | return value + 10; 37 | } 38 | } 39 | 40 | contract B is A { 41 | function runInnerAddTenFromA(uint256 value) public pure returns (uint256) { 42 | return A.innerAddTen(value); 43 | } 44 | 45 | function getInnerVal() public view returns (uint256) { 46 | return innerVal; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /033-more-on-events.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title More on Events in Solidity 7 | * @notice Events have lower gas cost that storage 8 | */ 9 | 10 | contract LearnMoreOnEvents { 11 | // To create an event we consider two things 12 | // 1. Declare th event and 13 | // 2. emit that event 14 | 15 | // example event declaration to funds transfer 16 | // use the CamelCase convention for naming your events 17 | // only use 3 indexed per events - which enables the outside 18 | // consumer to filter what they need 19 | event NewTrade( 20 | uint256 indexed data, 21 | address indexed from, 22 | address to, 23 | uint256 indexed amount 24 | ); 25 | 26 | // function to perform a trade 27 | function trade(address to, uint256 amount) external { 28 | // an outside consumer can see the event throught web3js 29 | // block.timestamp is a global varianle that gives us the current timestamp 30 | // emitting the event 31 | emit NewTrade(block.timestamp, msg.sender, to, amount); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /034-abstract-contracts.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Abstract Contracts 7 | * @notice Abstract contracts is one which contains a least one 8 | * function without any implementation. 9 | * 10 | * Generally an abstract contract contains both implemented 11 | * and abstract functions. 12 | * 13 | * Derived contract will implement the abstract function and use 14 | * the existing functions as they are and when required. 15 | * 16 | * Here we talk of two things 17 | * 1. base contract and 18 | * 2. the derived contract 19 | */ 20 | 21 | // this will act as out base contract 22 | abstract contract LearnMoreOnEvents { 23 | // since the function has no implementation we can mark it as virtual 24 | function sendMessage() public view virtual returns (string memory) {} 25 | } 26 | 27 | // derived contract 28 | contract DerivedContract is LearnMoreOnEvents { 29 | // overriding the method within the base contract 30 | function sendMessage() public pure override returns (string memory) { 31 | return "Hello World!"; 32 | } 33 | } 34 | 35 | // technically the contract is still abstract since it has atleast one 36 | // funtion without an implementation. 37 | contract Member { 38 | string name; 39 | uint256 age = 25; 40 | 41 | function setName() public virtual returns (string memory) {} 42 | 43 | function getAge() public view returns (uint256) { 44 | return age; 45 | } 46 | } 47 | 48 | // derived contract 49 | contract Teacher is Member { 50 | function setName() public override pure returns (string memory) { 51 | return "TheUnicornDev237"; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /035-interfaces-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Interfaces 7 | * @notice Interfaces are similar to abstract contracts 8 | * and are created using interface keyword. 9 | * 10 | * Interfaces can not have any function with implementation 11 | * Functions of an interface can be only of type external 12 | * Interfaces can not have a constructor 13 | * They can not have a state variable 14 | * Interface can have enum, structs which can be accessed 15 | * using the interface name dot notation. 16 | */ 17 | 18 | contract Counter { 19 | uint256 public count; 20 | 21 | function increment() external { 22 | count += 1; 23 | } 24 | } 25 | 26 | // creating interface 27 | interface ICounter { 28 | function count() external view returns (uint256); 29 | 30 | function increment() external; 31 | } 32 | 33 | // to execute copy the address of the Counter contract 34 | // and feed into the parameters of the functions defined 35 | // at MyContract 36 | 37 | contract MyContract { 38 | function incrementCounter(address _counter) external { 39 | ICounter(_counter).increment(); 40 | } 41 | 42 | function getCount(address _counter) external view returns (uint256) { 43 | return ICounter(_counter).count(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /036-uniswap-protocol.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Uniswap Protocol 7 | * @notice The Uniswap protocol is a peer-to-peer1 system designed for exchanging 8 | * cryptocurrencies (ERC-20 Tokens) on the Ethereum blockchain. 9 | * 10 | * Read more about it here: https://docs.uniswap.org/protocol/introduction 11 | */ 12 | 13 | // https://uniswap.org/docs/v2/smart-contracts/factory/ 14 | // https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Factory.solimplementation 15 | // UniswapV2Factory is deployed at 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f on the Ethereum mainnet, and the Ropsten, Rinkeby, Görli, and Kovan testnets 16 | 17 | // NOTE: Please do not deploy these contracts unless you knwo what you are doing 18 | // You will pay gas fees which youy might not want to 19 | 20 | interface UniswapV2Factory { 21 | // get the pair of tokens --tokenA and tokenB 22 | function getPair(address tokenA, address tokenB) 23 | external 24 | view 25 | returns (address pair); 26 | } 27 | 28 | interface UniswapV2Pair { 29 | function getReserves() 30 | external 31 | view 32 | returns ( 33 | uint112 reserve0, 34 | uint112 reserve1, 35 | uint32 blockTimestampLast 36 | ); 37 | } 38 | 39 | contract MyContract { 40 | address private factoryAddress = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f; 41 | 42 | // below are some etherium tokens running on the mainnet 43 | 44 | // gotten from ethercan.io --Dai Stablecoin's contract address 45 | address private dai = 0x6B175474E89094C44Da98b954EedeAC495271d0F; 46 | 47 | // etherscan --Wrapped Ether's contract address 48 | address private weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 49 | 50 | function getReservedTokens() external view returns (uint256, uint256) { 51 | address pair = UniswapV2Factory(factoryAddress).getPair(dai, weth); 52 | 53 | // getting the reserves 54 | (uint256 reserve0, uint256 reserve1, ) = UniswapV2Pair(pair) 55 | .getReserves(); 56 | return (reserve0, reserve1); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /037-libraries-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Libraries In Solidity 7 | * @notice Libraries are similar to Contracts but are mainly intended for reuse. 8 | * A Library contains functions which other contracts can call. 9 | * Solidity have certain restrictions on use of a Library. 10 | * 11 | * Following are the key characteristics of a Solidity Library. 12 | * 13 | * 1. Library functions can be called directly if they do not modify the state. 14 | * That means pure or view functions only can be called from outside the library. 15 | * 16 | * 2. Library can not be destroyed as it is assumed to be stateless. 17 | * 18 | * 3. A Library cannot have state variables. 19 | * 20 | * 4. A Library cannot inherit any element. 21 | * 22 | * 5. A Library cannot be inherited. 23 | */ 24 | 25 | library SearchLibrary { 26 | function indexOf(uint256[] storage self, uint256 value) 27 | public 28 | view 29 | returns (uint256) 30 | { 31 | for (uint256 i = 0; i < self.length; i++) { 32 | if (self[i] == value) return i; 33 | } 34 | 35 | // not practical 36 | // this is just so we do not get a warning first 37 | return 0; 38 | } 39 | } 40 | 41 | contract LibraryTest { 42 | uint256[] data; 43 | 44 | // instantiating our state 45 | constructor() { 46 | data.push(0); 47 | data.push(1); 48 | data.push(2); 49 | data.push(3); 50 | data.push(4); 51 | data.push(5); 52 | } 53 | 54 | // check if given value is present within the array 55 | function isValuePresent(uint256 val) external view returns (uint256) { 56 | uint256 value = val; 57 | uint256 index = SearchLibrary.indexOf(data, value); 58 | 59 | return index; 60 | } 61 | } 62 | 63 | // Exercise 64 | library SearchLibrary2 { 65 | function indexOf(uint256[] storage self, uint256 value) 66 | public 67 | view 68 | returns (uint256) 69 | { 70 | for (uint256 i = 0; i < self.length; i++) { 71 | if (self[i] == value) return i; 72 | } 73 | 74 | // not practical 75 | // this is just so we do not get a warning first 76 | return 0; 77 | } 78 | } 79 | 80 | contract LibraryTest2 { 81 | using SearchLibrary2 for uint256[]; 82 | uint256[] data; 83 | 84 | // instantiating our state 85 | constructor() { 86 | data.push(0); 87 | data.push(1); 88 | data.push(2); 89 | data.push(3); 90 | data.push(4); 91 | data.push(5); 92 | } 93 | 94 | // check if given value is present within the array 95 | function isValuePresent() external view returns (uint256) { 96 | uint256 index = data.indexOf(4); 97 | return index; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /038-library-assignment.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Library Assignment 7 | */ 8 | 9 | library Calculator { 10 | function performArithmeticOperation( 11 | uint256 value1, 12 | uint256 value2, 13 | string memory operator 14 | ) public pure returns (uint256) { 15 | // incase of subtraction 16 | if ( 17 | keccak256(abi.encodePacked(operator)) == 18 | keccak256(abi.encodePacked("-")) 19 | ) { 20 | return value1 - value2; 21 | } 22 | 23 | // incase of multiplication 24 | if ( 25 | keccak256(abi.encodePacked(operator)) == 26 | keccak256(abi.encodePacked("*")) 27 | ) { 28 | return value1 * value2; 29 | } 30 | 31 | // incase of division 32 | if ( 33 | (keccak256(abi.encodePacked(operator)) == 34 | keccak256(abi.encodePacked("/"))) 35 | ) { 36 | if (value2 == 0) return 0; 37 | return value1 / value2; 38 | } 39 | 40 | // default case: incase if addition 41 | return value1 + value2; 42 | } 43 | } 44 | 45 | contract CalculatorTest { 46 | // manipulate these values to affect the result 47 | uint256 value1 = 3; 48 | uint256 value2 = 4; 49 | 50 | // set an operator --available options (+, -, *, /) 51 | string operator = "*"; 52 | 53 | // contract owner 54 | address owner; 55 | 56 | // set the value of owner to the owner of the contract 57 | constructor() { 58 | owner = msg.sender; 59 | } 60 | 61 | // test execution of our calculator 62 | function CalculateResultOfExpression() 63 | public 64 | view 65 | returns (uint256, address) 66 | { 67 | uint256 result = Calculator.performArithmeticOperation( 68 | value1, 69 | value2, 70 | operator 71 | ); 72 | return (result, owner); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /039-assembly-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Assembly in Solidity 7 | */ 8 | 9 | contract LearnAssembly { 10 | function addToEVM() external { 11 | uint256 x; 12 | uint256 y; 13 | 14 | assembly { 15 | let z := add(x, y) 16 | 17 | // load the data for a specific slot 18 | let a := mload(0x40) 19 | 20 | // store something temporarily unto memory 21 | mstore(a, 4) 22 | 23 | // persistence storage 24 | sstore(a, 100) 25 | } 26 | } 27 | 28 | function addToEVM2() public view returns (bool success) { 29 | uint256 size; 30 | address addr; 31 | 32 | // checks whether an address contains any bytes of code or not 33 | assembly { 34 | size := extcodesize(addr) 35 | } 36 | 37 | if (size > 0) return true; 38 | return false; 39 | } 40 | 41 | // exercise 42 | function addToEVM3() external pure { 43 | bytes memory data = new bytes(10); 44 | 45 | // we can not convert this into a fixed size 46 | // this conversion will throw an error or will fail 47 | // bytes32 dataB32 = bytes32(data); 48 | 49 | bytes32 byteB32; 50 | 51 | assembly { 52 | byteB32 := mload(add(data, 32)) 53 | } 54 | 55 | // but if we care only about the first 32 bytes we can use assembly! 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /040-error-handling-in-solidity.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Error Handling in Solidity 7 | * @notice Solidity has functions that help in error handling 8 | * @dev A way of tackling this is that when an error happens, the state reverts back to its original state. 9 | Below are some of the important methods for error handling: 10 | 11 | assert(bool condition) − In case condition is not met, this method call causes an 12 | invalid opcode and any changes done to state got reverted. This method is to be used for internal errors. 13 | 14 | require(bool condition) − In case condition is not met, this method call reverts to original state. 15 | - This method is to be used for errors in inputs or external components. 16 | 17 | require(bool condition, string memory message) − In case condition is not met, this method call reverts to original state. 18 | - This method is to be used for errors in inputs or external components. It provides an option to provide a custom message. 19 | 20 | revert() − This method aborts the execution and revert any changes done to the state. 21 | 22 | revert(string memory reason) − This method aborts the execution and revert any changes done to the state. 23 | It provides an option to provide a custom message. 24 | */ 25 | 26 | contract LearnErrorHandling { 27 | bool public sunny = true; 28 | bool public umbrella = false; 29 | uint256 finalCalc = 0; 30 | 31 | // solar panel machine 32 | function solarCalc() public { 33 | // it should be sunny 34 | // require(sunny); 35 | require(sunny, "It is not sunny today!"); 36 | finalCalc += 3; 37 | } 38 | 39 | function internalTestUnits() public view { 40 | assert(finalCalc != 6); 41 | } 42 | 43 | // machine that controls the weather 44 | function weatherChange() public { 45 | sunny = false; 46 | } 47 | 48 | // get finalCalc value 49 | function getCalc() public view returns (uint256) { 50 | return finalCalc; 51 | } 52 | 53 | // determine if user should bring an unbrella 54 | // or not 55 | function bringUmbrella() public { 56 | if (!sunny) { 57 | umbrella = true; 58 | } else { 59 | revert("No need to bring an umbrella today!"); 60 | } 61 | } 62 | } 63 | 64 | contract Vendor { 65 | address seller; 66 | 67 | // modifier to let the msg.sender be the seller 68 | modifier onlySeller() { 69 | require(msg.sender == seller, "Only the seller can sell this!"); 70 | _; 71 | } 72 | 73 | // function to sell --only if you are the seller 74 | function sell(uint256 amount) public payable onlySeller { 75 | if (amount > msg.value) { 76 | // revert the contract if the funds in msg.sender is smaller 77 | // than the requested amount or price of the good. 78 | revert("There is not enought Ether provided!"); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /041-auction-app-project.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Building an Auction App 7 | * @notice Building a decentralised dApp with the Following 8 | * @dev Your mission is to write a decentralized auction DApplication which can at the minimum 9 | have the following functionality. 10 | 11 | Final Exercise: Create an Auction DApplication (The Decentralized Ebay) 12 | 13 | 1. You must create a contract called auction which contains state variables to keep track 14 | of the beneficiary (auctioneer), the highest bidder, the auction end time, and the highest bid. 15 | 16 | 2. There must be events set up which can emit whenever the highest bid changes both address 17 | and amount and an event for the auction ending emitting the winner address and amount. 18 | 19 | 3. The contract must be deployed set to the beneficiary address and how long the auction will 20 | run for. 21 | 22 | 4. There should be a bid function which includes at the minimum the following: 23 | 24 | a. revert the call if the bidding period is over. 25 | b. If the bid is not higher than the highest bid, send the money back. 26 | c. emit the highest bid has increased 27 | 28 | 5. Bearing in mind the withdrawal pattern, there should be a withdrawal function 29 | to return bids based on a library of keys and values. 30 | 31 | 6. There should be a function which ends the auction and sends the highest bid to 32 | the beneficiary! 33 | */ 34 | 35 | contract Auction { 36 | // state variables 37 | 38 | // address of the beneficiary 39 | address payable public beneficiary; 40 | 41 | // address of the highest bidder 42 | address public highestBidder; 43 | 44 | // to keep track of the bids in progress 45 | // until the end of the bidding process, 46 | // when the auction is over or when we 47 | // have a highest bidder 48 | mapping(address => uint256) bidsTracker; 49 | 50 | // keep tract of the auction end time 51 | uint256 public auctionEndTime; 52 | 53 | // highest bid 54 | uint256 public highestBid; 55 | 56 | // to be emitted when the bid price has increased 57 | event highestBidPriceIncreased(address bidder, uint256 amount); 58 | 59 | // to be emitted when the auction time has ended 60 | event auctionTimeEnded(address winner, uint256 amount); 61 | 62 | constructor(uint256 _biddingTime, address payable _beneficiaryAddress) { 63 | // instantiating the beneficiary address and auction end time 64 | // during contract deployment 65 | beneficiary = _beneficiaryAddress; 66 | auctionEndTime = block.timestamp + _biddingTime; 67 | } 68 | 69 | // the bid function 70 | function bid() public payable { 71 | // before a bid is made we have to verify that the 72 | // auction has not ended before 73 | if (block.timestamp > auctionEndTime) { 74 | // emit auction time ended event 75 | emit auctionTimeEnded(highestBidder, highestBid); 76 | 77 | // transfer the highest bid unto the beneficiary 78 | beneficiary.transfer(highestBid); 79 | 80 | revert("The auction has ended!"); 81 | } 82 | 83 | // make sure they have sufficient funds to bid 84 | if (msg.value <= highestBid) { 85 | revert("Sorry your bid is not high enough!"); 86 | } 87 | 88 | if (highestBid > 0) { 89 | bidsTracker[highestBidder] += highestBid; 90 | } 91 | 92 | // we have a new highest bidder 93 | highestBidder = msg.sender; 94 | highestBid = msg.value; 95 | 96 | // emit the event so we are notified 97 | // the highest bid price has increased 98 | // hence we have a new highest bidder 99 | emit highestBidPriceIncreased(msg.sender, msg.value); 100 | } 101 | 102 | // withdrawal function --following from the withdrawal pattern 103 | function withdraw() public payable returns (bool success) { 104 | uint256 amount = bidsTracker[msg.sender]; 105 | 106 | // make sure we get only one withdrawal 107 | if (amount > 0) { 108 | // we reset your bid amount to zero 109 | bidsTracker[msg.sender] = 0; 110 | } 111 | 112 | // this makes sure the address is payable 113 | // and can receive funds 114 | if (!payable(msg.sender).send(amount)) { 115 | bidsTracker[msg.sender] = amount; 116 | } 117 | 118 | return true; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Building Smart Contracts with Solidity 2 | ## Beginner to Advanced Concepts 3 | 4 | - Create an account on [remix.ethereum.org](http://remix.ethereum.org/). 5 | - Another possible way is to setup your PC for solidity development. 6 | - Run and test the smart contract code on the platform. 7 | - New to the remix platform? here is an introductory tutorial video to help you get started with the remix IDE [Link to Video](https://www.youtube.com/watch?v=eEQ41gD0iC4) 8 | 9 | Much ❤ From Cameroon 10 | - Please don't forget to give the repo a star. 11 | - And share 🤩🤩 if possible to help others get started with the solidity language. 12 | -------------------------------------------------------------------------------- /notes/blockchain.txt: -------------------------------------------------------------------------------- 1 | BLOCKCHAIN 2 | 3 | - A blockchain in the most basic form is an audible database(a backend for storing information 4 | or transactions). It can be regarded as a database in which data can only be added on. 5 | 6 | - It is a system in which a record of transactions made in bitcoin or another cryptocurrency are 7 | maintained across several computers that are linked in a peer-to-peer network. 8 | 9 | - Also a distributed database or ledger that is shared among the nodes of a computer network. 10 | 11 | KEY TAKEAWAYS 12 | 13 | - Blockchain is a type of shared database that differs from a typical database in the way that 14 | it stores information; blockchains store data in blocks that are then linked together via cryptography 15 | or using a crpyographic algorithm. 16 | 17 | - As new data comes in, it is entered into a fresh block. Once the block is filled with data, it is chained 18 | onto the previous block, which makes the data chained together in chronological order. 19 | 20 | - Different types of information can be stored on a blockchain, but the most common use so far has been as 21 | a ledger for transactions. 22 | 23 | - In Bitcoin’s case, blockchain is used in a decentralized way so that no single person or group has 24 | control —rather, all users collectively retain control. 25 | 26 | - Decentralized blockchains are immutable, which means that the data entered is irreversible. For Bitcoin, 27 | this means that transactions are permanently recorded and viewable to anyone. 28 | -------------------------------------------------------------------------------- /notes/dApps.txt: -------------------------------------------------------------------------------- 1 | dApps 2 | 3 | - A dApp is a decentralized application that runs on a blockchain 4 | 5 | - A decentralized application (dapp) is an application built on a decentralized 6 | network that combines a smart contract and a frontend user interface. 7 | 8 | - Because dApps are decentralized, they are free from the control and interference 9 | of a single authority. 10 | -------------------------------------------------------------------------------- /notes/ethereum_virtual_machine.txt: -------------------------------------------------------------------------------- 1 | Ethereum Virtual Machine 2 | - A runtime environment for smart contracts in ethereum. 3 | - It is not only sandboxed but isolated, has no access to network file systems 4 | - or any other processes. 5 | - Smart contracts has limited access to other smart contracts. 6 | 7 | The Ethereum protocol itself exists solely for the purpose of keeping the 8 | continuous, uninterrupted, and immutable operation of this special state 9 | machine; It's the environment in which all Ethereum accounts and smart 10 | contracts live. At any given block in the chain, Ethereum has one and only 11 | one 'canonical' state, and the EVM is what defines the rules for computing 12 | a new valid state from block to block. 13 | 14 | Two types of accounts exist for smart contracts 15 | 16 | External accounts 17 | - Belongs to investors or to the holders 18 | - The address of the contract is determined by a Public key 19 | 20 | Contracts accounts 21 | - Build and controlled by the developers 22 | - Here the Key determined when the contract is being created 23 | 24 | When transfering ethers from one account to another we make use of the public 25 | key, to add when we want to deal or bring up an account itself we work with the 26 | nonce value, which is derived from the creator address and the number of 27 | transactions sent from the address. 28 | 29 | --------------------------------------------------------------------------------