定长字节数组(Fixed-size byte arrays)之间的转换
定长字节数组我们可以通过bytes0 ~ bytes32
来进行声明,定长字节数组的长度不可变,内容不可修改。接下来我们通过下面的代码看看定长字节数组的转换关系。
pragma solidity ^0.4.0;
contract C {
bytes10 name10 = 0x77616e6773616e6a756e;
function bytes10ToBytes1() constant returns (bytes1) {
return bytes1(name10);
}
function bytes10ToBytes2() constant returns (bytes2) {
return bytes2(name10);
}
function bytes10ToBytes32() constant returns (bytes32) {
return bytes32(name10);
}
}
QQ20180319-114553@2x.png
结论:当bytes10
转bytes1
或者bytes2
时,会进行低位截断,0x77616e6773616e6a756e
转换为bytes1
,结果为0x77
,转换为bytes2
时结果为0x7761
。当0x77616e6773616e6a756e
转换为bytes32
时会进行低位补齐,结果为0x77616e6773616e6a756e00000000000000000000000000000000000000000000
。
定长字节数组(Fixed-size byte arrays)转动态字节数组(Dynamically-sized byte array)
pragma solidity ^0.4.0;
contract C {
bytes10 name = 0x77616e6773616e6a756e;
function fixedSizeByteArraysToDynamicallySizedByteArray() constant returns (bytes) {
return bytes(name);
}
}
编译运行时,代码报错:
TypeError: Explicit type conversion not allowed from "bytes10" to "bytes storage pointer".
return bytes(name);
^---------^
结论:定长字节数组
和动态字节数组
之间不能简单直接转换。
下面是定长字节数组转动态字节数组
正确的方式。
pragma solidity ^0.4.0;
contract C {
bytes10 name = 0x77616e6773616e6a756e;
function fixedSizeByteArraysToDynamicallySizedByteArray() constant returns (bytes) {
bytes memory names = new bytes(name.length);
for(uint i = 0; i < name.length; i++) {
names[i] = name[i];
}
return names;
}
}
在上面的代码中,我们根据定长字节数组的长度来创建一个memory
类型的动态类型的字节数组,然后通过一个for循环
将定长字节数组中的字节按照索引赋给动态字节数组即可。
定长字节数组(Fixed-size byte arrays)不能直接转换为string
pragma solidity ^0.4.0;
contract C {
bytes10 name = 0x77616e6773616e6a756e;
function namesToString() constant returns (string) {
return string(names);
}
}
DeclarationError: Undeclared identifier. Did you mean "name"?
return string(names);
^---^
动态字节数组(Dynamically-sized byte array)转string
重要:因为string是特殊的动态字节数组,所以string只能和动态字节数组(Dynamically-sized byte array)之间进行转换,不能和定长字节数组进行转行。
- 如果是现成的动态字节数组(Dynamically-sized byte array),如下:
pragma solidity ^0.4.0;
contract C {
bytes names = new bytes(4);
function C() {
names[0] = 0x77;
names[1] = 0x61;
names[2] = 0x6e;
names[3] = 0x67;
}
function namesToString() constant returns (string) {
return string(names);
}
}
QQ20180319-120635@2x.png
- 如果是定长字节数组转string,那么就需要先将字节数组转动态字节数组,再转字符串
pragma solidity ^0.4.0;
contract C {
function byte32ToString(bytes32 b) constant returns (string) {
bytes memory names = new bytes(b.length);
for(uint i = 0; i < b.length; i++) {
names[i] = b[i];
}
return string(names);
}
}
总结
string
本身是一个特殊的动态字节数组,所以它只能和bytes
之间进行转换,不能和定长字节数组进行直接转换,如果是定长字节数组,需要将其转换为动态字节数组才能进行转换。
网友评论