基本语法

版本指令

所有Solidity源码都必须指明版本,用于标明Solidity编译器的版本,这是为了避免将来新的编译器破坏代码

pragma solidity ^0.4.20; // 声明版本

// 定义一个合约
contract AntFamily { }

状态变量

状态变量是定义在合约内部,但是不在函数内部的变量,会永久保存在合约存储空间中,也就说它们会被写入区块链中

pragma solidity ^0.4.20;

contract AntFamily {

  uint dnaDigits = 12;

}

数学运算

在 Solidity 中,数学运算与其它程序设计语言相同:

  • 加法: x + y
  • 减法: x - y
  • 乘法: x * y
  • 除法: x / y
  • 取模: x % y
  • 幂运算:x ** y
// 表示6的2次方
uint a = 6 ** 2;

结构体

通过结构体来定义新的类型,结构体允许生成一个更复杂的数据类型,可以有多个属性

struct Book {
string name;
uint page;
}

函数定义

习惯上函数里的变量都是以(_)开头 (不是硬性规定) 以区别全局变量

function buyBook(string _name, uint _count) {

}

数组

如果想建立一个集合,可以使用数组这种数据类型,支持两种数组: 静态数组和动态数组

// 固定长度为3的静态数组:
uint[3] fixedArray;
// 固定长度为5的string类型的静态数组:
string[6] stringArray;
// 动态数组,长度不固定,可以动态添加元素:
uint[] dynamicArray;

也可以建立一个结构体类型的数组:

Book[] books;

状态变量被永久保存在区块链中,所以在合约中创建动态数组来保存结构化的数据是非常有意义的

公共数组:

Book[] public books;

数组和结构体的使用

如下传见了Ant结构体,和Ant类型的数组,定义了ceateAnt函数:

pragma solidity ^0.4.20;

contract AntFamily {

  uint dnaDigits = 12;
uint dnaModulus = 10 ** dnaDigits; struct Ant {
string name;
uint dna;
} Ant[] public ants; function createAnt(string _name, uint _dna) {
ants.push(Ant(_name,_dna)); // 创建一个结构体并添加到数组中
} }

keccak256散列函数的使用

该函数将一个字符串转换为一个256位的16进制数字

//bc6bb462e38af7da48e0ae7b5cbae860141c04e5af2cf92328cd6548df111fcb
keccak256('xxx');
//3a60bbc72c8477330650d5aae5e7d73f0d15a6efe7e8aab4fa3c33a3a8c3b467
keccak256('xxy');

事件

事件是合约和区块链通讯的一种机制,应用可以“监听”某些事件,并做出反应,使用event关键字来定义事件,使用emit关键字在函数中触发事件

pragma solidity ^0.4.20;

contract AntFamily {

  event NewAnt(uint indexed antId,string name,uint dna);

  uint dnaDigits = 12;
uint dnaModulus = 10 ** dnaDigits; struct Ant {
string name;
uint dna;
} Ant[] public ants; function createAnt(string _name, uint _dna) {
uint id = ants.push(Ant(_name, _dna))-1;
emit NewAnt(id,_name,_dna);
} function createRandomAnt(string _name) {
uint rand = uint(keccak256(_name));
uint randDna = rand % dnaModulus;
createAnt(_name, randDna);
} }

复杂组合

pragma solidity ^0.4.20;

contract AntFamily {

  event NewAnt(uint indexed antId, string name, uint dna);

  event NewHouse(uint indexed houseId,string name,uint existGoods,uint maxGoods);

  uint dnaDigits = 12;
uint dnaModulus = 10 ** dnaDigits; struct Ant {
string name;
uint dna;
} struct House {
string name;
uint existGoods;
uint maxGoods;
} Ant[] public ants; House[] public houses; function createAnt(string _name, uint _dna) {
uint id = ants.push(Ant(_name, _dna)) - 1;
emit NewAnt(id, _name, _dna);
} function createRandomAnt(string _name) {
uint rand = uint(keccak256(_name));
uint randDna = rand % dnaModulus;
createAnt(_name, randDna);
} function createHouse(string _houseName,uint _existGoods,uint _maxGoods) {
uint houseId = houses.push(House(_houseName,_existGoods,_maxGoods))-1;
emit NewHouse(houseId,_houseName,_existGoods,_maxGoods);
} }

