以太坊Solidity智能合约开发(二) - 数据类型

220 阅读4分钟

在上一篇文章 《以太坊Solidity智能合约开发(一) - 合约结构》中,我们学习掌握了简单的合约的基本结构,在这篇文章中,我们将开始学习合约的值类型和引用类型,让我们继续往下学习。

一. 值类型

布尔型

bool :可能的取值为字面常数值 true 和 false 。

运算符:

  • ! (逻辑非)
  • && (逻辑与, "and" )
  • || (逻辑或, "or" )
  • == (等于)
  • != (不等于)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Boolean {
    bool isTrue; // bool类型
    // ...
}

整数类型

int / uint :分别表示有符号和无符号的不同位数的整型变量。 支持关键字 uint8 到 uint256 (无符号,从 8 位到 256 位)以及 int8 到 int256,以 8 位为步长递增。 uint 和 int 分别是 uint256 和 int256 的别名。

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

contract Integer {
    uint8 age;
  	uint256 weight;
    // ...
}

地址类型

address:地址类型存储一个 20 字节的值(以太坊地址的大小)。 地址类型也有成员变量,并作为所有合约的基础。

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


contract Account {
    address addr; // address类型
    // ...
}

定长字节数组

关键字有:bytes1, bytes2, bytes3, ..., bytes32。byte 是 bytes1 的别名。

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

contract Bytes {
    bytes1 number1;
    bytes32 number2;
    // ...
}

地址字面量

地址值的长度一定是符合以太坊的正确的公钥地址。

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


contract Accounts {
    address account = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; // 地址字面量
    // ...
}

数值字面量

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


contract Accounts {
    uint128 a = 1; // 数值字面量
    // ...
}

字符字面量

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


contract String {
    string account = "str"; // 字符字面量
    // ...
}

枚举类型

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

contract test {
    
    enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
    ActionChoices choice;
    ActionChoices constant defaultChoice = ActionChoices.GoStraight;

    function setGoStraight() public {
        choice = ActionChoices.GoStraight;
    }


    function getChoice() public view returns (ActionChoices) {
        return choice;
    }


    function getDefaultChoice() public pure returns (uint) {
        return uint(defaultChoice);
    }
    
}

函数类型

函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量,也可以将一个函数作为参数进行传递,还能在函数调用中返回函数类型变量。 函数类型有internal内部函数,external外部函数,public公共函数,private私有函数,view函数和pure纯函数。其中,internal内部函数只能在本合约和继承本合约的内部被调用,private私有函数只能在本合约被调用。external外部函数只能被外部的合约调用,public公共函数可以在任何情况下都能被调用。view函数说明这个函数只有只读功能,pure纯函数说明这个函数也是只有只读功能,两者区别在于view可以进行运算,但是会发出警告,且结果不回因为运算而发生改变。pure是严令禁止写入的功能的。

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

contract test {

    uint age;
    
    function func_external() external { // 外部函数
        // ...
    }

    function func_internal() internal { // 内部函数
        // ...
    }

    function func_public() public { // 公共函数
        // ...
    }

    function func_private() private { // 私有函数
        // ...
    }

    function getAgeByView() public view returns(uint){
        age += 1; // 编译不通过
        return age; // return 30,但是!状态变量age的值不会改变,仍然为29!
    }
    
    function getAgeByPure() public pure returns(uint){
        return age; //编译报错!pure比constant和view都要严格,pure完全禁止读写状态变量!
        return 1;
    }
}

内存关键词

memory 和 storage

由于Solidity语言受到自身堆栈深度的限制,所以我们必须手动为数据分配存储位置。由于拷贝这些类型变量的开销相当大,我们不得不考虑它的存储位置,是将它们保存在 内存memory (并不是永久存储)中, 还是 存储storage (保存状态变量的地方)中。

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

contract Person {

  struct Student {
    string name;
    string status;
  }

  Student[] students;

  function test(uint _index) public {
    // Solidity 将会给出警告,告诉你应该明确在这里定义 `storage` 或者 `memory`。
    // 这里定义为 `storage`:
    Student storage stu1 = students[_index];
    stu1.status = "Active!";

    // 如果你只想要一个副本,可以使用`memory`:
    Student memory stu2 = students[_index + 1];
    stu2.status = "Negative!";
  }
  
}

二. 引用类型

字符串类型

string类型是一个字符序列。Solidity 支持使用单引号' '和双引号" "的字符串文字。

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

contract String_Example{
        string name = "John Doe";
}

数组类型

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

contract test {

    uint[] public arrays; // 数组

    function func_array() external { // 外部函数
        arrays.push(1); // 存放1
    }
}

映射类型

映射类型在声明时的形式为 mapping(_KeyType => _ValueType)。 其中 _KeyType 可以是除了映射、变长数组、合约、枚举以及结构体以外的几乎所有类型。 _ValueType 可以是包括映射类型在内的任何类型。

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

contract Person {

    struct Students {
        string name;
        uint age;
    }

    uint[] arrays;

    mapping(uint => address) map1; // value为address类型
    mapping(string => Students) map2; // value为结构体类型
    mapping(uint => mapping(uint=>string)) map3; // value为mapping类型
}

结构体类型

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

contract Person {

    struct Students {
        string name;
        uint age;
    }
  
}

以上这些都是常用一些数据类型,掌握了其写法后,我们后面就开始写大量的一些示例来具体学习,遇到不懂的,我们再来深入学习它,理解它。当然,提倡并鼓励大家多看官方的文档教程。