智能合约入门系列(四) -值类型

368 阅读4分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战

前言

对于solidity语言来说,它也有自己的类型,跟其他语言类似,分为值类型和引用类型,本文让我们去看看它所包含的类型,从值类型开始。

类型分类

1.布尔类型 bool

跟其他各类语言一样,布尔值true or false ,在代码中定义如下

bool b=false;

2.整型

关键字分为int和uint,int是带符号整形的(可能为负数),uint是不带符号整形。int从int8到int256,uint也是从uint8到uint256。

int8到int256,其取值范围逐渐变大,uint8到uint256也是同理,表示如下

Int8, 占1个字节.取值范围-128到 127
int16, 占2个字节.取值范围 -32768 到32767
uint8,占1个字节,取值范围0到255
uint16,占2个字节,取值范围0到65535

uint256 的取值范围为0到2^256-1

不写则默认int256/uint256

  uint c=1;  int d=2;

值得注意的是:uint256当取最大整数值,上溢之后直接回绕返回值为0,uint256当取0下溢之后直接回绕,返回值为2^256-1。

3.定长浮点型

关键字 fixed / ufixed:表示各种大小的有符号和无符号的定长浮点型。 在关键字 ufixedMxNfixedMxN 中,M 表示该类型占用的位数,N 表示可用的小数位数。 M 必须能整除 8,即 8 到 256 位。 N 则可以是从 0 到 80 之间的任意数。 ufixedfixed 分别是 ufixed128x19fixed128x19 的别名。

注意的是Solidity 还没有完全支持定长浮点型。可以声明定长浮点型的变量,但不能给它们赋值或把它们赋值给其他变量。

4.地址类型

关键字address

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

从 0.5.0 版本开始,合约不会从地址类型派生,但仍然可以显式地转换成地址类型。

这个类型比较特别,它还有其成员变量

balance  使用方式

.balance 返回uint256

transfer 使用方式

.transfer(uint256 amount)向某个地址发送代币。

5.定长字节数组

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

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

可以将 byte[] 当作字节数组使用,但这种方式非常浪费存储空间,准确来说,是在传入调用时,每个元素会浪费 31 字节。 更好地做法是使用 bytes。

6.枚举类型

枚举类型至少需要一个成员,且不能多于256个成员。整数类型和枚举类型只能显式转化,不能隐式转化。整数转枚举时需要在枚举值的范围内,否则会引发Panic error

pragma solidity ^0.4.16;

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

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

    // 由于枚举类型不属于 |ABI| 的一部分,因此对于所有来自 Solidity 外部的调用,
    // "getChoice" 的签名会自动被改成 "getChoice() returns (uint8)"。
    // 整数类型的大小已经足够存储所有枚举类型的值,随着值的个数增加,
    // 可以逐渐使用 `uint16` 或更大的整数类型。
    function getChoice() public view returns (ActionChoices) {
        return choice;
    }

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

7.函数类型

函数可以作为类型,可以被赋值,而且也可以作为其他函数的参数或者返回值。

分为- 内部(internal) 函数和 外部(external) 函数。

表示如下

function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]

函数类型默认是内部函数,内部函数相当于只有在合约内部才能调用,但是在合约内定义的函数可见性必须明确声明在合约内定义函数的位置时任意的,可以调用后面才定义的函数。

外部函数可以通过如下方式使用。

pragma solidity ^0.4.11;

contract Oracle {
  struct Request {
    bytes data;
    function(bytes memory) external callback;
  }
  Request[] requests;
  event NewRequest(uint);
  function query(bytes data, function(bytes memory) external callback) public {
    requests.push(Request(data, callback));
    NewRequest(requests.length - 1);
  }
  function reply(uint requestID, bytes response) public {
    // 这里要验证 reply 来自可信的源
    requests[requestID].callback(response);
  }
}

contract OracleUser {
  Oracle constant oracle = Oracle(0x1234567); // 已知的合约
  function buySomething() {
    oracle.query("USD", this.oracleResponse);
  }
  function oracleResponse(bytes response) public {
    require(msg.sender == address(oracle));
    // 使用数据
  }
}

总结

solidity的值类型大致有以上这些,在平常练习的时候可以多写写,请体会这些类型,就会逐渐理解它们之间的运用,还有一些地址字面常数、有理数和整数字面常数、字符串字面常数、十六进制字面常数等比较少,暂时不做详细说明,有兴趣还可以去了解。

附上一份其他平台翻译的官方文档链接可以看到更详细的说明

cw.hubwiz.com/card/c/soli…