{"id":15065222,"url":"https://github.com/yuvrajchandra/cryptozombies-solidity-notes","last_synced_at":"2025-04-10T13:23:15.369Z","repository":{"id":201662610,"uuid":"433527722","full_name":"Yuvrajchandra/CryptoZombies-Solidity-Notes","owner":"Yuvrajchandra","description":"This repository contains codes and notes from CryptoZombies (Solidity Tutorial \u0026 Etherium Blockchain Programming Course)","archived":false,"fork":false,"pushed_at":"2021-12-29T06:45:00.000Z","size":245,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T12:09:09.081Z","etag":null,"topics":["blockchain","etherium","solidity","solidity-contracts","solidity-language"],"latest_commit_sha":null,"homepage":"","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Yuvrajchandra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-11-30T17:42:45.000Z","updated_at":"2024-12-24T13:27:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"8f8dcad6-ba02-48b0-a00b-b0ea1bd54b05","html_url":"https://github.com/Yuvrajchandra/CryptoZombies-Solidity-Notes","commit_stats":null,"previous_names":["yuvrajchandra/cryptozombies-solidity-notes"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yuvrajchandra%2FCryptoZombies-Solidity-Notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yuvrajchandra%2FCryptoZombies-Solidity-Notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yuvrajchandra%2FCryptoZombies-Solidity-Notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yuvrajchandra%2FCryptoZombies-Solidity-Notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Yuvrajchandra","download_url":"https://codeload.github.com/Yuvrajchandra/CryptoZombies-Solidity-Notes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248225664,"owners_count":21068078,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","etherium","solidity","solidity-contracts","solidity-language"],"created_at":"2024-09-25T00:35:19.147Z","updated_at":"2025-04-10T13:23:15.336Z","avatar_url":"https://github.com/Yuvrajchandra.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eCryptoZombies\u003c/h1\u003e\n\n![Untitled design (4)](https://user-images.githubusercontent.com/53931942/144187820-a4cc5096-9f88-4978-87bc-e6022279e4f7.png)\n\nThis repository contains codes and notes from CryptoZombies (Solidity Tutorial \u0026amp; Etherium Blockchain Programming Course)\n\nCryptoZombies is a free, open source, interactive code school that teaches you to build games on Ethereum. The course is designed for beginners to Solidity and starts off with the absolute basics.  \n  \nLink to the course: https://cryptozombies.io/en/course/\n\n# Table of Contents\n- [Contracts](#contracts)\n- [Version Pragma](#version-pragma)\n- [State Variables](#state-variables)\n- [Unsigned Integers: uint](#unsigned-integers--uint)\n- [Math Operations](#math-operations)\n- [Structs](#structs)\n- [Strings](#strings)\n- [Arrays](#arrays)\n- [Public Arrays](#public-arrays)\n- [Function Declarations](#function-declarations)\n  * [What is a reference type you ask?](#what-is-a-reference-type-you-ask-)\n- [Working With Structs and Arrays](#working-with-structs-and-arrays)\n  * [Creating New Structs](#creating-new-structs)\n  * [How to create an object of struct and how to push the object to the array](#how-to-create-an-object-of-struct-and-how-to-push-the-object-to-the-array)\n- [array.push() Method](#arraypush---method)\n- [Private / Public Functions](#private---public-functions)\n  * [How to declare a private function](#how-to-declare-a-private-function)\n- [Return Values in a function](#return-values-in-a-function)\n- [Function modifiers: view](#function-modifiers--view)\n- [Function modifiers: pure](#function-modifiers--pure)\n- [Keccak256](#keccak256)\n- [Typecasting](#typecasting)\n- [Events](#events)\n- [Address Data Type](#address-data-type)\n- [Mapping Data Type](#mapping-data-type)\n- [msg.sender](#msgsender)\n- [require](#require)\n- [Inheritance](#inheritance)\n- [Import](#import)\n- [Storage vs Memory (Data location)](#storage-vs-memory--data-location-)\n- [Internal and External](#internal-and-external)\n- [Interacting with other contracts](#interacting-with-other-contracts)\n- [Handling Multiple Return Values](#handling-multiple-return-values)\n- [If statements](#if-statements)\n- [Immutability of Contracts](#immutability-of-contracts)\n- [Ownable Contracts](#ownable-contracts)\n  * [Constructors](#constructors)\n  * [Function Modifiers](#function-modifiers)\n- [Function Modifiers](#function-modifiers-1)\n- [Gas — the fuel Ethereum DApps run on](#gas---the-fuel-ethereum-dapps-run-on)\n- [Why is gas necessary?](#why-is-gas-necessary-)\n- [Time units](#time-units)\n- [Passing structs as arguments](#passing-structs-as-arguments)\n- [Function modifiers with arguments](#function-modifiers-with-arguments)\n- [Saving Gas With 'View' Functions](#saving-gas-with--view--functions)\n- [Storage is Expensive](#storage-is-expensive)\n- [Declaring arrays in memory](#declaring-arrays-in-memory)\n- [For Loops](#for-loops)\n\n## Quick Notes from the course:\n\n### Contracts\nSolidity's code is encapsulated in contracts. A contract is the fundamental building block of Ethereum applications — all variables and functions belong to a contract, and this will be the starting point of all your projects.\nAn empty contract named HelloWorld would look like this:\n```\ncontract HelloWorld {\n\n}\n```\n### Version Pragma\nAll solidity source code should start with a \"version pragma\" — a declaration of the version of the Solidity compiler this code should use. This is to prevent issues with future compiler versions potentially introducing changes that would break your code.\n```\npragma solidity \u003e=0.5.0 \u003c0.6.0;\n````\n### State Variables\nState variables are permanently stored in contract storage. This means they're written to the Ethereum blockchain. Think of them like writing to a DB.\n```\ncontract Example {\n  // This will be stored permanently in the blockchain\n  uint myUnsignedInteger = 100;\n}\n```\n### Unsigned Integers: uint\nThe uint data type is an unsigned integer, meaning its value must be non-negative. There's also an int data type for signed integers.  \n\nIn Solidity, uint is actually an alias for uint256, a 256-bit unsigned integer. You can declare uints with less bits — uint8, uint16, uint32, etc.. But in general you want to simply use uint except in specific cases, which we'll talk about in later lessons.\n### Math Operations\nMath in Solidity is pretty straightforward. The following operations are the same as in most programming languages:\n  \nAddition: x + y  \nSubtraction: x - y,  \nMultiplication: x * y  \nDivision: x / y  \nModulus / remainder: x % y  \n### Structs\nStructs allow you to create more complicated data types that have multiple properties.\n```\nstruct Person {\n  uint age;\n  string name;\n}\n```\n### Strings\nStrings are used for arbitrary-length UTF-8 data. Ex:\n```\nstring greeting = \"Hello world!\"\n```\n### Arrays\nWhen you want a collection of something, you can use an array. There are two types of arrays in Solidity: fixed arrays and dynamic arrays:\n```\n// Array with a fixed length of 2 elements:\nuint[2] fixedArray;\n// another fixed Array, can contain 5 strings:\nstring[5] stringArray;\n// a dynamic Array - has no fixed size, can keep growing:\nuint[] dynamicArray;\n```\nYou can also create an array of structs.\n```\nPerson[] people; // dynamic Array, we can keep adding to it\n```\nDynamic array of structs like this can be useful for storing structured data in your contract, kind of like a database.\n### Public Arrays\nYou can declare an array as public, and Solidity will automatically create a getter method for it. The syntax looks like:\n```\nPerson[] public people;\n```\nOther contracts would then be able to read from, but not write to, this array. So this is a useful pattern for storing public data in your contract.\n### Function Declarations\nA function declaration in solidity looks like the following:\n```\nfunction eatHamburgers(string memory _name, uint _amount) public {\n\n}\n```\nThis is a function named eatHamburgers that takes 2 parameters: a string and a uint. Note that we're specifying the function visibility as **public**. We're also providing instructions about where the _name variable should be stored- in **memory**. This is required for all reference types such as arrays, structs, mappings, and strings.\n  \n#### What is a reference type you ask?\nWell, there are two ways in which you can pass an argument to a Solidity function:\n\n- **By value**, which means that the Solidity compiler creates a new copy of the parameter's value and passes it to your function. This allows your function to modify the value without worrying that the value of the initial parameter gets changed.\n- **By reference**, which means that your function is called with a... reference to the original variable. Thus, if your function changes the value of the variable it receives, the value of the original variable gets changed.\n\u003e It's convention (but not required) to start function parameter variable names with an underscore (_) in order to differentiate them from global variables.\n### Working With Structs and Arrays\n#### Creating New Structs\n```\nstruct Person {\n  uint age;\n  string name;\n}\n\nPerson[] public people;\n```\nHere we are creating a new struct(Person) and defining an array of struct(people).\n#### How to create an object of struct and how to push the object to the array\n```\n// create a New Person:\nPerson satoshi = Person(172, \"Satoshi\");\n\n// Add that person to the Array:\npeople.push(satoshi);\n```\nIn one line of code:\n```\npeople.push(Person(172, \"Satoshi\"));\n```\n### array.push() Method\n array.push() adds something to the end of the array, so the elements are in the order we added them.\n ```\n uint[] numbers;\nnumbers.push(5);\nnumbers.push(10);\nnumbers.push(15);\n// numbers is now equal to [5, 10, 15]\n```\n### Private / Public Functions\nIn Solidity, functions are public by default. This means anyone (or any other contract) can call your contract's function and execute its code.  \n\nObviously this isn't always desirable, and can make your contract vulnerable to attacks. Thus it's good practice to mark your functions as private by default, and then only make public the functions you want to expose to the world.\n\n#### How to declare a private function\n```\nuint[] numbers;\n\nfunction _addToArray(uint _number) private {\n  numbers.push(_number);\n}\n```\nThis means only other functions within our contract will be able to call this function and add to the numbers array.\n### Return Values in a function\nTo return a value from a function, the declaration looks like this:\n```\nstring greeting = \"What's up dog\";\n\nfunction sayHello() public returns (string memory) {\n  return greeting;\n}\n```\nIn Solidity, the function declaration contains the type of the return value (in this case string).\n### Function modifiers: view\nView functions ensure that they will not modify the state. The view functions are read-only function.\n```\nfunction sayHello() public view returns (string memory) {\n  return greeting;\n}\n```\n### Function modifiers: pure\nThe pure functions do not read or modify the state variables, which returns the values only using the parameters passed to the function or local variables present in it.\n```\nfunction _multiply(uint a, uint b) private pure returns (uint) {\n  return a * b;\n}\n```\n\u003e It may be hard to remember when to mark functions as pure/view. Luckily the Solidity compiler is good about issuing warnings to let you know when you should use one of these modifiers.\n### Keccak256\nEthereum has the hash function keccak256 built in, which is a version of SHA3. A hash function basically maps an input into a random 256-bit hexadecimal number. A slight change in the input will cause a large change in the hash. It's useful for many purposes in Ethereum.\n\n**keccak256** expects a single parameter of type **bytes**. This means that we have to \"pack\" any parameters before calling **keccak256**:\n```\n//6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5\nkeccak256(abi.encodePacked(\"aaaab\"));\n//b1f078126895a1424524de5321b339ab00408010b7cf0e6ed451514981e58aa9\nkeccak256(abi.encodePacked(\"aaaac\"));\n```\n\u003e Secure random-number generation in blockchain is a very difficult problem. Our method here is insecure.\n### Typecasting\nSometimes you need to convert between data types. Take the following example:\n```\nuint8 a = 5;\nuint b = 6;\n// throws an error because a * b returns a uint, not uint8:\nuint8 c = a * b;\n// we have to typecast b as a uint8 to make it work:\nuint8 c = a * uint8(b);\n```\nIn the above, **a * b** returns a **uint**, but we were trying to store it as a **uint8**, which could cause potential problems. By casting it as a **uint8**, it works and the compiler won't throw an error.\n### Events\nEvents are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen.  \nExample:\n```\n// declare the event\nevent IntegersAdded(uint x, uint y, uint result);\n\nfunction add(uint _x, uint _y) public returns (uint) {\n  uint result = _x + _y;\n  // fire an event to let the app know the function was called:\n  emit IntegersAdded(_x, _y, result);\n  return result;\n}\n```\nYour app front-end could then listen for the event. A javascript implementation would look something like:\n```\nYourContract.IntegersAdded(function(error, result) {\n  // do something with result\n})\n```\n### Address Data Type\nThe Ethereum blockchain is made up of accounts, which you can think of like bank accounts. An account has a balance of Ether (the currency used on the Ethereum blockchain), and you can send and receive Ether payments to other accounts, just like your bank account can wire transfer money to other bank accounts.\n\nEach account has an **address**, which you can think of like a bank account number. It's a unique identifier that points to that account, and it looks like this:\n```\n0x0cE446255506E92DF41614C46F1d6df9Cc969183\n```\n### Mapping Data Type\nDefining a mapping looks like this:\n```\n// For a financial app, storing a uint that holds the user's account balance:\nmapping (address =\u003e uint) public accountBalance;\n// Or could be used to store / lookup usernames based on userId\nmapping (uint =\u003e string) userIdToName;\n```\nA mapping is essentially a key-value store for storing and looking up data. In the first example, the key is an address and the value is a uint, and in the second example the key is a uint and the value a string.\n### msg.sender\nIn Solidity, there are certain global variables that are available to all functions. One of these is msg.sender, which refers to the address of the person (or smart contract) who called the current function.\n\u003e In Solidity, function execution always needs to start with an external caller. A contract will just sit on the blockchain doing nothing until someone calls one of its functions. So there will always be a msg.sender.\nHere's an example of using msg.sender and updating a mapping:\n```\nmapping (address =\u003e uint) favoriteNumber;\n\nfunction setMyNumber(uint _myNumber) public {\n  // Update our `favoriteNumber` mapping to store `_myNumber` under `msg.sender`\n  favoriteNumber[msg.sender] = _myNumber;\n  // ^ The syntax for storing data in a mapping is just like with arrays\n}\n\nfunction whatIsMyNumber() public view returns (uint) {\n  // Retrieve the value stored in the sender's address\n  // Will be `0` if the sender hasn't called `setMyNumber` yet\n  return favoriteNumber[msg.sender];\n}\n```\n### require\nThus require is quite useful for verifying certain conditions that must be true before running a function. The function will throw an error and stop executing if some condition is not true:\n```\nfunction sayHiToVitalik(string memory _name) public returns (string memory) {\n  // Compares if _name equals \"Vitalik\". Throws an error and exits if not true.\n  // (Side note: Solidity doesn't have native string comparison, so we\n  // compare their keccak256 hashes to see if the strings are equal)\n  require(keccak256(abi.encodePacked(_name)) == keccak256(abi.encodePacked(\"Vitalik\")));\n  // If it's true, proceed with the function:\n  return \"Hi!\";\n}\n```\nIf you call this function with sayHiToVitalik(\"Vitalik\"), it will return \"Hi!\". If you call it with any other input, it will throw an error and not execute.\n### Inheritance\n```\ncontract Doge {\n  function catchphrase() public returns (string memory) {\n    return \"So Wow CryptoDoge\";\n  }\n}\n\ncontract BabyDoge is Doge {\n  function anotherCatchphrase() public returns (string memory) {\n    return \"Such Moon BabyDoge\";\n  }\n}\n```\nBabyDoge inherits from Doge. That means if you compile and deploy BabyDoge, it will have access to both catchphrase() and anotherCatchphrase() (and any other public functions we may define on Doge).\n### Import\nWhen you have multiple files and you want to import one file into another, Solidity uses the **import** keyword:\n```\nimport \"./someothercontract.sol\";\n\ncontract newContract is SomeOtherContract {\n\n}\n```\n### Storage vs Memory (Data location)\nIn Solidity, there are two locations you can store variables — in storage and in memory.  \n\nStorage refers to variables stored permanently on the blockchain. Memory variables are temporary, and are erased between external function calls to your contract. Think of it like your computer's hard disk vs RAM.\n\nMost of the time you don't need to use these keywords because Solidity handles them by default. State variables (variables declared outside of functions) are by default storage and written permanently to the blockchain, while variables declared inside functions are memory and will disappear when the function call ends.  \n\nHowever, there are times when you do need to use these keywords, namely when dealing with structs and arrays within functions.\n### Internal and External\nIn addition to public and private, Solidity has two more types of visibility for functions: internal and external.  \n\n**internal** is the same as **private**, except that it's also accessible to contracts that inherit from this contract. \n\n**external** is similar to **public**, except that these functions can ONLY be called outside the contract — they can't be called by other functions inside that contract. \n### Interacting with other contracts\nFor our contract to talk to another contract on the blockchain that we don't own, first we need to define an **interface**.\n\nLet's look at a simple example. Say there was a contract on the blockchain that looked like this:\n```\ncontract LuckyNumber {\n  mapping(address =\u003e uint) numbers;\n\n  function setNum(uint _num) public {\n    numbers[msg.sender] = _num;\n  }\n\n  function getNum(address _myAddress) public view returns (uint) {\n    return numbers[_myAddress];\n  }\n}\n```\nThis would be a simple contract where anyone could store their lucky number, and it will be associated with their Ethereum address. Then anyone else could look up that person's lucky number using their address.\n\nNow let's say we had an external contract that wanted to read the data in this contract using the getNum function.\n\nFirst we'd have to define an interface of the LuckyNumber contract:\n```\ninterface NumberInterface {\n  function getNum(address _myAddress) public view returns (uint);\n}\n```\nNotice that this looks like defining a contract, with a few differences. For one, we're only declaring the functions we want to interact with — in this case getNum — and we don't mention any of the other functions or state variables.\n\nSecondly, we're not defining the function bodies. Instead of curly braces ({ and }), we're simply ending the function declaration with a semi-colon (;).\n\nSo it kind of looks like a contract skeleton. This is how the compiler knows it's an interface.\n\nBy including this interface in our dapp's code our contract knows what the other contract's functions look like, how to call them, and what sort of response to expect.\n\nAfter defining the interface, we can use it in a contract as follows:\n```\ncontract MyContract {\n  address NumberInterfaceAddress = 0xab38... \n  // ^ The address of the FavoriteNumber contract on Ethereum\n  NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);\n  // Now `numberContract` is pointing to the other contract\n\n  function someFunction() public {\n    // Now we can call `getNum` from that contract:\n    uint num = numberContract.getNum(msg.sender);\n    // ...and do something with `num` here\n  }\n}\n```\nIn this way, your contract can interact with any other contract on the Ethereum blockchain, as long they expose those functions as **public** or **external**.\n### Handling Multiple Return Values\n```\nfunction multipleReturns() internal returns(uint a, uint b, uint c) {\n  return (1, 2, 3);\n}\n\nfunction processMultipleReturns() external {\n  uint a;\n  uint b;\n  uint c;\n  // This is how you do multiple assignment:\n  (a, b, c) = multipleReturns();\n}\n\n// Or if we only cared about one of the values:\nfunction getLastReturnValue() external {\n  uint c;\n  // We can just leave the other fields blank:\n  (,,c) = multipleReturns();\n}\n```\n### If statements\nIf statements in Solidity look just like javascript:\n```\nfunction eatBLT(string memory sandwich) public {\n  // Remember with strings, we have to compare their keccak256 hashes\n  // to check equality\n  if (keccak256(abi.encodePacked(sandwich)) == keccak256(abi.encodePacked(\"BLT\"))) {\n    eat();\n  }\n}\n```\n### Immutability of Contracts\nAfter you deploy a contract to Ethereum, it’s immutable, which means that it can never be modified or updated again.\n\nThe initial code you deploy to a contract is there to stay, permanently, on the blockchain. This is one reason security is such a huge concern in Solidity. If there's a flaw in your contract code, there's no way for you to patch it later. You would have to tell your users to start using a different smart contract address that has the fix.\n\nBut this is also a feature of smart contracts. The code is law. If you read the code of a smart contract and verify it, you can be sure that every time you call a function it's going to do exactly what the code says it will do. No one can later change that function and give you unexpected results.\n### Ownable Contracts\nYou can make contracts Ownable — meaning they have an owner (you) who has special privileges.\n\nBelow is the Ownable contract taken from the OpenZeppelin Solidity library. OpenZeppelin is a library of secure and community-vetted smart contracts that you can use in your own DApps.\n```\n/**\n * @title Ownable\n * @dev The Ownable contract has an owner address, and provides basic authorization control\n * functions, this simplifies the implementation of \"user permissions\".\n */\ncontract Ownable {\n  address private _owner;\n\n  event OwnershipTransferred(\n    address indexed previousOwner,\n    address indexed newOwner\n  );\n\n  /**\n   * @dev The Ownable constructor sets the original `owner` of the contract to the sender\n   * account.\n   */\n  constructor() internal {\n    _owner = msg.sender;\n    emit OwnershipTransferred(address(0), _owner);\n  }\n\n  /**\n   * @return the address of the owner.\n   */\n  function owner() public view returns(address) {\n    return _owner;\n  }\n\n  /**\n   * @dev Throws if called by any account other than the owner.\n   */\n  modifier onlyOwner() {\n    require(isOwner());\n    _;\n  }\n\n  /**\n   * @return true if `msg.sender` is the owner of the contract.\n   */\n  function isOwner() public view returns(bool) {\n    return msg.sender == _owner;\n  }\n\n  /**\n   * @dev Allows the current owner to relinquish control of the contract.\n   * @notice Renouncing to ownership will leave the contract without an owner.\n   * It will not be possible to call the functions with the `onlyOwner`\n   * modifier anymore.\n   */\n  function renounceOwnership() public onlyOwner {\n    emit OwnershipTransferred(_owner, address(0));\n    _owner = address(0);\n  }\n\n  /**\n   * @dev Allows the current owner to transfer control of the contract to a newOwner.\n   * @param newOwner The address to transfer ownership to.\n   */\n  function transferOwnership(address newOwner) public onlyOwner {\n    _transferOwnership(newOwner);\n  }\n\n  /**\n   * @dev Transfers control of the contract to a newOwner.\n   * @param newOwner The address to transfer ownership to.\n   */\n  function _transferOwnership(address newOwner) internal {\n    require(newOwner != address(0));\n    emit OwnershipTransferred(_owner, newOwner);\n    _owner = newOwner;\n  }\n}\n```\n#### Constructors\nconstructor() is an optional special function that has the same name as the contract. It will get executed only one time, when the contract is first created.\n#### Function Modifiers\n modifier onlyOwner(). Modifiers are kind of half-functions that are used to modify other functions, usually to check some requirements prior to execution.\n### Function Modifiers\nA function modifier looks just like a function, but uses the keyword modifier instead of the keyword function. And it can't be called directly like a function can — instead we can attach the modifier's name at the end of a function definition to change that function's behavior.\n\nLet's take a closer look by examining onlyOwner:\n```\npragma solidity \u003e=0.5.0 \u003c0.6.0;\n\n/**\n * @title Ownable\n * @dev The Ownable contract has an owner address, and provides basic authorization control\n * functions, this simplifies the implementation of \"user permissions\".\n */\ncontract Ownable {\n  address private _owner;\n\n  event OwnershipTransferred(\n    address indexed previousOwner,\n    address indexed newOwner\n  );\n\n  /**\n   * @dev The Ownable constructor sets the original `owner` of the contract to the sender\n   * account.\n   */\n  constructor() internal {\n    _owner = msg.sender;\n    emit OwnershipTransferred(address(0), _owner);\n  }\n\n  /**\n   * @return the address of the owner.\n   */\n  function owner() public view returns(address) {\n    return _owner;\n  }\n\n  /**\n   * @dev Throws if called by any account other than the owner.\n   */\n  modifier onlyOwner() {\n    require(isOwner());\n    _;\n  }\n\n  /**\n   * @return true if `msg.sender` is the owner of the contract.\n   */\n  function isOwner() public view returns(bool) {\n    return msg.sender == _owner;\n  }\n\n  /**\n   * @dev Allows the current owner to relinquish control of the contract.\n   * @notice Renouncing to ownership will leave the contract without an owner.\n   * It will not be possible to call the functions with the `onlyOwner`\n   * modifier anymore.\n   */\n  function renounceOwnership() public onlyOwner {\n    emit OwnershipTransferred(_owner, address(0));\n    _owner = address(0);\n  }\n\n  /**\n   * @dev Allows the current owner to transfer control of the contract to a newOwner.\n   * @param newOwner The address to transfer ownership to.\n   */\n  function transferOwnership(address newOwner) public onlyOwner {\n    _transferOwnership(newOwner);\n  }\n\n  /**\n   * @dev Transfers control of the contract to a newOwner.\n   * @param newOwner The address to transfer ownership to.\n   */\n  function _transferOwnership(address newOwner) internal {\n    require(newOwner != address(0));\n    emit OwnershipTransferred(_owner, newOwner);\n    _owner = newOwner;\n  }\n}\n```\nNotice the onlyOwner modifier on the renounceOwnership function. When you call renounceOwnership, the code inside onlyOwner executes first. Then when it hits the _; statement in onlyOwner, it goes back and executes the code inside renounceOwnership.\n\nSo while there are other ways you can use modifiers, one of the most common use-cases is to add a quick require check before a function executes.\n\nIn the case of onlyOwner, adding this modifier to a function makes it so only the owner of the contract (you, if you deployed it) can call that function.\n### Gas — the fuel Ethereum DApps run on\nIn Solidity, your users have to pay every time they execute a function on your DApp using a currency called gas. Users buy gas with Ether (the currency on Ethereum), so your users have to spend ETH in order to execute functions on your DApp.\n\nHow much gas is required to execute a function depends on how complex that function's logic is. Each individual operation has a gas cost based roughly on how much computing resources will be required to perform that operation (e.g. writing to storage is much more expensive than adding two integers). The total gas cost of your function is the sum of the gas costs of all its individual operations.\n\nBecause running functions costs real money for your users, code optimization is much more important in Ethereum than in other programming languages. If your code is sloppy, your users are going to have to pay a premium to execute your functions — and this could add up to millions of dollars in unnecessary fees across thousands of users.\n### Why is gas necessary?\nEthereum is like a big, slow, but extremely secure computer. When you execute a function, every single node on the network needs to run that same function to verify its output — thousands of nodes verifying every function execution is what makes Ethereum decentralized, and its data immutable and censorship-resistant.\n\nThe creators of Ethereum wanted to make sure someone couldn't clog up the network with an infinite loop, or hog all the network resources with really intensive computations. So they made it so transactions aren't free, and users have to pay for computation time as well as storage.\n### Time units\nSolidity provides some native units for dealing with time.\n\nThe variable now will return the current unix timestamp of the latest block (the number of seconds that have passed since January 1st 1970). The unix time as I write this is 1515527488.\nSolidity also contains the time units seconds, minutes, hours, days, weeks and years. These will convert to a uint of the number of seconds in that length of time. So 1 minutes is 60, 1 hours is 3600 (60 seconds x 60 minutes), 1 days is 86400 (24 hours x 60 minutes x 60 seconds), etc.\n\nHere's an example of how these time units can be useful:\n```\nuint lastUpdated;\n\n// Set `lastUpdated` to `now`\nfunction updateTimestamp() public {\n  lastUpdated = now;\n}\n\n// Will return `true` if 5 minutes have passed since `updateTimestamp` was \n// called, `false` if 5 minutes have not passed\nfunction fiveMinutesHavePassed() public view returns (bool) {\n  return (now \u003e= (lastUpdated + 5 minutes));\n}\n```\n### Passing structs as arguments\nYou can pass a storage pointer to a struct as an argument to a private or internal function. This is useful, for example, for passing around our Zombie structs between functions.\n\nThe syntax looks like this:\n```\nfunction _doStuff(Zombie storage _zombie) internal {\n  // do stuff with _zombie\n}\n```\nThis way we can pass a reference to our zombie into a function instead of passing in a zombie ID and looking it up.\n### Function modifiers with arguments\nFunction modifiers can also take arguments. \nFor example:\n```\n// A mapping to store a user's age:\nmapping (uint =\u003e uint) public age;\n\n// Modifier that requires this user to be older than a certain age:\nmodifier olderThan(uint _age, uint _userId) {\n  require(age[_userId] \u003e= _age);\n  _;\n}\n\n// Must be older than 16 to drive a car (in the US, at least).\n// We can call the `olderThan` modifier with arguments like so:\nfunction driveCar(uint _userId) public olderThan(16, _userId) {\n  // Some function logic\n}\n```\nYou can see here that the olderThan modifier takes arguments just like a function does. And that the driveCar function passes its arguments to the modifier.\n### Saving Gas With 'View' Functions\nview functions don't cost any gas when they're called externally by a user.\n\nThis is because view functions don't actually change anything on the blockchain – they only read the data. So marking a function with view tells web3.js that it only needs to query your local Ethereum node to run the function, and it doesn't actually have to create a transaction on the blockchain (which would need to be run on every single node, and cost gas).\n\u003e Note: If a view function is called internally from another function in the same contract that is not a view function, it will still cost gas. This is because the other function creates a transaction on Ethereum, and will still need to be verified from every node. So view functions are only free when they're called externally.\n### Storage is Expensive\nOne of the more expensive operations in Solidity is using storage — particularly writes.\n\nThis is because every time you write or change a piece of data, it’s written permanently to the blockchain. Forever! Thousands of nodes across the world need to store that data on their hard drives, and this amount of data keeps growing over time as the blockchain grows. So there's a cost to doing that.\n\nIn order to keep costs down, you want to avoid writing data to storage except when absolutely necessary. Sometimes this involves seemingly inefficient programming logic — like rebuilding an array in memory every time a function is called instead of simply saving that array in a variable for quick lookups.\n\nIn most programming languages, looping over large data sets is expensive. But in Solidity, this is way cheaper than using storage if it's in an external view function, since view functions don't cost your users any gas. (And gas costs your users real money!).\n### Declaring arrays in memory\nYou can use the memory keyword with arrays to create a new array inside a function without needing to write anything to storage. The array will only exist until the end of the function call, and this is a lot cheaper gas-wise than updating an array in storage — free if it's a view function called externally.\n\nHere's how to declare an array in memory:\n```\nfunction getArray() external pure returns(uint[] memory) {\n  // Instantiate a new array in memory with a length of 3\n  uint[] memory values = new uint[](3);\n\n  // Put some values to it\n  values[0] = 1;\n  values[1] = 2;\n  values[2] = 3;\n\n  return values;\n}\n```\n\u003e Note: memory arrays must be created with a length argument (in this example, 3). They currently cannot be resized like storage arrays can with array.push(), although this may be changed in a future version of Solidity.\n### For Loops\nThe syntax of for loops in Solidity is similar to JavaScript.\n\nLet's look at an example where we want to make an array of even numbers:\n```\nfunction getEvens() pure external returns(uint[] memory) {\n  uint[] memory evens = new uint[](5);\n  // Keep track of the index in the new array:\n  uint counter = 0;\n  // Iterate 1 through 10 with a for loop:\n  for (uint i = 1; i \u003c= 10; i++) {\n    // If `i` is even...\n    if (i % 2 == 0) {\n      // Add it to our array\n      evens[counter] = i;\n      // Increment counter to the next empty index in `evens`:\n      counter++;\n    }\n  }\n  return evens;\n}\n```\nThis function will return an array with the contents [2, 4, 6, 8, 10].\n### Visibility Modifiers\nVisibility modifiers controls when and where the function can be called from.  \n\n**Private:** Private means it's only callable from other functions inside the contract.  \n**Internal:** Internal is like private but can also be called by contracts that inherit from this one.  \n**External:** External can only be called outside the contract.  \n**Public:** Public can be called anywhere, both internally and externally.  \n### State Modifiers\nState Modifiers tells us how the function interacts with the BlockChain. \n\n**View:** View tells us that by running the function, no data will be saved/changed. They are read-only functions.  \n**Pure:** Pure tells us that not only does the function not save any data to the blockchain, but it also doesn't read any data from the blockchain.  \nBoth of these don't cost any gas to call if they're called externally from outside the contract (but they do cost gas if called internally by another function).\n### Custom Modifiers\nFor these we can define custom logic to determine how they affect a function. Ex- onlyOwner.  \n### The payable Modifier\npayable functions are part of what makes Solidity and Ethereum so cool — they are a special type of function that can receive Ether.  \n\nIn Ethereum, because both the money (Ether), the data (transaction payload), and the contract code itself all live on Ethereum, it's possible for you to call a function and pay money to the contract at the same time.\n```\ncontract OnlineStore {\n  function buySomething() external payable {\n    // Check to make sure 0.001 ether was sent to the function call:\n    require(msg.value == 0.001 ether);\n    // If so, some logic to transfer the digital item to the caller of the function:\n    transferThing(msg.sender);\n  }\n}\n```\nHere, **msg.value** is a way to see how much Ether was sent to the contract, and **ether** is a built-in unit.\n\nWhat happens here is that someone would call the function from web3.js (from the DApp's JavaScript front-end) as follows:\n```\n// Assuming `OnlineStore` points to your contract on Ethereum:\nOnlineStore.buySomething({from: web3.eth.defaultAccount, value: web3.utils.toWei(0.001)})\n```\nNotice the value field, where the javascript function call specifies how much ether to send (0.001). If you think of the transaction like an envelope, and the parameters you send to the function call are the contents of the letter you put inside, then adding a value is like putting cash inside the envelope — the letter and the money get delivered together to the recipient.\n\u003e If a function is not marked payable and you try to send Ether to it as above, the function will reject your transaction.\nAfter you send Ether to a contract, it gets stored in the contract's Ethereum account, and it will be trapped there — unless you add a function to withdraw the Ether from the contract.\n### Withdraw\nYou can write a function to withdraw Ether from the contract as follows:\n```\ncontract GetPaid is Ownable {\n  function withdraw() external onlyOwner {\n    address payable _owner = address(uint160(owner()));\n    _owner.transfer(address(this).balance);\n  }\n}\n```\nIt is important to note that you cannot transfer Ether to an address unless that address is of type address payable. But the _owner variable is of type uint160, meaning that we must explicitly cast it to address payable.\n\nOnce you cast the address from uint160 to address payable, you can transfer Ether to that address using the transfer function, and address(this).balance will return the total balance stored on the contract. So if 100 users had paid 1 Ether to our contract, address(this).balance would equal 100 Ether.\n\nYou can use transfer to send funds to any Ethereum address. For example, you could have a function that transfers Ether back to the msg.sender if they overpaid for an item:\n```\nuint itemFee = 0.001 ether;\nmsg.sender.transfer(msg.value - itemFee);\n```\n### So how do we generate random numbers safely in Ethereum?\nYou can read this [StackOverflow thread](https://ethereum.stackexchange.com/questions/191/how-can-i-securely-generate-a-random-number-in-my-smart-contract) for some ideas. One idea would be to use an oracle to access a random number function from outside of the Ethereum blockchain.\n### Tokens on Ethereum\nA token on Ethereum is basically just a smart contract that follows some common rules — namely it implements a standard set of functions that all other token contracts share, such as transferFrom(address _from, address _to, uint256 _tokenId) and balanceOf(address _owner).  \n\nInternally the smart contract usually has a mapping, mapping(address =\u003e uint256) balances, that keeps track of how much balance each address has.\n\nSo basically a token is just a contract that keeps track of who owns how much of that token, and some functions so those users can transfer their tokens to other addresses.\n#### Why does it matter?\nSince all ERC20 tokens share the same set of functions with the same names, they can all be interacted with in the same ways.\n\nThis means if you build an application that is capable of interacting with one ERC20 token, it's also capable of interacting with any ERC20 token. That way more tokens can easily be added to your app in the future without needing to be custom coded. You could simply plug in the new token contract address, and boom, your app has another token it can use.\n\nOne example of this would be an exchange. When an exchange adds a new ERC20 token, really it just needs to add another smart contract it talks to. Users can tell that contract to send tokens to the exchange's wallet address, and the exchange can tell the contract to send the tokens back out to users when they request a withdraw.\n\nThe exchange only needs to implement this transfer logic once, then when it wants to add a new ERC20 token, it's simply a matter of adding the new contract address to its database.\n### ERC721 tokens\nERC721 tokens are not interchangeable since each one is assumed to be unique, and are not divisible. You can only trade them in whole units, and each one has a unique ID. \n### ERC721 Standard\n```\ncontract ERC721 {\n  event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);\n  event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);\n\n  function balanceOf(address _owner) external view returns (uint256);\n  function ownerOf(uint256 _tokenId) external view returns (address);\n  function transferFrom(address _from, address _to, uint256 _tokenId) external payable;\n  function approve(address _approved, uint256 _tokenId) external payable;\n}\n```\n### Multiple Inheritance\nIn Solidity, your contract can inherit from multiple contracts as follows:\n```\ncontract SatoshiNakamoto is NickSzabo, HalFinney {\n  // Omg, the secrets of the universe revealed!\n}\n```\nAs you can see, when using multiple inheritance, you just separate the multiple contracts you're inheriting from with a comma, ,. \n### ERC721: Transfer Logic\nThe ERC721 spec has 2 different ways to transfer tokens:\n```\nfunction transferFrom(address _from, address _to, uint256 _tokenId) external payable;\n```\nand\n```\nfunction approve(address _approved, uint256 _tokenId) external payable;\n\nfunction transferFrom(address _from, address _to, uint256 _tokenId) external payable;\n```\n1. The first way is the token's owner calls transferFrom with his address as the _from parameter, the address he wants to transfer to as the _to parameter, and the _tokenId of the token he wants to transfer.\n\n2. The second way is the token's owner first calls approve with the address he wants to transfer to, and the _tokenID . The contract then stores who is approved to take a token, usually in a mapping (uint256 =\u003e address). Then, when the owner or the approved address calls transferFrom, the contract checks if that msg.sender is the owner or is approved by the owner to take the token, and if so it transfers the token to him.  \n\nNotice that both methods contain the same transfer logic. In one case the sender of the token calls the transferFrom function; in the other the owner or the approved receiver of the token calls it.\n### Contract security enhancements: Overflows and Underflows\nWhat's an **overflow**?\n\nLet's say we have a uint8, which can only have 8 bits. That means the largest number we can store is binary 11111111 (or in decimal, 2^8 - 1 = 255).\n\nTake a look at the following code. What is number equal to at the end?\n```\nuint8 number = 255;\nnumber++;\n```\nIn this case, we've caused it to **overflow** — so number is counterintuitively now equal to 0 even though we increased it. (If you add 1 to binary 11111111, it resets back to 00000000, like a clock going from 23:59 to 00:00).\n\nAn **underflow** is similar, where if you subtract 1 from a uint8 that equals 0, it will now equal 255 (because uints are unsigned, and cannot be negative).\n\nWhile we're not using uint8 here, and it seems unlikely that a uint256 will overflow when incrementing by 1 each time (2^256 is a really big number), it's still good to put protections in our contract so that our DApp never has unexpected behavior in the future.\n#### Using SafeMath\nTo prevent overflow and underflow, OpenZeppelin has created a library called SafeMath that prevents these issues by default. One of the things it is useful for is to attach functions to native data types.\n\nFor example, with the SafeMath library, we'll use the syntax using SafeMath for uint256. The SafeMath library has 4 functions — add, sub, mul, and div. And now we can access these functions from uint256 as follows:\n```\nusing SafeMath for uint256;\n\nuint256 a = 5;\nuint256 b = a.add(3); // 5 + 3 = 8\nuint256 c = a.mul(2); // 5 * 2 = 10\n```\nSafeMath's add, sub, mul, and div are functions that do the basic 4 math operations, but throw an error if an overflow or underflow occurs.\n### Library\nLibraries are similar to Contracts but are mainly intended for reuse. A Library contains functions which other contracts can call. \n### assert vs require\nassert is similar to require, where it will throw an error if false. The difference between assert and require is that require will refund the user the rest of their gas when a function fails, whereas assert will not. So most of the time you want to use require in your code; assert is typically used when something has gone horribly wrong with the code (like a uint overflow).\n### Comments \nCommenting in Solidity is just like JavaScript. \n#### Single-Line Comments\n```\n// This is a single-line comment. It's kind of like a note to self (or to others)\n```\n#### Multi-Line Comments\n```\ncontract CryptoZombies {\n  /* This is a multi-lined comment. I'd like to thank all of you\n    who have taken your time to try this programming course.\n    I know it's free to all of you, and it will stay free\n    forever, but we still put our heart and soul into making\n    this as good as it can be.\n\n    Know that this is still the beginning of Blockchain development.\n    We've come very far but there are so many ways to make this\n    community better. If we made a mistake somewhere, you can\n    help us out and open a pull request here:\n    https://github.com/loomnetwork/cryptozombie-lessons\n\n    Or if you have some ideas, comments, or just want to say\n    hi - drop by our Telegram community at https://t.me/loomnetworkdev\n  */\n}\n```\n### natspec standard\n```\n/// @title A contract for basic math operations\n/// @author H4XF13LD MORRIS 💯💯😎💯💯\n/// @notice For now, this contract just adds a multiply function\ncontract Math {\n  /// @notice Multiplies 2 numbers together\n  /// @param x the first uint.\n  /// @param y the second uint.\n  /// @return z the product of (x * y)\n  /// @dev This function does not currently check for overflows\n  function multiply(uint x, uint y) returns (uint z) {\n    // This is just a normal comment, and won't get picked up by natspec\n    z = x * y;\n  }\n}\n```\n@title and @author are straightforward.\n\n@notice explains to a user what the contract / function does. \n\n@dev is for explaining extra details to developers.\n\n@param and @return are for describing what each parameter and return value of a function are for.\n\nNote that you don't always have to use all of these tags for every function — all tags are optional. But at the very least, leave a @dev note explaining what each function does.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuvrajchandra%2Fcryptozombies-solidity-notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuvrajchandra%2Fcryptozombies-solidity-notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuvrajchandra%2Fcryptozombies-solidity-notes/lists"}