IntroductionRemixSoliditySetting Up Your First ContractGetting StartedVersioningTake notes in your code!What is a software licenseSPDX LicenseCompilingContract DeclarationBasic Solidity: TypesTypes & Declaring VariablesDefault InitializationsBasic Solidity: FunctionsFunctionsDeploying a ContractCalling a public state-changing FunctionVisibilityGas III | An exampleScopeView & Pure FunctionsBasic Solidity: Arrays & StructsStructsArraysDynamic Array & Fixed-Sized ArrayBasic Solidity: Compiler Errors and WarningsBasic Solidity: Memory, Storage, Calldata (Intro)CalldataMemoryStorageMappingsThe EVM(Ethereum Virtual Machine)
Introduction
Remix
Solidity smart contract IDE
Solidity
Solidity is the most dominant smart contract coding language out there.
Setting Up Your First Contract
Getting Started
- Go to Remix
- Paste the code from
SimpleStorage.sol
into a new file in Remix
// SPDX-License-Identifier: MIT pragma solidity 0.8.8; // pragma solidity ^0.8.0; // pragma solidity >=0.8.0 <0.9.0; contract SimpleStorage { uint256 favoriteNumber; struct People { uint256 favoriteNumber; string name; } // uint256[] public anArray; People[] public people; mapping(string => uint256) public nameToFavoriteNumber; function store(uint256 _favoriteNumber) public { favoriteNumber = _favoriteNumber; } function retrieve() public view returns (uint256){ return favoriteNumber; } function addPerson(string memory _name, uint256 _favoriteNumber) public { people.push(People(_favoriteNumber, _name)); nameToFavoriteNumber[_name] = _favoriteNumber; } }
- Hit
Compile
- Hit
Deploy
Versioning
use only 0.8.7
pragma solidity 0.8.7;// 0.8.7 is considered more staple
use 0.8.7 and above, such as 0.8.9、0.8.10
pragma solidity ^0.8.7;
use solidity version between a specific range
pragma solidity >=0.8.7 <0.9.0
Take notes in your code!
// I'm a comment!
What is a software license
// SPDX-License-Identifier: MIT
SPDX License
Compiling
Contract Declaration
contract SimpleStorage { }
Basic Solidity: Types
Types & Declaring Variables
bool hasFavoriteNumber = true; uint256 favoriteNumber = 5; int256 favoriteInt = -5; bytes32 favoriteBytes = "cat"; string favoriteNumberInText = "Five"; address myAddress = 0x5194db2e6E9f8E8955D37b34282a57a6FEDC218a;
Default Initializations
// This gets initialized to zero. uint256 favoriteNumber;
Basic Solidity: Functions
Functions
function store(uint256 _favoriteNumber) public { favoriteNumber = _favoriteNumber; }
Deploying a Contract
Calling a public state-changing Function
Visibility
State Variable Visibility
public
Public state variables differ from internal ones only in that the compiler automatically generates getter functions for them, which allows other contracts to read their values. When used within the same contract, the external access (e.g.
this.x
) invokes the getter while internal access (e.g. x
) gets the variable value directly from storage. Setter functions are not generated so other contracts cannot directly modify their values.internal
Internal state variables can only be accessed from within the contract they are defined in and in derived contracts. They cannot be accessed externally. This is the default visibility level for state variables.
private
Private state variables are like internal ones but they are not visible in derived contracts.
Function Visibility
external
External functions are part of the contract interface, which means they can be called from other contracts and via transactions. An external function cannot be called internally (i.e.
f()
does not work, but this.f()
works).public
Public functions are part of the contract interface and can be either called internally or via message calls.
internal
Internal functions can only be accessed from within the current contract or contracts deriving from it. They cannot be accessed externally. Since they are not exposed to the outside through the contract’s ABI, they can take parameters of internal types like mappings or storage references.
private
Private functions are like internal ones but they are not visible in derived contracts.
Gas III | An example
Scope
View & Pure Functions
view
& pure
View and pure functions disallow modification of state.
Pure functions additionally disallow you to read from blockchain state.
function retrieve() public view returns(uint256){ return favoriteNumber; } function add() public pure returns(uint256){ return 1 + 1; }
View and pure functions, we called alone, don’t spend gas. If a gas calling function calls a view or pure function, only then will it cost gas.
Basic Solidity: Arrays & Structs
Structs
struct People { uint256 favoriteNumber; string name; } People public person = People({favoriteNumber: 2, name: "cyfuer"});
- Intro to Storage
Arrays
a data structure that holds a list of other types.
People[] public people; uint256[] public favoriteNumberList;
Dynamic Array & Fixed-Sized Array
// Dynamic Array People[] public mans; mans.push(People(24, "Alex")); // Fixed-Sized Array People[3] public womens; // max is 3
Basic Solidity: Compiler Errors and Warnings
- Yellow: Warnings are Ok
- Red: Errors are not Ok
Basic Solidity: Memory, Storage, Calldata (Intro)
6 Places you can store and access data
- calldata
- memory
- storage
- code
- logs
- stack
Calldata
Calldata and memory mean that the variable is only going to exist temporarily.
Calldata is temporary variables that cann’t be modified.
function addPerson(string calldata name, uint256 _favoriteNumber) public { _name = "cat" ;// if we compile we run into an error people. push(People(_favoriteNumber, _name)); }
Memory
memory is temporary variables that can be modified.
// string is array of bytes, so it can be specified by memory or calldata // but the parameter _favoriteNumber cann't function addPerson(string memory name, uint256 _favoriteNumber) public { _name = "cat" ; people. push(People(_favoriteNumber, _name)); }
Data location(calldata、memory) can only be specified for array, struct or mapping types
Storage
Storage variables exist even outside of just the function executing.
storage variables are permanent and stay there forever.
function parameters can’t be storage variables because they’re only going to exist for the duration of the funciont.
Mappings
A mapping is a data structure where a key
is "mapped" to a single value.
mapping(string => uint256) public nameToFavoriteNumber; nameToFavoriteNumber["cyfuer"] = 10000;