您好,登錄后才能下訂單哦!
這篇文章主要介紹“Solidity函數(shù)的external/internal,public/private區(qū)別是什么”,在日常操作中,相信很多人在Solidity函數(shù)的external/internal,public/private區(qū)別是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Solidity函數(shù)的external/internal,public/private區(qū)別是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
函數(shù)類型是一種表示函數(shù)的類型??梢詫⒁粋€(gè)函數(shù)賦值給另一個(gè)函數(shù)類型的變量,也可以將一個(gè)函數(shù)作為參數(shù)進(jìn)行傳遞,還能在函數(shù)調(diào)用中返回函數(shù)類型變量。 函數(shù)類型有兩類:- 內(nèi)部(internal)函數(shù)和 外部(external) 函數(shù):
內(nèi)部函數(shù)只能在當(dāng)前合約內(nèi)被調(diào)用(更具體來(lái)說(shuō),在當(dāng)前代碼塊內(nèi),包括內(nèi)部庫(kù)函數(shù)和繼承的函數(shù)中),因?yàn)樗鼈儾荒茉诋?dāng)前合約上下文的外部被執(zhí)行。 調(diào)用一個(gè)內(nèi)部函數(shù)是通過(guò)跳轉(zhuǎn)到它的入口標(biāo)簽來(lái)實(shí)現(xiàn)的,就像在當(dāng)前合約的內(nèi)部調(diào)用一個(gè)函數(shù)。
外部函數(shù)由一個(gè)地址和一個(gè)函數(shù)簽名組成,可以通過(guò)外部函數(shù)調(diào)用傳遞或者返回。
函數(shù)類型表示成如下的形式
function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]
與參數(shù)類型相反,返回類型不能為空 —— 如果函數(shù)類型不需要返回,則需要?jiǎng)h除整個(gè) returns (<return types>) 部分。
函數(shù)類型默認(rèn)是內(nèi)部函數(shù),因此不需要聲明 internal 關(guān)鍵字。 與此相反的是,合約中的函數(shù)本身默認(rèn)是 public 的,只有當(dāng)它被當(dāng)做類型名稱時(shí),默認(rèn)才是內(nèi)部函數(shù)。
有兩種方法可以訪問(wèn)當(dāng)前合約中的函數(shù):
一種是直接使用它的名字,f ;
另一種是使用 this.f 。
前者適用于內(nèi)部函數(shù),后者適用于外部函數(shù)。
如果當(dāng)函數(shù)類型的變量還沒(méi)有初始化時(shí)就調(diào)用它的話會(huì)引發(fā)一個(gè)異常。 如果在一個(gè)函數(shù)被 delete之后調(diào)用它也會(huì)發(fā)生相同的情況。
如果外部函數(shù)類型在 Solidity 的上下文環(huán)境以外的地方使用,它們會(huì)被視為 function 類型。 該類型將函數(shù)地址緊跟其函數(shù)標(biāo)識(shí)一起編碼為一個(gè) bytes24 類型。
請(qǐng)注意,當(dāng)前合約的 public 函數(shù)既可以被當(dāng)作內(nèi)部函數(shù)也可以被當(dāng)作外部函數(shù)使用。 如果想將一個(gè)函數(shù)當(dāng)作內(nèi)部函數(shù)使用,就用 f 調(diào)用,如果想將其當(dāng)作外部函數(shù),使用 this.f 。
除此之外,public(或 external)函數(shù)也有一個(gè)特殊的成員變量稱作 selector,可以返回 ABI 函數(shù)選擇器:
pragma solidity ^0.4.16; contract Selector { function f() public view returns (bytes4) { return this.f.selector; } }
如果使用內(nèi)部函數(shù)類型的例子:
pragma solidity ^0.4.16; library ArrayUtils { // 內(nèi)部函數(shù)可以在內(nèi)部庫(kù)函數(shù)中使用, // 因?yàn)樗鼈儠?huì)成為同一代碼上下文的一部分 function map(uint[] memory self, function (uint) pure returns (uint) f) internal pure returns (uint[] memory r) { r = new uint[](self.length); for (uint i = 0; i < self.length; i++) { r[i] = f(self[i]); } } function reduce( uint[] memory self, function (uint, uint) pure returns (uint) f ) internal pure returns (uint r) { r = self[0]; for (uint i = 1; i < self.length; i++) { r = f(r, self[i]); } } function range(uint length) internal pure returns (uint[] memory r) { r = new uint[](length); for (uint i = 0; i < r.length; i++) { r[i] = i; } } } contract Pyramid { using ArrayUtils for *; function pyramid(uint l) public pure returns (uint) { return ArrayUtils.range(l).map(square).reduce(sum); } function square(uint x) internal pure returns (uint) { return x * x; } function sum(uint x, uint y) internal pure returns (uint) { return x + y; } }
另外一個(gè)使用外部函數(shù)類型的例子:
pragma solidity ^0.4.11; contract Oracle { struct Request { bytes data; function(bytes memory) external callback; } Request[] requests; event NewRequest(uint); function query(bytes data, function(bytes memory) external callback) public { requests.push(Request(data, callback)); NewRequest(requests.length - 1); } function reply(uint requestID, bytes response) public { // 這里要驗(yàn)證 reply 來(lái)自可信的源 requests[requestID].callback(response); } } contract OracleUser { Oracle constant oracle = Oracle(0x1234567); // 已知的合約 function buySomething() { oracle.query("USD", this.oracleResponse); } function oracleResponse(bytes response) public { require(msg.sender == address(oracle)); // 使用數(shù)據(jù) } }
注解 Lambda 表達(dá)式或者內(nèi)聯(lián)函數(shù)的引入在計(jì)劃內(nèi),但目前還沒(méi)支持。
public:內(nèi)部、外部均可見(jiàn)(參考為存儲(chǔ)/狀態(tài)變量創(chuàng)建 getter 函數(shù))
private:僅在當(dāng)前合約內(nèi)可見(jiàn)
external:僅在外部可見(jiàn)(僅可修飾函數(shù))——就是說(shuō),僅可用于消息調(diào)用(即使在合約內(nèi)調(diào)用,也只能通過(guò) this.func 的方式)
internal:僅在內(nèi)部可見(jiàn)(也就是在當(dāng)前 Solidity 源代碼文件內(nèi)均可見(jiàn),不僅限于當(dāng)前合約內(nèi),譯者注)
函數(shù)可見(jiàn)性說(shuō)明符格式:
function myFunction() <visibility specifier> returns (bool) { return true; }
pure 修飾函數(shù)時(shí):不允許修改或訪問(wèn)狀態(tài)——但目前并不是強(qiáng)制的。 view 修飾函數(shù)時(shí):不允許修改狀態(tài)——但目前不是強(qiáng)制的。 payable 修飾函數(shù)時(shí):允許從調(diào)用中接收 以太幣Ether 。 constant 修飾狀態(tài)變量時(shí):不允許賦值(除初始化以外),不會(huì)占據(jù) 存儲(chǔ)插槽storage slot 。 constant 修飾函數(shù)時(shí):與 view 等價(jià)。 anonymous 修飾事件時(shí):不把事件簽名作為 topic 存儲(chǔ)。 indexed 修飾事件時(shí):將參數(shù)作為 topic 存儲(chǔ)。
到此,關(guān)于“Solidity函數(shù)的external/internal,public/private區(qū)別是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。