Solidity数据类型

这篇具有很好参考价值的文章主要介绍了Solidity数据类型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Solidity 是一种静态类型语言,这意味着每个变量(状态变量和局部变量)都需要在编译时指定变量的类型。

Solidity 提供了几种基本类型,并且基本类型可以用来组合出复杂类型。

Solidity数据类型

除此之外,类型之间可以在包含运算符号的表达式中进行交互。

“​​undefined​​​”或“​​null​​​”值的概念在Solidity中不存在,但是新声明的变量总是有一个 默认值 ,具体的默认值跟类型相关。 要处理任何意外的值,应该使用错误处理来恢复整个交易,或者返回一个带有第二个​​bool​​ 值的元组表示成功。

bool/布尔类型

布尔值的取值范围为 true 和 false 。

默认值:​​false​

pragma solidity ^0.8.0;

contract TestBool {
  error NotEqual(bool A,bool B);
  bool public A; // false
  bool public B = true; //true
    // require(A==B,"A not equal B");

  if (A != B) {
    error NotEqual(A,B);
  }
}

运算符:

  • ​!​​(逻辑非)
  • ​&&​​ (逻辑与, “and” )
  • ​||​​ (逻辑或, “or” )
  • ​==​​ (等于)
  • ​!=​​ (不等于)

int、uint/整数类型

int 有符号整型

默认为​​int256​

不同位长的整形范围如下:

  • ​int8​​ 取值范围:-(2 ** 7)到 2 ** 7 -1
  • ​int16​​取值范围:-(2 ** 15)到 2 ** 15 -1
  • ...
  • ​intX​​取值范围:-(2**​​X​​​-1)到 2**(​​X​​-1) -1
  • ​int256​​取值范围:-(2 ** 255)到 2 ** 255 -1

uint 无符号整型

默认为​​uint256​

不同位长的整形范围如下:

  • ​uint8​​取值范围:0 到 2 ** 8 - 1
  • ​uint16​​取值范围:0 到 2 ** 16 - 1
  • ...
  • ​uintX​​取值范围:0 到 2 ** ​​X​​ - 1
  • ​uint256​​取值范围:0 到 2 ** 256 - 1

运算符:

  • 比较运算符: <= , < , == , != , >= , > (返回布尔值)
  • 位运算符: & , | , ^ (异或), ~ (位取反)
  • 移位运算符: << (左移位) , >> (右移位)
  • 算数运算符: + , - , 一元运算负 - (仅针对有符号整型), * , / , % (取余或叫模运算) , ** (幂)

对于整形 X,可以使用 type(X).min 和 type(X).max 去获取这个类型的最小值与最大值。

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

contract TestIntval {
    int8 public i8 = -1;
    int public i256 = 456;
    int public i = -123; // int 等同于 int256
    // int 的最大最小值
    int public minInt = type(int).min;
    int public maxInt = type(int).max;

    uint8 public u8 = 1;
    uint256 public u256 = 456;
    uint public u = 123; // uint  等同于 uint256 
        // uint 的最大最小值
    uint public minUInt = type(uint).min;
    uint public maxUInt = type(uint).max;

    
    function mini() public pure returns(uint8){
        return type(uint8).max;
    }
}

0.8.0 开始,算术运算有两个计算模式:一个是 “wrapping”(截断)模式或称 “unchecked”(不检查)模式,一个是”checked” (检查)模式。 默认情况下,算术运算在 “checked” 模式下,即都会进行溢出检查,如果结果落在取值范围之外,调用会通过 失败异常 回退。 你也可以通过 ​​unchecked { ... }​​切换到 “unchecked”模式

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract C {
    function f(uint a, uint b) pure public returns (uint) {
        // 减法溢出会返回“截断”的结果
        unchecked { return a - b; }
    }
    function g(uint a, uint b) pure public returns (uint) {
        // 溢出会抛出异常
        return a - b;
    }
}

Solidity数据类型

调用 ​​f(2, 3)​​​将返回 ​​2**256-1,​​​ 而​​ g(2, 3)​​ 会触发失败异常。

​unchecked​​ 代码块可以在代码块中的任何位置使用,但不可以替代整个函数代码块,同样不可以嵌套。

