solidity学习之固定长度字节数组byte

隐身守侯 提交于 2020-09-23 16:47:41

在学习solidity过程中,发现这门语言和之前学的C、C++、Java以及Python有很多不同之处,但目前我学到的来看,字节数组byte使用的很频繁,而且也有很多不一样的东西。

1byte=8位(XXXX XXXX)X为0或1,二进制表示
byte数组的类型有:bytes1,bytes2,。。。,bytes32,以八个位递增,即是对位的封装
举例
bytes1=uint8
bytes2=unit16
......
bytes32=unit256





目前我自己了解到的byte使用这么频繁大致是因为它能更好的表示16进制

举例:bytes1=0x6A,bytes1=(XXXX XXXX)正好四个表示一个16进制,以此类推

下面我们通过一些例子来看看byte的用法

1.下面声明了一个一字节以及一个4字节的变量

pragma solidity ^0.4.0;

contract test{
    bytes1  num1 = 0x12;  //0x是16进制的表示方法 12是一字节
    bytes4  num2 = 0x12121212; //以此类推12 12 12 12 共四字节
}

如果我们想运行这个合约,点击这个变量就可以返回相应的结果可以使用下面这种方法:

pragma solidity ^0.4.0;

contract test {
    bytes1 public num1 = 0x12;  
    bytes4 public num2 = 0x12121212;
}

bytes数据声明时加入public可以自动生成调用长度的函数,相当于写了个get()方法。

å¨è¿éæå¥å¾çæè¿°

2.bytes内部自带length长度函数,而且长度固定,而且长度不可以被修改,通过.length可以返回字节长度

pragma solidity ^0.4.0;

contract test {
    bytes1 public num1 = 0x12;  
    bytes4 public num2 = 0x12121212;

    function getlength1() public view returns(uint8){
        return num1.length;
    }

    function getlength2() public view returns(uint8){
        return num2.length;
}

3.固定字节数组与string之间的转换

上面我们说过字节数组byte可以通过.length获取其长度,但是字符串却不能这样使用,而且字符串也不能直接像字节数组一样num[0]通过索引这样来获取字符,如果需要获取长度或者元素,string需要先转换为byte类型才可以

通过下面的例子大家可以体会下具体的用法。

pragma solidity ^0.4.0;


contract String_Math{
    string name = "wangyufeng"; //0x77616e67797566656e67
    string name1 = "王不二";
    
    function getlength()  returns(uint){
        // return name.length; 错误
        return bytes(name).length;
    }
    
    function getName()  returns(bytes){
        return bytes(name);
    }
    
     function getName1()  returns(bytes){ // 0xe78e8be4b88de4ba8c
        return bytes(name1);
    }
    
    function changeName(){ 
        bytes(name)[0] = "p";  // 0x70616e67797566656e67
    }
}

通过上面的例子我们大概知道了字节数组与string之间的转换,现在我们通过下面的一个例子进一步深入讲解

我们现在想将字节数组拷贝到字符串里面去,那么我们该怎么实现呢?

pragma solidity ^0.4.0;

contract test_bytesTostring{
    
    bytes2 name = 0x7a68;
    
    function bytes32Tostring(bytes32 new_name) returns(string){
        bytes memory _newName = new bytes(new_name.length);
        
        for(uint i=0;i<new_name.length;i++){
            _newName[i] = new_name[i];
        }
        
        return string(_newName);
    }
    
}

通过传入一个字节长度为32(最大可输入的字节长度为32,不一定是32位)的变量然后通过转换位一个string类型,运行结果如下:

可以看到我们输入与输出是一样的,但是这里我们可以发现我们输入的是0x7a68,但是输出的是:

"0": "string: zh\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"

这显然不是我们想要的结果,因为后面有30个0,这是我们不需要的,我们只需要zh这个结果(0x7a68对应的字母是zh),所以我们需要通过方法将后面的0截掉。

pragma solidity ^0.4.0;

contract test_bytesTostring{
    
    bytes2 name = 0x7a68;
    

    
    function bytes32Tostring2(bytes32 new_name) returns(string){
      
        uint count = 0; //定义一个计数器
        
        for(uint i=0;i<new_name.length;i++){//通过循环判断单个字符是否为0
            bytes1 char = new_name[i];
            if(char != 0){ // 如果字符不为0,就将count+1
                count++;
            }
        }
        
        bytes memory _newName = new bytes(count);//此时字节数组的长度变为了count,因为count不包含0
        
        for(uint j = 0;j < count;j++){//进行赋值
            _newName[j] = new_name[j];
        }
        
        return string(_newName);//输出结果
    }
    
    
    
}

运行结果如下:

 

目前对byte字节数组了解的只有这么多了,后续还有新知识我会在下面更新的。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!