从零构建以太坊(Ethereum)智能合约到项目实战——学习笔记9

P50 、1-Solidity Types - 动态大小字节数组、固定大小字节数组 、string之间的转换关系

大纲

1. 固定大小字节数组(Fixed-size byte arrays)之间的转换

2. 固定大小字节数组(Fixed-size byte arrays)转动态大小字节数组(Dynamically-sized byte array)

3. 固定大小字节数组(Fixed-size byte arrays)不能直接转换为string

4. 动态大小字节数组(Dynamically-sized byte array)转string

  • 本身就是动态大小字节数组
  • 固定大小字节数组转string,需要先转动态字节数组,再转string(string本身就是特殊的动态大小字节数组)

 

P51 、2-固定大小字节数组(Fixed-size byte arrays)之间的转换

固定大小字节可以通过bytes1~bytes32来声明,固定大小字节数组的长度不可变,内容不可修改。接下来我们通过下面的代码看看固定大小字节之间的转换关系。

pragma solidity ^0.4.4;

contract C{
    //0x6c697975656368756e
    //初始化一个两个字节空间的字节数组
    bytes9 name9 = 0x6c697975656368756e;

    function bytes9toBytes1() constant returns(bytes1){
        return bytes1(name9);
    }
    
    function bytes9toBytes2() constant returns(bytes2){
        return bytes2(name9);
    }
    
    function bytes9toBytes32() constant returns(bytes32){
        return bytes32(name9);
    }
}

 

 

P52 、3-固定大小字节数组(Fixed-size byte arrays)转动态大小字节数组(Dynamically-sized byte array)

pragma solidity ^0.4.4;

contract C{
    //0x6c697975656368756e
    //初始化一个两个字节空间的字节数组
    bytes9 name9 = 0x6c697975656368756e;
    
    function zhuanhaun() constant returns(bytes){
        //报错
        return bytes(name9);
    }
}

 

备注:简言之,固定大小字节数组和动态大小字节数组之间不能简单直接转换。

下面是 固定大小字节数组转动态大小字节数组 正确的姿势。

pragma solidity ^0.4.4;

contract C{
    //0x6c697975656368756e
    //初始化一个两个字节空间的字节数组
    bytes9 name9 = 0x6c697975656368756e;
    
    function fixedSizeByteArraysToDynamicallySizeByteArray() constant returns(bytes){
        
        bytes memory names = new bytes(name9.length);
        
        for(uint i = 0; i < name9.length ; i++){
            names[i] = name9[i];
        }
        
        return names;
    }
}

P53 、4-固定大小字节数组(Fixed-size byte arrays)不能直接转换为string

pragma solidity ^0.4.4;

contract C{
    //0x6c697975656368756e
    //初始化一个两个字节空间的字节数组
    bytes9 names = 0x6c697975656368756e;
    
    function nameToString() constant returns(string){
        //报错
        return string(names);
    }
}

 


P54 、5-动态大小字节数组(Dynamically-sized byte array)转string

重要:因为string是特殊的动态字节数组,所以string只能和动态大小字节数组(Dynamically-sized byte array)之间进行转换,不能和固定大小字节数组进行转换。

  • 如果是现成的动态大小字节数组(Dynamically-sized byte array),如下:
pragma solidity ^0.4.4;

contract C{
    
    bytes names = new bytes(2);
    
    function C() {
        names[0] = 0x6c;
        names[1] = 0x69;
    }
    
    function namesToString() constant returns(string){
        return string(names);
    }
}

 

  • 如果是固定大小字节数组转string,那么就需要先将字节数组转动态字节数组,在转字符串,如下:
pragma solidity ^0.4.4;

contract C{
    
    bytes9 names9 = 0x6c697975656368756e;

    bytes public name = new bytes(9);
    
    function C() {for(uint i=0;i<names9.length;i++){
            name[i] = names9[i];
        }
    }
    
    function nameToString() constant returns(string){
        return string(name);
    }
}

 


P55 、6-固定大小字节数组转string问题深度分析

pragma solidity ^0.4.4;

contract C{
    
    //0x6c697975656368756e;
    string _name;
    bytes names = new bytes(32);
    
    function returnbytes32(bytes32 bb) constant returns(bytes32) {
        return bb;
    }
    
    function bytes32ToString1( bytes32 b) {
        for(uint i=0;i<32;i++){
            names[i] = b[i];
        }
        _name = string(names);
    }
    
    function bytes32ToString2( bytes32 b)  constant returns(string){
        bytes memory tempNames = new bytes(32);
        
        for(uint i=0;i<32;i++){
            tempNames[i] = b[i];
        }
        return string(tempNames);
    }
    
    function nameLength() constant returns(uint){
        return bytes(_name).length;
    }
}

 


P56 、7-固定大小字节数组转string标准函数实现

 

pragma solidity ^0.4.4;

contract C{
    
    function bytes32ToString( bytes32 x) constant returns(string ) {
        bytes memory bytesString = new bytes(32);
        uint charCount = 0;
        
        for(uint j = 0 ; j < 32 ; j++){
            byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
            if(char != 0){
                bytesString[charCount] = char;
                charCount ++;
            }
        }
        bytes memory bytesStringTrimmed = new bytes(charCount);
        for(j=0;j<charCount;j++){
            bytesStringTrimmed[j]=bytesString[j];
        }
        return string(bytesStringTrimmed);
    }
    
    function bytes32ArrayToString( bytes32[] data) constant returns(string ) {
        bytes memory bytesString = new bytes(data.length * 32);
        uint urlLength = 0;
        
        for(uint i = 0 ; i < data.length ; i++){
            for(uint j =0;j<32;j++){
                byte char = byte(bytes32(uint(data[i]) * 2 ** (8 * j)));
                if(char != 0){
                    bytesString[urlLength] = char;
                    urlLength ++;
                }
            }
        }
        bytes memory bytesStringTrimmed = new bytes(urlLength);
        for(i=0;i<urlLength;i++){
            bytesStringTrimmed[i]=bytesString[i];
        }
        return string(bytesStringTrimmed);
    }
}

 

posted @ 2019-01-31 16:44  m0w3n  阅读(260)  评论(0编辑  收藏  举报