W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
源文件可以包含任意數(shù)量的 合約定義、import、 pragma和 using for指令以及 struct、enum、function、 error 和常量變量定義。
如果智能合約的源代碼可用,則可以更好地建立對(duì)智能合約的信任。由于提供源代碼總是涉及版權(quán)方面的法律問(wèn)題,Solidity 編譯器鼓勵(lì)使用機(jī)器可讀的SPDX 許可證標(biāo)識(shí)符。每個(gè)源文件都應(yīng)以說(shuō)明其許可證的注釋開(kāi)頭:
// SPDX-License-Identifier: MIT
編譯器不會(huì)驗(yàn)證許可證是否是 SPDX 允許的列表的一部分,但它會(huì)在字節(jié)碼元數(shù)據(jù)中包含提供的字符串。
如果您不想指定許可證或者源代碼不是開(kāi)源的,請(qǐng)使用特殊值UNLICENSED
。請(qǐng)注意UNLICENSED
(不允許使用,不在 SPDX 許可證列表中)與UNLICENSE
(向所有人授予所有權(quán)利)不同。Solidity 遵循npm 建議。
當(dāng)然,提供此注釋并不能免除您與許可相關(guān)的其他義務(wù),例如必須在每個(gè)源文件或原始版權(quán)所有者中提及特定的許可標(biāo)題。
編譯器在文件級(jí)別的文件中的任何位置都可以識(shí)別注釋?zhuān)ㄗh將其放在文件的頂部。
有關(guān)如何使用 SPDX 許可證標(biāo)識(shí)符的更多信息,請(qǐng)?jiān)L問(wèn) SPDX 網(wǎng)站。
該pragma
關(guān)鍵字用于啟用某些編譯器功能或檢查。pragma 指令始終位于源文件的本地,因此如果要在整個(gè)項(xiàng)目中啟用它,則必須將 pragma 添加到所有文件中。如果您導(dǎo)入另一個(gè)文件,該文件中的編譯指示不會(huì)自動(dòng)應(yīng)用于導(dǎo)入文件。
源文件可以(并且應(yīng)該)使用版本編譯指示進(jìn)行注釋?zhuān)跃芙^使用可能引入不兼容更改的未來(lái)編譯器版本進(jìn)行編譯。我們?cè)噲D將它們保持在絕對(duì)最低限度,并以語(yǔ)義變化也需要以語(yǔ)法變化的方式引入它們,但這并不總是可能的。因此,至少對(duì)于包含重大更改的版本,通讀更改日志總是一個(gè)好主意。這些版本始終具有形式 0.x.0
或x.0.0
.
版本編譯指示使用如下:pragma solidity ^0.5.2;
具有上述行的源文件不能使用 0.5.2 版本之前的編譯器進(jìn)行編譯,并且它也不能在從 0.6.0 版本開(kāi)始的編譯器上工作(這第二個(gè)條件是通過(guò) using 添加的^
)。因?yàn)樵?version 0.6.0
之前不會(huì)有重大更改,您可以確保您的代碼按照您的預(yù)期方式編譯。編譯器的確切版本不固定,因此仍然可以發(fā)布錯(cuò)誤修復(fù)版本。
可以為編譯器版本指定更復(fù)雜的規(guī)則,這些規(guī)則與npm使用的語(yǔ)法相同。
筆記
使用版本編譯指示不會(huì)更改編譯器的版本。它也不會(huì)啟用或禁用編譯器的功能。它只是指示編譯器檢查其版本是否與 pragma 所需的版本匹配。如果不匹配,編譯器會(huì)發(fā)出錯(cuò)誤。
通過(guò)使用?pragma abicoder v1
?或pragma abicoder v2
您可以在 ABI 編碼器和解碼器的兩種實(shí)現(xiàn)之間進(jìn)行選擇。
新的 ABI 編碼器 (v2) 能夠編碼和解碼任意嵌套的數(shù)組和結(jié)構(gòu)。它可能會(huì)產(chǎn)生不太理想的代碼,并且沒(méi)有像舊編碼器那樣接受過(guò)多的測(cè)試,但從 Solidity 0.6.0 開(kāi)始被認(rèn)為是非實(shí)驗(yàn)性的。您仍然必須使用pragma abicoder v2;
。 由于它將默認(rèn)從 Solidity 0.8.0 開(kāi)始激活,因此可以選擇使用 ?pragma abicoder v1;
?。
新編碼器支持的類(lèi)型集是舊編碼器支持的類(lèi)型的嚴(yán)格超集。使用它的合約可以與沒(méi)有限制的合約進(jìn)行交互。僅當(dāng)非?abicoder v2
?合約不嘗試進(jìn)行需要僅由新編碼器支持的解碼類(lèi)型的調(diào)用時(shí),反向才是可能的。編譯器可以檢測(cè)到這一點(diǎn)并將發(fā)出錯(cuò)誤。只需為您的合同啟用?abicoder v2
?就足以使錯(cuò)誤消失。
筆記
此編譯指示適用于激活它的文件中定義的所有代碼,無(wú)論該代碼最終在何處結(jié)束。這意味著選擇了源文件以使用 ABI coder v1 編譯的合約仍然可以包含通過(guò)從另一個(gè)合約繼承來(lái)使用新編碼器的代碼。如果新類(lèi)型僅在內(nèi)部使用而不在外部函數(shù)簽名中使用,則允許這樣做。
筆記
在 Solidity 0.7.4 之前,可以使用?pragma experimental ABIEncoderV2
? 選擇 ABI coder v2 ,但無(wú)法顯式選擇 coder v1,因?yàn)樗悄J(rèn)設(shè)置。
第二個(gè) pragma 是實(shí)驗(yàn)性 pragma。它可用于啟用默認(rèn)情況下尚未啟用的編譯器或語(yǔ)言的功能。當(dāng)前支持以下實(shí)驗(yàn)性編譯指示:
因?yàn)?ABI 編碼器 v2 不再被認(rèn)為是實(shí)驗(yàn)性的,所以從 Solidity 0.7.4 開(kāi)始可以通過(guò)?pragma abicoder v2
?(請(qǐng)參見(jiàn)上文)選擇它。
在構(gòu)建 Solidity 編譯器時(shí)必須啟用此組件,因此它并非在所有 Solidity 二進(jìn)制文件中都可用。構(gòu)建說(shuō)明解釋了如何激活此選項(xiàng)。在大多數(shù)版本中,它為 Ubuntu PPA 版本激活,但不適用于 Docker 映像、Windows 二進(jìn)制文件或靜態(tài)構(gòu)建的 Linux 二進(jìn)制文件。如果您在本地安裝了 SMT 求解器并通過(guò)節(jié)點(diǎn)(而不是通過(guò)瀏覽器)運(yùn)行 solc-js,則可以通過(guò)smtCallback為 solc-js 激活它 。
如果您使用?pragma experimental SMTChecker;
?,那么您會(huì)收到額外 的安全警告,這些警告是通過(guò)查詢(xún) SMT 求解器獲得的。該組件尚不支持 Solidity 語(yǔ)言的所有功能,并且可能會(huì)輸出許多警告。如果它報(bào)告不支持的功能,則分析可能不完全正確。
Solidity 支持導(dǎo)入語(yǔ)句,以幫助模塊化您的代碼,這些代碼類(lèi)似于 JavaScript(從 ES6 開(kāi)始)中可用的代碼。但是,Solidity 不支持默認(rèn)導(dǎo)出的概念。
在全局級(jí)別,您可以使用以下形式的導(dǎo)入語(yǔ)句:
import "filename";
該filename
部分稱(chēng)為導(dǎo)入路徑。此語(yǔ)句將所有全局符號(hào)從“文件名”(以及從那里導(dǎo)入的符號(hào))導(dǎo)入當(dāng)前全局范圍(與 ES6 不同,但向后兼容 Solidity)。不推薦使用這種形式,因?yàn)樗鼤?huì)意外地污染命名空間。如果您在“文件名”中添加新的頂級(jí)項(xiàng)目,它們會(huì)自動(dòng)出現(xiàn)在所有從“文件名”導(dǎo)入的文件中。最好顯式地導(dǎo)入特定符號(hào)。
以下示例創(chuàng)建一個(gè)新的全局符號(hào)symbolName
,其成員是來(lái)自 的所有全局符號(hào)"filename"
:
import * as symbolName from "filename";
這導(dǎo)致所有全局符號(hào)都以symbolName.symbol
.
這種語(yǔ)法的一個(gè)變體不是 ES6 的一部分,但可能有用的是:
import "filename" as symbolName;
這相當(dāng)于。import * as symbolName from "filename";
如果存在命名沖突,您可以在導(dǎo)入時(shí)重命名符號(hào)。例如,下面的代碼分別創(chuàng)建了新的全局符號(hào)alias
和從內(nèi)部symbol2
引用 symbol1
和。symbol2
"filename"
import {symbol1 as alias, symbol2} from "filename";
為了能夠在所有平臺(tái)上支持可重現(xiàn)的構(gòu)建,Solidity 編譯器必須抽象出存儲(chǔ)源文件的文件系統(tǒng)的細(xì)節(jié)。由于這個(gè)原因,導(dǎo)入路徑不直接引用主機(jī)文件系統(tǒng)中的文件。相反,編譯器維護(hù)一個(gè)內(nèi)部數(shù)據(jù)庫(kù)(虛擬文件系統(tǒng)或簡(jiǎn)稱(chēng)VFS),其中為每個(gè)源單元分配一個(gè)唯一的源單元名稱(chēng),該名稱(chēng)是一個(gè)不透明且非結(jié)構(gòu)化的標(biāo)識(shí)符。導(dǎo)入語(yǔ)句中指定的導(dǎo)入路徑被翻譯成源單元名稱(chēng),用于在該數(shù)據(jù)庫(kù)中查找對(duì)應(yīng)的源單元。
使用標(biāo)準(zhǔn) JSON API,可以直接提供所有源文件的名稱(chēng)和內(nèi)容作為編譯器輸入的一部分。在這種情況下,源單元名稱(chēng)確實(shí)是任意的。但是,如果您希望編譯器自動(dòng)查找源代碼并將其加載到 VFS 中,則您的源單元名稱(chēng)的結(jié)構(gòu)需要使導(dǎo)入回調(diào)能夠找到它們。使用命令行編譯器時(shí),默認(rèn)導(dǎo)入回調(diào)僅支持從主機(jī)文件系統(tǒng)加載源代碼,這意味著您的源單元名稱(chēng)必須是路徑。一些環(huán)境提供更通用的自定義回調(diào)。例如, Remix IDE提供了一個(gè)讓您從 HTTP、IPFS 和 Swarm URL 導(dǎo)入文件或直接引用 NPM 注冊(cè)表中的包。
有關(guān)虛擬文件系統(tǒng)和編譯器使用的路徑解析邏輯的完整描述,請(qǐng)參見(jiàn)路徑解析。
可以使用單行注釋 ( //
) 和多行注釋 ( /*...*/
)。
// This is a single-line comment. /* This is a multi-line comment. */
筆記
單行注釋由 UTF-8 編碼中的任何 unicode 行終止符(LF、VF、FF、CR、NEL、LS 或 PS)終止。結(jié)束符在注釋之后仍然是源代碼的一部分,所以如果它不是ASCII符號(hào)(這些是NEL、LS和PS),就會(huì)導(dǎo)致解析器錯(cuò)誤。
此外,還有另一種類(lèi)型的注釋?zhuān)Q(chēng)為 NatSpec 注釋?zhuān)?a rel="external nofollow" target="_blank" >樣式指南中有詳細(xì)說(shuō)明。它們用三斜杠 (///
) 或雙星號(hào)塊 ( ?/** ... */
?) 編寫(xiě),應(yīng)直接在函數(shù)聲明或語(yǔ)句上方使用。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: