通学智能合约系列(八)--字节数组转换

固定长度字节数组转化

我们之前也学习了那么多的数组了,那么这些数组类型是否可以相互转换呢?答案是肯定的。

我们先来看看固定长度字节数组各bytes之间是怎么转换的吧~

pragma solidity ^0.4.16;

contract DynamicString{
     
    
    bytes12 name =  0x7a68656e676a69616e78756e;
    
    function changeBytes1() view returns(bytes1){
     
        return bytes1(name);
    }
    
    function changeByte2() view returns(bytes2){
     
        return bytes2(name);
    }
    
    function changeByte3() view returns(bytes16){
     
        return bytes16(name);
    }
}

编译运行之后,我们查看结果发现:

通学智能合约系列(八)--字节数组转换_第1张图片

就是说,转小从头截取,转大末尾补零

固定长度字节数组转动态字节数组

我们知道了固定长度字节数组之间的转换,那么固定长度字节数组如何转为动态字节数组呢?它来了~~~

对于不太熟悉编程的朋友们,不要害怕,跟着我把这段代码敲出来先。

pragma solidity ^0.4.16;

contract DynamicString{
     
    
    bytes12 name =  0x7a68656e676a69616e78756e;
    
   function fixBytesToDynamicBytes() view returns(bytes){
     
       //return bytes(name);
       bytes memory newName = new bytes(name.length);
       for(uint i= 0;i < name.length;i++){
     
           newName[i] = name[i];
       }
       return newName;
   }
}

上述注释部分,我们直接return想直接转成动态字节数组,显然是行不通的。于是,我们采用迂回战术,使用一个for循环来挨个字节进行转换,目的达成。

然后这里,我们要注意两点:

​ 一是局部变量(也就是newName在我们的方法内部,这里需要加memory,先照着写,至于为什么,这里先卖个关子,我们后续会细细介绍。)

​ 二是,for循环的初始化参数,我们使用uint:代表无符号整型。这里有别与其他语言哦。

动态长度字节数组转为string

废话不多说,直接上代码:

pragma solidity ^0.4.16;

contract Bytes2String{
     
    
    bytes name =  new bytes(2);
    
    function init(){
     
        name[0] = 0x7a;
        name[1] = 0x68;
    }
    
    function bytesToString() view returns(string){
     
        return string(name);
    }
}

我们线执行初始化方法、在执行bytesToString方法,会展示结果,也就是我们原作者的名字开头zh。这里再次向原作者致敬,想看原视频请转链:

https://www.bilibili.com/video/BV1St411a7Pk?p=15

固定长度数组转string

我们上面都知道了动态长度数组可以强制转换为string,那么固定长度数组可不可以强制转为string呢?

我们编写如下合约:

pragma solidity ^0.4.16;

contract Bytes32ToString{
     
    
    bytes2 name =  0x7a68;
    
    function bytes32ChangeString() returns(string){
     
        return string(name);    
    }
 
}

会发现编译报错,显然不能这么写。

通学智能合约系列(八)--字节数组转换_第2张图片

那我们该如何操作呢?

从上面的学习中,我们知道。固定长度字节数组可以转为动态字节数组,而动态字节数组可以转为string。所以,这就是我们的思路

请看下面代码:

pragma solidity ^0.4.16;

contract Bytes32ToString{
     
    
    function byts32ToString(bytes32 inputName)  view returns(string){
     
        bytes memory newName = new bytes(inputName.length);
        for(uint i = 0;i<newName.length;i++){
     
            newName[i] = inputName[i];
        }
        return string(newName);
    }
 
}

编译部署后,我们输入0x7a68,输出zh,但是我们会发现后续还跟了很多个零,显然不符合我们的诉求。

如图:

通学智能合约系列(八)--字节数组转换_第3张图片

在作者原视频中,详细地介绍了for循环的步骤,鉴于大家都是有经验的开发人员,这里就不做过多介绍了。

那么想要去掉后面的零,该怎么做呢?俗话说的好:遇事不决则判断。我们既然已经知道了结果,那处理起来便很简单了。具体代码如下:

pragma solidity ^0.4.16;

contract Bytes32ToString{
     
    
    function byts32ToString(bytes32 inputName)  view returns(string){
     
        
        uint  count = 0;
        
        for(uint i = 0;i<inputName.length;i++){
     
            if(inputName[i] != 0){
     
                count++;
            }
        }
        
        bytes memory finalName = new bytes(count);
        for(uint j = 0;j<count;j++){
     
            finalName[j] = inputName[j];
        }
        
        return string(finalName);
            
    }
 
}

上述的思路呢,就是我们先去掉输入字节末尾默认追加的零,然后再根据真实长度去拷贝一下我们的字节数组。

如此一来,我们的目的就达成了。

字节数组小节

到这里,字节数组就告一段落啦,我们在此做一个小节.

  • 固定长度字节数组

    • byte1到byte32
  • 动态长度字节数组

    • bytes的初始化–new bytes
    • 获取bytes的长度和内容
    • 修改长度和内容
  • string

    • 不能够直接获取长度和内容
    • 需要转换为bytes获取长度和内容
    • 特殊字符的长度的内容和获取
    • 中文字符占用3个字节
  • 固定长度字节数组之间转换

    • 转小从头截取,转大末尾补零
  • 固定长度转动态长度字节数组

    • 利用new bytes(),然后循环转换。
  • 动态长度字节数组转string

    • 强制转换string();
  • 固定长度字节数组转string

    • 先获取输入字节数组长度,然后再转动态长度字节数组,在强制转换为string();

你可能感兴趣的:(区块链之变化,智能合约,区块链)