合约之间间隔
- 在 solidity 源码中合约声明之间留出两个空行。
contract A {
...
}
contract B {
...
}
contract C {
...
}
- 在一个合约中的函数声明之间留有一个空行。在相关联的各组单行语句之间可以省略空行。(例如抽象合约的 stub 函数)。
pragma solidity ^0.6.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 {
// ...
}
}
- 基于 PEP 8 recommendation ,将代码行的字符长度控制在 79(或 99)字符来帮助读者阅读代码。折行时应该遵从以下指引:
- 第一个参数不应该紧跟在左括号后边
- 用一个、且只用一个缩进
- 每个函数应该单起一行
- 结束符号 ); 应该单独放在最后一行
thisFunctionCallIsReallyLong(
longArgument1,
longArgument2,
longArgument3
);
thisIsALongNestedMapping[being][set][to_some_value] = someFunction(
argument1,
argument2,
argument3,
argument4
);
event LongAndLotsOfArgs(
adress sender,
adress recipient,
uint256 publicKey,
uint256 amount,
bytes32[] options
);
- Import 语句应始终放在文件的顶部。
- 排序有助于读者识别他们可以调用哪些函数,并更容易地找到构造函数和 fallback 函数的定义。
函数应根据其可见性和顺序进行分组:
- 构造函数
- receive 函数(如果存在)
- fallback 函数(如果存在)
- 外部函数(external)
- 公共函数(public)
- 内部(internal) 一般以_开头
- 私有(private) 一般以_开头
- 在一个分组中,把 view 和 pure 函数放在最后。
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;
contract A {
function A() public {
...
}
receive() external payable {
// ...
}
fallback() external {
// ...
}
// External functions
// ...
// External functions that are view
// ...
// External functions that are pure
// ...
// Public functions
// ...
// Internal functions
// ...
// Private functions
// ...
}
- 控制结构
用大括号表示一个合约,库、函数和结构。 应该:
- 开括号与声明应在同一行。
- 闭括号在与之前函数声明对应的开括号保持同一缩进级别上另起一行。
- 开括号前应该有一个空格。
contract Coin {
struct Bank {
address owner;
uint balance;
}
}
if (...) {
...
}
if (x < 3) {
x += 1;
} else if (x > 7) {
x -= 1;
} else {
x = 5;
}
for (...) {
...
}
function increment(uint x) public pure returns (uint) {
return x + 1;
}
function increment(uint x) public pure onlyowner returns (uint) {
return x + 1;
}
- Visibility
- Mutability
- Virtual
- Override
- Custom modifiers
function balance(uint from) public view override returns (uint) {
return balanceOf[from];
}
function shutdown() public onlyowner {
selfdestruct(owner);
}
对于长函数声明,建议将每个参数独立一行并与函数体保持相同的缩进级别。闭括号和开括号也应该 独立一行并保持与函数声明相同的缩进级别。
function thisFunctionHasLotsOfArguments(
address a,
address b,
address c,
address d,
address e,
address f
)
public
{
doSomething();
}
如果一个长函数声明有修饰符,那么每个修饰符应该下沉到独立的一行。
function thisFunctionNameIsReallyLong(address x, address y, address z)
public
onlyowner
priced
returns (address)
{
doSomething();
}
function thisFunctionNameIsReallyLong(
address x,
address y,
address z,
)
public
onlyowner
priced
returns (address)
{
doSomething();
}
- 对于继承合约中需要参数的构造函数,如果函数声明很长或难以阅读,建议将基础构造函数像多个修饰符的风格那样 每个下沉到一个新行上书写。
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.7.0;
// Base contracts just to make this compile
contract B {
constructor(uint) {
}
}
contract C {
constructor(uint, uint) {
}
}
contract D {
constructor(uint) {
}
}
contract A is B, C, D {
uint x;
constructor(uint param1, uint param2, uint param3, uint param4, uint param5)
B(param1)
C(param2, param3)
D(param4)
{
// do something with param5
x = param5;
}
}
mapping(uint => uint) map;
mapping(address => bool) registeredAddresses;
mapping(uint => mapping(bool => Data[])) public data;
mapping(uint => mapping(uint => s)) data;
uint[] x;
str = "foo";
str = "Hamlet says, 'To be or not to be...'";
x = 3;
x = 100 / 10;
x += 3 + 4;
x |= y && z;
|