此设置仅影响语法上位于 ​​unchecked​​ 块内的语句。 在块中调用的函数不会此影响。

address/地址

默认值: 0x0000000000000000000000000000000000000000

运算符:

  • <=, <, ==, !=, >= and >

示例:

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

contract TestAddress {
    //与其他机器语言相区别的类型就是这个address 类型,160-bit/20byte
    address public myAddr = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
    //合约自己的地址
    address contractAddress = address(this);
    //跟普通的地址类型一样,但多了两个方法 transfer/send 这两个方法后面章节会讲到
    // address sender = payable(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4);
    //可以使用 balance 属性来查询一个地址的余额
    function getBalance()
        public view
        returns (uint256, uint256)
    {
        require(myAddr.balance < contractAddress.balance, "1 must lg 2");
        return (myAddr.balance, contractAddress.balance);
    }
}

Solidity数据类型

bytes/字节数组

在计算机中的最小存储单位是 bit(位)

  • 1byte等于8位
  • Solidity中,byte可以赋值为
  • 16进制数字
  • 单引号的单个或多个字符

定长字节数组

bytes1 后面数字1是表示1字节 bytes默认等于bytes1
Bytes2 后面数字2是表示2字节
Bytes3 后面数字3是表示3字节
bytes4 后面数字4是表示4字节

...

bytes32 后面数字32是表示32字节

bytes32 等价于 int256或uint256 的位数

运算符

  • 比较运算符: <=, <, ==, !=, >=, > (返回布尔型)
  • 位运算符: &, |, ^ (按位异或), ~ (按位取反)
  • 移位运算符: << (左移位), >> (右移位)
  • 索引访问:如果 x 是 bytesI 类型,那么 x[k] (其中 0 <= k < I)返回第 k 个字节(只读)。

成员变量

​.length​​ 表示这个字节数组的长度(只读)

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

contract BytesTest {
    //定长字节数组,长度不可变
    bytes1 public num1 = 0x12;
    // bytes1 public num1 = 0x112; 溢出最大长度,这样会报错

    // 也可以写成字符串类型
    bytes4 public num2 = "0x12";
    //也支持直接写 16 进制
        bytes4 public num3 = 0x12121212;
    //不足位的补0
    bytes32 public num4 = 'abc';  //0x6162630000000000000000000000000000000000000000000000000000000000
    
    function getlength1() public view returns (uint8) {
        return num1.length;
    }
    function getlength2() public view returns (uint8) {
        return num2.length;
    }
}

string/字符串

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

contract TestString {
    string public myString = "hello";
    string public myStringUnicl = unicode"你好"; //unicode 编码
    string public myStringUnicl2 = unicode"你好😄"; //unicode 编码

    // 两个字符串连接用 concat
    function strConcat(string memory _a, string memory _b)
        public
        pure
        returns (string memory)
    {
        return string.concat(_a, _b);
    }
    // 也可以转成bytes,bytes 和 string 可以互转
    function bytesConcat(string memory _a, string memory _b) public pure returns (string memory){
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
        bytes memory ret = bytes.concat(_ba,_bb);
        return string(ret);
    }
}

enum/枚举

枚举可以在合约之外声明,也可在合约内声明.

默认取值为第一个元素的值

contract UserState {
  // 枚举
  //默认值是列表中的第一个元素
  enum State { 
    Online,   // 0
    Offline,  // 1
    Unknown   // 2
  } 

  Status public status;
  function get() public view returns (Status) {
      return status;
  }
  // 通过将uint传递到输入来更新状态
  function set(Status _status) public {
      status = _status;
  }
  // 也可以是这样确定属性的更新
  function off() public {
      status = Status.Offline;
  }
  // delete 将枚举重置为其第一个值 0
  function reset() public {
      delete status;
  }
}

struct/结构体

您可以通过创建结构来定义自己的类型。

它们用于将相关数据分组在一起。

结构可以在合约之外声明,也可以在另一个合约中导入。

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

