1. 值类型

1.1. INT / UINT

uint 是……的简称 无符号整数,您可以从以下选项中选择尺寸: uint8uint256

  • uint8 起价为 02 × 8 - 1
  • uint16 起价为 02 ** 16 - 1
    ...
  • uint256 起价为 02 × 256 - 1

uint8 public u8 = 1;
uint256 public u256 = 456;
uint public u = 123; // uint 是 uint256 的简写形式

int 是……的简称 整数,您可以从以下选项中选择尺寸: int8int256

  • int8 起价为 -2 × 72 ** 7 - 1
  • int16 起价为 -2 × 152 ** 15 - 1 ...
  • int128 起价为 -2 × 1272 × 127 - 1
  • int256 起价为 -2 ** 2552 ** 255 - 1
int8 public i8 = -1;
int256 public i256 = 456;
int public i = -123; // int 是 int256 的简写

int 和 uint 运算符:

  • Comparisons: <=, <, ==, !=, >=, > (returns bool)
  • 位运算:&、|、^(按位异或)、~(按位取反)
  • Shifts: << (left shift), >> (right shift)
  • 加法、减法和乘法: +, -, 否 - (如 带符号整数), *, /, % (模), ** (幂运算)

对于一种类型 整数 变量 X,你可以使用 type(X).min 以及 type(X).max 分别获取该类型的最小值和最大值。

// int 类型的最小值和最大值: 
int public minInt = type(int).min;
int public maxInt = type(int).max;

// uint 类型的最小值和最大值:
uint public minUint = type(uint).min;
uint public maxUint = type(uint).max;

1.2. BOOL

bool 意味着 布尔 并且有 2 个可能的值,即 true 以及 false

bool public trueVar = true;
bool public falseVar = false;

1.3. 运算符:

  • ! (逻辑否定)
  • && (逻辑连词“和”)
  • || (逻辑析取,即“或”)
  • == (平等)
  • != (不等式)

运营商 || 以及 && 应用常见的短路求值规则。这意味着在表达式中 f(x) || g(y), 如果 f(x) 计算结果为 true, g(y) 即使它可能产生副作用,也不会被求值。

1.4. 地址

  • 地址 是 Solidity 中的一个特殊数据类型,用于存储 Kaia 账户地址(大小为 20 字节)
  • 收件地址 类似于 地址 但增加了 2 个方法 转账 以及 发送
地址 public exampleAddress = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;
可支付地址 public examplePayableAddress = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;

1.5. 字节

在 Solidity 中,byte 数据类型表示一串字节。Solidity 有两种字节类型:

  • 固定大小的字节数组
  • 动态大小的字节数组。

在 Solidity 中,“bytes” 表示一个动态的字节数组。基本上相当于 byte[]。

bytes1 a = 0xb5; //  [10110101]
bytes1 b = 0x56; //  [01010110]
字节 c = "abc"; //  [01100001, 01100010, 01100011]

1.6. 默认值

未赋值的声明变量将采用其默认值。

bool public defaultBool; // false
uint public defaultUint; // 0
int public defaultInt; // 0
address public defaultAddr; // 0x0000000000000000000000000000000000000000
bytes1 public defaultByte; // 0x00

1.7. 合同

合同 用于在Solidity中声明合约。

contract HelloWorld {}

合同 还可以使用关键字从另一个合约继承

合同中的“Mercedes”是汽车 {}

1.8. ENUM

枚举 是 Solidity 中创建用户定义类型的一种方式。它们可以与所有整数类型进行显式转换,但不允许隐式转换。从整数进行的显式转换会在运行时检查该值是否在枚举的范围内,并导致 恐慌错误 否则。 枚举 枚举必须至少包含一个成员,声明时的默认值是第一个成员。枚举的成员数量不得超过 256 个。

该数据的表示形式与 枚举 在 C 语言中:选项由从 0 开始的连续无符号整数值表示。

