智能合約最佳實(shí)踐 之 Solidity 編碼規(guī)范

最新內(nèi)容會(huì)更新在主站深入淺出區(qū)塊鏈社區(qū)
原文鏈接:智能合約最佳實(shí)踐 之 Solidity 編碼規(guī)范

每一門語言都有其相應(yīng)的編碼規(guī)范缀程, Solidity 也一樣妻坝, 下面官方推薦的規(guī)范及我的總結(jié),供大家參考铣鹏,希望可以幫助大家寫出更好規(guī)范的智能合約敷扫。

命名規(guī)范

避免使用

小寫的l,大寫的I诚卸,大寫的O 應(yīng)該避免在命名中單獨(dú)出現(xiàn)葵第,因?yàn)楹苋菀桩a(chǎn)生混淆绘迁。

合約、庫卒密、事件缀台、枚舉及結(jié)構(gòu)體命名

合約、庫哮奇、事件及結(jié)構(gòu)體命名應(yīng)該使用單詞首字母大寫的方式膛腐,這個(gè)方式也稱為:帕斯卡命名法或大駝峰式命名法,比如:SimpleToken鼎俘, SmartBank依疼, CertificateHashRepository,Player而芥。

函數(shù)律罢、參數(shù)、變量及修飾器

函數(shù)棍丐、參數(shù)误辑、變量及修飾器應(yīng)該使用首單詞小寫后面單詞大寫的方式,這個(gè)方式也稱為:(懈璺辍)駝峰式命名法巾钉,是一種混合大小寫的方式,如:

  • 函數(shù)名應(yīng)該如:getBalance秘案,transfer砰苍,verifyOwner,addMember阱高。
  • 參數(shù)和變量應(yīng)該如:initialSupply赚导,senderAddress,account赤惊,isPreSale吼旧。
  • 修飾器應(yīng)該如:onlyAfter,onlyOwner未舟。

代碼格式相關(guān)

縮進(jìn)

使用空格(spaces)而不是Tab, 縮進(jìn)應(yīng)該是4個(gè)空格

空行

合約之間應(yīng)該有空行圈暗,例如:

contract A {
    ...
}
    
    
contract B {
    ...
}
    
    
contract C {
    ...
}

而不是使用:

contract A {
    ...
}
contract B {
    ...
}
    
contract C {
    ...
}
  • 函數(shù)之間應(yīng)該有空行,例如:
contract A {
    function spam() public {
        ...
    }
    
    function ham() public {
        ...
    }
}

沒有實(shí)現(xiàn)的話裕膀,空行可以省去员串,如:

contract A {
    function spam() public;
    function ham() public;
}

而不是:

contract A {
    function spam() public {
        ...
    }
    function ham() public {
        ...
    }
}

左括號(hào)應(yīng)該跟定義在一行

定義包括合約定義、函數(shù)定義昼扛、庫定義寸齐、結(jié)構(gòu)體定義等等,例如推薦使用:

 contract Coin {
    struct Bank {
        address owner;
        uint balance;
    }
}

而不是:

contract Coin
{
    struct Bank {
        address owner;
        uint balance;
    }
}

左括號(hào)應(yīng)該跟條件控制在一行

在使用if, else, while, for 時(shí),推薦的寫法是:

if (...) {
    ...
}

for (...) {
    ...
}

而不是:

if (...)
{
    ...
}

while(...){
}

for (...) {
    ...;}

如果控制語句內(nèi)只有一行访忿,括號(hào)可省略瞧栗,如:

if (x < 10)
    x += 1;

但像下面一個(gè)語句有多方就不能省略,如:

if (x < 10)
    someArray.push(Coin({
        name: 'spam',
        value: 42
    }));

