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 modifieronlyOwner
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 theonlyOwner
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
equals3600 seconds
andnow
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
orinternal
- 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 }
- it is possible to pass a storage pointer to a struct as an argument to functions that are
-
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
orprivate
- make sure that only those contracts are marked as
-
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 forexternal 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 }
- in an