Solidity 从入门到实战(一)

solidity 从入门到实战(一)

注意:本专栏主要来自于https://www.bilibili.com/video/BV1St411a7Pk?p=11&spm_id_from=pageDriver的学习笔记

编写第一个案例

//声明版本号
pragma solidity ^0.4.16;
//合约 有点类似于java中的class
contract HelloWorld{
     
    //合约属性变量
    string myName = "HelloWorld";
    //合约中方法 注意语法顺序 其中此处view 代表方法只读 不会消耗gas
    function getName() public view returns(string){
     
        return myName;
    }
    //可以修改属性变量的值 消耗gas
    function changeName(string _newName) public{
     
        myName = _newName;
    }
    // pure:不能读取也不能改变状态变量
    function pureName(string _name) public pure returns(string){
     
        return _name;
    }
    
}

用constant、view、pure修饰function分别表示:

  • constant:只能读取不可改变状态变量(就是contract中定义的变量)
  • view:只能读取不可改变状态变量,和constant一样
  • pure:不能读取也不能改变状态变量

想要详细了解他们的区别,请点击: https://www.jianshu.com/p/5f1bc0d39d79

solidity 语法介绍

注意:由于以下内容都是一些基本的语言特性,相信有编程基础的同学都可以看懂,因此,关于它的语法代码可以运行一下,看看效果,这里就不做过多的解释。

真假与或非

pragma solidity ^0.4.16;

contract BoolTest{
     
    
    bool a;
    
    int c = 100;
    int d = 200;
    
    function getBoolDefault() returns(bool){
     
        return a;
    }
    
    function getBoolean() returns(bool){
     
        return !a;
    }
    
    function judge() returns(bool){
     
        return c==d;
    }
    
    function logicAnd() returns(bool){
     
        return c==d && true;
    }
    
    function logicOr() returns(bool){
     
        return c==d || true;
    }
    
    function logicNot() returns(bool){
     
        return c!=d && true;
    }
    
}

整型与算术运算

在solidity中,基本的整型有int(有符号整型,有正有负)uint(无符号整型,无负数)。并且他们以8位为区间,int支持int8,int16,int24int256,uint同理。int默认为int256,uint默认为uint256

基本算术运算

pragma solidity ^0.4.16;

contract Math{
     
    //加
    function add(uint a,uint b) public returns(uint){
     
        return a+b;
    }
	//减
    function minus(uint a,uint b) public returns(uint){
     
        return a-b;
    }
    //乘
    function multiply(uint a,uint b) public returns(uint){
     
        return a*b;
    }
    //除
    function divide(uint a,uint b) public returns(uint){
     
        return a/b;
    }
    //取余
    function mod(uint a,uint b) public returns(uint){
     
        return a%b;
    }
    //幂运算
    function square(uint a,uint b) public returns(uint){
     
        return a**b;
    }
}

位运算

solidity支持的位运算有以下几种位与&位或|位非~位异或^左移>>,右移<<

pragma solidity ^0.4.16;

contract Math{
     
    
    uint8 a = 3;
    uint8 b = 4;
    function bitwiseAnd() public returns(uint8){
     
        return a&b;
    }

    function bitwiseOr() public returns(uint8){
     
        return a|b;
    }
    
    function tilde() public returns(uint8){
     
        return ~a;
    }
    
    function caret() public returns(uint8){
     
        return a^b;
    }
    
    function leftShift() public returns(uint8){
     
        return a<<1;
    }
    
    function rightShift() public returns(uint8){
     
        return a>>1;
    }
}

复合运算

++和-- 只需要记住谁在前,结果输出谁(加号在前,结果加一;数字在前,结果输出数字本身);而变量本身等于运算后的值

pragma solidity ^0.4.16;

contract Math{
     
    //输出a
    function add2(uint a) public returns(uint){
     
        return a++;
    }
    //输出a+1
    function add3(uint a) public returns(uint){
     
        return ++a;
    }
    //输出a
    function minus2(uint a) public returns(uint){
     
        return a--;
    }
    //输出a-1
    function minus3(uint a) public returns(uint){
     
        return --a;
    }
}

整型溢出及异常处理

我们先看一下以下代码

pragma solidity ^0.4.16;

contract Math{
     
    
    function flow() view public returns(uint8){
     
        uint8 mm  = 255;
        mm++;
        return mm;
    }
    
    function flow2() view public returns(uint256){
     
        uint8 mm  = 255;
        mm++;
        return mm;
    }
    
     function flow3() view public returns(uint){
     
        uint mm  = 255;
        mm++;
        return mm;
    }
}

通过运行,我们会发现flow=0,flow2=0, flow3=256,出现这个原因就是因为那就是进位溢出导致。
我们再来看看下面这段代码

pragma solidity ^0.4.16;

contract Math{
     
    
    function flowMinus() view returns(uint8){
     
        uint8 nn = 0;
        nn--;
        return nn;
    }
    
    function flowMinus3() view returns(uint8){
     
        uint8 nn = 0;
        return nn--;
    }
}

上述的复合减运算答案分别是2550,你猜对了吗?

要避免的异常

例如:除数不能为0

pragma solidity ^0.4.16;

contract Math{
     
    
    function errorTest() view returns(int){
     
        int a = 2;
        int b = 3;
        return a/b;
    }
    
    function errorTest2() view returns(int){
     
        int a = 2;
        int b = 0;
        return a/b;
    }
    
}

