Introduction to Solidity

1. Solidity language

The Solidity language is a contract -oriented high-level programming language for implementing smart contracts on the Ethereum blockchain network. The Solidity language is heavily influenced by c++, Python, and JavaScript, and is designed for the Ethereum Virtual Machine (EVM).

The Solidity language is a statically typed language that supports inheritance, libraries, and complex user-defined types.

1. Statically typed language : A language with type declarations when variables are defined.

(1) The type of the variable is determined at compile time

(2) The type of the variable cannot be modified at runtime, so that the compiler can determine the total amount of memory required at runtime .

         For example: C, Scala, Java, F# languages ​​are statically typed languages.

2. Dynamically typed language : A language with no type declaration when variables are defined.

(1) The type of the variable is determined at runtime

(2) The type of variable can be modified at runtime

For example: python, Javascript, Ruby languages ​​are dynamically typed languages.

3. Strongly typed language

A language that enforces data type definitions. That is to say, once a variable is assigned a certain data type, if it is not cast, it will always be of this data type. For example: If you define an integer variable a, it is impossible for the program to treat a as a string type. Strongly typed languages ​​are type-safe languages.

4. Weakly typed language

Languages ​​where datatypes can be ignored. It is the opposite of a strongly typed language, where a variable can be assigned values ​​of different data types. A strongly typed language may be slightly inferior to a weakly typed language in terms of speed, but the rigor brought by a strongly typed language can effectively avoid many errors.

Various types of smart contracts such as voting, crowdfunding, and wallets that run on the blockchain can be created using the Solidity language .

What is Ethereum/Ethereum?

Ethereum is a decentralized blockchain platform that runs smart contracts .

Ethereum/Ethereum Virtual Machine (EVM)

The Ethereum Virtual Machine, also known as EVM, is the runtime environment for smart contracts in Ethereum/Ethereum .

A certain language, such as Solidity , can be used to develop a smart contract program, compiled into bytecode/bytecode supported by the Ethereum virtual machine , and then the program can be executed in the virtual machine.

What is a smart contract?

A smart contract is a computer protocol designed to disseminate , verify or enforce contracts in an informational manner . Smart contracts allow for trusted transactions without third parties , which are traceable and irreversible . The concept of smart contracts was first proposed by Nick Szabo in 1995.

The purpose of smart contracts is to provide a method of security superior to traditional contracts and to reduce other transaction costs associated with contracts.

Simply put, a smart contract can be understood as a self-executing agreement . Smart contracts can automatically handle the fulfillment, management, and payment of agreements.

For example, you can write such a smart contract: before the end of this month, Lao Wang transfers 1 ether to Xiao Zhang. After this smart contract is deployed, it will automatically transfer Lao Wang’s 1 ether to Xiao Zhang before the end of the month. No human intervention is required.

It’s okay if you don’t understand smart contracts right now, we’ll cover them in more detail later.


2. Solidity installs a local compiler

Install native compiler

install nodejs/npm

Download node from the node official website , recommend the LTS version, follow the prompts to complete the installation, and npm will install it at the same time.

Verify Node version:

> node -v
v10.16.3

> npm -v
6.11.3

Install the Solidity compiler solc

Once the Node.js package manager is installed, you can install the Solidity compiler by following the steps below

$ npm install -g [email protected]

The above command will install the solcjs program and make it available system-wide.

Verify solc installation:

$ solcjs --version

If all goes well, this will print something like

0.4.25+commit.c082d0b4.Emscripten.clang

Now, you can use the native solcjs, which has a lot less features than the standard solidity compiler, but is good enough for learning.


3. Basic Grammar

A Solidity source file can contain any number of contract definitions , import directives , and pragma directives .

Let's start with a simple Solidity source program. Here is an example Solidity source file:

Pragma

The first line is the pragma directive, which tells us that the source code was written for Solidity version 0.4.25.

The pragma directive only works on its own source file. If file B is imported into file A, the pragma of file B will not be automatically applied to file A.

pragma solidity ^0.4.0;

The pragma directive above means that the source file cannot be compiled with a compiler version lower than 0.4.0, nor can it be compiled with a compiler version 0.5.0 and above.

