当前位置:首页>区块链文章>区块链引流>技术入门 | Solidity编程语言 : 字节数组、mapping

技术入门 | Solidity编程语言 : 字节数组、mapping

[db:标签]节数组

字节数组可以看作一种特殊的数组,其元素类型是字节。在类型声名时有其专有的声名方式。作为数组他有不固定长度字节数组和固定长度字节数组。 1. 固定长度字节数组。

pragma solidity >=0.4.0 <0.6.0;

contract EgFixedByteArray { byte[5] ba5; bytes5 bs5;

function modify() public{ ba5 = [byte(\'1\'),\'2\',\'3\',\'4\',\'5\']; //ba5.push(6); //ba5.length = 6; //bs5 = [byte(\'1\'),\'2\',\'3\',\'4\',\'5\']; ba5[1] = \'0\'; bs5 = \'12345\'; //bs5.length = 6; //bs5.push(6); //bs5[1] = \'0\'; }}

1.1 固定长度字节数组可以使用以下两种方式声名,一种是使用数组声名,一种是使用关键字声名,其中bytes 后边的数字范围是从1至32,即不能使用bytes33。在实际编码中,如果确定长度最好使用这种方式。 byte[5] bs5; bytes5 bs5_; 1.2 不管哪种方式声名的,都不可以修改length以及使用push方法。 1.3 bytes5这种方式的声名不能使用数组来进行赋值的。 1.4 bytes5这种方式声名的字节数组其内容是不可修改的。 2. 不固定长度字节数组(动态数组)。 不固定长度字节数组同理也有两种方式声名,数组和关键字。数组方式其特性就是数组的特性,这里我们看下 使用关键字bytes的方式。

pragma solidity >=0.4.0 <0.6.0;

contract EgUnFixedByteArray { bytes name = new bytes(5);

function modifyName() public returns( bytes memory) { name.length = 6; name.push(\'9\'); name[1] = \'1\'; return name; }

}

3. 转换 这里主要说下固定长度字节数组、不固定长度字节数组以及string之间的转换。 3.1 固定长度字节数组之间的转换。

contract EgSwitchBytes{    function switchBytes1() public returns(bytes2) {        bytes2 bs2 = \'12\';        bytes5 bs5 = \'00000\';        //return bytes2(bs5);        return bytes2(bs5);    }}

长度较长的固定长度字节数组可以转成转短的,反过来则不行,而长的转成短的会将后边的部分长度截取掉,比如上边的bs5转成bytes2的时候会把‘234’截取掉的。 3.2 固定长度字节数组和不固定长度字节数组或者string的转换 function switchBytes2() public { /*bytes5 bs5 = ‘00000’; bytes bs = bytes(bs5);//固定长度字节数组与不固定长度字节数组不能直接转换。

bytes memory bs = new bytes(10);    bytes5 bs5 = bytes5(bs);//固定长度字节数组与不固定长度字节数组不能直接转换    */    bytes memory bs = new bytes(10);    string memory str = string(bs);

string memory str1 = \"abcd\"; bytes memory bs1 = bytes(str1);

/*bytes5 memory bs5 = \'00000\'; string memory str2 = string(bs5);//固定长度字节数组与string不能直接转换

string memory str3 = \"abcd\"; bytes5 memory bs5_ = bytes5(str3);//固定长度字节数组与string不能直接转换 */}

固定长度字节数组与不固定长度字节数组或者string(本质也是不固定长度字节数组)不能互相直接转换,但是 string和bytes可以。 3.3 怎么转换固定长度字节数组。 这里说下思路,就是遍历固定长度字节数组,然后逐个把元素赋值到不固定长度字节数组中,这样就得到了不固定长度字节数组,也可以再次通过不固定长度字节数组转换成string。其中有个问题是比如bytes5 bs5 = ‘1’,本来bs5的类型是bytes5,也就是应该包含5个字节,但实际只赋值了‘1’,那么其余4个字节是啥呢?是空的,也就是\\u0000,即空字符(不是空格,也不是null),所以在遍历的时候会把四个\\u0000也进行了遍历。导致不固定长度字节数组中包含了4个\\u0000,转成的string也有问题。所在在转换的时候要考虑\\u0000的问题。 bytes和string是一种特殊的数组。bytes类似byte[],但在外部函数作为参数调用中,会进行压缩打包,更省空间,所以应该尽量使用bytes4。string类似bytes,但不提供长度和按序号的访问方式。

mapping

mapping的使用特性 mapping是用来保存键值对的,其书写方式与一般的编程语言有些不同,mapping(keyType => valueType)。mapping只能使用在合约的状态变量中,或者在函数内进行storage的引用,如var storage mappVal的用于存储状态变量的引用的对象,不能使用非状态变量来初始化这个引用,也就是mapping最终会保存在区块链上的,不可能是内存型变量。

pragma solidity >=0.4.0 <0.6.0;

contract EgMapping{ mapping(uint => string) public kvs;

function put () public{ kvs[1] = \"a\"; kvs[2] = \"b\"; mapping(uint => string) storage kvs1 = kvs; string memory a = kvs[1]; }}

1. mapping的key可以使用除了mapping类型以外的所有类型,value没有任何限制。 2. mapping实际上并不存储key的值,而是把key转换成keccak256的哈希值进行存储,所以通过mapping是无法获取保存的key的。 3. mapping只能用来定义状态变量,如果要在函数内部使用的话,则也需要将其声名为一个storage类型的引用,引用指向的是还是状态变量。 4. 增加元素,比如kvs[1] = “a”。 5. 更新元素,和增加一样,只不过key已经存在了。 6. 查找元素,比如string memory a = kvs[1]。 7. 删除元素,使用关键delete,比如delete kvs[1]。注意delete操作修改的是状态变量,所以会有gas的消耗,一般不会轻易的delete元素的。 上边已经知道mapping是不保存key的值的,所以无法进行mapping的直接遍历。但是如果把key保存下来不就可以进行遍历了吗。其具体实现可以看这个工具包,是将key保存到一个不固定长度的数组中,所以你在插入元素的时候也需要使用这个工具包的插入方法。 作者:感谢HPB 蓝莲花团队整理供稿。 汪晓明博客:http://wangxiaoming.com/ 汪晓明:HPB芯链创始人,巴比特专栏作家。十余年金融大数据、区块链技术开发经验,曾参与创建银联大数据。主创区块链教学视频节目《明说》30多期,编写了《以太坊官网文档中文版》,并作为主要作者编写了《区块链开发指南》,在中国区块链社区以ID“蓝莲花”知名。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
区块链引流

Zcash季度报告:营运成本降低25%,创始人奖励重新调整

2021-11-12 23:06:15

区块链引流

研究 | 区块链思维和知识产权质押融资行业

2021-11-12 23:06:17

重要说明

本站资源大多来自网络,如有侵犯你的权益请联系管理员 区块链Bi站  或给邮箱发送邮件834379394@qq.com 我们会第一时间进行审核删除。 站内资源为网友个人学习或测试研究使用,未经原版权作者许可,禁止用于任何商业途径!请在下载24小时内删除!


如果你遇到支付完成,找不到下载链接,或者不能下载,或者解压失败,先不要忙,加客服主的QQ:834379394 (客服有可能有事情或者在睡觉不能及时的回复您,QQ留言后,请耐心等待即可!)

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索