contract Structs {
    struct Todo {
        string text;
        bool completed;
    }
    // 结构体数组
  
    Todo[] public todos;

    // 初始化结构的3种方法
    function create(string calldata _text) public {
        // 1.像函数一样调用它
        todos.push(Todo(_text, false));
        // 2. 键值对
        todos.push(Todo({text: _text, completed: false}));
        // 3.初始化一个空结构,然后更新它
        Todo memory todo;
        todo.text = _text;
        todos.push(todo);// completed 没有定义,默认为 false
    }
    //通过索引获取结构体数组中一个元素,并更新内部的属性
    function update(uint _index) public {
        Todo storage todo = todos[_index];
        todo.completed = !todo.completed;
    }
}

mapping/映射

映射是使用语法映射(keyType=>valueType)创建的。

keyType可以是任何内置值类型、字节、字符串或任何约定。

valueType可以是任何类型,包括另一个映射或数组。

映射不可迭代。

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

contract Mapping {
    //从地址到uint的映射
    mapping(address => uint) public myMap;

    function get(address _addr) public view returns (uint) {
        //映射始终返回一个值。
                //如果从未设置该值,它将返回默认值。
        return myMap[_addr];
    }
    // 更新此地址的值  
    function set(address _addr, uint _i) public {
        myMap[_addr] = _i;
    }

    function remove(address _addr) public {
                //将值重置为默认值
        delete myMap[_addr];
    }
}
//嵌套 mapping
contract NestedMapping {
    //嵌套映射(从地址映射到另一个映射)
    mapping(address => mapping(uint => bool)) public nested;

    function get(address _addr1, uint _i) public view returns (bool) {
        // 可以从嵌套映射中获取值
        return nested[_addr1][_i];
    }

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

    // 删除 mapping 的一个元素
    function remove(address _addr1, uint _i) public {
        delete nested[_addr1][_i];
    }
}

array/数组

初始化数组的几种方法


//初始化数组的几种方法
    uint256[] public arr;
    uint256[] public nums = [1, 2, 3];
    //定长数组,所有元素初始化为 0
    uint256[10] public myFixedSizeArr;
    //未定义初始值的元素默认为 0
    uint256[3] public three = [4, 5];

    // 直接打印数组列表;
    function getNums()
        external
        view
        returns (
            uint256[] memory,
            uint256[] memory,
            uint256[10] memory,
             uint256[3] memory
        )
    {
        return (arr, nums, myFixedSizeArr,three);
    }

Solidity数据类型文章来源地址https://www.toymoban.com/news/detail-414615.html

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

contract Array {
    //初始化数组的几种方法
    uint256[] public arr;
    uint256[] public nums = [1, 2, 3];
    //定长数组,所有元素初始化为 0
    uint256[10] public myFixedSizeArr;
    uint256[3] public three = [4, 5, 6];

    // 获取数组长度
    function getLen() external view returns (uint256) {
        return nums.length;
    }
    //向数组中添加值
    function pushIndex(uint256 _x) external {
        nums.push(_x);
    }
    // 这样删除数组不会改变数组长度,被删除的数字索引值会变成 0
    function deleteIndex(uint256 _x) external {
        delete nums[_x];
    }
    //不改变数组顺序情况下删除数组
    //通过循环删除数组索引 [1,2,3,4] => [1,3,4,4] => [1,3,4]
    function removeIndex(uint256 _x) public {
        require(_x < nums.length, "out of index");
        for (uint256 i = _x; i < nums.length - 1; i++) {
            nums[i] = nums[i + 1];
        }
        nums.pop();
    }
    // 删除数组会改变元素的顺序,但是节省 gas
    //[1,2,3,4]=> [1,4,3,4]=>[1,4,3]
    function removeIndex2(uint256 _x) public {
        require(_x < nums.length, "out of index");
        nums[_x] = nums[nums.length - 1];
        nums.pop();
    }
    //移除数组最后一个元素
    function pop() external {
        nums.pop();
    }
    //方法测试
    function testRemove() external {
        nums = [1, 2, 3, 4];
        removeIndex(2);
        assert(nums[0] == 1 && nums[1] == 2);
        assert(nums[2] == 4);
        assert(nums.length == 3);
    }
}