The second condition here is added ^, which means that it does not exceed version 0.5.0. The meaning behind it is that minor version changes between 0.4.0 and 0.4.9 usually do not have destructive changes, and the source code should be all Compatible.

Contract/smart contract

A smart contract is a collection of code (functions) and data (state) located at a specific address on the Ethereum blockchain .

This line of code: uint number ;, declares a state variable named numberuint,set , of type and getfunction that can be used to modify or retrieve the value of the variable.

Importing files

The above example has no import statement, but Solidity supports import statements very similar to JavaScript.

The following statement imports all global symbols from "filename".

import "filename";

The following example creates a new global symbol symbolNamewhose members are all global symbols from "filename".

import * as symbolName from "filename";

To import file x from the current directory , use import "./x". If you do not specify the current path , it may be in the global "include directory

;Records” references another file.

reserved keywords

The following are reserved keywords in the Solidity language:

abstract auto case default final
after immutable implements in inline
alias let macro match mutable
apply null of override partial
catch promise reference relocatable sealed
copyof sizeof static supports switch
define try typedef typeof unchecked


4. The first program

For simplicity, we use the online Solidity development tool Remix IDE to compile and run Solidity programs.

Step 1  – File explorersUnder the tab, create a new test1.sol file with the following code:

example

pragma solidity ^0.5.0;
contract SolidityTest {
   constructor() public{
   }
   
   function getResult() public view returns(uint){
      uint a = 1;
      uint b = 2;
      uint result = a + b;
      return result;
   }
}

Step 2  - CompilerUnder the tab, click  the Compile  button to start compiling
Step 3  - Under Runthe tab, click  the Deploy  button to deploy
Step 4  - Under Runthe tab, select  SolidityTest at 0x...  drop down
Step 5  - Click  the getResult  button to display the result.

output

0: uint256: 3

Five, code comments

Solidity supports C-style and C++-style comments.

  • //The text after that to the end of the line is regarded as a comment, and the compiler ignores this content, " ctrl+/ "
  • /* The text between and  */ is regarded as a comment, the compiler ignores this content, " shift+ctrl+a "

example

function getResult() public view returns(uint){
   // 这是一行注释,类似于c++中的注释

   /*
    * 这是多行注释
    * 类似于c语言中的注释
    */
   uint a = 1;
   uint b = 2;
   uint result = a + b;
   return result;
}

6. Data type

When writing a program in any language, you need to use variables to store various information . A variable is the name of a memory space , and there are different types of variables, such as integers, strings, and so on. The operating system allocates memory according to the data type of the variable.

In Solidity, variable types fall into the following categories:

  • value type
  • address type
  • reference type

1. Value type

type reserved word value
Boolean bool true/false
integer int/uint Signed integer/unsigned integer.
integer int8 to int256 8-bit to 256-bit signed integer. int256 is the same as int.
integer uint8 to uint256 8-bit to 256-bit unsigned integer. uint256 is the same as uint.
fixed-length float fixed/unfixed Signed and unsigned fixed-length floating-point types
fixed-length float fixedMxN Signed fixed-length floating-point type, where M represents the number of digits taken by type, and N represents the decimal point. M should be divisible by 8, from 8 to 256. N can be 0 to 80. fixed is the same as fixed128x18.
fixed-length float ufixedMxN Unsigned fixed-length floating-point type, where M represents the number of digits taken by type, and N represents the decimal point. M should be divisible by 8, from 8 to 256. N can be 0 to 80. fixed is the same as fixed128x18.

2. Address type

The address type represents an Ethereum address , with a length of 20 bytes. Addresses can use .balancemethods to obtain balances and .transfermethods to transfer balances to another address .

address x = 0x212;
address myAddress = this;

if (x.balance < 10 && myAddress.balance >= 10) 
    x.transfer(10);

3. Reference type/composite data type

In Solidity, some data types are composed of value types . Compared with simple value types, these types are usually referred to by names and are called reference types .

Reference types include:

  • Arrays (strings and bytes are special arrays, so they are also reference types)
  • struct (structure)
  • map

7. Variables

Solidity supports three types of variables:

  • State variable  – a variable whose value is permanently stored in the contract storage space .
  • Local variables  – variables whose value is only valid during the execution of the function , after the function exits, the variable is invalid.
  • Global variables  – special variables stored in the global namespace for obtaining blockchain-related information .