映射

//可以用来通过userId 存储/查找的用户名
mapping (uint => string) userIdToName;

使用:

pragma solidity ^0.4.20;

contract AntFamily {

  event NewAnt(uint indexed antId, string name, uint dna);
event NewHouse(uint indexed houseId, string name, uint existGoods, uint maxGoods); uint dnaDigits = 12;
uint dnaModulus = 10 ** dnaDigits; struct Ant {
string name;
uint dna;
} struct House {
string name;
uint existGoods;
uint maxGoods;
} Ant[] public ants;
House[] public houses; mapping (uint => identity) public antToOwner;
mapping (identity => uint) ownerAntCount;
mapping (uint => identity) houseToOwner; function createAnt(string _name, uint _dna) {
uint id = ants.push(Ant(_name, _dna)) - 1;
antToOwner[id] = msg.sender;
ownerAntCount[msg.sender]++; emit NewAnt(id, _name, _dna);
} function createRandomAnt(string _name) {
uint rand = uint(keccak256(_name));
uint randDna = rand % dnaModulus;
createAnt(_name, randDna);
} function createHouse(string _houseName, uint _existGoods, uint _maxGoods) {
uint houseId = houses.push(House(_houseName, _existGoods, _maxGoods)) - 1;
houseToOwner[houseId] = msg.sender; emit NewHouse(houseId, _houseName, _existGoods, _maxGoods);
} }

require

使得函数在执行过程中,当不满足某些条件时抛出错误,并停止执行

function sayHiToBob(string _name) public returns (string) {
// 比较 _name 是否等于 "Bob". 如果不成立,抛出异常并终止程序
require(keccak256(_name) == keccak256("Bob"));
// 如果返回 true, 运行如下语句
return "Hi!";
}

这样调用函数 sayHiToBob(“Bob”),它会返回“Hi!”。而如果你调用的时候使用了其他参数,它则会抛出错误并停止执行。 因此,在调用一个函数之前,用 require 验证前置条件是非常有必要的

