Smart contract development based on Ethereum Solidity (array promotion)

Reference tutorial:[Data Storage] 1. String memory principle - special dynamic array_bilibili_bilibili

1. Syntax - string:

//声明版本号(程序中的版本号要和编译器版本号一致)
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)To obtain the length of a string, you need to first cast it into a dynamic length byte array through bytes() (String does not provide a length attribute).

(2)For string, a certain character cannot be obtained in the form of array subscript.

(3)A Chinese character occupies 3 bytes. This is because Chinese characters are stored in the memory through UTF8 type. As for < /span>. Occupies one byteissome special characters and numbersitits

2. Syntax - byte array conversion:

(1) Convert fixed-length byte array to fixed-length byte array:

//声明版本号(程序中的版本号要和编译器版本号一致)
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) Convert fixed-length byte array to dynamic-length byte array:

//声明版本号(程序中的版本号要和编译器版本号一致)
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) Convert dynamic length byte array to string:

//声明版本号(程序中的版本号要和编译器版本号一致)
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) Convert fixed-length byte array to string:

//声明版本号(程序中的版本号要和编译器版本号一致)
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. Syntax - Combining arrays and functions:

(1) Fixed length array:

//声明版本号(程序中的版本号要和编译器版本号一致)
pragma solidity ^0.5.17;
//合约
contract FixArray
{
   //(定义语法:数据类型[元素个数] 数组名)
   uint[5] arr = [1,2,3,4,5];  //定义时可以不进行初始化,那么初值将会全部置为0
   
   function 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) Variable length array:

//声明版本号(程序中的版本号要和编译器版本号一致)
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
   }
 
}

You can directly return the array (regardless of whether the length is variable or not) as the return value (you can also When passing an array as a parameter) and as a return value, please note that the data type declared by returns must be strictly the same as the return value (for a fixed-length array, The number of declared elements must be the same as the number of returned elements, the same applies when passed as a parameter to a function).

4. Syntax - two-dimensional array:

(1) Fixed-length two-dimensional array:

//声明版本号(程序中的版本号要和编译器版本号一致)
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) Variable length two-dimensional array:

//声明版本号(程序中的版本号要和编译器版本号一致)
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. Syntax - array literal (array constant):

//声明版本号(程序中的版本号要和编译器版本号一致)
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:让实际返回值类型和声明返回值匹配
   }
}

Guess you like

Origin blog.csdn.net/Zevalin/article/details/134889590