Solidity is a statically typed language, which means that variable types need to be specified during declaration . Every variable, when declared, has a default value based on its type . There is no concept of undefinedor null.

1. State variables

The variable value is permanently stored in the variable in the contract storage space.

pragma solidity ^0.5.0;
contract SolidityTest {
   uint storedData;      // 状态变量
   constructor() public {
      storedData = 10;   // 使用状态变量
   }
}

2. Local variables

The variable value is only valid during the execution of the function, and the variable is invalid after the function exits. Function parameters are local variables.

pragma solidity ^0.5.0;
contract SolidityTest {
   uint storedData; // 状态变量
   constructor() public {
      storedData = 10;   
   }
   function getResult() public view returns(uint){
      uint a = 1; // 局部变量
      uint b = 2;
      uint result = a + b;
      return result; // 访问局部变量
   }
}

example

pragma solidity ^0.5.0;
contract SolidityTest {
   uint storedData; // 状态变量
   constructor() public {
      storedData = 10;   
   }
   function getResult() public view returns(uint){
      uint a = 1; // 局部变量
      uint b = 2;
      uint result = a + b;
      return storedData; // 访问状态变量
   }
}

You can run the above program using the steps in the first program in Solidity.

output

0: uint256: 10

3. Global variables

These are special variables that exist in the global workspace and provide information about blockchain and transaction properties.

name return
blockhash(uint blockNumber) returns (bytes32) Hash of a given block – only for the 256 most recent blocks, not including the current block.
block.coinbase (address payable) The address of the current block miner
block.difficulty (uint) The difficulty of the current block
block.gaslimit (uint) The gas limit of the current block
block.number (uint) the number of the current block
block.timestamp (uint) The timestamp of the current block, in seconds since the unix epoch
gasleft() returns (uint256) remaining gas
msg.data (bytes calldata) complete calldata
msg.sender (address payable) message sender (current caller)
msg.sig (bytes4) The first four bytes of calldata (function identifier)
msg.value (uint) The wei value of the current message
now (uint) Timestamp of the current block
tx.gasprice (uint) transaction gas price
tx.origin (address payable) sender of the transaction

Solidity variable names

When naming variables , keep the following rules in mind

  • Solidity reserved keywords should not be used as variable names. For example, breakor booleanthe variable name is invalid.
  • Should not start with a number (0-9) , must start with a letter or underscore. For example, 123testis an invalid variable name, but _123testis a valid variable name.
  • Variable names are case sensitive . For example, Nameand nameare two different variables.

Eight, variable scope

The scope of local variables is limited to the function in which they are defined , but state variables can have three scope types.

  • Public  – Public state variables can be accessed internally or via messages. For public state variables, an automatic getter function will be generated .
  • Internal  – Internal state variables can only be accessed from within the current contract or its derived contracts .
  • Private  – Private state variables can only be accessed from within the current contract , not from derived contracts.

example

pragma solidity ^0.5.0;
contract C {
   uint public data = 30;
   uint internal iData= 10;

   function x() public returns (uint) {
      data = 3; // 内部访问
      return data;
   }
}
contract Caller {
   C c = new C();
   function f() public view returns (uint) {
      return c.data(); // 外部访问
   }
}
contract D is C {
   uint storedData; // 状态变量

   function y() public returns (uint) {
      iData = 3; // 派生合约内部访问
      return iData;
   }
   function getResult() public view returns(uint){
      uint a = 1; // 局部变量
      uint b = 2;
      uint result = a + b;
      return storedData; // 访问状态变量
   }
}

9. Operators

1. Arithmetic operators

The arithmetic operators supported by Solidity are shown in the table below:

Suppose variable A has a value of 10 and variable B has a value of 20.

serial number Operators and Descriptions
1 + (addition)  summation  example:  A + B = 30
2 – (subtraction)  subtraction  example:  A – B = -10
3 *** (Multiplication)** Multiplication  example:  A * B = 200
4 / (division) Example of  division  :  B / A = 2
5 % (modulus)  Modulo operation  example:  B % A = 0
6 ++ (Increment)  Increment  Example:  A++ = 11
7 — (Decrement)  Decrement  Example:  A– = 9
8 **(How to)  Example: 2**2 = 4

example

The code below shows how to use arithmetic operators.

pragma solidity ^0.5.0;

contract SolidityTest {
   constructor() public{
   }
   function getResult() public view returns(uint){
      uint a = 1; 
      uint b = 2;
      uint result = a + b; // 算术运算
      return result; 
   }
}

output

0: uint256: 3

2. Comparison operators

The comparison operators supported by Solidity are shown in the following table:

serial number Operators and Descriptions
1 == (equal to)
2 != (not equal to)
3 > (greater than)
4 < (less than)
5 >= (大于等于)
6 <= (小于等于)

下面的代码展示了如何使用比较运算符。

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint a = 1; // 局部变量
      uint b = 2;
      uint result = a + b;
      return integerToString(result); 
   }
   function integerToString(uint _i) internal pure 
      returns (string memory _uintAsString) {

      if (_i == 0) {   // 比较运算符
         return "0";
      }
      uint j = _i;
      uint len;

      while (j != 0) {  // 比较运算符
         len++;
         j /= 10;
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;

      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);// 访问局部变量
   }
}

输出

0: string: 3

3.逻辑运算符

Solidity 支持的逻辑运算符,如下表所示:

假设变量A的值为10,变量B的值为20。

序号 运算符与描述
1 && (逻辑与) 如果两个操作数都非零,则条件为真。 例: (A && B) 为真
2 || (逻辑或) 如果这两个操作数中有一个非零,则条件为真。 例: (A || B) 为真
3 ! (逻辑非) 反转操作数的逻辑状态。如果条件为真,则逻辑非操作将使其为假。 例: ! (A && B) 为假

示例

下面的代码展示了如何使用逻辑运算符

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; // 状态变量
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint a = 1; // 局部变量
      uint b = 2;
      uint result = a + b;
      return integerToString(storedData); // 访问状态变量
   }
   function integerToString(uint _i) internal pure 
      returns (string memory) {

      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;

      while (!(j == 0)) {  // 逻辑运算符
         len++;
         j /= 10;
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;

      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);
   }
}

输出

0: string: 3

4.位运算符

Solidity 支持的位运算符,如下表所示:

假设变量A的值为2,变量B的值为3。

序号 运算符与描述
1 & (位与) 对其整数参数的每个位执行位与操作。 例: (A & B) 为 2.
2 | (位或) 对其整数参数的每个位执行位或操作。 例: (A | B) 为 3.
3 ^ (位异或) 对其整数参数的每个位执行位异或操作。 例: (A ^ B) 为 1.
4 ~ (位非) 一元操作符,反转操作数中的所有位。 例: (~B) 为 -4.
5 << (左移位)) 将第一个操作数中的所有位向左移动,移动的位置数由第二个操作数指定,新的位由0填充。将一个值向左移动一个位置相当于乘以2,移动两个位置相当于乘以4,以此类推。 例: (A << 1) 为 4.
6 >> (右移位) 左操作数的值向右移动,移动位置数量由右操作数指定 例: (A >> 1) 为 1.

示例

下面的代码展示了如何使用位运算符

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint a = 2; // 局部变量
      uint b = 2;
      uint result = a & b;  // 位与
      return integerToString(result); 
   }
   function integerToString(uint _i) internal pure 
      returns (string memory) {
      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;

      while (j != 0) {
         len++;
         j /= 10;
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;

      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);// 访问局部变量
   }
}

输出

0: string: 2

5.赋值运算符

Solidity 支持的赋值运算符,如下表所示:

序号 运算符与描述
1 = (简单赋值) 将右侧操作数的值赋给左侧操作数 例: C = A + B 表示 A + B 赋给 C
2 += (相加赋值) 将右操作数添加到左操作数并将结果赋给左操作数。 例: C += A 等价于 C = C + A
3 −= (相减赋值) 从左操作数减去右操作数并将结果赋给左操作数。 例: C -= A 等价于 C = C – A
4 *= (相乘赋值) 将右操作数与左操作数相乘,并将结果赋给左操作数。 例: C *= A 等价于 C = C * A
5 /= (相除赋值) 将左操作数与右操作数分开,并将结果分配给左操作数。 例: C /= A 等价于 C = C / A
6 %= (modulo assignment)  takes a modulo of two operands and assigns the result to the left operand. Example:  C %= A is equivalent to C = C % A

Note  – the same logic applies to bitwise operators, so they become <<=, >>=, >>=, &=, |=and ^=.

The code below shows how to use the assignment operator.

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint a = 1; 
      uint b = 2;
      uint result = a + b;
      return integerToString(storedData); 
   }
   function integerToString(uint _i) internal pure 
      returns (string memory) {
      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;
      while (j != 0) {
         len++;
         j /= 10; // 赋值运算
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;
      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;// 赋值运算
      }
      return string(bstr);  // 访问局部变量
   }
}

output

0: string: 10

6. Conditional Operators

Solidity supports conditional operators.

serial number Operators and Descriptions
1 ? : (conditional operator)  if the condition is true? then take value X : otherwise value Y

example

The code below shows how to use this operator

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint a = 1; // 局部变量
      uint b = 2;
      uint result = (a > b? a: b);  //条件运算
      return integerToString(result); 
   }
   function integerToString(uint _i) internal pure 
      returns (string memory) {
      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;
      while (j != 0) {
         len++;
         j /= 10;
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;
      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);
   }
}

output

0: string: 2

10. Loop statement

1. while loop

grammar

In Solidity, the syntax of while loop is as follows:

while (表达式) {
   被执行语句(如果表示为真)
}

example

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint a = 10; 
      uint b = 2;
      uint result = a + b;
      return integerToString(result); 
   }
   function integerToString(uint _i) internal pure 
      returns (string memory) {

      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;

      while (j != 0) {
         len++;
         j /= 10;
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;

      while (_i != 0) { // while 循环
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);
   }
}

output

0: string: 12

2.do...while loop

grammar

In Solidity, the syntax of the do…while loop is as follows:

do {
   被执行语句(如果表示为真)
} while (表达式);

Note : Don't miss the semicolon after do

example

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint a = 10; 
      uint b = 2;
      uint result = a + b;
      return integerToString(result); 
   }
   function integerToString(uint _i) internal pure 
      returns (string memory) {

      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;

      while (j != 0) {
         len++;
         j /= 10;
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;

      do {                   // do while 循环 
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      while (_i != 0);
      return string(bstr);
   }
}

output

0: string: 12

3. for loop

grammar

In Solidity, the syntax of a for loop is as follows:

for (初始化; 测试条件; 迭代语句) {
   被执行语句(如果表示为真)
}

example

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }

   function getResult() public view returns(string memory){
      uint a = 10; 
      uint b = 2;
      uint result = a + b;
      return integerToString(result); 
   }

   function integerToString(uint _i) internal pure 
      returns (string memory) {
      if (_i == 0) {
         return "0";
      }
      uint j=0;
      uint len;
      for (j = _i; j != 0; j /= 10) {  //for循环的例子
         len++;         
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;
      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);//访问局部变量
   }
}

output

0: string: 12

4.break 和 continue

  • continue – Jump out of this loop and continue to execute the next loop
  • break – break out of the loop (or break out of the code block )

break example

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint a = 1; 
      uint b = 2;
      uint result = a + b;
      return integerToString(result); 
   }
   function integerToString(uint _i) internal pure 
      returns (string memory) {

      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;

      while (true) {
         len++;
         j /= 10;
         if(j==0){
            break;   // break 语句跳出循环
         }
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;

      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);
   }
}

output

0: string: 3

continue example

pragma solidity ^0.5.0;

contract SolidityTest {
   uint storedData; 
   constructor() public{
      storedData = 10;   
   }
   function getResult() public view returns(string memory){
      uint n = 1;
      uint sum = 0;

      while( n < 10){
         n++;
         if(n == 5){
            continue; // 当n的和是5时,跳过n。
         }
         sum = sum + n;
      }
      return integerToString(sum); 
   }
   function integerToString(uint _i) internal pure 
      returns (string memory) {

      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;

      while (true) {
         len++;
         j /= 10;
         if(j==0){
            break;   // break跳出循环
         }
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;

      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);
   }
}

output

0: string: 49	

Guess you like

Origin blog.csdn.net/m0_65436732/article/details/127583719