Solidity学习笔记(一) 基础总结

Solidity学习笔记(一) 基础总结_第1张图片

简介

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

目前尝试Solidity的最好方式是使用基于浏览器的编译器Remix、中文版Remix(需要一点时间加载,请耐心等待)。

有用的链接:

Ethereum

Browser-Based CompilerChangelog

Story Backlog

Source Code

Gitter Chat

结构

Solidity的合约和面向对象语言中的类的定义相似。每个合约包括了状态变量,函数,函数修饰符,事件,结构类型 和枚举类型。另外,合约也可以从其他合约中继承 。

状态变量是在合约存贮器中永久存贮的值

函数是合约中可执行单位的代码

函数修饰符可以在声明的方式中补充函数的语义

事件是和EVM(以太虚拟机)日志设施的方便的接口

结构是一组用户定义的变量

枚举是用来创建一个特定值的集合的类型

函数

函数可见性分析

public - 任意访问

private - 仅当前合约内

internal - 仅当前合约及所继承的合约

external - 仅外部访问(在内部也只能用外部访问方式访问

函数的限制访问

在Solidity中constant、view、pure三个函数修饰词的作用是告诉编译器,函数不改变/不读取状态变量,这样函数执行就可以不消耗gas了,因为不需要矿工来验证。在Solidity v4.17之前,只有constant,后续版本将constant拆成了view和pure。view的作用和constant一模一样,可以读取状态变量但是不能改;pure则更为严格,pure修饰的函数不能改也不能读状态变量,智能操作函数内部变量,否则编译通不过。大家可以运行以下测试代码来加深这3个关键字的理解。

Solidity学习笔记(一) 基础总结_第2张图片

详细描述

Constant 状态变量

状态变量可以被声明为 constant。在这种情况下,只能使用那些在编译时有确定值的表达式来给它们赋值。 任何通过访问 storage,区块链数据(例如 now, this.balance 或者 block.number)或执行数据( msg.gas ) 或对外部合约的调用来给它们赋值都是不允许的。 在内存分配上有边界效应(side-effect)的表达式是允许的,但对其他内存对象产生边界效应的表达式则不行。 内建(built-in)函数 keccak256,sha256,ripemd160,ecrecover,addmod 和 mulmod 是允许的(即使他们确实会调用外部合约)。

允许带有边界效应的内存分配器的原因是这将允许构建复杂的对象,比如查找表(lookup-table)。 此功能尚未完全可用。

编译器不会为这些变量预留存储,它们的每次出现都会被替换为相应的常量表达式(这将可能被优化器计算为实际的某个值)。

不是所有类型的状态变量都支持用 constant 来修饰,当前支持的仅有值类型和字符串

Solidity学习笔记(一) 基础总结_第3张图片

View 函数:可以将函数声明为view类型,这种情况下要保证不修改状态。

下面的语句被认为是修改状态:

修改状态变量。

产生事件。

创建其他合约

使用selfdestruct。

通过调用发送以太币。

调用任何没有标记为view或者pure的函数。

使用低级调用。

使用包含特定操作码的内联汇编。

Solidity学习笔记(一) 基础总结_第4张图片

注解:

onstant 是 view 的别名。

Getter 方法被标记为 view。

编译器没有强制 view 方法不能修改状态。

Pure 函数:函数可以声明为 pure ,在这种情况下,承诺不读取或修改状态。

除了上面解释的状态修改语句列表之外,以下被认为是从状态中读取:

读取状态变量。

访问 this.balance 或者

.balance。

访问 block、tx、msg 中任意成员 (除 msg.sig 和 msg.data 之外)。

调用任何未标记为 pure 的函数。

使用包含某些操作码的内联汇编。

Solidity学习笔记(一) 基础总结_第5张图片

警告:编译器没有强制 pure 方法不能读取状态。

Modifier 函数:modifier即函数的修改器,可以用来改变一个函数的行为,控制函数的逻辑。修改器是一种合约属性,可以被继承和重写。

例------设置投票者权限:

Solidity学习笔记(一) 基础总结_第6张图片

Payable 函数:函数指定了payable才能拿获取msg.value , 接收以太币。

Solidity学习笔记(一) 基础总结_第7张图片

Fallback函数:没有名字,不能有参数,没有返回值。在合约调用没有匹配到函数签名,或者调用没有带任何数据时被自动调用。

Solidity学习笔记(一) 基础总结_第8张图片

ether发送send():

address.send(ether to send)向某个合约直接转帐时,address指向的合约必须有fallback函数,且为payable的,才可以接收到发送来的ether,因为:address.send(ether to send)这个行为没有发送任何数据,所以接收合约总是会调用fallback函数。

fallback的限制:

send()函数总是会调用fallback,这个行为非常危险,著名的DAO被黑也与这有关。如果我们在分红时,对一系列帐户进行send()操作,其中某个做恶意帐户中的fallback函数实现了一个无限循环,将因为gas耗尽,导致所有send()失败。为解决这个问题,send()函数当前即便gas充足,也只会附带限定的2300gas,故而fallback函数内除了可以进行日志操作外,你几乎不能做任何操作。

下述行为消耗的gas都将超过fallback函数限定的gas值:

注意:上述仅对使用send()方式的有2300gas的限制,对使用call()方式没有这样的限制。

向区块链中写数据

创建一个合约

调用一个external的函数

发送ether

int和uint(整型)

int(m):有符号整数,此类整数可以表示正整数,又可以表示负整数。

uint(m):无符号整数,此类整数一定是正整数。

m关键字取值为8~256步长是8 ,表示在内存中2进制的位数,控制了整数的取值范围,不写默认为256。

uint和int分别是uint256和int256的别名。

m一定要是8的整数倍。

在使用整型过程中,如果在已经确定了数据大小的上限情况下,尽量使用与其最靠近的步长。节省公链资源。

Solidity中,转化的时候不支持8进制。

整型的上溢和下溢。

上溢:如果一个整型变量的值达到其类型的上限,再给他加上一个正数,最终结果会是变量值+正数-类型上限下溢

下溢:如果一个整型变量的值达到其类型的下限,再给他减上一个正数,最终结果会是上限值-该正数的值

Solidity学习笔记(一) 基础总结_第9张图片

Solidity学习笔记(一) 基础总结_第10张图片

Solidity学习笔记(一) 基础总结_第11张图片

Solidity学习笔记(一) 基础总结_第12张图片

Mapping(映射)

映射类型,一种键值对的映射关系存储结构。定义方式为mapping(_KeyType => _KeyValue)。

键类型允许除映射、变长数组、合约、枚举、结构体外的几乎所有类型()

值类型没有任何限制,可以为任何类型包括映射类型。

映射可以被视作为一个哈希表,所有可能的键会被虚拟化的创建,映射到一个类型的默认值(二进制的全零表示)。在映射表中,并不存储键的数据,仅仅存储它的keccak256哈希值,这个哈希值在查找值时需要用到。

映射是没有长度的,也没有键集合或值集合的概念。

映射类型,仅能用来作为状态变量,或在内部函数中作为storage类型的引用。

可以通过将映射标记为public,来让Solidity创建一个访问器。通过提供一个键值做为参数来访问它,将返回对应的值。

映射的值类型也可以是映射,使用访问器访问时,要提供这个映射值所对应的键,不断重复这个过程。

映射不能return给外界,数组可以。

Delete映射中的一个key值,实际不是在删除,而是在重置为初始值。

在solidity中,map不支持遍历

Solidity学习笔记(一) 基础总结_第13张图片

全局单位

1.货币单位

Wei 1

Kwei 1e3

Mwei 1e6

Gwei 1e9

Mircroether 1e12

Milliether(finney) 1e15

Ether 1e18

2.时间单位(没有month)

时间分类:Seconds,minutes,hours,days,weeks,years

Solidity学习笔记(一) 基础总结_第14张图片

3.内建的全局变量

在solidity中,内建的全局变量可以在合约脚本的任何地方调用

Msg的所有成员

Sender:发送者地址

Value:发送给合约的以太币,默认单位是位

Data:调用数据

Gas:剩余gas

This的部分成员:Balance: 余额

Tx的部分成员

Origin:交易发送者的地址

Gasprice:gas的价格

Now :当前时间

Block成员

Number:区块号

Difficulty:当前区块难度

Coinbase:矿工地址

Timestamp:时间戳

Gaslimit():当前区块的gaslimit

Blockhash(num):给定区块的哈希值,只支持最近的256个区块

参考文章

Fallback 讲解

Solidity 语法讲解

Solidity constant view pure关键字的区别与联系

合约官网参考

你可能感兴趣的:(区块链)