solidity系列教程<五>繼承、Storage與Memory

繼承

當(dāng)我們的合約代碼越來(lái)越長(zhǎng)蜒滩。 當(dāng)代碼過(guò)于冗長(zhǎng)的時(shí)候,最好將代碼和邏輯分拆到多個(gè)不同的合約中捡遍,以便于管理画株。

有個(gè)讓 Solidity 的代碼易于管理的功能谓传,就是合約 inheritance (繼承):

當(dāng)一個(gè)合約繼承自多個(gè)合約時(shí)续挟,只會(huì)在區(qū)塊鏈上創(chuàng)建單個(gè)合約诗祸,并將所有父合約中的代碼復(fù)制到創(chuàng)建的合約中直颅。

Solidity的繼承與Python非常相似肘习,特別是多繼承漂佩。

contract Doge {
  function catchphrase() public returns (string) {
    return "So Wow CryptoDoge";
  }
}
contract BabyDoge is Doge {
  function anotherCatchphrase() public returns (string) {
    return "Such Moon BabyDoge";
  }
}

由于 BabyDoge 是從 Doge 那里 inherits (繼承)過(guò)來(lái)的。 這意味著當(dāng)你編譯和部署了 BabyDoge养葵,它將可以訪問(wèn) catchphrase() 和 anotherCatchphrase()和其他我們?cè)?Doge 中定義的其他公共函數(shù)关拒。

這可以用于邏輯繼承(比如表達(dá)子類的時(shí)候佃蚜,Cat 是一種 Animal)。 但也可以簡(jiǎn)單地將類似的邏輯組合到不同的合約中以組織代碼着绊。

父構(gòu)造函數(shù)的參數(shù)
派生的合約需要為父構(gòu)造函數(shù)提供所有的參數(shù)谐算。有兩種方式:

pragma solidity ^0.4.14;
contract Base {
    uint x;
    function Base(uint _x) public { x = _x; }
}
contract Derived is Base(7) {
    function Derived(uint _y) Base(_y * _y) public {
    }
}
  • 第一種是直接在繼承列表里實(shí)現(xiàn)is Base(7)
  • 第二種是在派生的構(gòu)造器的頭部,修飾符被調(diào)用時(shí)實(shí)現(xiàn)Base(_y * _y)归露。

使用原則:

  • 如果構(gòu)造函數(shù)參數(shù)是一個(gè)常量洲脂,并且定義了合約的行為或描述了它的行為,第一種方式比較方便剧包。
  • 如果父構(gòu)造函數(shù)參數(shù)依賴于派生合約的構(gòu)造函數(shù)恐锦,則必須使用第二種方法。
  • 如果在這個(gè)荒謬的例子中疆液,這兩個(gè)地方都被使用一铅,修飾符樣式的參數(shù)優(yōu)先。

當(dāng)我們多個(gè)合約為多個(gè)文件的時(shí)候我們?cè)撛趺蠢^承潘飘?

當(dāng)你有多個(gè)文件并且想把一個(gè)文件導(dǎo)入另一個(gè)文件時(shí),可以使用 import 語(yǔ)句:

import "./someothercontract.sol";

contract newContract is SomeOtherContract {

}

這樣當(dāng)我們?cè)诤霞s(contract)目錄下有一個(gè)名為 someothercontract.sol 的文件( ./ 就是同一目錄的意思),它就會(huì)被編譯器導(dǎo)入现喳。

多繼承

import "./someothercontract.sol"
import "./othercontract.sol";
contract newContract is SomeOtherContract,othercontract {

}

多繼承順序:

在is指令中給出父類的順序很重要幌缝。在下面的代碼中荒叼,Solidity會(huì)報(bào)錯(cuò):“Linearization of inheritance graph impossible”萝玷。

// 以下代碼無(wú)法編譯
pragma solidity ^0.4.14;
contract X {}
contract A is X {}
contract C is A, X {}
------------------------------------------------------
// 以下代碼可以編譯通過(guò)
pragma solidity ^0.4.14;
contract X {}
contract A is X {}
contract C is X, A {}

原因是C要求X來(lái)重寫(xiě)A(定義A,X這個(gè)順序),但A本身的要求重寫(xiě)X,這是一個(gè)矛盾辽装,不能解決丰涉。

