Solidity is a common language for developing smart contracts. Here are some basics about Solidity.
Table of contents
source code structure
A source file can contain any number of contract definitions, import source file instructions, version identification instructions, structures, enumerations, and function definitions.
SPDX copyright license mark (The Software Package Data Exchange): This line is to indicate what kind of open standard the smart contract you write adopts. This standard stipulates whether others have the right to commercial development, learning and use, etc.
Common open sources:
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: GPL-3.0
Private or Unlicensed:
// SPDX-License-Identifier: UNLICENSED
Version ID
pragma solidity ^0.7.0;
orpragma solidity >=0.7.0 <0.9.0;
ABI Coder Pragma
Before Solidity 0.7.4:pragma experimental ABIEncoderV2
After Solidity 0.7.4:pragma abicoder v2
note
natspec comment
single line://
multi-line:/**/
Import other sources
Import other source files, use import
代码:
1,import "filename"
2, import * as name from ""
3.import "" as name;
4,import {symbol1 as a,symbol2} from "";
contract structure
Each contract can contain declarations of state variables, functions, function modifiers, events, logs, structure types, and enumeration types. Additionally, contracts can inherit from other contracts.
State variables
A state variable is a variable whose value is permanently stored in the contract storage
variable type
(Development note: 1. In some versions, Chinese character strings cannot be directly used for string assignment, and unicode is added to modify the value type;
2. Out-of-bounds problems, SafeMath library for data operations
)
function
A function is an executable unit of code. Functions are usually defined inside a contract, but they can also be defined outside a contract.
function modifier
Function modifiers can be used to modify the semantics of a function in a declarative way (see Function modifiers in the Contracts section ).
common modifiers
1. public and private: public means that both public and private can be used, and private means that it can only be used by this contract
2. Internal and external: internal is similar to private, but internal modified can be used by inherited contracts
3.external is similar to public, but cannot be used by this contract
4.pure and view: view means that this function will not modify or save anything, pure means that it is only related to output and input, not only does not write data in the blockchain, but also does not use the data in it, only the input data
5.payable modifier (payable):
- The payable function is a special function that can accept ether,
- Any function, as long as it is modified as payable, can assign a value to the value field when calling this method, and then transfer the value of value to the contract.
- If this function does not specify payable, but assigns a value, then this call will report an error.
Modifier modifier
The behavior of functions can be easily changed using modifiers. For example, they can automatically check a certain condition before executing a function. A modifier is an inheritable property of a contract and may be overridden by derived contracts.
The call function modifier is often used in a position such as public and private after the function to determine whether to execute the function
Function modifiers usually end with an underscore
如:modifier olderThan(uint _age,uint _userId){
require(age[_userID]>= _age);
_; //Ending with _; indicates that the function returns normally and continues to execute the previous function
}
event
Events are a convenient interface to EVM logging facilities.
log
Define descriptive names and data for failure conditions.
structure type
Structs are custom defined types that can group multiple variables
enumerated type
Enums can be used to create custom types with a limited set of "constant values"
global variable
abi.encode(...) returns (bytes)
: ABI-encodes the given parameter.abi.encodePacked(...) returns (bytes)
: Performes packed encoding of the given argumentsabi.encodeWithSelector(bytes4 selector, ...) returns (bytes)
:: ABI-encodes the given arguments - starting with the given four-byte selector from the second presetabi.encodeWithSignature(string signature, ...) returns (bytes)
: equivalent toabi.encodeWithSelector(bytes4(keccak256(signature), ...)
block.blockhash(uint blockNumber) returns (bytes32)
: The hash value of a given block, only the hash value of the last 256 blocks - please use after 0.4.22blockhash(uint blockNumber)
.block.coinbase
(address
): the address of the miner of the current blockblock.difficulty
(uint
): The difficulty of the current blockblock.gaslimit
(uint
): the gaslimit of the current blockblock.number
(uint
): the number of current blocksblock.timestamp
(uint
): the timestamp of the current blockgasleft() returns (uint256)
: remaining gasmsg.data
(bytes
): complete calldatamsg.gas
(uint
): remaining gas - please use after 0.4.21gasleft()
msg.sender
(address
): sender of the message (current call)msg.value
(uint
): the number of wei sent with the messagenow
(uint
): the timestamp of the current block (block.timestamp
alias for)tx.gasprice
(uint
): the gas price of the transactiontx.origin
(address
): The sender of the transaction (full call chain)assert(bool condition)
: abort execution and revert state changes if condition isfalse
(for internal errors)require(bool condition)
: abort execution and revert state changes if condition isfalse
(for input errors or external component errors)require(bool condition, string message)
: abort execution and revert state changes if condition isfalse
(for input errors or errors of external components). And provide error information.revert()
: Abort execution and revert state changesrevert(string message)
: Abort execution and revert state changes, providing an explanation stringblockhash(uint blockNumber) returns (bytes32)
: : The hash value of a given block, only the hash value of the last 256 blockskeccak256(...) returns (bytes32)
: Calculate the Ethereum-SHA3 hash value of the (compactly arranged) parameterssha3(...) returns (bytes32)
: an alias tokeccak256
sha256(...) returns (bytes32)
: Computes the SHA256 hash of the (compactly packed) parametersripemd160(...) returns (bytes20)
: computes RIPEMD of 256 (compactly packed) parametersecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)
: Elliptic curve signature public key recovery, return 0 in case of erroraddmod(uint x, uint y, uint k) returns (uint)
: compute(x + y) % k
where the addition is performed with arbitrary precision and does not wrap around at2**256
. Assert thatk != 0
starting from version 0.5.0.mulmod(uint x, uint y, uint k) returns (uint)
: compute(x * y) % k
where the multiplication is performed with arbitrary precision and does not wrap around at2**256
. Assert thatk != 0
starting from version 0.5.0.this
(current contract's type): the current contract, explicitly converted on the addresssuper
: a contract one level above the hierarchical relationshipselfdestruct(address recipient)
: Destroy the current contract, sending its funds to the specifiedaddress
suicide(address recipient)
: a deprecated alias toselfdestruct
<address>.balance
(uint256
): account balance in address address (in wei)<address>.send(uint256 amount) returns (bool)
: Send a certain amount of wei to the address address, and return if it failsfalse
.<address>.transfer(uint256 amount)
: Send a certain amount of wei to the address address, and throw an exception if it fails.
Currency Unit
The smallest unit of ETH is wei
Commonly used units: finney, szabo, ether, wei
library use
Keywords library using for
using for Extend type
A is library library
using A for B associate library function (from library A) to type B
A library has function add(B b), then use b.add()
ABI : The interface description when Ethereum calls the contract, that is, the definition of the operation function signature, parameter encoding, and return encoding.
Mapping : Reference type, storage key, value pair
Structure : Structure is a custom type that can group several variables Enumeration type
enum : Enumeration can be used to create a custom type consisting of a certain number of "constant values"
abnormal
1. Condition checking
Solidity provides assert and require to perform
*require: The require function is used to check whether input variables or contract state variables meet the conditions and to verify the return value of calling an external contract. Can have a return value require(condition, 'Something bad happened');
* assert: The assert function is usually used to check (test) internal errors
Note: Also as a function to judge whether a condition is met, require will return the remaining gas, and assert will consume all gas.
2. Triggering exceptions
Revert and throw are provided to trigger exceptions:
* throw: The keyword throws an exception (from version 0.4.13, the throw keyword has been deprecated and will be eliminated in the future.) Roll back all state changes and return " Invalid operation code error", and consume the remaining gas
* revert: function can be used to mark the error and roll back the current call, allowing to return a value, and return the remaining gas to the caller
The traditional way of handling exceptions if...throw mode
is if(msg.sender != owner) { throw; }
is equivalent to:
* if(msg.sender != owner) { revert(); }//If not equal Then exception
*assert(msg.sender == owner);//Check whether it is equal to
*require(msg.sender == owner);
3. How to choose
the require() function for:
(1). Confirm valid conditions, such as input,
(2). Confirm that the contract declaration variable is consistent
(3). Return a valid value from the call to the external contract
The revert() function is used for:
processing the same type as require(), but requiring more complex processing logic scenarios.
If there is a complex if/else logic flow, then you should consider using the revert() function instead of require().
The assert() function is used to prevent things that should not have happened. If it happens, it means that there is a bug in the contract that needs to be fixed (such as assert(1 > 2)). In general, use assert calls as little as possible, generally assert should use events and logs at the end of the function
Event event is a basic function provided by Ethereum, which is used to record data as a log and save it on the blockchain. Users can customize the data to be recorded, as well as topic and index; the log refers to the data stored on the blockchain. . Events emphasize operational behavior, while logs emphasize storage content. The two are completely different concepts.
Use keywords event
to define events
Reference materials: Solidity latest (0.8.0) Chinese documentation — Solidity Chinese documentation — Denglian Community
Solidity Development - 01 Introduction to Smart Contract and Solidity Language_哔哩哔哩_bilibili