使用 type(枚举名称).min 以及 type(枚举名称).max 你可以获取给定枚举的最小值和最大值。

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

contract Enum {
    // Enum representing shipping status
    enum Status {
        Pending,
        Shipped,
        Accepted,
        Rejected,
        Canceled
    }

    // Default value is the first element listed in
    // definition of the type, in this case "Pending"
    Status public status;

    // Returns uint
    // Pending  - 0
    // Shipped  - 1
    // Accepted - 2
    // Rejected - 3
    // Canceled - 4
    function get() public view returns (Status) {
        return status;
    }

    // Update status by passing uint into input
    function set(Status _status) public {
        status = _status;
    }

    // You can update to a specific enum like this
    function cancel() public {
        status = Status.Canceled;
    }

    // delete resets the enum to its first value, 0
    function reset() public {
        delete status;
    }
}

1.9. 类型

用户定义的值类型允许在基本值类型之上创建一种零开销的抽象。这类似于别名,但类型要求更为严格。

用户定义的值类型通过以下方式定义: C型是V,其中 C 是新引入的类型的名称,并且 V 必须是内置值类型(即“底层类型”)

// SPDX-License-Identifier: GPL-3.0
pragma solidity^0.8.8;

// 使用用户定义的值类型表示一个 18 位十进制、256 位宽的定点类型。
type UFixed256x18 is uint256;

1.10. 函数

函数 在Solidity中,`keyword` 用于声明函数。

我们可以声明一个 函数 如下所示:

contract Counter {
    uint public count;

    // Function to view count variable
    function get() public view returns (uint) {
        return count;
    }
}

2. 引用类型

2.1. 数据存储位置

变量使用以下关键字进行声明: 存储, 内存calldata 指定保存数据的位置。

  • 存储 - 该变量是状态变量(存储在区块链上)
  • 内存 - 变量存储在内存中,并且仅在 函数 正在运行
  • calldata - 一个专门用于存储传递给该函数的数据的数据存储区
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract DataLocations {
    uint storage varStorage
    uint memory varMemory
    uint calldata varCallData
}

2.2. 数组

数组 是相同格式下多个值元素的组合,类似于 列表 在 Python 中以及 数组JavaScript.

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

contract Array {
    // Several ways to initialize an array
    uint[] public arr;
    uint[] public arr2 = [1, 2, 3];
    // Fixed sized array, all elements initialize to 0
    uint[10] public myFixedSizeArr;

    function get(uint i) public view returns (uint) {
        return arr[i];
    }

    // Solidity can return the entire array.
    // But this function should be avoided for
    // arrays that can grow indefinitely in length.
    function getArr() public view returns (uint[] memory) {
        return arr;
    }

    function push(uint i) public {
        // Append to array
        // This will increase the array length by 1.
        arr.push(i);
    }

    function pop() public {
        // Remove last element from array
        // This will decrease the array length by 1
        arr.pop();
    }

    function getLength() public view returns (uint) {
        return arr.length;
    }

    function remove(uint index) public {
        // Delete does not change the array length.
        // It resets the value at index to it's default value,
        // in this case 0
        delete arr[index];
    }

    function examples() external {
        // create array in memory, only fixed size can be created
        uint[] memory a = new uint[](5);
    }
}

2.3. 结构体

结构 是一种数据格式,程序员通过声明该格式,将多种不同格式的变量归集到一个名称下,以便在 合同.

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

