solidity中String和bytes家族
对solidity没有怨恨,习惯了go,python,C/C++的我,在使用solidity写合约时,总有些兴奋(dandan)忧伤不能表达
本文就是本菜鸟遇到的坑总结一下,如果不对或者不满意的欢迎指正,我会尽量☺及时修正。
solidity简介
Solidity 是一门面向合约的、为实现智能合约而创建的高级编程语言。这门语言受到了 C++,Python 和 Javascript 语言的影响,设计的目的是能在以太坊虚拟机(EVM)上运行。
solidity使用
Solidity 是静态类型语言,支持继承、库和复杂的用户定义类型等特性。它的语法接近于Javascript,是一种面向对象的语言。
solidity字符串使用
首先明确solidity中应尽量的减少字符串的使用,变长 UTF-8 编码字符串类型,并不是值类型,solidity对字符串的支持有限,在很多操作上受到限制:
- 无法确定字符串的长度;
- 无法按照位置更改某个特定字符;
- 无法字符串拼接;
- 无法提取其中一部分;
String简单介绍:
1.solidity 中的字符串拼接需要通过bytes转换进行拼接
//错误示范:
String str1 = 'asdf'
String str2 = str1 + 'sdf' //这种行为是不允许的在solidity中
//常用写法:
function joinString(string _str1, string _str2) internal returns (string){
bytes memory _str1ToBytes = bytes(_str1);
bytes memory _str2ToBytes = bytes(_str2);
string memory ret = new string(_str1ToBytes.length + _str2ToBytes.length);
bytes memory retTobytes = bytes(ret);
uint index = 0;
for (uint i = 0; i < _str1ToBytes.length; i++)retTobytes[index++] = _str1ToBytes[i];
for (i = 0; i < _str2ToBytes.length; i++) retTobytes[index++] = _str2ToBytes[i];
return string(retTobytes)
}
//第三方库的使用:请自行百度 ~~~~~~~~~~~~~~~
//todo
2.solidity中String字符串基本上是任意长度的byte array字节数组(即byte[]),因此String []是二维字节数组(即byte[][])。根据solidity的说法,二维数组作为参数还不支持。
function setStrings(string [] row) // 编译会失败滴>
3.solidity 中每个字符串至少需要32个字节,这个就需要在字符串长度小于32字节下的gas消耗了。
对于bytes(1==>32)的使用减少gas消耗 不香吗?,下文介绍
bytes家族介绍
1.bytes(1==>32),这里的1==>32 指可以定义为:bytes1, bytes2, bytes3… 以此类推
- 指定固定空间大小
- 可以随意截取长度
- gas消耗明确可控
- 一旦声明不可更改
//以bytes32 举例
function setBytes(bytes32 [] _a) // 形参 _a 是一个一维数组
//solitdity 允许这样传参。
2.比较定长与非定长
bytes5 hh = 0x6c6abcdef8;
byte[5] yy = [byte(0x6a),0x68,0x79,0x75,0x65];
function changeIndexTohh() public {
// 错误,不可修改
hh[0] = 0x89;
}
function changeIndexToyy() public {
yy[0] = 0x89;
}
3.bytes[] 在solidity中不属于值类型,其实是一个变长字节数组,这点与String类似
//bytes声明方式
bytes b = new bytes(len) //len表示长度
String和bytes族的比较
1.String在处理时相对复杂,且消耗gas,对于字符串中含有中文的情况下,处理难度会增加
2.bytes字符串处理灵活,基本不涉及二维数组的问题
3.从语言的偏好来说,可以看出,solidity更支持开发者使用bytes而非String。
4.String在处理复杂业务时,做参数返回值等情况,很容易导致solidity开发者很头痛的问题之
EVM栈溢出
划重点这里考试要考的。
总结
对于只能合约来说,代码逻辑越多,相对的不可查未知漏洞也会增加,如果在设计合约方案时,减少对String的依赖,不香吗。