表達(dá)式內(nèi)的空格

  • 一個(gè)單行的表達(dá)里海铆,在小括號(hào)迹恐、中括號(hào)、大括號(hào)里應(yīng)該避免不必要的空格卧斟,例如推薦使用:

    spam(ham[1], Coin({name: "ham"}));
    

    而不是:

    spam( ham[ 1 ], Coin( { name: "ham" } ) );
    

    有一種例外是殴边,結(jié)尾的括號(hào)跟在結(jié)束的分號(hào)后面, 應(yīng)該加一個(gè)空格珍语,如下面的方式也是推薦的:

    function singleLine() public { spam(); }
    
  • 分號(hào)锤岸;前不應(yīng)該有空格,例如推薦使用:

    function spam(uint i, Coin coin) public;
    

    而不是:

    function spam(uint i , Coin coin) public ;
    
  • 不要為對(duì)齊添加不必要的空格板乙,例如推薦使用:

    x = 1;
    y = 2;
    long_variable = 3;
    

    而不是:

    x             = 1;
    y             = 2;
    long_variable = 3;
    
  • 回退函數(shù)不應(yīng)該有空格是偷,例如推薦使用:

    function() public {
        ...
    }
    
    

    而不是:

    function () public {
        ...
    }
    

控制每一行長度

每行不應(yīng)該太長,最好在79(或99)個(gè)字符以內(nèi)募逞,函數(shù)的參數(shù)應(yīng)該是單獨(dú)的行蛋铆,且只有一個(gè)縮進(jìn),例如推薦的方式是:

thisFunctionCallIsReallyLong(
    longArgument1,
    longArgument2,
    longArgument3
);

而不是:

thisFunctionCallIsReallyLong(longArgument1,
                              longArgument2,
                              longArgument3
);

thisFunctionCallIsReallyLong(longArgument1,
    longArgument2,
    longArgument3
);

thisFunctionCallIsReallyLong(
    longArgument1, longArgument2,
    longArgument3
);

thisFunctionCallIsReallyLong(
longArgument1,
longArgument2,
longArgument3
);

thisFunctionCallIsReallyLong(
    longArgument1,
    longArgument2,
    longArgument3);

對(duì)應(yīng)的賦值語句應(yīng)該是這樣寫:

thisIsALongNestedMapping[being][set][to_some_value] = someFunction(
   argument1,
   argument2,
   argument3,
   argument4
);

而不是:

thisIsALongNestedMapping[being][set][to_some_value] = someFunction(argument1,
                                                                   argument2,
                                                                   argument3,
                                                                   argument4);

事件定義也應(yīng)該遵循同樣的原則放接,例如應(yīng)該使用:

event LongAndLotsOfArgs(
    adress sender,
    adress recipient,
    uint256 publicKey,
    uint256 amount,
    bytes32[] options
);

LongAndLotsOfArgs(
    sender,
    recipient,
    publicKey,
    amount,
    options
);

而不是:

event LongAndLotsOfArgs(adress sender,
                        adress recipient,
                        uint256 publicKey,
                        uint256 amount,
                        bytes32[] options);

LongAndLotsOfArgs(sender,
                  recipient,
                  publicKey,
                  amount,
                  options);

文件編碼格式

推薦使用utf-8 及 ASCII 編碼

引入文件應(yīng)該在最上方

建議使用:

import "owned";


contract A {
    ...
}


contract B is owned {
    ...
}

而不是:

contract A {
    ...
}


import "owned";


contract B is owned {
    ...
}

函數(shù)編寫規(guī)范

函數(shù)的順序

在編寫函數(shù)的時(shí)候刺啦,應(yīng)該讓大家容易找到構(gòu)造函數(shù),回退函數(shù)纠脾,官方推薦的的函數(shù)順序是:

  1. 構(gòu)造函數(shù)
  2. 回退函數(shù) (如果有)
  3. 外部函數(shù)(external)
  4. 公有函數(shù)(public)
  5. 內(nèi)部函數(shù)(internal)
  6. 私有函數(shù)(private)

同一類函數(shù)時(shí)玛瘸,constant函數(shù)放在后面, 例如推薦方式為:

 contract A {
    // 構(gòu)造函數(shù)
    function A() public {
        ...
    }

    // 回退函數(shù)
    function() public {
        ...
    }

    // 外部函數(shù)
    // ...

    // 帶有constant 外部函數(shù) 
    // ...

    // 公有函數(shù)
    // ...

    // 內(nèi)部函數(shù)
    // ...

    // 私有函數(shù)
    // ...
}

而不是下面的函數(shù)順序:

 contract A {


    // 外部函數(shù)
    // ...

    // 公有函數(shù)
    // ...

    // 內(nèi)部函數(shù)
    // ...
    
    function A() public {
        ...
    }

    function() public {
        ...
    }

    // 私有函數(shù)
    // ...
}