contract Todos {
    struct Todo {
        string text;
        bool completed;
    }

    // An array of 'Todo' structs
    Todo[] public todos;

    function create(string calldata _text) public {
        // 3 ways to initialize a struct
        // - calling it like a function
        todos.push(Todo(_text, false));

        // key value mapping
        todos.push(Todo({text: _text, completed: false}));

        // initialize an empty struct and then update it
        Todo memory todo;
        todo.text = _text;
        // todo.completed initialized to false

        todos.push(todo);
    }

    // Solidity automatically created a getter for 'todos' so
    // you don't actually need this function.
    function get(uint _index) public view returns (string memory text, bool completed) {
        Todo storage todo = todos[_index];
        return (todo.text, todo.completed);
    }

    // update text
    function updateText(uint _index, string calldata _text) public {
        Todo storage todo = todos[_index];
        todo.text = _text;
    }

    // update completed
    function toggleCompleted(uint _index) public {
        Todo storage todo = todos[_index];
        todo.completed = !todo.completed;
    }
}

3. 映射类型

绘制地图

映射 可用于创建一个 哈希表 (类似于 词典Python) 在 1 之间 类型 到另一个 类型.

注:
当您创建一个 映射, 所有 同时存在。这意味着:
例如,你创建 mapping(address => uint256) addressToValue;. 如果您尚未设置任何 以及 那么所有 地址 您输入的内容将返回默认值 uint256 即 0。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Mapping {
    // Mapping from address to uint
    mapping(address => uint) public myMap;

    function get(address _addr) public view returns (uint) {
        // Mapping always returns a value.
        // If the value was never set, it will return the default value.
        return myMap[_addr];
    }

    function set(address _addr, uint _i) public {
        // Update the value at this address
        myMap[_addr] = _i;
    }

    function remove(address _addr) public {
        // Reset the value to the default value.
        delete myMap[_addr];
    }
}

contract NestedMapping {
    // Nested mapping (mapping from address to another mapping)
    mapping(address => mapping(uint => bool)) public nested;

    function get(address _addr1, uint _i) public view returns (bool) {
        // You can get values from a nested mapping
        // even when it is not initialized
        return nested[_addr1][_i];
    }

    function set(address _addr1, uint _i, bool _boo) public {
        nested[_addr1][_i] = _boo;
    }

    function remove(address _addr1, uint _i) public {
        delete nested[_addr1][_i];
    }
}

4. 简易存储

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

contract SimpleStorage {

    // Declare a variable to store the name of the maintainer
    string public maintainerName = "zxstim";
    // Declare the version of the contract
    uint8 public version = 1;
    // Declare an address to receive donation
    address public donationAddress = 0xe3d25540BA6CED36a0ED5ce899b99B5963f43d3F;

    // Declare a Person type to store information of a person
    struct Person {
        string name; // name    
        uint8 age; // age
        bool overEighteen; // Over eighteen?
        address uuid; // UUID
        uint256 assetValue; // asset value
        int256 debtValue; // debt value
    }

    Person[] private listOfPeople; // this syntax means creating an array to store Person named listOfPeople
    
    mapping(address => Person) uuidToPerson; // this syntax means creating a mapping from address to Person named uuidToPerson

    //  this function will store the information of a new person with name, age, overEighteen, assetValue, debtValue
    function storePerson(string memory _name, uint8 _age, bool _overEighteen, uint256 _assetValue, int256 _debtValue) public returns (Person memory person) {
        _assetValue *= 1e18; // Convert asset value to wei unit
        _debtValue *= 1e18; // Convert debt value to wei unit
        // Add information of the new person to the listOfPeople array
        listOfPeople.push(Person({name: _name, age: _age, overEighteen: _overEighteen, uuid: msg.sender, assetValue: _assetValue, debtValue: _debtValue}));
        // Add information of the new person to the uuidToPerson mapping
        uuidToPerson[msg.sender] = Person({name: _name, age: _age, overEighteen: _overEighteen, uuid: msg.sender, assetValue: _assetValue, debtValue: _debtValue});
        return Person({name: _name, age: _age, overEighteen: _overEighteen, uuid: msg.sender, assetValue: _assetValue, debtValue: _debtValue});
    }

    // this function will retrieve the information of a person based on the address
    function retrievePerson(address _address) public view returns (Person memory person) {
        return uuidToPerson[_address];
    }
}