Solidity编程语言(8)--字节数组

字节数组可以看作一种特殊的数组,其元素类型是字节。在类型声名时有其专有的声名方式。作为数组他有不固定长度字节数组和固定长度字节数组。

###不固定长度字节数组

###固定长度字节数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pragma solidity >=0.4.0 <0.6.0;

contract EgFixedByteArray {
byte[5] ba5;
bytes5 bs5;

function modify() public{
ba5 = [byte('1'),'2','3','4','5'];
//ba5.push(6);
//ba5.length = 6;
//bs5 = [byte('1'),'2','3','4','5'];
ba5[1] = '0';
bs5 = '12345';
//bs5.length = 6;
//bs5.push(6);
//bs5[1] = '0';
}
}
  1. 固定长度字节数组可以使用以下两种方式声名,一种是使用数组声名,一种是使用关键字声名,其中bytes后边的数字范围是从1至32,即不能使用bytes33。在实际编码中,如果确定长度最好使用这种方式。
  • byte[5] bs5;
  • bytes5 bs5_;
  1. 不管哪种方式声名的,都不可以修改length以及使用push方法
  2. bytes5这种方式的声名不能使用数组来进行赋值的
  3. bytes5这种方式声名的字节数组其内容是不可修改的
    ###不固定长度字节数组(动态数组)
    不固定长度字节数组同理也有两种方式声名,数组和关键字。数组方式其特性就是数组的特性,这里我们看下使用关键字bytes的方式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    pragma solidity >=0.4.0 <0.6.0;

    contract EgUnFixedByteArray {
    bytes name = new bytes(5);

    function modifyName() public returns( bytes memory) {
    name.length = 6;
    name.push('9');
    name[1] = '1';
    return name;
    }

    }

###转换
这里主要说下固定长度字节数组、不固定长度字节数组以及string之间的转换

  1. 固定长度字节数组之间的转换
    1
    2
    3
    4
    5
    6
    7
    8
    contract EgSwitchBytes{
    function switchBytes1() public returns(bytes2) {
    bytes2 bs2 = '12';
    bytes5 bs5 = '00000';
    //return bytes2(bs5);
    return bytes2(bs5);
    }
    }

长度较长的固定长度字节数组可以转成转短的,反过来则不行,而长的转成短的会将后边的部分长度截取掉,比如上边的bs5转成bytes2的时候会把‘234’截取掉的。

  1. 固定长度字节数组和不固定长度字节数组或者string的转换
    function switchBytes2() public {

    /*bytes5 bs5 = '00000';
    bytes bs = bytes(bs5);//固定长度字节数组与不固定长度字节数组不能直接转换
    
    bytes memory bs = new bytes(10);
    bytes5 bs5 = bytes5(bs);//固定长度字节数组与不固定长度字节数组不能直接转换
    */
    bytes memory bs = new bytes(10);
    string memory str = string(bs);
    
    string memory str1 = "abcd";
    bytes memory bs1 = bytes(str1);
    
    /*bytes5 memory bs5 = '00000';
    string memory str2 = string(bs5);//固定长度字节数组与string不能直接转换
    
    string memory str3 = "abcd";
    bytes5 memory bs5_ = bytes5(str3);//固定长度字节数组与string不能直接转换
    */

    }
    固定长度字节数组与不固定长度字节数组或者string(本质也是不固定长度字节数组)不能互相直接转换,但是string和bytes可以。

  2. 怎么转换固定长度字节数组
    这里说下思路,就是遍历固定长度字节数组,然后逐个把元素赋值到不固定长度字节数组中,这样就得到了不固定长度字节数组,也可以再次通过不固定长度字节数组转换成string。其中有个问题是比如bytes5 bs5 = ‘1’,本来bs5的类型是bytes5,也就是应该包含5个字节,但实际只赋值了‘1’,那么其余4个字节是啥呢?是空的,也就是\u0000,即空字符(不是空格,也不是null),所以在遍历的时候会把四个\u0000也进行了遍历。导致不固定长度字节数组中包含了4个\u0000,转成的string也有问题。所在在转换的时候要考虑\u0000的问题。

bytes和string是一种特殊的数组。bytes类似byte[],但在外部函数作为参数调用中,会进行压缩打包,更省空间,所以应该尽量使用bytes4。string类似bytes,但不提供长度和按序号的访问方式。