solidity学习之固定长度字节数组byte

素颜马尾好姑娘i 2022-12-03 08:29 257阅读 0赞

在学习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字节的变量

  1. pragma solidity ^0.4.0;
  2. contract test{
  3. bytes1 num1 = 0x12; //0x是16进制的表示方法 12是一字节
  4. bytes4 num2 = 0x12121212; //以此类推12 12 12 12 共四字节
  5. }

如果我们想运行这个合约,点击这个变量就可以返回相应的结果可以使用下面这种方法:

  1. pragma solidity ^0.4.0;
  2. contract test {
  3. bytes1 public num1 = 0x12;
  4. bytes4 public num2 = 0x12121212;
  5. }

bytes数据声明时加入public可以自动生成调用长度的函数,相当于写了个get()方法。

å¨è¿éæå¥å¾çæè¿°

2.bytes内部自带length长度函数,而且长度固定,而且长度不可以被修改,通过.length可以返回字节长度

  1. pragma solidity ^0.4.0;
  2. contract test {
  3. bytes1 public num1 = 0x12;
  4. bytes4 public num2 = 0x12121212;
  5. function getlength1() public view returns(uint8){
  6. return num1.length;
  7. }
  8. function getlength2() public view returns(uint8){
  9. return num2.length;
  10. }

3.固定字节数组与string之间的转换

上面我们说过字节数组byte可以通过.length获取其长度,但是字符串却不能这样使用,而且字符串也不能直接像字节数组一样num[0]通过索引这样来获取字符,如果需要获取长度或者元素,string需要先转换为byte类型才可以。

通过下面的例子大家可以体会下具体的用法。

  1. pragma solidity ^0.4.0;
  2. contract String_Math{
  3. string name = "wangyufeng"; //0x77616e67797566656e67
  4. string name1 = "王不二";
  5. function getlength() returns(uint){
  6. // return name.length; 错误
  7. return bytes(name).length;
  8. }
  9. function getName() returns(bytes){
  10. return bytes(name);
  11. }
  12. function getName1() returns(bytes){ // 0xe78e8be4b88de4ba8c
  13. return bytes(name1);
  14. }
  15. function changeName(){
  16. bytes(name)[0] = "p"; // 0x70616e67797566656e67
  17. }
  18. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ZjIwMTc_size_16_color_FFFFFF_t_70

通过上面的例子我们大概知道了字节数组与string之间的转换,现在我们通过下面的一个例子进一步深入讲解

我们现在想将字节数组拷贝到字符串里面去,那么我们该怎么实现呢?

  1. pragma solidity ^0.4.0;
  2. contract test_bytesTostring{
  3. bytes2 name = 0x7a68;
  4. function bytes32Tostring(bytes32 new_name) returns(string){
  5. bytes memory _newName = new bytes(new_name.length);
  6. for(uint i=0;i<new_name.length;i++){
  7. _newName[i] = new_name[i];
  8. }
  9. return string(_newName);
  10. }
  11. }

通过传入一个字节长度为32(最大可输入的字节长度为32,不一定是32位)的变量然后通过转换位一个string类型,运行结果如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ZjIwMTc_size_16_color_FFFFFF_t_70 1

可以看到我们输入与输出是一样的,但是这里我们可以发现我们输入的是0x7a68,但是输出的是:

  1. "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截掉。

  1. pragma solidity ^0.4.0;
  2. contract test_bytesTostring{
  3. bytes2 name = 0x7a68;
  4. function bytes32Tostring2(bytes32 new_name) returns(string){
  5. uint count = 0; //定义一个计数器
  6. for(uint i=0;i<new_name.length;i++){//通过循环判断单个字符是否为0
  7. bytes1 char = new_name[i];
  8. if(char != 0){ // 如果字符不为0,就将count+1
  9. count++;
  10. }
  11. }
  12. bytes memory _newName = new bytes(count);//此时字节数组的长度变为了count,因为count不包含0
  13. for(uint j = 0;j < count;j++){//进行赋值
  14. _newName[j] = new_name[j];
  15. }
  16. return string(_newName);//输出结果
  17. }
  18. }

运行结果如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5ZjIwMTc_size_16_color_FFFFFF_t_70 2

目前对byte字节数组了解的只有这么多了,后续还有新知识我会在下面更新的。

发表评论

表情:
评论列表 (有 0 条评论,257人围观)

还没有评论,来说两句吧...

相关阅读