前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零构建以太坊(Ethereum)智能合约到项目实战——学习笔记8

从零构建以太坊(Ethereum)智能合约到项目实战——学习笔记8

作者头像
墨文
发布2020-02-28 14:41:47
5260
发布2020-02-28 14:41:47
举报
文章被收录于专栏:m0w3nm0w3n

P35 、Solidity Types - 字符串(String Literals)

Solidity中的string字符串不像C语言一样以\0结束。

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract StringLiterals{
    string _name;//状态变量
    
    //构造函数
    function StringLiterals(){
        _name = "this is a girl!";
    }
    
    function setName(string name){
        _name = name;
    }
    
    function name() constant returns(string){
        return _name;
    }
}

备注:string字符串不能通过length方法获取其长度。

P36 、1-固定大小字节数组(Fixed-size byte arrays) bytes1 ~P 、 bytes32

固定大小字节数组(Fixed-size byte arrays)

固定大小字节数组可以通过bytes1,bytes2,bytes3,....,bytes32来进行声明。PS:byte的别名就是byte1。

  • bytes1只能存储一个字节,也就是二进制8位的内容。
  • bytes2只能存储两个字节,也就是二进制16位的内容。
  • bytes3只能存储三个字节,也就是二进制24位的内容。
  • ........
  • bytes32只能存储三十二个字节,也就是二进制256位的内容。
代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    byte public a = 0x6c;
    bytes1 public b = 0x6c;
    bytes2 public c = 0x6c69;
    bytes3 public d = 0x6c6979;
    bytes4 public e = 0x6c697975;
}

P37 、2-Solidity Types - 固定大小字节数组(Fixed-size byte arrays) - 比较运算符

操作运算符

  • 比较运算符:<=、<、==、!=、>=、>
  • 位运算符:&、|、^(异或)、~(取反)、<<(左移)、>>(右移)
  • 索引访问:如果x是一个bytesI,那么可以通过X[k](0<k<I)获取对应索引的字节,PS:X[k]是只读,不可写。
代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes1 b10 = 0x6c; //  l 
    bytes2 b11 = 0x69; //  i 
    
    //  <=、<、==、!=、>=、>
    
    function test1() constant returns(bool){
        return b10<=b11;
    }
    
    function test2() constant returns(bool){
        return b10<b11;
    }
    
    function test3() constant returns(bool){
        return b10==b11;
    }
    
    function test4() constant returns(bool){
        return b10!=b11;
    }
    
    function test5() constant returns(bool){
        return b10>=b11;
    }
    
    function test6() constant returns(bool){
        return b10>b11;
    }
    
}

P38 、3-Solidity Types - 固定大小字节数组(Fixed-size byte arrays) - 位操作符

操作运算符

  • 比较运算符:<=、<、==、!=、>=、>
  • 位运算符:&、|、^(异或)、~(取反)、<<(左移)、>>(右移)
  • 索引访问:如果x是一个bytesI,那么可以通过X[k](0<k<I)获取对应索引的字节,PS:X[k]是只读,不可写。
代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes1 b10 = 0x6c; //  l 
    bytes1 b11 = 0x69; //  i 
    
    // &、|、^(异或)、~(取反)、<<(左移)、>>(右移)
    
    function test1() constant returns(bytes1){
        return b10 & b11;
        //0110 1100 -> 0x6c
        //0110 1001 -> 0x69
        //0110 1000 -> 0x68
    }
    
    function test2() constant returns(bytes1){
        return b10 | b11;
        //0110 1100 -> 0x6c
        //0110 1001 -> 0x69
        //0110 1101 -> 0x6d
    }
    
    function test3() constant returns(bytes1){
        return ~ b10;
        //0110 1100 -> 0x6c
        //1001 0011 -> 0x93
    }
    
    function test4() constant returns(bytes1){
        return b10 << 1;
        //0110 1100 -> 0x6c
        //1101 1000 -> 0xd8
    }
    
    function test5() constant returns(bytes1){
        return b10 >> 1;
        //0110 1100 -> 0x6c
        //0011 0110 -> 0x36
    }
    
}

P39 、4-Solidity Types - 固定大小字节数组(Fixed-size byte arrays) - 索引访问

操作运算符

  • 比较运算符:<=、<、==、!=、>=、>
  • 位运算符:&、|、^(异或)、~(取反)、<<(左移)、>>(右移)
  • 索引访问:如果x是一个bytesI,那么可以通过x[k](0<k<I)获取对应索引的字节,PS:x[k]是只读,不可写。
代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes9 b9 = 0x6c6979756563687563;
    
    function test(uint index) constant returns(byte){
        return b9[index];
    }
}

P40 、5-Solidity Types - 固定大小字节数组(Fixed-size byte arrays) - length

操作运算符

  • 比较运算符:<=、<、==、!=、>=、>
  • 位运算符:&、|、^(异或)、~(取反)、<<(左移)、>>(右移)
  • 索引访问:如果x是一个bytesI,那么可以通过X[k](0<k<I)获取对应索引的字节,PS:X[k]是只读,不可写。

成员函数

  • .length返回字节的个数。(只读)
代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes9 b9 = 0x6c6979756563687563;
    
    function test() constant returns(uint){
        return b9.length;
    }
}

P41 、6-Solidity Types - 固定大小字节数组(Fixed-size byte arrays) - 不可变深度理解

不可变深度解析

