basic
基本规范,编码风格如下:
表达式空格
以下场景避免使用空格:
- 括号、中括号,花括号之后避免使用空格
✔️规范的方式:
spam(ham[1], Coin({name: “ham”}));
❌不规范的方式:
spam( ham[ 1 ], Coin( { name: “ham” } ) );
- 逗号和分号之前避免使用空格
✔️规范的方式:
function spam(uint i, Coin coin);
❌不规范的方式:
function spam(uint i , Coin coin) ;
- 赋值符前后避免多个空格
✔️规范的方式:
x = 1;
y = 2;
long_variable = 3;
❌不规范的方式:
x = 1;
y = 2;
long_variable = 3;
控制结构
合约、库、函数、结构体的花括号使用方法:
- 左花括号和声明同一行
- 右括号和左括号声明保持相同缩进位置
- 左括号后应回车
✔️规范的方式:
contract Coin {
struct Bank {
address owner;
uint balance;
}
}
❌不规范的方式:
contract Coin
{
struct Bank {
address owner;
uint balance;
}
}
以上建议也同样适用于if、else、while、for。
此外,if、while、for条件语句之间必须空行。
✔️规范的方式:
if (...) {
...
}
for (...) {
...
}
❌不规范的方式:
if (...)
{
...
}
while(...)
{
}
对于控制结构内部如果只有单条语句可以不需要使用括号。
✔️规范的方式:
if (x < 10)
x += 1;
❌不规范的方式:
if (x < 10)
someArray.push(Coin({
name: 'spam',
value: 42
}));
变量声明
对于数组变量声明,类型和数组中括号直接不能有空格。
✔️规范的方式:
uint[] x;
❌不规范的方式:
uint [] x;
- 赋值运算符两边要有一个空格
✔️规范的方式:
x = 3;x = 100 / 10;x += 3 + 4;x |= y && z;
❌不规范的方式:
x=3;x = 100/10;x += 3+4;x |= y&&z;
- 为了显示优先级,优先级运算符和低优先级运算符之间要有空格,这也是为了提升复杂声明的可读性。对于运算符两侧的空格数目必须保持一致。
✔️规范的方式:
x = 2**3 + 5;x = 2***y + 3*z;x = (a+b) * (a-**b);
❌不规范的方式:
x = 2** 3 + 5;x = y+z;x +=1;
contract
合约应该使用CapWords规范命名(首字母大写)。
contract BucketCrow {
// ...
}
enum
声明首字母大写,定义enum枚举变量首字母小写,如:
// 游戏状态
enum GameState {
GameStart, // 游戏开始
InGaming, // 游戏中
GameOver // 游戏结束
}
GameState public gameState; // 本轮游戏的状态
event
声明首字母大写,变量首字母小写,发送event需加关键字emit
,如:
event Deposit(
address from, // 转入地址
uint amount // 转入金额
);
function() public payable {
emit Deposit(msg.sender, msg.value);
}
constant
常量定义全部使用大写,便于与变量和函数参数区分,如:
uint constant public ENTRANCE_FEE = 1 ether; // 入场费
Storage
storage的变量,使用小写定义,如:
// 根据roomId => gameId => playerId => Player
mapping (uint => mapping (uint => mapping (uint => Player))) public players;
modifier
修饰符定义使用驼峰命名法,首字母小写,如:
modifier onlyOwner {
require (msg.sender == owner, "OnlyOwner methods called by non-owner.");
_;
}
默认修饰符应该放在其他自定义修饰符之前。
✔️规范的方式:
function kill() public onlyowner {
selfdestruct(owner);
}
❌不规范的方式:
function kill() onlyowner public {
selfdestruct(owner);
}
function
对于参数较多的函数声明可将所有参数逐行显示,并保持相同的缩进。函数声明的右括号和函数体左括号放在同一行,并和函数声明保持相同的缩进。
✔️规范的方式:
function thisFunctionHasLotsOfArguments(
address a,
address b,
address c,
address d,
address e,
address f
) {
do_something;
}
❌不规范的方式:
function thisFunctionHasLotsOfArguments(address a, address b, address c,
address d, address e, address f) {
do_something;
}
如果函数包括多个修饰符,则需要将修饰符分行并逐行缩进显示。函数体左括号也要分行。
✔️规范的方式:
function thisFunctionNameIsReallyLong(address x, address y, address z)
public
onlyowner
priced
returns (address)
{
do_something;
}
❌不规范的方式:
function thisFunctionNameIsReallyLong(address x, address y, address z)
public onlyowner priced returns (address){
do_something;
}
对于需要参数作为构造函数的派生合约,如果函数声明太长或者难于阅读,建议将其构造函数中涉及基类的构造函数分行独立显示。
✔️规范的方式:
contract A is B, C, D {
function A(uint param1, uint param2, uint param3, uint param4, uint param5)
B(param1)
C(param2, param3)
D(param4)
{
// do something with param5
}
}
❌不规范的方式:
contract A is B, C, D {
function A(uint param1, uint param2, uint param3, uint param4, uint param5)
B(param1)
C(param2, param3)
D(param4)
{
// do something with param5
}
}
public function
使用驼峰命名法,首字母小写,如:
function createRoom() public payable entranceFeeIsValid(msg.value) {
// ...
}
private function
私有方法也使用驼峰命名法,但是需要加_
作为前缀用于与public function
区分,如:
function _calOdds() private pure {
// ...
}
parameter
function的参数命名都在前面加_
,用于与常量以及全局变量区分,如:
function playerBet(uint _roomId,uint _gameId,uint _betAmount) public {
// ...
}
get
获取存储数据的function,使用驼峰命名法,并加前缀get
,如:
function getPlayersOfRoom(uint _roomId) public view returns (address[2]){
Room storage currentRoom = rooms[_roomId];
return currentRoom.players;
}
网友评论