Solidity入门【多知识点详解】

01-Solidity新特性

02-Hello World

// 首先需要写一个版权声明
// SPDX-License-Identifier: MIT
// 版本号:^表示改版本之后的版本可以编译
pragma solidity ^0.8.7;

contract HelloWorld {
    string public myString = "Hello World";
}

03-变量的类型

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract HelloWorld {
    bool public b = true;
    uint public u = 123; // uint = uint256
                         //        uint8
                         //        uint16
    int public i = -123; // int = int256
                         //       int128
    int public minInt = type(int).min;
    int public maxInt = type(int).max;
    address public addr = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
    bytes32 public b32 = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4345613456434567854334556;
}

04-函数

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract FunctionIntro{
    function add(uint x, uint y) external pure returns (uint) {
        return x + y;
    }

    function sub(uint x, uint y) external pure returns (uint) {
        return x - y;
    }
}

05-状态变量

// 就是把变量写在区块链上,如果不执行修改值的方法,将永远保持这个值
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract StateVariables {
    uint public myUint = 123;

    // external外部可视,也就是说内部是无法调用这个函数的
    function foo() external {
        uint notStateVariable = 456;
    }
}

06-局部变量

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract LocalVariables {
    uint public i;
    bool public b;
    address public myAddress;

    function foo() external {
        uint x = 123;
        bool f = false;
        // more code
        x += 456;
        f = true;

        i = 123;
        b = true;
        myAddress = address(1);
    }
}

07-全局变量

// 三个常用的全局变量
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract GlobalVariables {
    // 只要读了链上的信息就要写view关键字
    function globalVars() external view returns (address, uint, uint) {
        // 上一个调用的地址
        address sender = msg.sender;
        // 当前时间戳
        uint timestamp = block.timestamp;
        // 当前区块数
        uint blockNum = block.number;

        return (sender, timestamp, blockNum);
    }
}

08-只读函数

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract ViewAndPureVariables {
    uint public num;

    // 读取链上的状态必须使用view
    function viewFunc() external view returns (uint) {
        return num;
    }

    // 局部变量不需要view,只读只需要pure
    function pureFunc() external pure returns (uint) {
        return 1;
    }
}

09-计数器合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract Counter {
    uint public count;

    function inc() external {
        count += 1;
    }
    
    function dec() external {
        count -= 1;
    }
}

10-变量的默认值

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract defaultValues {
    bool public b; // false
    uint public u; // 0
    int public i; // 0
    address public a; // 0x0000000000000000000000000000000000000000
    bytes32 public b32; // 0x0000000000000000000000000000000000000000000000000000000000000000
    // mapping, struct, enums, fixed sized arrays
}

11-常量

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract Constants {
    address public constant MY_ADDRESS = 0x0000000000000000000000000000000000000001;
    uint public constant MY_UINT = 123;
}

contract Var {
    address public MY_ADDRESS = 0x0000000000000000000000000000000000000001;
}

12-结构控制

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract IfElse {
    function example(uint _x) external pure returns (uint) {
        if (_x < 10) {
            return 1;
        } else if (_x < 20) {
            return 2;
        } else {
            return 3;
        }
    }

    function example2(uint _x) external pure returns (bool) {
        return _x > 10 ? true : false;
    }
}

13-循环

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract IfElse {
    function loops() external pure {
        for (uint i = 0; i < 10; i++) {
            if (i == 3) {
                continue;
            }
        }

        uint j = 0;
        while (j < 10) {
            j++;
        }
    }
}

14-报错控制

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract Error {
    // require revert assert
    // 三种报错控制都有 gas refund, state updates are reverted
    // custom error save gas
    function testRequire(uint _i) public pure {
        require(_i <= 10, "i > 10");
    }

    function testRevert(uint _i) public pure {
        if (_i > 10) {
            revert ("i > 10");
        }
    }

    uint public num = 123;
    function testAssert() public view {
        assert(num == 123);
    }
    function foo() public {
        num += 1;
    }

    error MyError(address caller, uint i);

    function testCunstomError(uint _i) public view {
        if (_i > 10) {
            revert MyError(msg.sender, _i);
        }
    }
}

15-函数修改器

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract FunctionModifier {
    bool public paused;
    uint public count;

    function setPause(bool _paused) external {
        paused = _paused;
    }

    modifier whenNotPaused() {
        require(!paused, "paused");
        _;
    }

    function inc() external whenNotPaused {
        count++;
    }

    function dec() external whenNotPaused {
        count--;
    }

    modifier cap(uint x) {
        require (x < 100, "x >= 100");
        _;
    }

    function incBy(uint x) external whenNotPaused cap(x) {
        count += x;
    }

    modifier sandwich() {
        count += 10;
        _;
        count *= 2;
    }

    function foo() external sandwich {
        count += 1;
    }
}

16-构造函数

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract Constructor {
    address public owner;
    uint public x;

    constructor(uint _x) {
        owner = msg.sender;
        x = _x;
    }
}

17-Ownable合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract Ownable {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }

    function setOwner(address _newOwner) external onlyOwner {
        require(_newOwner != address(0), "invalid address");
        owner = _newOwner;
    }

    function onlyOwnerCanCallThisFunc() external onlyOwner {
        // code
    }

    function anyOneCanCallThisFunc() external {
        // code
    }
}