从零构建以太坊(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); } }