明確函數(shù)的可見性

所有的函數(shù)(包括構(gòu)造函數(shù))應(yīng)該在定義的時(shí)候明確函數(shù)的可見性苟蹈,例如應(yīng)該使用:

function explicitlyPublic(uint val) public {
    doSomething();
}

而不是

function implicitlyPublic(uint val) {
    doSomething();
}

可見性應(yīng)該在修飾符前面

函數(shù)的可見性應(yīng)該寫在自定義的函數(shù)修飾符前面糊渊,例如:

function kill() public onlyowner {
    selfdestruct(owner);
}

而不是

function kill() onlyowner public {
    selfdestruct(owner);
}

區(qū)分函數(shù)和事件

為了防止函數(shù)和事件(Event)產(chǎn)生混淆,聲明一個(gè)事件使用大寫并加入前綴(可使用LOG)汉操。對(duì)于函數(shù)再来, 始終以小寫字母開頭,構(gòu)造函數(shù)除外磷瘤。

// 不建議
event Transfer() {}
function transfer() {}

// 建議
event LogTransfer() {}
function transfer() external {}

常量

常量應(yīng)該使用全大寫及下劃線分割大詞的方式,如:MAX_BLOCKS搜变,TOKEN_NAME采缚, CONTRACT_VERSION。

參考視頻

我們也推出了目前市面上最全的視頻教程:深入詳解以太坊智能合約語言Solidity

目前我們也在招募體驗(yàn)師挠他,可以點(diǎn)擊鏈接了解扳抽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贸呢,更是在濱河造成了極大的恐慌镰烧,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件楞陷,死亡現(xiàn)場(chǎng)離奇詭異怔鳖,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)固蛾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門结执,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人艾凯,你說我怎么就攤上這事献幔。” “怎么了趾诗?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵蜡感,是天一觀的道長。 經(jīng)常有香客問我恃泪,道長郑兴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任悟泵,我火速辦了婚禮杈笔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘糕非。我一直安慰自己蒙具,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布朽肥。 她就那樣靜靜地躺著禁筏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衡招。 梳的紋絲不亂的頭發(fā)上篱昔,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音始腾,去河邊找鬼州刽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛浪箭,可吹牛的內(nèi)容都是我干的穗椅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼奶栖,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼匹表!你這毒婦竟也來了门坷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤袍镀,失蹤者是張志新(化名)和其女友劉穎默蚌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苇羡,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绸吸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宣虾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惯裕。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绣硝,靈堂內(nèi)的尸體忽然破棺而出蜻势,到底是詐尸還是另有隱情,我是刑警寧澤鹉胖,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布握玛,位于F島的核電站,受9級(jí)特大地震影響甫菠,放射性物質(zhì)發(fā)生泄漏挠铲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一寂诱、第九天 我趴在偏房一處隱蔽的房頂上張望拂苹。 院中可真熱鬧,春花似錦痰洒、人聲如沸瓢棒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脯宿。三九已至,卻和暖如春泉粉,著一層夾襖步出監(jiān)牢的瞬間连霉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工嗡靡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跺撼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓讨彼,卻偏偏與公主長得像财边,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子点骑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • --< > 令人討厭的小人物身上有著愚蠢的一致性 --(A Foolish Consistency is the ...
    LittleWizard閱讀 3,231評(píng)論 0 4
  • 源地址:http://www.runoob.com/w3cnote/google-python-styleguid...
    skaiger閱讀 506評(píng)論 0 0
  • ====== 一致性考慮 ======代碼更多是用來讀而不是寫酣难,本指南旨在改善Python代碼的可讀性。風(fēng)格指南強(qiáng)...
    marry_mei閱讀 410評(píng)論 0 0
  • PEP介紹 PEP是 Python Enhancement Proposal 的縮寫黑滴,是Python增強(qiáng)建議書的意...
    JasonDing閱讀 4,823評(píng)論 3 40
  • 手里捧著一個(gè)蘋果 懷揣著一份期盼 自行車的踏板還未落停 臉上的汗滴還在滑落 排練著 看見你嫣然一笑的那一刻 每天 ...
    a張廣明a閱讀 271評(píng)論 0 0