The goal of this guide is not to be the right way or the best way to write solidity code.
本指南的目标并不是编写稳定性代码的正确方法或最佳方法。
1. 在一个solidity源文件中,合约与合约(或库、接口等)空两行。
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract A {
// ...
}
contract B {
// ...
}
contract C {
// ...
}
2. 在一个合约中,函数与函数之间空一行。
abstract 合约,未实现的函数体可不留白行。
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
abstract contract A {
function spam() public virtual pure;
function ham() public virtual pure;
}
contract B is A {
function spam() public pure override {
// ...
}
function ham() public pure override {
// ...
}
}
3. 导入语句应该总是放在文件的顶部。
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
import "./Owned.sol";
contract A {
// ...
}
contract B is Owned {
// ...
}
4. 函数的顺序
函数应该根据其可见性和顺序进行分组:
- constructor
- receive function (if exists)
- fallback function (if exists)
- external
- public
- internal
- private
在分组中,最后放置view和pure函数。
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract A {
constructor() {
// ...
}
receive() external payable {
// ...
}
fallback() external {
// ...
}
// External functions
// ...
// External functions that are view
// ...
// External functions that are pure
// ...
// Public functions
// ...
// Internal functions
// ...
// Private functions
// ...
}
5.代码中各部分的顺序
代码中各部分顺序如下:
Pragma 语句
Import 语句
Interface
库
Contract
在Interface、库或Contract中,各部分顺序应为:
Type declaration / 类型声明
State variable / 状态变量
Event / 事件
Function / 函数
// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Import Ownable from the OpenZeppelin Contracts library
import "@openzeppelin/contracts/access/Ownable.sol";
// Make Box inherit from the Ownable contract
contract Box is Ownable {
uint256 private _value;
event ValueChanged(uint256 value);
// The onlyOwner modifier restricts who can call the store function
function store(uint256 value) public onlyOwner {
_value = value;
emit ValueChanged(value);
}
function retrieve() public view returns (uint256) {
return _value;
}
}