【Solidity智能合约开发第17篇】3分钟了解动态字节数组、固定大小字节数组、string之间的转换关系

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

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

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.7.0;

contract C {

   bytes9 name9 = 0x6c697975656368756e;

   function bytes9ToBytes1() view public returns (bytes1) {

       return bytes1(name9); //bytes1: 0x6c
   }

   function bytes9ToBytes2() view public returns (bytes2) {

       return bytes2(name9); //0x6c69
   }

   function bytes9ToBytes32() view public returns (bytes32) {

       return bytes32(name9);// bytes32: 0x6c697975656368756e0000000000000000000000000000000000000000000000
   }

}

结论:bytes9bytes1或者bytes2时,会进行低位截断,0x6c697975656368756e转换为bytes1,结果为0x6c,转换为bytes2时结果为0x6c69。当0x6c697975656368756e转换为bytes32时会进行低位补齐,结果为0x6c697975656368756e0000000000000000000000000000000000000000000000

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

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.7.0;

contract C {

   bytes9 name9 = 0x6c697975656368756e;

   function fixedSizeByteArraysToDynamicallySizedByteArray() view public returns (bytes memory) {

       return bytes(name9);
   }

}

对于刚接触的童鞋,很多人都会用上面的方法进行转换,以为理所当然,殊不知编译运行时,代码报错,原因如下:

【Solidity智能合约开发第17篇】3分钟了解动态字节数组、固定大小字节数组、string之间的转换关系

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

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

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.7.0;

contract C {

   bytes9 name9 = 0x6c697975656368756e;

   function fixedSizeByteArraysToDynamicallySizedByteArray() view public returns (bytes memory) {

       bytes memory names = new bytes(name9.length);

       for(uint i = 0; i < name9.length; i++) {

           names[i] = name9[i];
       }

       return names;
   }

}

在上面的代码中,我们根据固定字节大小数组的长度来创建一个memory类型的动态类型的字节数组,然后通过一个for循环将固定大小字节数组中的字节按照索引赋给动态大小字节数组即可。

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

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.7.0;

contract C {

   bytes9 names = 0x6c697975656368756e;

    function namesToString() view public returns (string memory) {

        return string(names);
    }

}

【Solidity智能合约开发第17篇】3分钟了解动态字节数组、固定大小字节数组、string之间的转换关系

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

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

  • 如果是现成的动态大小字节数组(Dynamically-sized byte array),如下:
    
    // SPDX-License-Identifier: MIT
    pragma solidity >=0.5.0 <0.7.0;

contract C {

bytes names = new bytes(2);

constructor() internal {

    names[0] = 0x6c;
    names[1] = 0x69;
}

function namesToString() view public returns (string memory) {

    return string(names);
}

}


- 如果是固定大小字节数组转string,那么就需要先将字节数组转动态字节数组,再转字符串

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.7.0;

contract C {

// 0x6c697975656368756e
bytes9 b = 0x6c697975656368756e;
function byte32ToString() view public returns (string memory) {

   bytes memory names = new bytes(b.length);

   for(uint i = 0; i < b.length; i++) {

       names[i] = b[i];
   }

   return string(names); // liyuechun

}
}



## 总结

string本身是一个特殊的动态字节数组,所以它只能和bytes之间进行转换,不能和固定大小字节数组进行直接转换,如果是固定字节大小数组,需要将其转换为动态字节大小数组才能进行转换。

该内容来自于互联网公开内容,非区块链原创内容,如若转载,请注明出处:https://htzkw.com/archives/24995

联系我们

aliyinhang@gmail.com