solidity基础-值类型

数据和变量

  • Solidity 是一种静态强类型的语言
  • 变量类型和需要赋值的数据类型必须匹配,或者所赋值的数据可以隐式转换为变量类型

两种类型的数据

值类型

  • 值类型传值时会将值拷贝一份,传递的是值本身
  • 始终按值来传递

引用类型

  • 引用类型进行传递时,传递的是其指针
  • 引用类型进行传递时,可以为值传递,也可以为引用传递
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    uint256 public u = 123;
    string public str1 = "b00l";
    string public str2 = "b00l";
  
    function test() external {

        // 修改值类型
        uint256 x = u;
        x = 1;

        // 修改引用类型,引用传递
        string storage str3 = str1;
        bytes(str3)[0] = bytes1("B"); // str1 的值变为 B00l

        // 修改引用类型,值传递
        string memory str4 = str2;
        bytes(str4)[0] = bytes1("B"); // str2 的值不变
    }
}

值类型

布尔类型

  • 只有 true 和 false 两个值
  • 布尔值除了赋值得到外,还可以通过运算符的运算结果得到

    • ! 逻辑非
    • == 等于, != 不等于
    • && 逻辑与,|| 逻辑或
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    bool public b1 = true;
    bool public b2 = false;

    bool public b3 = b1 == b2;
    bool public b4 = b1 != b2;

    bool public b5 = true && true;
    bool public b6 = true || false;
}

整数类型

  • 类型

    • 有符号整型,用 int 标识
    • 无符号整型,用 uint 标识
  • 属性

    • type(T).min 获取整型 T 的最小值
    • type(T).max 获取整型 T 的最大值
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    int256 public u = 123; // 123

    int8 public u8Min = type(int8).min; // -128
    int8 public u8Max = type(int8).max; // 127

    int256 public u256Min = type(int256).min; // -(2的128次方)
    int256 public u256Max = type(int256).max; // 2的128次方减1
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    uint256 public u = 123; // 123
    
    uint8 public u8Min = type(uint8).min; // 0
    uint8 public u8Max = type(uint8).max; // 0

    uint256 public u256Min = type(uint256).min; // 0
    uint256 public u256Max = type(uint256).max; // 2的256次方减1
}

整数字面常量

  • 整数字面常量中用 _ 增加可读性,不能出现在数字开头和结尾,且不能连写
  • 字面常量支持任意精度
  • 除法截断
  • 优先使用较小类型计算
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    uint public c1 = 123_456_789;
    int public c2 = -123_456_789;
    uint public c3 = 123456_789;
}

定长浮点型

  • Solidity还没有完全支持定长浮点型
  • 可以声明定长浮点型的变量,但不能给它们赋值或把它们的值给其他变量
  • 可以通过用户定义的值类型的 wrap / unwrap 来模拟出来

    • fixed / ufixed 表示各种大小的有符号和无符号的定长浮点数

定长字节数组

  • 定义方式 bytesN ,其中 N 可以取 1~32 中任意整数

    • bytes1 / bytes32
  • bytesN 和 bytes 不同

    • bytesN:是定长的字节数组,是值类型
    • bytes:是变长字节数组,是引用类型
  • 属性

    • length,通过 length 属性可以获取定长字节数组的长度
    • [index],获取定长字节数组的某个字节,但是不能修改
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    bytes1 public a1 = 0x66;
    bytes2 public a2 = 0x6600;
    bytes4 public a3 = 0x66000000;
    bytes6 public a4 = 0x660000000000;
    bytes7 public a5 = 0x66000000000000;
    bytes8 public a6 = 0x6600000000000000;
    bytes16 public a7 = 0x66000000000000000000000000000000;
    bytes32 public a8 =
        0x6600000000000000000000000000000000000000000000000000000000000000;

    uint8 public len8 = a8.length;
    bytes1 public index1 = a8[0];
    
}

字符串字面常量

  • 表现形式:" " 或 ' '
  • 字符串字面常量赋值给bytesN 时被解释为原始的字节形式
  • 转义字符

    • \':单引号
    • \":双引号
    • \\:反斜杠
    • \b:退格
    • \f:换页
    • \n:换行符
    • \r:回车
    • \t:标签tab
    • \v:垂直标签
    • \<newline>:(转义实际换行)

Unicode字符串字面常量

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

contract Demo {
    string public ustr = unicode'你好'; // 你好
}

十六进制字面常量

  • 十六进制字面常量以关键字 hex 开头,后面紧跟着用单引号或双引号包裹的字符串,例:hex"66"
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    bytes1 public h = hex"66"; // 0x66
    bytes3 public h3 = hex"66" hex"66" hex"66"; // 0x666666
    
}

Enum枚举

  • enum 是一种用于自定义的类型,用于表示多种状态

    • 主要作用是用于限制某个事务的有限选择,比如将咖啡容量限制为:大、中、小,这样就可以确保任何人都不能购买其他容量的咖啡
  • 枚举类型返回值是索引,默认值是0
  • 枚举类型至少应该有一个成员
  • 枚举不能多于256个成员

用户定义的值类型

Solidity允许我们在一个基本的值类型上创建一个零成本的抽象,类似于别名,但有更严格的类型要求

  • 定义
type UserType is DefaultType;
  • 方法

    • UserType.wrap():从底层类型转换到自定义类型
    • UserType.unwrap():从自定义类型转换到底层类型
  • 没有运算符,没有成员变量,连基本的 == 都没有

地址类型

地址类型分为外部地址和合约地址,每个地址都有一块持久化内存区,称为存储

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

contract Demo {
    address a = 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990;
}

address/uint/bytesN之间的转换

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

contract Demo {

    // 0x111122223333444455556666777788889999aaaabbbbccccddddeeeeffffcccc
    bytes32 public a1 =
        0x111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFFCCCC;

    //  0x111122223333444455556666777788889999aAaa
    address public a2 = address(uint160(bytes20(a1)));

    // 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc
    address public a3 = address(uint160(uint256(a1)));
    
}

两种形式的地址

  • address
  • address payable

属性

  • balance:返回以 wei 为单位的余额
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    // 获取输入地址的余额
    function getBalance1(address addr) public view returns (uint256) {
        return addr.balance;
    }

    // 获取调用账户的余额
    function getBalance2() external view returns (uint256) {
        return address(msg.sender).balance;
    }
}
  • code:返回当前地址的代码字节码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    function getCode() public view returns (bytes memory) {
        return address(this).code;
    }

}
  • codehash:返回地址的hash
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    function getCodeHash() public view returns (bytes32) {
        return address(this).codehash;
    }

}

方法

  • address():将地址转换到地址类型
  • payable():将普通地址转换为可支付地址
  • transfer(uint256 amount):将余额转到当前地址(合约地址转账)
  • send(uint256 amount):将余额转到当前地址,并返回交易成功状态(合约地址转账)
  • call(bytes memory):用给定的有效载荷(payable)发出低级 CALL 调用,并返回交易成功状态和返回数据(调用合约的方法并转账)
  • delegatecall(bytes memory):用给定的有效载荷(payable)发出低级 DELEGATECALL 调用,并返回交易成功状态和返回数据(调用合约的方法并转账)
  • staticcall(bytes memory):用给定的有效载荷(payable)发出低级 STATICALL 调用,并返回交易成功状态和返回数据(调用合约的方法并转账)

合约类型

在合约中可以将另一个合约当做类型使用

本文链接:

https://www.55geek.cn/index.php/archives/125/
1 + 7 =
快来做第一个评论的人吧~