长度不可变

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes9 name = 0x6c6979756563687563;
    
    function setNameLength(uint length) {
        //报错
        name.length = length;
    }
}

内部字节不可修改

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes9 name = 0x6c6979756563687563;
    
    function setNameFirstByte(byte b) {
        //报错
        name[0] = b;
    }
}

总结:bytesI (1<= I <= 32)可以声明固定字节大小的字节数组变量,一旦声明,内部的字节和字节数组长度不可修改,当然可以通过索引读取(只读)对应索引的字节,或者通过length读取字节数组的字节数。

P42 、1-Solidity Types - 动态大小字节数组(Dynamically-sized byte array)

一、Dynamically-sized byte array

  • string是一个动态尺寸的utf-8编码字符串,它其实是一个特殊的可变字节数组,string是引用类型,而非值类型。
  • bytes动态字节数组、引用类型。

根据经验,在我们不确定字节数据大小的情况下,我们可以使用string或者bytes,而如果我们清楚知道或者能够将字节数控制在bytes1~bytes32,那么我们就使用bytes1~bytes32,这样的话能够降低存储成本。

P43 、2-Solidity Types - 动态大小字节数组(Dynamically-sized byte array) - string to bytes

二、常规字符串string转换为bytes

string字符串中没有提供length方法获取字符串长度,也没有提供方法修改某个索引的字节码,不过我们可以将string转换为bytes,再调用length方法获取字节长度,当然可以修改某个索引的字节码。

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes9 g = 0x6c697975656368756e;
    string name = "liyuechun";
    
    function gByteLength() constant returns(uint){
        return g.length;
    }
    
    function nameBytes() constant returns(bytes){
        return bytes(name);
    }
    
    function nameLength() constant returns(uint){
        return bytes(name).length;
    }
    
    function setNameFirstByteForL(bytes1 z){
        // 0x4c=>"L"
        bytes(name)[0] = z;
    }
}

P44 、3-Solidity Types - 动态大小字节数组(Dynamically-sized byte array) - 特殊字符对应的字节数

三、汉字字符串或特殊字符的字符串转换为bytes

1、特殊字符

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    string public name = "a!+&520";
    
    function nameBytes() constant returns(bytes){
        return bytes(name);
    }
    
    function nameLength() constant returns(uint){
        return bytes(name).length;
    }
}

在这个案例中,我们声明了一个name字符串,值为a!+&520,根据nameBytes和nameLength返回的结果中,我们不难看出,不管是字母、数字还是特殊符号,每个字母对应一个byte(字节)。

P45 、4-Solidity Types - 动态大小字节数组(Dynamically-sized byte array) - 汉字对应的字节数

2、中文字符串

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    string public name = "黎跃春";
    
    function nameBytes() constant returns(bytes){
        return bytes(name);
    }
    
    function nameLength() constant returns(uint){
        return bytes(name).length;
    }
}

在上面的代码中,我们不难看出,黎跃春 转换为bytes以后的内容为0xe9bb8ee8b783e698a5,一共9个字节。也就是一个汉字需要通过3个字节来进行存储。

P46 、5-Solidity Types - 动态大小字节数组(Dynamically-sized byte array) - 创建bytes字节数组

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes public name = new bytes(1);
    
    function nameBytes() constant returns(bytes){
        return bytes(name);
    }
    
    function setNameLength(uint length){
        name.length = length;
    }
    
    function nameLength() constant returns(uint){
        return name.length;
    }
}

P47 、6-Solidity Types - 动态大小字节数组(Dynamically-sized byte array) - 可变字节数组和不可变字节数组深度对比

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    bytes public name = new bytes(1);
    
    function nameBytes() constant returns(bytes){
        return bytes(name);
    }
    
    function setNameLength(uint length){
        name.length = length;
    }
    
    function nameLength() constant returns(uint){
        return name.length;
    }
    
    function setIndexByte(byte data, uint index){
        name[index] = data;
    }
    
    function clearBytes(uint len){
        name.length = len;
        //清空数组
        //name.length = 0;
        //或者delete清空
        //delete name;
    }
}

P48 、7-Solidity Types - 动态大小字节数组(Dynamically-sized byte array) - 可变字节数组中push方法的使用

代码语言:javascript
复制
pragma solidity ^0.4.4;

contract C{
    //0x6c697975656368756e
    //初始化一个两个字节空间的字节数组
    bytes public name = new bytes(2);

    function setNameLength(uint length){
        name.length = length;
    }
    
    function nameLength() constant returns(uint){
        return name.length;
    }
    
    function pushAByte(byte b){
        name.push(b);
    }
}

说明:当字节数组的长度只有2时,如果你通过push往里面添加一个字节,那么它的长度将变为3,当字节数组里面有3个字节,但是你通过length方法将其长度修改为2时,字节数组中最后一个字节将被从字节数组中移除。

P49 、8-Solidity Types - 动态大小字节数组(Dynamically-sized byte array) - 小结

对比分析:

  • 不可变字节数组

  我们之前的文章中提到过如果我们清楚我们存储的字节大小,那么我们可以通过bytes1,bytes2,bytes3,。。。,bytes32来声明字节数组变量,不过通过bytes1来声明的字节数组为不可变字节数组,字节不可修改,字节数组长度不可修改。

  • 可变字节数组

  我们可以通过bytes name = new bytes(length)-length为字节数组长度,来声明可变大小和修改字节内容的可变字节数组。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-01-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档