solidity读书笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013818374/article/details/78834456
1.地址是所有合约的基础,所有的合约都会继承地址对象,也可以随时将一个地址串,得到对应的代码进行调用。当然地址代表一个普通帐户时,就没有这么多丰富的功能啦。
地址类型的成员:
属性:balance
函数:send(),call(),delegatecall(),callcode()。
2.调用一个函数f()时,我们可以直接调用f(),或者使用this.f()。但两者有一个区别。前者是通过internal的方式在调用,而后者是通过external的方式在调用。请注意,这里关于this的使用与大多数语言相背。
3.复杂类型,如数组(arrays)和数据结构(struct)在Solidity中有一个额外的属性,数据的存储位置。可选为memory和storage。
memory存储位置同我们普通程序的内存一致。即分配,即使用,越过作用域即不可被访问,等待被回收。而在区块链上,由于底层实现了图灵完备,故而会有非常多的状态需要永久记录下来。比如,参与众筹的所有参与者。那么我们就要使用storage这种类型了,一旦使用这个类型,数据将永远存在。
基于程序的上下文,大多数时候这样的选择是默认的,我们可以通过指定关键字storage和memory修改它。
默认的函数参数,包括返回的参数,他们是memory。默认的局部变量是storage的1。而默认的状态变量(合约声明的公有变量)是storage。
另外还有第三个存储位置calldata。它存储的是函数参数,是只读的,不会永久存储的一个数据位置。外部函数的参数(不包括返回参数)被强制指定为calldata。效果与memory差不多。
数据位置指定非常重要,因为不同数据位置变量赋值产生的结果也不同。在memory和storage之间,以及它们和状态变量(即便从另一个状态变量)中相互赋值,总是会创建一个完全不相关的拷贝。
将一个storage的状态变量,赋值给一个storage的局部变量,是通过引用传递。所以对于局部变量的修改,同时修改关联的状态变量。但另一方面,将一个memory的引用类型赋值给另一个memory的引用,不会创建另一个拷贝。
4.数组有一个.length属性,表示当前的数组长度。storage的变长数组,可以通过给.length赋值调整数组长度。memory的变长数组不支持。

5.将一个struct赋值给一个局部变量(默认是storage类型),实际是拷贝的引用,所以修改局部变量值时,会影响到原变量。6.delete运算符,用于将某个变量重置为初始值。对于整数,运算符的效果等同于a = 0。而对于定长数组,则是把数组中的每个元素置为初始值,变长数组则是将长度置为0。对于结构体,也是类似,是将所有的成员均重置为初始值。

需要强调的是delete a的行为更像赋值,为a赋予一个新对象。
7.不支持switch和goto,支持if,else,while,do,for,break,continue,return,?:
if(1){...}在Solidity中是无效的。
8.表达式this.g(8);和c.g(2)(这里的c是一个合约实例)是外部调用函数的方式。实现上是通过一个消息调用,而不是直接通过EVM的指令跳转。需要注意的是,在合约的构造器中,不能使用this调用函数,因为当前合约还没有创建完成。
9.赋值给一个状态变量总是创建一个完全无关的拷贝。
赋值给一个局部变量,仅对基本类型,如那些32字节以内的静态类型(static types),创建一份完全无关拷贝。
如果是数据结构或者数组(包括bytes和string)类型,由状态变量赋值为一个局部变量,局部变量只是持有原始状态变量的一个引用。对这个局部变量再次赋值,并不会修改这个状态变量,只是修改了引用。但修改这个本地引用变量的成员值,会改变状态变量的值。
10.函数内定义的变量,在整个函数中均可用,无论它在哪里定义
11.合约可以通过Solidity,或不通过Solidity创建。当合约创建时,一个和合约同名的函数(构造器函数)会调用一次,用于初始化。
构造器函数是可选的。仅能有一个构造器,所以不支持重载。
如果不通过Solidity,我们可以通过web3.js,使用JavaScript的API来完成合约创建:
12.Solidity对函数和状态变量提供了四种可见性。分别是external,public,internal,private。其中函数默认是public。状态变量默认的可见性是internal。
13.编译器为自动为所有的public的状态变量创建访问函数。下面的合约例子中,编译器会生成一个名叫data的无参,返回值是uint的类型的值data。状态变量的初始化可以在定义时完成。
14.需要注意的是public的mapping默认访问参数是需要参数的,并不是之前说的访问函数都是无参的。
15.modifier?
16.不是所有的类型都支持常量,当前支持的仅有值类型和字符串。
访问器(Accessor)方法默认被标记为constant。当前编译器并未强制一个constant的方法不能修改状态。但建议大家对于不会修改数据的标记为constant。
17.每一个合约有且仅有一个没有名字的函数。这个函数无参数,也无返回值。如果调用合约时,没有匹配上任何一个函数(或者没有传哪怕一点数据),就会调用默认的回退函数。
此外,当合约收到ether时(没有任何其它数据),这个函数也会被执行。在此时,一般仅有少量的gas剩余,用于执行这个函数(准确的说,还剩2300gas)。所以应该尽量保证回退函数使用少的gas。

猜你喜欢

转载自blog.csdn.net/u013818374/article/details/78834456