http://www.7klian.com

Solidity编程语言 : 字节数组、mapping

字节数组字节数组可以看作一种非凡的数组,其元素范例是字节。在范例声名时有其专有的声名方法。作为数组他有不牢靠长度字节数组和牢靠长度字节数组。 1. 牢靠长度字节数组。<code>pragma solidity >=0.4.0 <0.6.0;<p>contract EgFixedByteArray { byte[5] ba5; bytes5 bs5;</p></code><p><code> 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'; } }</code></p>1.1 牢靠长度字节数组可以利用以下两种方法声名,一种是利用数组声名,一种是利用要害字声名,个中bytes 后边的数字范畴是从1至32,即不能利用bytes33。在实际编码中,假如确定长度最好利用这种方法。 byte[5] bs5; bytes5 bs5_; 1.2 不管哪种方法声名的,都不行以修改length以及利用push要领。 1.3 bytes5这种方法的声名不能利用数组来举办赋值的。 1.4 bytes5这种方法声名的字节数组其内容是不行修改的。 2. 不牢靠长度字节数组(动态数组)。 不牢靠长度字节数组同理也有两种方法声名,数组和要害字。数组方法其特性就是数组的特性,这里我们看下 利用要害字bytes的方法。<code>pragma solidity >=0.4.0 <0.6.0;<p>contract EgUnFixedByteArray { bytes name = new bytes(5);</p><p> function modifyName() public returns( bytes memory) { name.length = 6; name.push('9'); name[1] = '1'; return name; }</p></code><p><code>}</code></p>3. 转换 这里主要说下牢靠长度字节数组、不牢靠长度字节数组以及string之间的转换。 3.1 牢靠长度字节数组之间的转换。<code>contract EgSwitchBytes{ function switchBytes1() public returns(bytes2) { bytes2 bs2 = '12'; bytes5 bs5 = '00000'; //return bytes2(bs5); return bytes2(bs5); } }</code>长度较长的牢靠长度字节数组可以转成转短的,反过来则不可,而长的转成短的会将后边的部门长度截取掉,好比上边的bs5转成bytes2的时候会把‘234’截取掉的。 3.2 牢靠长度字节数组和不牢靠长度字节数组可能string的转换 function switchBytes2() public { /*bytes5 bs5 = ‘00000’; bytes bs = bytes(bs5);//牢靠长度字节数组与不牢靠长度字节数组不能直接转换。<code>bytes memory bs = new bytes(10); bytes5 bs5 = bytes5(bs);//牢靠长度字节数组与不牢靠长度字节数组不能直接转换 */ bytes memory bs = new bytes(10); string memory str = string(bs);<p> string memory str1 = "abcd"; bytes memory bs1 = bytes(str1);</p><p> /*bytes5 memory bs5 = '00000'; string memory str2 = string(bs5);//牢靠长度字节数组与string不能直接转换</p></code><p><code> string memory str3 = "abcd"; bytes5 memory bs5_ = bytes5(str3);//牢靠长度字节数组与string不能直接转换 */ }</code></p>牢靠长度字节数组与不牢靠长度字节数组可能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,但不提供长度和按序号的会见方法。mappingmapping的利用特性 mapping是用来生存键值对的,其书写方法与一般的编程语言有些差异,mapping(keyType => valueType)。mapping只能利用在合约的状态变量中,可能在函数内举办storage的引用,如var storage mappVal的用于存储状态变量的引用的工具,不能利用非状态变量来初始化这个引用,也就是mapping最终会生存在区块链上的,不行能是内存型变量。<code>pragma solidity >=0.4.0 <0.6.0;<p>contract EgMapping{ mapping(uint => string) public kvs;</p></code><p><code> function put () public{ kvs[1] = "a"; kvs[2] = "b"; mapping(uint => string) storage kvs1 = kvs; string memory a = kvs[1]; } }</code></p>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 蓝莲花团队整理供稿。 汪晓明博客: 汪晓明:HPB芯链首创人,巴比特专栏作家。十余年金融大数据、区块链技能开拓履历,曾参加建设银联大数据。主创区块链解说视频节目《明说》30多期,编写了《以太坊官网文档中文版》,并作为主要作者编写了《区块链开拓指南》,在中国区块链社区以ID“蓝莲花”知名。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。