Lesson 3 Recap - cogeorg/teaching GitHub Wiki

The third lesson covers advanced Solidity concepts like contract ownership, gas costs, code optimization, and security.

  • Chapter 1: emphasizes the important point that Solidity contracts are immutable

    • you should not hard-code anything that may change in the future (like the address of another contract)
    • use a setter function to maintain the flexibility to change variables
  • Chapter 2 + 3: introduce the concept of ownership and owner rights

    • you don't want all public functions to be callable by just anybody, some are very dangerous and should only be called by the owner
    • this is comparable to admin rights
    • the chapter introduces OpenZeppelin's Ownable contract, which is open source and contains the modifier onlyOwner as well as a function to transfer the ownership, transferOwnership, among others
    • to make your contracts more secure, inherit from the Ownable contract and apply the onlyOwner modifier to delicate functions
  • Chapter 4: introduces the concept of gas and how to save gas

    • executing a function on the EVM costs gas to prevent functions to run forever and clog the system
    • it saves gas to use the smallest possible data type in structs
    • it saves gas to group the same data types inside structs
    // more expensive
    struct Normal {
        uint a;
        uint b;
        uint c;
    }
    
    // less expensive
    struct MiniMe {
        uint32 a;
        uint32 c;
        unit b;
    }
  • Chapter 5: introduces Time Units

    • time units are native to Solidity
    • it contains
      • seconds
      • minutes
      • hours
      • days
      • weeks
      • months
      • years
      • now
    • it converts all units to seconds, so 1 hours equals 3600 seconds and now is the unix time in seconds since 1970-01-01
    • all return a uint256
  • Chapter 6: explains how to pass a struct as argument

    • it is possible to pass a storage pointer to a struct as an argument to functions that are private or internal
    • therefore, you can modify the actual struct and don't modify a copy of it
    function _someFunction(struct storage _someStruct) internal {
        _someStruct.param1 = 8;
        //this changes param1 in _someStruct permanently and not only inside this function
    }
  • Chapter 7: emphasizes security

    • make sure that only those contracts are marked as public that actually need to be public and for which it is save
    • otherwise, set them to internal or private
  • Chapter 8 + 9: modifiers with arguments

    • function modifiers can accept arguments
    mapping(uint => uint) marks;
    
    modifier withDistinction(uint _distinction, unit _studentId) {
        require(marks[_studentId] >= _distinction);
        _;
    }
    
    function graduateWithDistinction(uint _studentId) public withDistinction(90, _studentId) {
        // some stuff
    }
  • Chapter 10: saving gas with view functions

    • external view functions are for free because they don't write to storage (this also holds for external pure)
    • note that view functions that are called internally by other functions do cost gas
  • Chapter 11 + 12: saving gas with arrays in memory and for loops

    • in an external view function, building an array in memory using a for loop is cheaper (in fact, it is for free) than storing the array to a variable
    • this is very different compared to other programming languages, where looping is usually very expensive
    mapping(uint => uint) marks;
    
    function getMarksForSubset(uint[] _studentIds) external view returns(uint[]){
        uint[] memory someMarks = new uint[](_studentIds.length)
        for (uint i = 0; i < _studentIds.length; i++) {
            someMarks.push(marks[_studentIds[i]]);
        }
        return someMarks;
    }
    • for-loops in Solidity are very similar to JavaScript for-loops
    for (<type><iterator>; <condition>; <iterator>++) {
        // do something
    }
⚠️ **GitHub.com Fallback** ⚠️