P35 、Solidity Types - 字符串(String Literals)
Solidity中的string字符串不像C语言一样以\0结束。
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。
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) - 比较运算符
操作运算符
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) - 位操作符
操作运算符
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) - 索引访问
操作运算符
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
操作运算符
成员函数
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或者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为字节数组长度,来声明可变大小和修改字节内容的可变字节数组。