Cover photo

值类型

Solidity基本数据类型

  1. 值类型(Value Type):包括布尔类型,整形等。

  2. 引用类型(Reference Tyep):包括数组和结构体等。

  3. 映射类型(Mapping Type):键值对数据结构。

值类型

布尔类型

布尔类型是二值变量,取值为 true 或 false

    bool public _bool = true;          //定义bool类型变量_b

布尔类型的运算符包括:

  • ! (逻辑非)

  • && (逻辑与)

  • || (逻辑或)

  • == (相等)

  • != (不相等)

运算符||&&都遵循短路规则,如f(x) || g(y)中,如果f(x)的值为true,那么g(y)就不会被执行

    //布尔类型
    bool public _bool = true;          //定义bool类型变量_b
    bool public _bool1 = !_bool;          //非运算
    bool public _bool2 = _bool && _bool1;    //与运算
    bool public _bool3 = _bool || _bool1;    //或运算
    bool public _bool4 = _bool == _bool1;    //相等判断
    bool public _bool5 = _bool != _bool1;    //不相等判断

整形

int/uint:分别表示有符号和无符号整形变量。关键字uint8uint256(无符号整形,从8位到256)以及int8int256,以8位位步长递增(就是按字节为单位增长,int8占一个字节,int16占两个字节,int256占32字节)。uintint分别是uint256int256的别名。

    //整形
    int public _max_int8 = type(int8).max;      //127
    int public _min_int8 = type(int8).min;      //-128
    uint public _max_uint8 = type(uint8).max;   //255
    uint public _min_uint8 = type(uint8).min;   //0
    int public _max_int16 = type(int16).max;    //32767
    int public _min_int16 = type(int16).min;    //-32768
    uint public _max_uint16 = type(uint16).max; //65535
    uint public _min_uint16 = type(uint16).min; //0
    int public _max_int256 = type(int256).max; 
    int public _min_int256 = type(int256).min;
    uint public _max_uint256 = type(uint256).max;
    uint public _min_uint256 = type(uint256).min;

对于整形X,可以使用type(X).maxtype(X).min来获取对应大小。

运算符:

  • 比较运算符: <=<==!=>=> 返回布尔类型

  • 位运算符:&(与),|(或),^(异或),~(取反) 返回位运算后的值

  • 移位运算符:<<(左移),>>(右移) 返回移位后的值

  • 算数运算符:+-*/%**(幂运算) 返回算数运算后的值

    //运算符
    uint256 public _number = 1;
    uint256 public _number1 = _number + 1;          //算数运算
    uint256 public _number2 = 2**2;                 //幂运算
    uint256 public _number3 = 7 % 2;                //取余
    int256 public _number4 = ~int256(0);            //取反
    uint256 public _number5 = _number >> 2;         //右移
    uint256 public _number6 = _number << 2;         //左移
    bool public _numberbool = _number2 > _number3;  //比较运算

地址类型

地址类型有两种大致相同的类型:

  • address:保存一个20字节的值(一个以太坊地址的大小)。

  • address payable:与address类型相同,但有额外的方法transfersend

这种区别背后的想法是,address payable是一个可以发送以太币的地址,address是不应该发送以太币的地址,因为它可能是一个合约地址,合约地址不是为了接收以太币而建立的。

类型转换:

允许从address payableaddress的隐式转换,而从addressaddress payable的转换必须通过payable(address)来实现。

对于uint160、整数、bytes20和合约类型,允许对address进行明确的转换和输出。

只有address类型和合约类型的表达式可以通过payable(……)显式转换为address payable类型。对于合约类型,只有在合约可以接收以太币的情况下才允许这种转换,也就是说,合约要么有一个receive函数,要么有一个payable类型的fallback函数。请注意,payable(0)是有效的,是这个规则的例外。

运算符:

  • <=<==!=>=>

如果您使用较大字节的类型转换为 address,例如 bytes32,那么 address 就被截断了。为了减少转换的模糊性,从 0.4.24 版本开始,编译器将强迫您在转换中明确地进行截断处理。以32字节的值0x111122333344556677888899AAAABBBBCCCCDDDDEEFFFFCCCC 为例。

您可以使用address(uint160(bytes20(b))),结果是0x111122223333444455556666777788889999aAaa,或者您可以使用 address(uint160(uint256(b))),结果是 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc。

    uint256 public _uint256_number = 0x111122333344556677888899AAAABBBBCCCCDDDDEEFFFFCCCC; 
    address public _unit256_address = address(uint160(_uint256_number));             //截取地址
    address public _bytes20_address = address(bytes20(bytes32(_uint256_number)));    //截取地址

    address payable public _payable_address = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;    //接收地址
    address payable public _my_address = address(this);                                      //发送地址

地址类型成员变量

  • balancetransfer

可以上使用balance属性来查询一个地址的以太币余额,也可以使用transfer函数向一个地址发送以太币,单位位wei。

    address payable public _receive_address = payable(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2);    //接收地址
    address public _send_address = address(this);                                                     //发送地址

    function addressTransfer() public {
        if (_receive_address.balance < 10 && _send_address.balance > 10) {
            _receive_address.transfer(10);  //转账
        }
    }

如果当前合约的余额不足,或者以太币转账被接收者拒收,那么transfer功能就会失败,transfer功能在失败后会还原。

  • send

sendtransfer的低级对应部分。如果执行失败,当前的合约不会因异常而停止,但send会返回false.

    function addressSend() public {
            if (_receive_address.balance < 10 && _send_address.balance > 10) {
                _receive_address.send(10);  //转账,编译带警告,提示用transfer来替换send

            }
        }
  • calldelegatecallstaticcall

为了与不遵守ABI的合约对接,或者为了更直接的控制编码,所以提供了calldelegatecallstaticcall函数。它们都接收一个bytes memory参数,并返回是否成功条件bool和返回数据bytes memory。函数abi.encodeabi.encodePackedabi.encodeWithSelectorabi.encodeWithSignature可以用来编码结构化数据。

枚举 enum

枚举(enum)是 Solidity 中用户定义的数据类型。它主要用于为 uint 分配名称,使程序易于阅读和维护。它与 C 语言 中的 enum 类似,使用名称来代替从 0 开始的 uint

    // 用enum将uint 0, 1, 2表示为Buy, Hold, Sell
    enum ActionSet { Buy, Hold, Sell }
    // 创建enum变量 action
    ActionSet action = ActionSet.Buy;

枚举可以显式地和 uint 相互转换,并会检查转换的正整数是否在枚举的长度内,否则会报错:

    // enum可以和uint显式的转换
    function enumToUint() external view returns(uint){
        return uint(action);
    }