区块链编程语言Solidity学习:bilibili课(二)

105 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

本文章主要是将在学习b站Solidity学习的摘要笔记课程链接
源代码链接

5.calldata在函数中使用,对应可以在函数中再次调用函数的时候,勿需复制数据就可以直接到内部的函数中调用

但是如果是使用memory,函数就会把数据复制一份,会大大增加gas

//Data location can only be specified for array, struct or mapping types
不定长的都要指定数据位置吧

calldata比memory使用的gas更少

存事件(event)比存memory更加省gas

Image.png

但是在这样的情况,storage的数据更少.因为如果是calldata,直接从内存里读取出来,勿需有memory的转化,而memory就需要转化

6.数组其实是带有一个get方法的

7.子合约中如果要重写函数

需要在父合约中加上virtual,子合约加上 override

如果需要再次被重写,就需要同时写virtual override

8.合约多重继承

从左往右,从基类到派生;

如过在函数中重写两个继承的合约的共同函数,则需要写override(x,y),其中xy的顺序没有关系

合约内构造👇

Image.png 即使是这样的话,构造的顺序也是由is后面的数据决定的

9.合约super,运行父合约的

Image.png
super函数会让f.bar()和g.bar()都被运行,
但是如果f,g都继承于e合约,且两个bar()中都有super(),这个e的bar只会运行一次

(无论是使用e.或者是super.都一样)

10.cannot call contract via function name

出现这个问题可能是因为你的函数可见性出错了,了解一下external、public这些东西的区别
Solidity对函数和状态变量提供了四种可见性
分别是external,public,internal,private。其中函数默认是public
状态变量默认的可见性是internal

  • interal - 函数只能通过内部访问(当前合约或者继承的合约),可在当前合约或继承合约中调用。类似于Java的protected
  • public - public标识的函数是合约接口的一部分。可以通过内部,或者消息来进行调用。与Java的public含义一致。
  • external - external标识的函数是合约接口的一部分。函数只能通过外部的方式调用,继承也不行。外部函数在接收大的数组时更有效。Java中无与此对应的关键字。
  • private - 只能在当前合约内访问,在继承合约中都不可访问。与Java中的private含义一致。

调用例子中的两个函数,我们能看到,调用test函数(public)使用496 gas,调用test2(external)函数仅花费261 gas。这是为什么呢?

对于public函数,每次调用时Solidity会将参数copy到内存中;而调用external函数,则可以直接读取calldata。存储分配在EVM中是非常昂贵的,而读取calldata则相对廉价很多。

那为什么public需要做内存复制呢?

答:那是因为public需要支持内部调用,而内部调用与外部调用的处理机制是完全不同的。内部调用是通过jump指令执行的,参数数据在内部是指向内存的。因此,当编译器在编译可内部调用的函数时,函数希望它的参数是载入内存的。
而对于external,编译器是不需要允许内部调用的,因此编译器可以直接从calldata读取数据,而省略了内存复制。

Image.png