Solidity作为一个图灵完备的编程语言,跟javascript还有这诸多相似之处。作为目前主流的智能合约语言,有着易学,易用的特点。但是由于区块链的早期阶段和EVM的早期阶段,所有有着各种概念需要区分。
首先讲一下可见性,可见性分为变量可见性和函数可见性。
对于public变量,会自动生成getter函数
//solidity source codes contract Token{ string public name = "Hardhat Token"; string public symbol = "HHT"; .... }//javascript describe("getter test", function(){ it("getter test", async function(){ const name = await token.name(); console.log("name: "+ name); }); });不会默认生成setter函数,内部直接访问name
internal 内部可见性变量, 可以在派生和本合约内访问。
private 本合约内部可见,派生合约不可见。
值得注意的是无论是internal, private,还是public都可以通过getStorageA(index)的方式,从区块链节点获取变量的内容,所以不要将confidential的内容上传到blockchain上。
public
public 函数是合约接口的一部分,可以在内部或通过消息调用。Java中含义一致。函数默认是public。
private
只能在当前合约内部访问,外部和派生的合约是无法访问的。这个与java的private含义也是一致的。
external
external标识的函数是合约接口的一部分。函数只能通过外部的方式调用。外部函数在接收大的数组时更有效。Java中无与此对应的关键字。
internal
函数只能通过内部访问(当前合约或者继承的合约),可在当前合约或继承合约中调用。类似于Java的protected。
这里最让人迷惑的其实就是public和external,有了public为什么还要提供external呢?
这里涉及到一个概念叫calldata,就是在交易中发出交易的data部分。
当使用external的时候,函数不会对参数进行copy,仅仅从calldata引用就可以了。
当使用public的时候,函数会对参数进行复制操作。public为了支持从内部和从外部两种调用方式,所以要一视同仁的进行参数拷贝。
所以如果你能确认只有外部调用,那么就使用external,这样可以为你节省不少gas。
以下是calldata的说明

以上是Transaction部分的源码,有兴趣可以自己看。

