代码编织梦想

solidity 数据类型

Solidity 数据类型可以大致分为以下两种类型:

  • 值类型
  • 引用类型

这两种类型在变量赋值和存储在 EVM 中的方式方面有所不同。值类型维护变量的独立副本,并且在一个变量中更改值不会影响另一个变量中的值。但是,更改引用类型变量中的值可确保任何引用该变量的地方都会获取更新值。

1. 值类型

如果一个类型将数据(值)直接保存在内存中,则称该类型为值类型。

值类型是大小不超过32字节内存的类型。Solidity 提供以下值类型:

  • bool:可以保存 true 或 false 作为其值的布尔值
  • uint:这是无符号整数,只能保存0和正值
  • int:这是可以保存负值和正值的有符号整数
  • address:这表示以太坊环境中的账户地址
  • byte:这表示固定大小的字节数组(byte1bytes32

1.1 整形

整数有助于将数字存储在合约中。Solidity 提供以下两种类型的整数:

  • 有符号的整数:带符号的整数可以同时具有负值和正值。
  • 无符号整数:无符号整数只能保持正值和零。除正值和零值以外,它们也可以保持负值。

对于每种类型,Solidity 都有多种类型的整数。Solidity 提供了 uint8 类型来表示8位无符号整数,并且以8的倍数表示,直到达到256。总之,可以声明32个不同的具有8的倍数的无符号整数,例如 uint8uint16unit24uint256 位。同样,有符号整数的数据类型也是相同的,如 int8int16,直到 int256

根据要求,应选择适当大小的整数。例如,当存储0〜255之间的值时,uint8是合适的,而存储介于-128〜127 之间则 int8 更合适。对于更高的值,可以使用更大的整数。

有符号和无符号整数的缺省值为零,在声明时它们会自动初始化。

可以对整数执行数学运算,例如加法、减法、乘法、除法、指数、否定、后增量和预增量

1.2 布尔类型

像任何编程语言一样,Solidity 提供了一种布尔数据类型。bool 数据类型可用于表示具有二进制结果的场景,例如 truefalse、1或0等。此数据类型的有效值为 truefalse。值得注意的是,Solidity 中的布尔不能转换为整数,就像它们在其他编程语言中一样。它是一个值类型,任何赋值给其他的布尔变量都会创建一个新副本。Soliditybool的默认值为 false

声明和赋值 bool 数据类型的代码如下:

bool isPaid = true;

1.3 字节数据类型

字节是指8位有符号整数。内存中的所有内容都存储在由二进制值0和1组成的位中。Solidity 还提供字节数据类型以存储二进制格式信息。通常,编程语言只有一种数据类型来表示字节。但是,Solidity 具有多种字节类型。它提供的数据类型范围为 bytes1bytes32(含),以根据需要表示不同的字节长度。这些被称为固定大小的字节数组,并被实现为值类型。bytes1 数据类型代表1个字节,bytes2 代表2个字节。字节的默认值是 0x00,并用此值初始化。Solidity 也有一个 byte 类型,它是 bytes1 的别名。

一个字节可以以十六进制格式赋值,如下所示:

bytes1 aa = 0x65;

一个字节可以被赋值为十进制格式的整数值,如下所示:

bytes1 bb = 10;

一个字节可以被赋值为十进制格式的负整数值,如下所示:

bytes1 ee = -100;

一个字节可以赋值为字符值,如下所示:

bytes1 dd = 'a';

在下面的代码片段中,256不适合放入单个字节,需要更大的字节数组:

bytes2 cc = 256;

1.4 枚举类型

枚举是包含一个预定义的常量值列表的值类型。它们通过值传递,每个副本都维护自己的值。不能在函数内声明枚举,并在合约的全局域命名空间内声明。预定义的常量是连续赋值的,从零开始增加整数值。如:

    enum status {created, approved, provisioned, rejected, deleted}

1.5 地址类型

地址是20字节的数据类型。它是为了存储以太坊中的账户地址而特别设计的,其大小为160位或20字节。它可以保存合约账户地址以及外部拥有的账户地址。地址是一种值类型,它被赋值给另一个变量时会创建一个新副本。

地址具有 balance 属性,该属性返回账户可用的以太币数量,并具有一些用于账户间交易以太币和调用合约函数的功能。

它提供以下两个函数来交易以太币:

  • transfer
  • send

当向一个账户发送以太币时,更应该选择 transfer 函数而不是send函数。send 函数返回一个布尔值,具体取决于以太币发送是否成功执行,而 transfer 函数引发异常并将以太币返还给调用者。

它还提供了以下三个用于调用合约函数的函数:

  • Call
  • DelegateCall
  • Callcode

2. 引用类型

引用类型不直接将其值存储在变量本身中。它们存储的不是值,而是值存储位置的地址。该变量保存了指向另一个实际存储数据的内存位置的指针。

Solidity 提供以下引用类型:

  • 数组:这是固定大小或动态大小的数组。
  • 结构:这是自定义的即用户定义的结构。
  • 字符串:这是字符序列。在 Solidity 中,字符串最终被存储为字节。
  • 映射:与存储键值对的其他语言中的散列表或字典相似。

2.1 数组

数组是数据类型,但更具体地说,它们是依赖于其他数据类型的数据结构。数组是指相同类型的数值组。数组有助于将这些值存储在一起,并简化迭代、排序和搜索该组中元素或子元素的过程。Solidity 提供了丰富的数组结构,可以满足不同的需求。

Solidity 中的数组示例如下:

uint[5] intArray

Solidity 中的数组可以是固定的或动态的。

固定数组

固定数组是指声明了预定大小的数组。固定数组的例子如下:

int[5] age;
byte[4] flags; 

固定数组无法使用new关键字进行初始化。它们只能以内联方式初始化,如下面的代码所示:

int[5] age = [1,2,3,4,5];

它们也可以稍后在函数中内联初始化,如下所示:

int[5] age;
age = [1,2,3,4,5];

动态数组

动态数组是指在声明时没有预定大小的数组,但是,它们的大小是在运行时确定的。看看下面的代码:

int[] age;
byte[] flags;

动态数组可以内联初始化,可以在声明时初始化,如下所示:

int[] age = [1,2,3,4,5];

特殊数组

Solidity 提供了以下两个特殊数组:

  • 字节数组
  • 字符串数组

a.字节数组:

字节数组是一个动态数组,可以容纳任意数量的字节。它与byte[]不同。byte[] 数组每个元素占用32个字节,而字节数组紧紧地将所有字节保存在一起。

字节可以声明为具有初始长度大小的状态变量,如以下代码所示:

bytes localBytes = new bytes(0);

这也可以分成与以前讨论的数组类似的以下两条代码行:

bytes localBytes;
localBytes = new bytes(10);

字节数组可以直接赋值,如下所示:

localBytes = "solidity is good";

此外,如果数据位于存储位置,则可以将值压栈其中,如下面的代码所示:

localBytes.push(byte(10));

字节数组还提供读/写长度属性,如下所示:

return localBytes.length;

localBytes.length = 4;

b.字符串数组

字符串是基于上一节讨论的字节数组的动态数据类型。它们与附加约束的字节数组非常相似。字符串不能被索引或压栈,也不具有 length 属性。要对字符串变量执行任何这些操作,应首先将其转换为字节,然后在操作后将其转换回字符串。

字符串可以由单引号或双引号内的字符组成。字符串可以直接声明并赋值,如下所示:

String name = "mike"; 

它们也可以转换为字节,如下所示:

Bytes byteName = bytes(name);

数组属性

数组支持一些基本的属性。在 Solidity 中,由于有多种类型的数组,并非每种类型都支持所有这些属性。

这些属性如下所示:

  • index:除了字符串类型外,所有类型的数组都支持用于读取单个数组元素的 index 属性。仅动态数组,固定数组和字节类型支持用于写入单个数组元素的 index 属性。字符串和固定大小的字节数组不支持写入。
  • push:仅动态数组支持此属性。
  • length:除了字符串类型外,此属性由读取透视图中的所有数组支持。只有动态数组和字节支持修改长度属性。

2.2 结构

结构或结构体有助于实现自定义的用户数据类型。结构是一种复合数据类型,由多个不同数据类型的变量组成。它们与合约非常相似,但是,它们不包含任何代码。它们只包含变量。

Solidity 的结构中的 struct 关键字进行声明。结构中的变量在花括号{}内定义,如图所示:

  struct user {
    string name;
    uint   age;
    int   id;
    address addr;
  }

使用下面的语法来创建一个结构的实例。不需要显式调用关键字 new。关键字new只用于创建合约或者数组的实例,如图所示:

student = user("LiMing", 23, 1, 0xc6a115f2abc09746963d6a6800bd82157d27d8e7);

2.3 映射

映射是 Solidity 中最常用的复杂数据类型之一。映射类似于其他语言中的散列表或字典。它们存储键值对,并允许根据提供的键来检索值。

使用 mapping 关键字声明映射,后跟由=>表示法分隔的键和值的数据类型。映射具有与任何其他数据类型一样的标识符,并且它们可用于访问映射。

一个声明映射的例子如下:

mapping(uint => address) Names;

在前面的代码中,uint 数据类型用于存储键而 address 数据类型用于存储值。Names 用作映射的标识符。

虽然它类似于散列表和字典,但 Solidity 不允许迭代映射。如果键已知,则可以检索映射中的值。下一个示例说明如何使用映射。合约中维护有一个 uint 类型的计数器作为映射的键,并且在函数的帮助下存储和检索地址详细信息。

要访问映射中的任何特定值,相关键应与映射名一起使用,如下所示:

Names[uint(3)]

要在映射中存储值,请使用以下语法:

Names[uint(4)] = 0xc6a115f2abc09746963d6a6800bd82157d27d8e7

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/Liuzhiwang29/article/details/107557351