当前位置: 首页 > news >正文

基于以太坊的智能合约开发Solidity(数组提升篇)

参考教程:【数据存储篇】1、string内存原理——特殊动态数组_哔哩哔哩_bilibili

1、语法——字符串:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract DynamicString
{string name = "lalalalalalala啦啦啦";function getLength() public returns(uint){return bytes(name).length;  //要想获取字符串的长度,需要先将其强制转换成动态长度字节数组(string不提供长度属性)}function getPartName() public returns(bytes1){return bytes(name)[0];  //返回字符串第一个字符(1个字节)的二进制形式(不能直接通过数组下标的形式获取其中的字符)}function changeName() public {bytes(name)[0] = 'T';  //对字符串的某一个字符进行修改//一个英文字母(以及特殊字符和数字等)占1个字节,一个中文汉字占3个字节}
}

(1)要想获取字符串的长度,需要通过bytes()先将其强制转换成动态长度字节数组(string不提供长度属性)。

(2)对于string,不能通过数组下标的形式获取其中的某个字符

(3)一个汉字占3个字节,这是因为汉字在内存中是通过UTF8类型存储的,至于一些特殊字符和数字则是占用一个字节

2、语法——字节数组转换:

(1)固定长度字节数组转为固定长度字节数组:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract DynamicString
{bytes12 name =  0x7a68656e676a69616e78756e;function changeBytes1() public view returns(bytes1){return bytes1(name);  //返回的结果为“0x7a”,后面的内容全部丢失}function changeByte2() public view returns(bytes2){return bytes2(name);  //返回的结果为“0x7a68”,后面的内容全部丢失}function changeByte3() public view returns(bytes16){return bytes16(name);  //返回的结果为“0x7a68656e676a69616e78756e00000000”,强制转换后多余的空间由0填充}
}

(2)固定长度字节数组转为动态长度字节数组:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract DynamicString
{bytes12 name =  0x7a68656e676a69616e78756e;function fixBytesToDynamicBytes() public view returns(bytes memory){//return bytes(name);  不允许直接将字符串的强制类型转换返回,需要借助for循环将固定长度字节数组复制到动态长度字节数组中bytes memory newName = new bytes(name.length);  //方法内的动态长度字节数组要加“memory”,这里暂时不做解释for(uint i = 0; i < name.length; i++)  //数组元素下标的数据类型只能是uint,除此之外for循环的使用与c语言基本相同(if语句、while语句以及相关关键字的用法也基本相同){newName[i] = name[i];  //复制行为}return newName;}
}

(3)动态长度字节数组转为字符串:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract Bytes2String
{bytes name =  new bytes(2);function init() public{name[0] = 0x7a;name[1] = 0x68;}function bytesToString() public view returns(string memory){return string(name);  //允许将动态长度字节数组强制转换字符串的结果直接返回}
}

(4)固定长度字节数组转为字符串:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract Bytes32ToString
{function byts32ToString(bytes32 inputName)  public view returns(string memory){uint count = 0;  //定义一个无符号变量记录字节数组的实际长度,否则转换而得的字符串尾部会有不定量的NUT字符for(uint i = 0; i < inputName.length; i++)  //利用for循环计算inputName数组的实际长度{if(inputName[i] != 0){count++;}}bytes memory finalName = new bytes(count);  //动态长度字节数组的初始长度为inputName数组的实际长度//利用for循环将固定长度字节数组转换为动态长度字节数组,再强制转换为字符串for(uint j = 0; j<count; j++){finalName[j] = inputName[j];  //复制行为}return string(finalName);}}

3、语法——数组与函数结合使用:

(1)固定长度数组:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract FixArray
{//(定义语法:数据类型[元素个数] 数组名)uint[5] arr = [1,2,3,4,5];  //定义时可以不进行初始化,那么初值将会全部置为0function init() public{arr[0] = 100;  //可以对单个元素值进行修改arr[1] = 200;}function sumArr() public view returns(uint){uint sum = 0;for(uint i = 0; i < arr.length; i++)  //除了数组元素下标是uint类型以外,其它地方和c语言基本相同{sum += arr[i];}return sum;}//固定长度数组可以通过length获取其长度,但是不能对其长度进行更改,也不能进行push操作
}

(2)可变长度数组:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract DynamicArray
{uint[] arr = [1,2,3,4,5];  //在定义数组时不写出元素个数,就是定义可变长度数组function changeLength() public{arr.length = 1;  //对可变长度数组的长度进行缩短,原数组的多余部分会丢失}function changeLength2() public{arr.length = 10;  //对可变长度数组的长度进行增长,多余部分用0填充}function getContent() public view returns(uint[] memory){return arr;  //可以直接将数组(不管长度是否可变)作为返回值返回(也可以将数组作为参数传入)}function getLength() public view returns(uint){return arr.length;}function push() public{arr.push(6);  //在可变长度数组末尾追加元素6}}

可以直接将数组(不管长度是否可变)作为返回值返回(也可以将数组作为参数传入),作为返回值时,需注意returns声明的数据类型要与返回值严格相同(对于固定长度数组,声明的元素个数要与返回的元素个数相同,作为参数传入函数时也同理)。

4、语法——二维数组:

(1)固定长度二维数组:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract TwoArray
{uint[2][3] arr = [[1,2],[3,4],[5,6]];  //与大多数编程语言不同,solidity定义二维数组时先声明列数再声明行数(个人认为比较别扭)function getLength() public view returns(uint){return arr.length;  //该例中返回3,代表有3个元素(其中每个元素自己又由2个元素组成)}function getContent() public view returns(uint[2][3] memory){return arr;  //可以将二维数组作为返回值直接返回(输出“unit256[2][3]:1,2,3,4,5,6”,是线性表示的)}function add() public view returns(uint){uint sum = 0;//遍历二维数组需要借助嵌套循环for(uint i = 0; i<arr.length; i++)  //arr.length代表arr中有3行{for(uint j=0; j<arr[0].length; j++)  //arr.length[0]代表arr中每一行有2个元素(即2列){sum += arr[i][j];  //虽然二维数组的声明比较别扭,但使用时和c语言基本也完全一样}}return sum;}
}

(2)可变长度二维数组:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract DynamicTwoArray
{uint[][] arr = [[1,2],[3,4],[6,7]];  //可变长二维数组初始化时不允许每个一维数组长度不相同/*function getContent()  public view returns(uint[][] memory){return arr;  //动态长度数组不支持直接返回}*/function changeLength() public{arr.length = 10;  //修改二维数组的行数}function getLength() public view returns(uint){return arr.length;  //二维数组的行数}function getContntLength() public view returns(uint) {return arr[0].length;  //二维数组的列数}}

5、语法——数组字面量(数组常量):

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract ArrayLiterals
{/* function getArrayLiterals() public returns(uint[3] memory){return [1,2,3];  //uint默认为256位,但是1、2、3都是uint8类型,类型不匹配,会报错}function getArrayLiterals2() public returns(uint[3] memory){return [256,255,3];  //uint默认为256位,但是256是uint16类型,类型不匹配,会报错(255、3是uint8类型)}*/function getArrayLiterals1() public view returns(uint16[3] memory){return [256,2,3];  //解决办法1:让声明的返回值类型和实际返回值匹配(将返回值参数中的类型改为数组元素中最大值的类型)}function getArrayLiterals2() public view returns(uint[3] memory){return [uint(256),2,3];  //解决办法2:让实际返回值类型和声明返回值匹配}
}

相关文章:

  • 智能时代:互联网+如何改变我们的生活与工作
  • STM32CubeIDE串口空闲中断实现不定长数据接收
  • 华为OD机试真题-智能成绩表-2023年OD统一考试(C卷)
  • 线性代数入门与学习笔记
  • ViT:视觉 Transformer
  • VS Code 上已达250万 Java 开发者!微软和红帽一起公布 VS Code Java 未来六个月路线图
  • 机器学习实验三:支持向量机模型
  • 连锁零售企业如何优化网络性能?
  • 【开源】基于Vue+SpringBoot的教学资源共享平台
  • Redis研学-三种特殊类型的常用命令
  • blender 数字键盘上的快捷键
  • el-tree搜索的使用
  • svn使用步骤
  • Qt开发 之 记一次安装 Qt5.12.12 安卓环境的失败案例
  • IntelliJ插件开发-Code Vision Hints
  • JS变量作用域
  • js正则,这点儿就够用了
  • Making An Indicator With Pure CSS
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • Node 版本管理
  • 阿里云前端周刊 - 第 26 期
  • 大主子表关联的性能优化方法
  • 复习Javascript专题(四):js中的深浅拷贝
  • 构建二叉树进行数值数组的去重及优化
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 关于extract.autodesk.io的一些说明
  • 前端
  • 悄悄地说一个bug
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 通过git安装npm私有模块
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​iOS安全加固方法及实现
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #1015 : KMP算法
  • #laravel 通过手动安装依赖PHPExcel#
  • #LLM入门|Prompt#3.3_存储_Memory
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (一)80c52学习之旅-起始篇
  • (转)程序员疫苗:代码注入
  • .NET Core 中的路径问题
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • 。Net下Windows服务程序开发疑惑
  • @Import注解详解
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [1127]图形打印 sdutOJ
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [C/C++]数据结构----顺序表的实现(增删查改)
  • [C++]类和对象【上篇】