zoukankan      html  css  js  c++  java
  • 从零构建以太坊(Ethereum)智能合约到项目实战——学习笔记8

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

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

    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位的内容。
    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]是只读,不可写。
    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]是只读,不可写。
    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]是只读,不可写。
    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返回字节的个数。(只读)
    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) - 不可变深度理解

    不可变深度解析

    长度不可变

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

    内部字节不可修改

    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方法获取字节长度,当然可以修改某个索引的字节码。

    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、特殊字符

    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、中文字符串

    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字节数组

    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) - 可变字节数组和不可变字节数组深度对比

    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方法的使用

    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为字节数组长度,来声明可变大小和修改字节内容的可变字节数组。

  • 相关阅读:
    在HttpHandlers (ASHX files)中使用Session
    EventCalendar控件源码和ASP.NET 2.0 Beta 2 Starter Kits中可能遇到的问题
    C# 获取数据库中某个某个表的创建脚本[原创]
    Linq 合并多个查询条件
    自定义WCF RIA Services 超时时间
    也来学学插件式开发续利用MEF
    HTML5程序设计 Geolocation API
    反射实体模型生成Oracle SQL脚本
    Entity Framework With Oracle
    Entity Framework Code First在Oracle下的伪实现
  • 原文地址:https://www.cnblogs.com/little-kwy/p/10333568.html
Copyright © 2011-2022 走看看