solidity系列教程<一>类型

Solidity 第一天

什么是智能合约?

简单地说,智能合约就是传统合约的数字化版本。它们是在区块链数据库上运行的计算机程序,可以在满足其源代码中写入的条件时自行执行。智能合约一旦编写好就可以被用户信赖,合约条款不能被改变,因此合约是不可更改的。

应用智能合约

现实世界是怎么样应用智能合约的呢?开发人员会为智能合约撰写代码。智能合约可用于交易和(或)两方/多方之间的任何交换行为。该代码包含一些会触发合约自动执行的条件。一旦编码完成,智能合约就会被上传到区块链网络上,即它们被发送到所有连接到网络的设备上。一旦将数据上传到所有设备上,用户就可以与执行程序代码的结果达成协议。然后更新数据库以记录合约的执行情况,并监督合约的条款以检查合规性。

MetaMask安装教程

MetaMask使用教程

Solidity编辑器vscode安装

solidity网页编辑器

https://remix.ethereum.org/

什么是solidity?

solidity是一种语法类似JavaScript的高级语言,它被设计成以编译的方式生成以太坊虚拟机代码。在后续的内容中你将会发现,使用它很容易创建用于投票、众筹、封闭拍卖、多重签名钱包等等的合约。

1、合约结构

看看最简单的合约结构

pragma solidity ^0.4.14;
// 第一句声明此合约的版本内容,目前是向下兼容0.4.14的版本
contract HelloWold {
     // 声明合约的关键字 contract, 后面跟的是合约名字
     // 这就是最简单的合约,接下来再完成合约的内容
}

版本声明:pragma solidity ^0.4.14;

这段代码的声明表示,源文件不会被0.4.14以下版本的编译器编译。当然同时也不会被0.5.0以上版本的编译器起作用(这是由^符号来决定的)。如果0.4.0编译器有问题,可以将其调整为0.4.1。向上兼容的

2、注释

  • 单行注释 : //
  • 多行注释 : /* This is a */
  • natspec注释
/**  
     @title(标题) 和 @author (作者)很直接了
     @notice (须知)向 用户 解释这个方法或者合约是做什么的。 @dev (开发者) 是向开发者解释更多的细节。
     @param (参数)和 @return (返回) 用来描述这个方法需要传入什么参数以及返回什么值
      @dev 注释来解释每个方法是做什么的
*/
contract shapeCalculator {
    /** @dev 求矩形表明面积与周长。
    * @param w 矩形宽度。
    * @param h 矩形高度。
    * @return s 求得表面积。
    * @return p 求得周长。
    */
    function rectangle(uint w, uint h) returns (uint s, uint p) {
        s = w * h;
        p = 2 * (w + h);
    }
}

3、定义变量(每一行代码结束后必须以;结尾,否则报错)

  • 定义变量:变量类型 变量名; uint bb;
  • 定义并且赋值变量: 变量类型 变量名 = 对应的值; uint aa = 10;
contract Example {
  // 这个无符号整数将会永久的被保存在区块链中
  uint myUnsignedInteger = 100;
}

4、变量类型

(1)bool(布尔类型)

和其他语言一样,只存在2个常量值(true, false)

操作符(Operators):

  • ! 逻辑非
  • && (logical conjunction, “and”) 逻辑与
  • || (logical disjunction, “or”) 逻辑或
  • == (equality) 相等
  • != (inequality) 不等
bool a = true;
bool b = !a;

// a == b -> false
// a != b -> true
// a || b -> true
// a && b -> false
(2)Integers(整型)

整型分为有符号整型int和无符号整型uint,都有从int8~int256的类型,步长为8,eg:int8\int16\int24…\int256,int和uint分别是int256和uint256的别名

操作符(Operators):

  • 比较操作符(Comparisons):<=, <, ==, !=, >=, >
  • 位操作符(Bit operators):&, |, ^(按位异或),~(按位取反)
  • 运算操作符(Arithmetic operators):++, –, *, /, %, **, +, -, >>, <<
pragma solidity ^0.4.14;

contract Math {

  function mul(int a, int b) constant returns (int) {

      int c = a * b;
      return c;
  }

  function div(int a, int b) constant returns (int) {

      int c = a / b;
      return c;
  }

  function sub(int a, int b) constant returns (int) {
      
      return a - b;
  }

  function add(int a, int b) constant returns (int) {

      int c = a + b;
      return c;
  }
}
(3)地址类型(Address)

以太坊中的地址的长度为20字节,一字节等于8位,一共160位,所以address其实亦可以用uint160来声明

我的以太坊钱包的地址为0xc1ce4f401951cd996f2628935acc858647489eef,0x代表十六进制,一个16进制由4个二进制组成,它的二进制刚好160位

Address的属性 (property):

  • balance 是一个uint256的数,成员属性
address x = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;
x.balance // x地址上的余额,单位 wei,1 ether = 10^18 wei;

  • transfer 成员方法

地址的成员方法和属性先不讲,后面再看

(4)字符串类型(String Literals)

字符串可以通过""或者''来表示字符串的值,Solidity中的string字符串不像C语言一样以\0结束

pragma solidity ^0.4.14;

contract StringLiterals{ 
    
    string  _name = "Gao";
}

备注:string字符串不能通过length方法获取其长度。

(5)固定大小字节数组类型

固定大小字节数组可以通过 bytes1, bytes2, bytes3, …, bytes32来进行声明。byte的别名就是 bytes1

  • bytes1只能存储一个字节,也就是二进制8位的内容。
  • bytes2只能存储两个字节,也就是二进制16位的内容。
  • bytes3只能存储三个字节,也就是二进制24位的内容。