数组

固定长度字节数组

关键字有:bytes1,bytes2mbytes3,…,bytes32(以步长1递增)。byte代表bytes1。

pragma solidity ^0.4.16;

contract ByteArray{
     
    
    bytes1 public num1 = 0x7a;
    
    bytes2 public num2 = 0x7a68;
    
    bytes12 public num3 = 0x7a68656e676a69616e78756e;
}

固定长度字节数组对于数值来说,有点等同于我们的uint。一个字节等于8位。即bytes1 有点等同于uint8,至少在位数上是相等的。
**
注意:上面的例子,我们同时引入了一个public修饰合约成员变量的范例,在solidity中,直接用public声明成员变量,编译部署后,会为我们生成一个默认的get方法,让我们可以直接调用这个成员属性。

**

动态长度字节数组

pragma solidity ^0.4.16;

contract DynamicByteArray{
     
   
    bytes public name = new bytes(2);
    
    function initName(){
     
        name[0] = 0x7a;
        name[1] = 0x68;
    }
    
    function getLength() view returns(uint){
     
        return name.length;
    }
    
    function changeName(){
     
        name[0] = 0x88;
    }
    
    function changeLength(){
     
        name.length = 5;
    }
}

依次执行getLength,initNamename,changNamename,changeLength,getLength看看结果
此外,我们的动态数组,还提供了一个push方法,可以在我们自己数组的末尾继续添加我们的字节元素。

function pushTest(){
     
    name.push(0x99);
}

字符串

在上节我们学习了动态字节数组,而我们的字符串,可不可以按照动态字节的数组去获取他的长度和其中的元素呢?

pragma solidity ^0.4.16;

contract DynamicString{
     
    
    string name = "tongxuejava";
    
    function getLength() returns(uint){
     
        // return name.length; 不能够直接的获取string的长度
        return bytes(name).length;//通过bytes强转的转换
    }
    
    function getPartName() returns(bytes1){
     
        return bytes(name)[0];
    }
    
    function changeName() {
     
       // return name[0];不能够直接通过下标的方式获取string里面的内容
          
         bytes(name)[0] = 'T';
    }
}

通过实验,我们发现要想获取字符串中的元素,得通过bytes()进行强制转换。

固定长度字节数组转化

pragma solidity ^0.4.16;

contract DynamicString{
     
    
    bytes12 name =  0x7a68656e676a69616e78756e;
    
    function changeBytes1() view returns(bytes1){
     
        return bytes1(name);
    }
    
    function changeByte2() view returns(bytes2){
     
        return bytes2(name);
    }
    
    function changeByte3() view returns(bytes16){
     
        return bytes16(name);
    }
}

Solidity 从入门到实战(一)_第1张图片

通过运行,我们可以发现规律:转小从头截取,转大末尾补零

固定长度字节数组转动态字节数组

pragma solidity ^0.4.16;

contract DynamicString{
     
    
    bytes12 name =  0x7a68656e676a69616e78756e;
    
   function fixBytesToDynamicBytes() view returns(bytes){
     
       //return bytes(name); 直接转换为动态字节数组是不行的
       bytes memory newName = new bytes(name.length);//使用一个for循环来挨个字节进行转换
       for(uint i= 0;i < name.length;i++){
      //注意uint 无符号整型
           newName[i] = name[i];
       }
       return newName;
   }
}

动态长度字节数组转为string

(bytes===>string)

pragma solidity ^0.4.16;

contract Bytes2String{
     
    
    bytes name =  new bytes(2);
    
    function init(){
     
        name[0] = 0x7a;
        name[1] = 0x68;
    }
    
    function bytesToString() view returns(string){
     
        return string(name);
    }
}

固定长度字节数组转string

我们上面都知道了动态长度数组可以强制转换为string,那么固定长度数组可不可以强制转为string呢?

pragma solidity ^0.4.16;

contract Bytes32ToString{
     
    
    bytes2 name =  0x7a68;
    
    function bytes32ChangeString() returns(string){
     
        return string(name);    
    }
 
}

通过编写以上合约,会发现编译出错,那么我们该如何转换呢?
从上面的学习中,我们知道。固定长度字节数组可以转为动态字节数组,而动态字节数组可以转为string。所以,这就是我们转换的思路。

pragma solidity ^0.4.16;

contract Bytes32ToString{
     
    
    function byts32ToString(bytes32 inputName)  view returns(string){
     
        bytes memory newName = new bytes(inputName.length);
        for(uint i = 0;i<newName.length;i++){
     
            newName[i] = inputName[i];
        }
        return string(newName);
    }
 
}

接下来,我们将以上内容做一个总结:

  • 动态长度字节数组
    • bytes的初始化–new bytes
    • 获取bytes的长度和内容
    • 修改长度和内容
  • string
    • 不能够直接获取长度和内容
    • 需要转换为bytes获取长度和内容
    • 特殊字符的长度的内容和获取
    • 中文字符占用3个字节
  • 固定长度字节数组之间转换
    • 转小从头截取,转大末尾补零
  • 固定长度转可变长度数组
    • 利用new bytes(),然后循环转换。

你可能感兴趣的:(solidity,编程语言,区块链)