Solid learning notes
Solidity is a programming language created to write smart contracts. Solidity runs in Ethereum virtual machine (EVM).
data type
Value type
When a value type is used as a function parameter or in an assignment statement, the value is always copied
bool
The values are literal constant values true and false, and the default is false
int / uint
Signed and unsigned integer variables with different digits. Support (int8 to int256 / uint8 to uint256)
address
A 20 byte value (the size of the Ethereum address) can be converted to uint160 type.
Member variable
- Balance: the balance of the address
- transfer: send Ether (in wei) to an address. When the execution fails, the Ether transaction will be returned, the execution will be terminated and an exception will be thrown
- Send: a low-level version of transfer. If the execution fails, the contract currently executed will not be terminated, but send will return false
- Call: call the external contract, and the return value is true or false. Only when this method can be found and executed successfully, it will return true. If this function cannot be found or execution fails, it will return false. If the external contract has a callback function, the callback function will be executed when the called function cannot be found. The status of external contracts will be modified, and the status of local contracts will not be modified
- delegatecall: call the external contract, and the return value is true or false. Only when this method can be found and executed successfully, it will return true. If this function cannot be found or execution fails, it will return false. If the external contract has a callback function, the callback function will be executed when the called function cannot be found. The status variable in the external contract will not be modified, but the value of the local contract status variable will be modified
Starting with version 0.5.0, contracts do not derive from address types, but can still be explicitly converted to address types
Fixed length byte array
The fixed length byte array includes bytes1, bytes2, bytes3,..., bytes32. Byte is an alias for bytes1.
Member variable
- . length indicates the length of this byte array (read-only)
Enumeration type
Use the keyword enum to create an enumeration type
enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
reference type
Compared with value type, reference type has an additional attribute data location to indicate whether the data is stored in memory or storage. This is because the Gas overhead is quite large when copying these types of variables. In order to minimize the overhead, it is very necessary to execute the data location.
Depending on the context, the data has a default location most of the time, but it can also be modified by adding the keyword storage or memory after the type name
Default data location:
-
Function parameters not included: LDA
-
Status variable: storage
-
Function parameters (including return parameters): memory
-
All other local variables: storage
A separate copy is created by assigning two values between storage and memory, or by assigning storage to a state variable or (state variable to state variable)
When a state variable assigns a value to a local variable, it only passes a reference, and this reference always points to the state variable. Therefore, when the latter changes, the former will also change
Assigning a reference type from one memory store to another does not create a copy
string
String literal constants are strings ("foo" or 'bar') enclosed in double or single quotes. It can be implicitly converted to bytes1,..., bytes32
array
Arrays in solidity can be declared with specified length or dynamically resized. An array with element type T and fixed length k can be declared as T[k], while a dynamic array can be declared as t []
For the array storing storage, the element type can be arbitrary (that is, the element can also be array type, mapping type or structure). For an array of memory, the element type cannot be mapping. If it is used as a parameter of public function, it can only be ABI type.
Create memory array
You can use the new keyword to create a variable length array in memory. In contrast to storing storage arrays, you cannot modify member variables Length changes the size of the memory array
// Create an array of length 7, uint256 type uint256[] memory a = new uint256[](7); // This line will report an error because x is a variable length memory array and [1, 3, 4] is a fixed length array with a length of 3 uint[] x = [1, 3, 4];
A fixed length memory array cannot be assigned to a variable length memory array
Member variable
- Length: the length of the current array. Dynamic arrays can be stored in storag by changing member variables Length changes the size of the array
- Push: variable length storage arrays and bytes have push functions, which are used to append a new element to the end of the array and return the length of the new array
If used Length reduces the length of the array, and the excess elements will be cleared
You can delete an array using the delete keyword
// Delete the element in subscript 2 in the array delete arr[2]; // Delete all elements in the array delete arr
structural morphology
Structure is a new data type composed of a batch of data. Use the keyword struct to define the structure in Solidity
contract UserManage { // Define a structure named User, which contains two attributes id and name struct User { uint8 id; string name; } mapping (uint8 => User) Users; function add() public { // Instantiate a user and store it in memory User memory user1 = User(1, "Alice"); User memory user2 = User({id: 2, name: "Bobo"}); // Put the instantiated user in mapping Users[1] = user1; Users[2] = user2; } function getNameById(uint8 id) public view returns(string name){ User memory user = Users[id]; // You can use examples Property to access the properties of the structure return user.name; } }
A structure cannot contain itself, but it can be referenced by using the mapping type
Mapping
Mapprng in Solidity is similar to map type and stores data in K-V structure. However, in mapprng, the key is not stored, but the keccak256 hash value of the key is stored
Declaration method
mapping(_KeyType => _ValueType)
_ KeyType can be almost any type except mapping, variable length arrays, contracts, enumerations, and structs
_ ValueType can be any type, including mapping type
Iteration is not supported. value can only be obtained according to the determined key
Control and circulation
if, else, while, do, for, break, continue, return,?: Control loop statement
Non Boolean values in Solidity cannot be converted to Boolean types, so if (1) {...} The notation of is invalid in Solidity
visibility
external
It cannot be used in this contract, but only in external contracts
public
Both this contract and external contract can be called
internal
Used in this contract or sub contract
private
It can only be used in this contract
function
Declaration method
// Function identification function name parameter visibility state declaration return value (there can be multiple return values) function getNameById(uint8 id) public view returns(string name){ return "aaa"; }
Function modifier
The function modifier is a bit like a slot in Vue. The function is executed at the specified position of the modifier. However, before or after the function is executed, the statements in the function modifier will be executed. The modifier can be inherited and overridden by the derived contract
// Declaration statement modifier name modifier checkSender { require(msg.sender == owner); _; // The modified function will be executed here } // Use the modifier checkSender to modify the close function. After the close function is called, the require(msg.sender == owner) statement will be executed first function close() public checkSender { }
Function state declaration
View
When the function is declared as view, the contract status can be read and cannot be modified
The following statements are considered modification status:
- Modify state variables
- Generate event
- Create other contracts
- Make selfdestruct destroy the contract
- Send Ethernet by calling
- Call any function that is not marked as view or pure
- Use low-level call statements (call,)
- Use inline assemblies that contain specific opcodes
Pure
Contract status cannot be read or modified
In addition to the above modification state statements, the following statements are considered to be read from the state:
- Read state variable
- Visit this Balance or < address > balance
- Access any member in block, tx and MSG (except msg.sig and msg.data)
- Call any function that is not marked pure.
- Use an inline assembly that contains some opcodes
Fallback (callback function)
A function that has no name and cannot have parameters and return values
In the call of a contract, if no other function matches the given function name, the callback function will be executed
In addition, the callback function can also be used to accept Ethernet. When receiving Ethernet, the callback function must be marked payable
// Ethernet cannot be received because the fallback function does not have the payable modifier function() public { } // Can receive Ethernet function() public payable { }
function overloading
Functions with the same name can have multiple different parameters in the contract
event
Events allow us to easily use EVM's logging infrastructure
These parameters are stored in the transaction log when they are called
Logs and events cannot be accessed directly within the contract (even the contract that created the log cannot be accessed)
Events can be inherited in the contract
// Define an event event log( string id, string name, ); function test(string id, string name) public { // Call event log(id, name); }
contract
The Solidity contract is similar to the class in the object-oriented language. The contract contains constants, variables and functions.
When calling the function of another contract instance, an EVM function call will be executed. This operation will switch the execution context, so that the state variable of the previous contract cannot be accessed
statement
Solidity declares contracts using the keyword contract
// Declare the version of the contract pragma solidity ^0.4.24; // Declare A contract named A contract A { // Define a private variable data of uint type uint private data; // Define a private function f function f(uint a) private returns(uint b) { return a + 1; } }
Constructor
The constructor of a contract can be declared in two ways,
-
Use the same function declaration as the contract name
-
Declare using the keyword constructor
contract A { bytes32 name; // Method 1: use the same function as the contract name to declare the constructor // Declare the constructor of contract A function A(bytes32 _name) public { name = _name; } // Method 2: declare the constructor with the keyword constructor constructor(){ } }
inherit
Solidness uses the keyword is to inherit or implement other contracts. Solidness supports multiple inheritance
pragma solidity ^0.4.24; contract A { function owned() public { owner = msg.sender; } address owner; } // Use is to inherit contract A. Contract B can access all non private members of contract A, including internal functions and state variables, // But it cannot be accessed externally through this. contract B is A { function kill() public { if (msg.sender == owner) { selfdestruct(owner); } } }
multiple inheritance
// The following code compilation error occurs because 'C' requires' x 'to rewrite' A '(because the defined order is' A, X'), but 'A' itself requires rewriting 'x', which cannot solve this conflict pragma solidity ^0.4.24; contract X {} contract A is X {} contract C is A, X {}
You can remember by a simple rule: specify all base classes in the order from most base like to most derived
Abstract contract
Contract functions can lack implementation, and contracts containing unimplemented functions are abstract contracts
Abstract contract cannot be compiled
If the contract inherits from the abstract contract and does not implement all unimplemented functions by rewriting, it is also abstract in itself
pragma solidity ^0.4.24; contract A { function test() public returns (bytes32); } // Succession A contract contract B is A { // Implement the test method in A contract function test() public returns (bytes32) { return "hello"; } }
Interface
The interface cannot implement any function. In addition, the interface has the following limitations:
- Cannot inherit other contracts or interfaces
- Cannot define constructor
- Cannot define variable
- Structure cannot be defined
- Unable to define enumeration
Contracts can inherit interfaces using the is keyword