pragma solidity ^0.4.4;

contract C {
    byte  a = 0x6c; // 0110 1100
    bytes1  b = 0x6c; // 0110 1100
    bytes2  c = 0x6c69; // 0110 1100 0110 1001
    bytes3  d = 0x6c6979; // 0110 1100 0110 1001 0111 1001  

        //.length 返回字节的个数  
        function gByteLength() constant returns (uint) {
        return a.length;
    }

        // a.length = length; 报错

        // 内部字节不可修改
        c[0] = b; // c是2个字节的,将第一个字节改为b

        // 访问某个字节
        c[1];
}
(6)动态大小字节数组类型

string 是一个动态尺寸的UTF-8编码字符串,它其实是一个特殊的可变字节数组,string是引用类型,而非值类型。
bytes 动态字节数组,引用类型。

在我们不确定字节数据大小的情况下,我们可以使用string或者bytes,而如果我们清楚的知道或者能够将字节书控制在bytes1 ~ bytes32,那么我们就使用bytes1 ~ bytes32,这样的话能够降低存储成本。

创建bytes字节数组
pragma solidity ^0.4.14;

contract C {
    
   // 初始化一个两个字节空间的字节数组
    bytes public name = new bytes(2);
    
    
   // 设置字节数组的长度
    function setNameLength(uint len) {
        
        name.length = len;
    }
    
    // 返回字节数组的长度
    function nameLength() constant returns (uint) {
        
        return name.length;
    }
         // 往字节数组中添加字节
    function pushAByte(byte b) {
        
        name.push(b);
    }
    // 当字节数组的长度只有2时,如果你通过push往里面添加了一个字节,那么它的长度将变为3,当字节数组里面有3个字节,但是你通过length方法将其长度修改为2时,字节数组中最后一个字节将被从字节数组中移除。
}
(7)数组类型(Arrays)
  • 固定长度的数组(Arrays)
pragma solidity ^0.4.14;

contract C {
    
    // 数组的长度为6,数组里面的存储的值的类型为uint类型
    uint [6] T = [1,2,3,4,5,6];

        // 固定长度为2的静态数组:
        uint[2] fixedArray;
        
        // 固定长度为5的string类型的静态数组:
        string[5] stringArray;
}

通过length方法获取数组长度遍历数组求总和

pragma solidity ^0.4.4;

contract C {
    
    // 数组的长度为5,数组里面的存储的值的类型为uint类型
    uint [5] T = [1,2,3,4,5];
    
    
    // 通过for循环计算数组内部的值的总和
    function numbers() constant public returns (uint) {
        uint num = 0;
        for(uint i = 0; i < T.length; i++) {
            num = num + T[i];
        }
        return num;
    }

}

声明数组时,一旦长度固定,将不能再修改数组的长度。

  • 可变长度的Arrays
可变长度类型数组的声明
pragma solidity ^0.4.14;

contract C {
    
    uint [] T = [1,2,3,4,5];
        // uint [] T = [1,2,3,4,5],这句代码表示声明了一个可变长度的T数组,因为我们给它初始化了5个无符号整数,所以它的长度默认为5。

        // 尝试通过push往T数组中添加值
      function pushUintToT() public {
        T.push(6);
    }
}

对可变长度的数组而言,可随时通过length修改它的长度。

(8) 枚举类型(Enums)

ActionChoices就是一个自定义的整型,当枚举数不够多时,它默认的类型为uint8,当枚举数足够多时,它会自动变成uint16,下面的GoLeft == 0,GoRight == 1, GoStraight == 2, SitStill == 3。在setGoStraight方法中,我们传入的参数的值可以是0 - 3当传入的值超出这个范围时,就会中断报错。

pragma solidity ^0.4.14;

contract test {

      // 定义枚举类型
    enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }

    ActionChoices _choice;

    ActionChoices  defaultChoice = ActionChoices.GoStraight;

    function setGoStraight(ActionChoices choice) public {
        _choice = choice;
    }

    function getChoice() constant public returns (ActionChoices) {
        return _choice;
    }

    function getDefaultChoice() pure public returns (uint) {
        return uint(defaultChoice);
    }
}

(9) 结构体类型(Structs)

自定义结构体

pragma solidity ^0.4.14;

contract Students {
    
    struct Person {
        uint age;
        string name;
    }
    // Person就是我们自定义的一个新的结构体类型,结构体里面可以存放定义类型的值。
}

初始化一个结构体

方法一:
pragma solidity ^0.4.14;

contract Students {
    
    struct Person {
        uint age;
        string name;
    }
    Person _person = Person(22,"gao");
}
------------------------------------------------------------
方法二:
pragma solidity ^0.4.4;

contract Students {
    struct Person {
        uint age;
        string name;
    }
    Person _person = Person({age:18,name:"liyuechun"});
}
(10) 字典类型(Mappings)

语法:mapping(_KeyType => _ValueType) 键值对存储关系

pragma solidity ^0.4.14;

contract MappingExample {
    
    // 测试账号
    // 0xc1ce4f401951cd996f2628935acc858647489eef
    mapping(address => uint)  balances;

    function update(address a,uint newBalance) public {
        balances[a] = newBalance;
    }
}

4、值类型与引用类型

值类型包含:

  • 布尔(Booleans)
  • 整型(Integer)
  • 地址(Address)
  • 定长字节数组(fixed byte arrays)
  • 有理数和整型(Rational and Integer Literals,String literals)
  • 枚举类型(Enums)
  • 函数(Function Types)

引用类型包含:

  • 不定长字节数组(bytes)
  • 字符串(string)
  • 数组(Array)
  • 结构体(Struts)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容