storage 和 memory

在 Solidity 中,有兩個(gè)地方可以存儲(chǔ)變量 —— storage 或 memory

Storage 變量是指永久存儲(chǔ)在區(qū)塊鏈中的變量。 Memory 變量則是臨時(shí)的加袋,當(dāng)外部函數(shù)對(duì)某合約調(diào)用完成時(shí),內(nèi)存型變量即被移除。 你可以把它想象成存儲(chǔ)在你電腦的硬盤(pán)或是RAM中數(shù)據(jù)的關(guān)系。

大多數(shù)時(shí)候你都用不到這些關(guān)鍵字拭卿,默認(rèn)情況下 Solidity 會(huì)自動(dòng)處理它們。 狀態(tài)變量(在函數(shù)之外聲明的變量)默認(rèn)為“存儲(chǔ)”形式,并永久寫(xiě)入?yún)^(qū)塊鏈;而在函數(shù)內(nèi)部聲明的變量是“內(nèi)存”型的呐馆,它們函數(shù)調(diào)用結(jié)束后消失收班。

然而也有一些情況下舵变,你需要手動(dòng)聲明存儲(chǔ)類型,主要用于處理函數(shù)內(nèi)的 結(jié)構(gòu)體 和 數(shù)組 時(shí):

contract SandwichFactory {
  struct Sandwich {
    string name;
    string status;
  }

  Sandwich[] sandwiches;

  function eatSandwich(uint _index) public {
    // Sandwich mySandwich = sandwiches[_index];

    // ^ 看上去很直接,不過(guò) Solidity 將會(huì)給出警告
    // 告訴你應(yīng)該明確在這里定義 `storage` 或者 `memory`住涉。

    // 所以你應(yīng)該明確定義 `storage`:
    Sandwich storage mySandwich = sandwiches[_index];
    // ...這樣 `mySandwich` 是指向 `sandwiches[_index]`的指針
    // 在存儲(chǔ)里柳爽,另外...
    mySandwich.status = "Eaten!";
    // ...這將永久把 `sandwiches[_index]` 變?yōu)閰^(qū)塊鏈上的存儲(chǔ)

    // 如果你只想要一個(gè)副本,可以使用`memory`:
    Sandwich memory anotherSandwich = sandwiches[_index + 1];
    // ...這樣 `anotherSandwich` 就僅僅是一個(gè)內(nèi)存里的副本了
    // 另外
    anotherSandwich.status = "Eaten!";
    // ...將僅僅修改臨時(shí)變量俩功,對(duì) `sandwiches[_index + 1]` 沒(méi)有任何影響
    // 不過(guò)你可以這樣做:
    sandwiches[_index + 1] = anotherSandwich;
    // ...如果你想把副本的改動(dòng)保存回區(qū)塊鏈存儲(chǔ)
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末脚粟,一起剝皮案震驚了整個(gè)濱河市团南,隨后出現(xiàn)的幾起案子拷橘,更是在濱河造成了極大的恐慌另萤,老刑警劉巖目养,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伐蒂,死亡現(xiàn)場(chǎng)離奇詭異缕减,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)融虽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事洒擦∫蔚耍” “怎么了慕购?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)烤送。 經(jīng)常有香客問(wèn)我讯泣,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任贞滨,我火速辦了婚禮尚困,結(jié)果婚禮上掌实,老公的妹妹穿的比我還像新娘耕渴。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般棒呛。 火紅的嫁衣襯著肌膚如雪蒲凶。 梳的紋絲不亂的頭發(fā)上拆内,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天刻肄,我揣著相機(jī)與錄音噪馏,去河邊找鬼瓶颠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呻纹,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼堆生,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼专缠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起淑仆,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤涝婉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蔗怠,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體墩弯,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年寞射,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渔工。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怠惶,死狀恐怖涨缚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情策治,我是刑警寧澤脓魏,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站通惫,受9級(jí)特大地震影響茂翔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜履腋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一珊燎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧遵湖,春花似錦悔政、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至迁沫,卻和暖如春芦瘾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背集畅。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工近弟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挺智。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓祷愉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谣辞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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