Solidity 入门的更多相关文章

  1. Solidity中的基本类型转换

    Solidity中的基本类型转换(十四)|入门系列 2017/4/29 posted in Solidity入门系列 点击查看原文,获得优化的排版. 隐式转换 如果一个运算符能支持不同类型.编译器会隐 ...

  2. 《区块链DAPP开发入门、代码实现、场景应用》笔记2——Solidity实现简单的智能合约

    本节仅以一个简单的智能合约示例,介绍智能合约的基本组成元素,本合约定义一个uint类型的变量,以及对应这个变量的读写函数. 01 pragma solidity >=0.4.0 <0.6. ...

  3. 区块链入门到实战(38)之Solidity – 条件语句

    Solidity支持条件语句,让程序可以根据条件执行不同的操作.条件语句包括: if if...else if...else if 语法 if (条件表达式) { 被执行语句(如果条件为真) } 示例 ...

  4. 区块链入门到实战(37)之Solidity – 循环语句

    与其他语言类似,Solidity语言支持循环结构,Solidity提供以下循环语句. while do ... while for 循环控制语句:break.continue. Solidity – ...

  5. 区块链入门到实战(36)之Solidity – 运算符

    Solidity – 算术运算符 Solidity 支持的算术运算符,如下表所示: 假设变量A的值为10,变量B的值为20. 序号 运算符与描述 1 + (加)求和例: A + B = 30 2 – ...

  6. 区块链入门(5)Truffle 项目实战,Solidity IDE, 智能合约部署

    在上一张我们学习了Truffle项目的创建,部署等相关内容,今天我们就来实战一下. 今天我们要做3件事: 1) 学习搭建一个Solidity IDE(Remix). 2) 使用这个Solidity I ...

  7. Solidity 文档--第一章:智能合约入门

    一个简单的智能合约 先从一个非常基础的例子开始,不用担心你现在还一点都不了解,我们将逐步了解到更多的细节. 存储 contract SimpleStorage { uint storedData; f ...

  8. 区块链入门到实战(35)之Solidity – 变量作用域

    局部变量的作用域仅限于定义它们的函数,但是状态变量可以有三种作用域类型. Public – 公共状态变量可以在内部访问,也可以通过消息访问.对于公共状态变量,将生成一个自动getter函数. Inte ...

  9. 区块链入门到实战(34)之Solidity – 变量

    Solidity 支持三种类型的变量: 状态变量 – 变量值永久保存在合约存储空间中的变量. 局部变量 – 变量值仅在函数执行过程中有效的变量,函数退出后,变量无效. 全局变量 – 保存在全局命名空间 ...

  10. 区块链入门到实战(33)之Solidity – 数据类型

    在用任何语言编写程序时,都需要使用变量来存储各种信息.变量是内存空间的名称,变量有不同类型,例如整型.字符串类型等等.操作系统根据变量的数据类型分配内存. Solidity中,变量类型有以下几大类: ...

随机推荐

  1. drf视图类

    1 2个视图基类 # django 内置的View# drf 的APIView ,继承自View# GenericAPIView -两个重要的类属性:    queryset = Book.objec ...

  2. [Leetcode 787]中转K站内最便宜机票

    题目 n个城市,想求从src到dist的最廉价机票 有中转站数K的限制,即如果k=5,中转10次机票1000,中转5次机票2000,最后返回2000 There are n cities connec ...

  3. 一次CentOS 出现“Too many open files"错误的解决

    一.原因分析 出现本问题,应该是打开文件最多数量不足,默认是1024个,在生产环境中经常出现该问题. 使用ulimit -a 查看打开文件数量限制 二.解决方案A(临时有效) 1.如果是非root用户 ...

  4. HOOK大法

    // 请求头hook 测试网站同花顺 OK var header_old = window.XMLHttpRequest.prototype.setRequestHeader;window.XMLHt ...

  5. HTML5的语义标签

    H5新增了很多标签,也更加语义化了,但是除了header.footer.nav等,其他的还真的没有去了解过,今天整理一下H5新增的语义化标签. Header: 不用多说,就是定义头部,可以多个. Fo ...

  6. springboot的websocket因IP问题无法连接

    首先遇到这个问题有点奇葩,出现在项目上线时的客户现场,头两天一直都无法确定原因,因为它的表现方式很奇怪,基于springboot实现的websocket,同样的代码在公司研发环境不会有问题,客户现场会 ...

  7. 样例1-http接口的waiting(TTFB)时间从5.5s优化为100ms

    问题 :如何解决网页响应慢,waiting(TTFB)时间过长,接口返回耗时等问题? 首先需要了解什么是Waiting (TTFB) 时间?TTFB 是Time to First Byte 的缩写,指 ...

  8. JsonResult向前端返回值,报错500

    1,问题原因 因为返回信息为json对象,我在controller方法所在的入口类上,添加的注解是:@Controller 而@Controller是不适合返回json内容的 2,解决方法 方法一:不 ...

  9. Centos7 禁用IPV6地址的方法

    方法 1 编辑文件/etc/sysctl.conf, vi /etc/sysctl.conf 添加下面的行: net.ipv6.conf.all.disable_ipv6 =1 net.ipv6.co ...

  10. P4555 [国家集训队]最长双回文串 回文树(回文自动机)简单题

    贴个题目链接:https://www.luogu.org/problem/P4555 题目:输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(∣X∣,∣Y∣≥1)且X和Y都是回文 ...