在学习solidity过程中,发现这门语言和之前学的C、C++、Java以及Python有很多不同之处,但目前我学到的来看,字节数组byte使用的很频繁,而且也有很多不一样的东西。
1byte=8位(XXXX XXXX)X为0或1,二进制表示
byte数组的类型有:bytes1,bytes2,。。。,bytes32,以八个位递增,即是对位的封装
举例
bytes1=uint8
bytes2=unit16
......
bytes32=unit256
目前我自己了解到的byte使用这么频繁大致是因为它能更好的表示16进制
举例:bytes1=0x6A,bytes1=(XXXX XXXX)正好四个表示一个16进制,以此类推
下面我们通过一些例子来看看byte的用法
1.下面声明了一个一字节以及一个4字节的变量
pragma solidity ^0.4.0;
contract test{
bytes1 num1 = 0x12; //0x是16进制的表示方法 12是一字节
bytes4 num2 = 0x12121212; //以此类推12 12 12 12 共四字节
}
如果我们想运行这个合约,点击这个变量就可以返回相应的结果可以使用下面这种方法:
pragma solidity ^0.4.0;
contract test {
bytes1 public num1 = 0x12;
bytes4 public num2 = 0x12121212;
}
bytes数据声明时加入public可以自动生成调用长度的函数,相当于写了个get()方法。
2.bytes内部自带length长度函数,而且长度固定,而且长度不可以被修改,通过.length可以返回字节长度
pragma solidity ^0.4.0;
contract test {
bytes1 public num1 = 0x12;
bytes4 public num2 = 0x12121212;
function getlength1() public view returns(uint8){
return num1.length;
}
function getlength2() public view returns(uint8){
return num2.length;
}
3.固定字节数组与string之间的转换
上面我们说过字节数组byte可以通过.length获取其长度,但是字符串却不能这样使用,而且字符串也不能直接像字节数组一样num[0]通过索引这样来获取字符,如果需要获取长度或者元素,string需要先转换为byte类型才可以。
通过下面的例子大家可以体会下具体的用法。
pragma solidity ^0.4.0;
contract String_Math{
string name = "wangyufeng"; //0x77616e67797566656e67
string name1 = "王不二";
function getlength() returns(uint){
// return name.length; 错误
return bytes(name).length;
}
function getName() returns(bytes){
return bytes(name);
}
function getName1() returns(bytes){ // 0xe78e8be4b88de4ba8c
return bytes(name1);
}
function changeName(){
bytes(name)[0] = "p"; // 0x70616e67797566656e67
}
}
通过上面的例子我们大概知道了字节数组与string之间的转换,现在我们通过下面的一个例子进一步深入讲解
我们现在想将字节数组拷贝到字符串里面去,那么我们该怎么实现呢?
pragma solidity ^0.4.0;
contract test_bytesTostring{
bytes2 name = 0x7a68;
function bytes32Tostring(bytes32 new_name) returns(string){
bytes memory _newName = new bytes(new_name.length);
for(uint i=0;i<new_name.length;i++){
_newName[i] = new_name[i];
}
return string(_newName);
}
}
通过传入一个字节长度为32(最大可输入的字节长度为32,不一定是32位)的变量然后通过转换位一个string类型,运行结果如下:
可以看到我们输入与输出是一样的,但是这里我们可以发现我们输入的是0x7a68,但是输出的是:
"0": "string: zh\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
这显然不是我们想要的结果,因为后面有30个0,这是我们不需要的,我们只需要zh这个结果(0x7a68对应的字母是zh),所以我们需要通过方法将后面的0截掉。
pragma solidity ^0.4.0;
contract test_bytesTostring{
bytes2 name = 0x7a68;
function bytes32Tostring2(bytes32 new_name) returns(string){
uint count = 0; //定义一个计数器
for(uint i=0;i<new_name.length;i++){//通过循环判断单个字符是否为0
bytes1 char = new_name[i];
if(char != 0){ // 如果字符不为0,就将count+1
count++;
}
}
bytes memory _newName = new bytes(count);//此时字节数组的长度变为了count,因为count不包含0
for(uint j = 0;j < count;j++){//进行赋值
_newName[j] = new_name[j];
}
return string(_newName);//输出结果
}
}
运行结果如下:
目前对byte字节数组了解的只有这么多了,后续还有新知识我会在下面更新的。