到了这里,关于Solidity数据类型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 以太坊开发学习-solidity(三)函数类型

    目录 函数类型 函数类型 solidity官方文档里把函数归到数值类型 函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量, 也可以将一个函数作为参数进行传递,还能在函数调用中返回函数类型变量。 函数类型有两类:-  内部(internal)  函数和  外

    2024年04月09日
    浏览(58)
  • 玩以太坊链上项目的必备技能(类型-引用类型-Solidity之旅三)

    在前文我们讲述了值类型,也就说再修改值类型的时候,每次都有一个独立的副本,如:string 类型的状态变量,其值是无法修改,而是拷贝出一份该状态的变量,将新值存起来。对于处理稍微复杂地值类型时,拷贝将变得愈发大了,也正是介于此,才考虑到将数据存放在 内

    2024年01月24日
    浏览(44)
  • 一起学solidity写智能合约——地址类型(address)

    在区块链中说地址重不重要,其实会被笑,然后会让你去恶补一下知识点,哈哈哈哈哈哈,地址可以没有区块链,但是区块链不能没有地址,这句话不是开玩笑。 地址类型是在以太坊的诞生之后出现的一个特有类型,他是一个大小160位的二进制数字 在地址中我们可以说有很

    2023年04月16日
    浏览(39)
  • Solidity之变量数据存储和作用域

    引用类型(Reference Type):包括数组(array),结构体(struct)和映射(mapping),这类变量占空间大,赋值时候直接传递地址(类似指针)。由于这类变量比较复杂,占用存储空间大,我们在使用时必须要声明数据存储的位置。 solidity数据存储位置有三类:storage,memory和calldat

    2024年02月05日
    浏览(40)
  • 如何使用solidity将数据链上存储

    # 如何使用solidity将数据链上存储 ## 文章起始 在看过FISCO BCOS张开翔老师的一文说清“链上”和“链下”过后,我对于数据链上存储有了非常浓厚的兴趣,因此写下了本篇文章,用于自己进行学习 环境:solidity,webase-font,FISCO-BCOS节点链   ## 正文 首先,当我第一次看到这篇文

    2024年01月20日
    浏览(39)
  • solidity第五课——变量数据存储和作用域

    solidity中的引用类型 solidity中的引用类型包括数组array,结构体struct和映射mapping。这类变量占空间大,赋值时候直接传递地址(类似指针)。由于这类变量比较复杂,占用存储空间大,我们在使用时必须要声明数据存储的位置。 solidity数据存储位置有三类:storage,memory和calld

    2024年02月07日
    浏览(42)
  • Solidity拓展:数学运算过程中数据长度溢出的问题

    在数学运算过程中 假如超过了长度则值会变成该类型的最小值,如果小于了该长度则变成最大值 数据上溢  uint8的定义域为[0,255],现在numA已经到顶了,numA++会使num变成0(由于256已经超过定义域,它会越过256,变成0),即数据发生上溢(越过上边界,叫上溢)。255 -- 256 --0 上溢。

    2024年02月11日
    浏览(32)
  • 【区块链 | EVM】深入理解学习EVM - 深入Solidity数据存储位置:内存

    图片来源: Mech Mind on Unsplash 这是深入Solidity数据存储位置系列的另一篇。在今天的文章中,我们将学习EVM内存的布局,它的保留空间,空闲内存指针,如何使用 memory 引用来读写内存,以及使用内存时的常规最佳做法。 我们将使用 Ethereum Name Service (ENS)中的合约代码片段,

    2024年02月02日
    浏览(50)
  • Solidity迁移Flow Cadence指南13-Flow 1000+合约大数据分析

    熟读唐诗三百首,不会做诗也会吟,Flow合约哪里读?自然是链上了,Flow的链上合约都是开源的,只要知道合约地址,都可以直接使用API获得具体的合约代码。本节就把flow链上的主要合约下载下来,然后分析,哪些可以读,哪些可以抄@#¥@#¥ 数据来源 本文主要分析合约账号

    2024年02月03日
    浏览(43)
  • 【java的类型数据】——八大类型数据

    字面常量就是在程序运行期间,固定不变的量。 1.字符串常量:括号括起来的,比如”12345”、“hello”、 “你好” 2.整形常量:程序中直接写的数字(注意没有小数点),比如: 100、1000 3.浮点数常量:程序中直接写的小数,比如: 3.14、 0.49 4.字符常量:由单引号括起来的当个字符,比

    2024年02月15日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包