You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
contract MyContract {
uint public data;
function externalFunction() external {
// 只能通过外部调用
}
}
为什么**external** 比public函数更加节省gas?
让我们首先看一个示例:
contract GasComparison {
// Public function
function publicFunction(uint[] memory data) public pure returns (uint) {
return data.length;
}
// External function
function externalFunction(uint[] calldata data) external pure returns (uint) {
return data.length;
}
}
// 调用示例
contract Caller {
GasComparison public gc = new GasComparison();
function callPublic(uint[] memory data) public {
gc.publicFunction(data);
}
function callExternal(uint[] memory data) public {
gc.externalFunction(data);
}
}
基本概念:
在Solidity中,函数的可见性(Visibility)定义了谁可以访问该函数。主要有四种可见性修饰符:
private
(私有)、internal
(内部)、public
(公共)和external
(外部)。它们的区别如下:private
(私有):private
函数。internal
(内部):private
修饰符一样,也是不能外部调用的。internal
函数。internal
是默认的函数可见性修饰符。public
(公共):public
函数时,Solidity会生成一个与该public
函数相对应的外部接口,使得它能够被外部调用。external
(外部):public
函数更节省 gas,因为参数不需要从内存复制到calldata为什么**
external
** 比public
函数更加节省gas?让我们首先看一个示例:
这涉及到Solidity中的内存管理和gas优化,是一个比较深入的话题。
memory
是一个临时的存储区域, 用于在函数执行期间存储数据。calldata
是一个特殊的数据位置, 包含函数调用的输入数据, 它是只读的, 并且不会被复制。public
函数时, 无论是从合约内部还是外部调用, 参数都会被复制到内存中。publicFunction
使用memory
关键字, 意味着data
数组会被复制到内存中。external
函数只能从合约外部调用。calldata
中的数据,而不需要将其复制到内存中。externalFunction
使用calldata
关键字,直接从调用数据中读取data
数组。calldata
读取数据,external
函数避免了这个复制步骤,从而节省了gas。external
可能会更有效率。public
函数可能更合适。需要注意的是,这种gas节省主要适用于大型数据结构。对于简单的值类型(如
uint
,bool
等),差异可能不明显。 这就是为什么在某些情况下,external
函数比public
函数更节省gas的原因。它避免了不必要的数据复制,直接利用了以太坊虚拟机(EVM)的底层机制。什么时候使用memory修饰符,什么时候使用calldata修饰符?
在Solidity中,
memory
和calldata
是两种用于指定数据存储位置的关键字,它们在函数参数和局部变量中的使用有所不同。理解何时使用memory
和calldata
对优化gas消耗和确保正确的数据处理非常重要。memory
修饰符memory
表示数据只在函数执行期间临时存储。函数执行完毕后,这些数据会被自动销毁。memory
中的数据是可变的(即可以修改)。如果你需要在函数中对数据进行修改,通常使用memory
。memory
中。使用场景
memory
。memory
。calldata
修饰符calldata
表示数据直接从调用者的输入中读取(即从事务的输入数据中读取),它是只读的,无法修改。calldata
中的数据不需要在内存中进行复制,且是只读的,所以在处理较大数据结构(如数组)时,使用calldata
可以节省gas。calldata
只能用于外部函数(external
函数)的参数,因为它直接映射到事务的输入数据。使用场景
external
的,使用calldata
。calldata
可以避免不必要的内存复制,从而节省gas。memory
vscalldata
总结使用
memory
:public
或internal
,而非external
。使用
calldata
:external
)中处理大数据结构且需要优化gas消耗时。举例对比
通过合理使用
memory
和calldata
,你可以在优化gas消耗的同时确保函数的正确性和效率。总结
private
:只能在合约内部调用,子合约不能访问。internal
:只能在合约内部或继承的子合约中调用。public
:可以被任何人、包括合约内外部调用。external
:只能从合约外部调用,不能在合约内部直接调用(除非通过this
关键字)。The text was updated successfully, but these errors were encountered: