美文网首页
solidity合约开发规范

solidity合约开发规范

作者: Jisen | 来源:发表于2019-01-11 11:41 被阅读9次

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;
}

相关文章

网友评论

      本文标题:solidity合约开发规范

      本文链接:https://www.haomeiwen.com/subject/kzztdqtx.html