良好统一的编程风格,有助于提高代码的可读性和可维护性。下面是有关Solidity编程风格的几条建议。
代码布局
- 缩进 – 使用4个空格代替制表符作为缩进。避免空格与制表符混用。
- 空2行规则 – 2个合约定义之间空2行。
pragma solidity ^0.5.0;
contract LedgerBalance {
//...
}
contract Updater {
//...
}
- 空1行规则 – 2个函数之间空1行。在只有声明的情况下,不需要空行。
pragma solidity ^0.5.0;
contract A {
function balance() public pure;
function account() public pure;
}
contract B is A {
function balance() public pure {
// ...
}
function account() public pure {
// ...
}
}
- 行长度 – 一行不超过79个字符。
- 换行规则 – 函数声明中左括号不换行,每个参数一行并缩进,右括号换行,并对齐左括号所在行。
function_with_a_long_name(
longArgument1,
longArgument2,
longArgument3
);
variable = function_with_a_long_name(
longArgument1,
longArgument2,
longArgument3
);
event multipleArguments(
address sender,
address recipient,
uint256 publicKey,
uint256 amount,
bytes32[] options
);
MultipleArguments(
sender,
recipient,
publicKey,
amount,
options
);
- 源码编码 – UTF-8
- Import – Import语句应该放在文件的顶部,pragma声明之后。
- 函数顺序 – 函数应该根据它们的可见性来分组。
pragma solidity ^0.5.0;
contract A {
constructor() public {
// ...
}
function() external {
// ...
}
// External functions
// ...
// External view functions
// ...
// External pure functions
// ...
// Public functions
// ...
// Internal functions
// ...
// Private functions
// ...
}
- 避免多余空格 – 避免在圆括号、方括号或大括号后有空格。
- 控制结构 – 大括号的左括号不换行,右括号换行,与左括号所在行对齐。
pragma solidity ^0.5.0;
contract Coin {
struct Bank {
address owner;
uint balance;
}
}
if (x < 3) {
x += 1;
} else if (x > 7) {
x -= 1;
} else {
x = 5;
}
if (x < 3)
x += 1;
else
x -= 1;
- 函数声明 – 使用上面的大括号规则。添加可见性标签。可见性标签应该放在自定义修饰符之前。
function kill() public onlyowner {
selfdestruct(owner);
}
- 映射 – 在声明映射变量时避免多余空格。
mapping(uint => uint) map; // 不是 mapping (uint => uint) map;
mapping(address => bool) registeredAddresses;
mapping(uint => mapping(bool => Data[])) public data;
mapping(uint => mapping(uint => s)) data;
- 变量声明 – 声明数组变量时避免多余空格。
uint[] x; // 不是 unit [] x;
- 字符串声明 – 使用双引号声明字符串,而不是单引号。
str = "foo";
str = "Hamlet says, 'To be or not to be...'";
代码中各部分的顺序
代码中各部分顺序如下:
- Pragma 语句
- Import 语句
- Interface
- 库
- Contract
在Interface、库或Contract中,各部分顺序应为:
- Type declaration / 类型声明
- State variable / 状态变量
- Event / 事件
- Function / 函数
命名约定
- 合约和库应该使用驼峰式命名。例如,SmartContract, Owner等。
- 合约和库名应该匹配它们的文件名。
- 如果文件中有多个合约/库,请使用核心合约/库的名称。
Owned.sol
pragma solidity ^0.5.0;
// Owned.sol
contract Owned {
address public owner;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
//....
}
function transferOwnership(address newOwner) public onlyOwner {
//...
}
}
Congress.sol
pragma solidity ^0.5.0;
// Congress.sol
import "./Owned.sol";
contract Congress is Owned, TokenRecipient {
//...
}
- 结构体名称
驼峰式命名,例如: SmartCoin - 事件名称
驼峰式命名,例如:AfterTransfer - 函数名
驼峰式命名,首字母小写,比如:initiateSupply - 局部变量和状态变量
驼峰式命名,首字母小写,比如creatorAddress、supply - 常量
大写字母单词用下划线分隔,例如:MAX_BLOCKS - 修饰符的名字
驼峰式命名,首字母小写,例如:onlyAfter - 枚举的名字
驼峰式命名,例如:TokenGroup