Solidity知識點集 — Storage與Memory 與接口(四)

Storage與Memory

在 Solidity 中,有兩個地方可以存儲變量 —— storagememory

Storage 變量是指永久存儲在區(qū)塊鏈中的變量叛拷。 Memory 變量則是臨時的,當外部函數(shù)對某合約調(diào)用完成時灯谣,內(nèi)存型變量即被移除。

大多數(shù)時候你都用不到這些關鍵字,默認情況下 Solidity 會自動處理它們汽久。 然而也有一些情況下,你需要手動聲明存儲類型踊餐,主要用于處理函數(shù)內(nèi)的 結(jié)構體數(shù)組 時:

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

  Sandwich[] sandwiches;

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

    // ^ 看上去很直接景醇,不過 Solidity 將會給出警告
    // 告訴你應該明確在這里定義 `storage` 或者 `memory`。

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

    // 如果你只想要一個副本三痰,可以使用`memory`:
    Sandwich memory anotherSandwich = sandwiches[_index + 1];
    // ...這樣 `anotherSandwich` 就僅僅是一個內(nèi)存里的副本了
    // 另外
    anotherSandwich.status = "Eaten!";
    // ...將僅僅修改臨時變量,對 `sandwiches[_index + 1]` 沒有任何影響
    // 不過你可以這樣做:
    sandwiches[_index + 1] = anotherSandwich;
    // ...如果你想把副本的改動保存回區(qū)塊鏈存儲
  }
}

函數(shù)可見性: internal 和 external

internalprivate 類似窜管,不過散劫, 如果某個合約繼承自其父合約,這個合約即可以訪問父合約中定義的“內(nèi)部”函數(shù)幕帆。

externalpublic 類似获搏,只不過這些函數(shù)只能在合約之外調(diào)用 - 它們不能被合約內(nèi)的其他函數(shù)調(diào)用。

contract Sandwich {
  uint private sandwichesEaten = 0;

  function eat() internal {
    sandwichesEaten++;
  }
}

contract BLT is Sandwich {
  uint private baconSandwichesEaten = 0;

  function eatWithBacon() public returns (string) {
    baconSandwichesEaten++;
    // 因為eat() 是internal 的失乾,所以我們能在這里調(diào)用
    eat();
  }
}

與其他合約的交互

如果我們的合約需要和區(qū)塊鏈上的其他的合約會話常熙,則需先定義一個 interface (接口)。

假設在區(qū)塊鏈上有這么一個合約:

contract LuckyNumber {
  mapping(address => uint) numbers;

  function setNum(uint _num) public {
    numbers[msg.sender] = _num;
  }

  function getNum(address _myAddress) public view returns (uint) {
    return numbers[_myAddress];
  }
}

現(xiàn)在假設我們有一個外部合約碱茁,使用 getNum 函數(shù)可讀取其中的數(shù)據(jù)裸卫。

首先,我們定義 LuckyNumber 合約的 interface :

contract NumberInterface {
  function getNum(address _myAddress) public view returns (uint);
}

在我們的 app 代碼中使用這個接口纽竣,合約就知道其他合約的函數(shù)是怎樣的墓贿,應該如何調(diào)用,以及可期待什么類型的返回值蜓氨。

使用接口

上面的接口募壕,我們可以在合約中這樣使用:

contract MyContract {
  address NumberInterfaceAddress = 0xab38...;
  // ^ 這是FavoriteNumber合約在以太坊上的地址
  NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);
  // 現(xiàn)在變量 `numberContract` 指向另一個合約對象

  function someFunction() public {
    // 現(xiàn)在我們可以調(diào)用在那個合約中聲明的 `getNum`函數(shù):
    uint num = numberContract.getNum(msg.sender);
    // ...在這兒使用 `num`變量做些什么
  }
}

通過這種方式,只要將您合約的可見性設置為public(公共)或external(外部)语盈,它們就可以與以太坊區(qū)塊鏈上的任何其他合約進行交互舱馅。

處理多返回值

function multipleReturns() internal returns(uint a, uint b, uint c) {
  return (1, 2, 3);
}

function processMultipleReturns() external {
  uint a;
  uint b;
  uint c;
  // 這樣來做批量賦值:
  (a, b, c) = multipleReturns();
}

// 或者如果我們只想返回其中一個變量:
function getLastReturnValue() external {
  uint c;
  // 可以對其他字段留空:
  (,,c) = multipleReturns();
}

if 語句

function eatBLT(string sandwich) public {
  // 看清楚了,當我們比較字符串的時候刀荒,需要比較他們的 keccak256 哈希碼
  if (keccak256(sandwich) == keccak256("BLT")) {
    eat();
  }
}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末代嗤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子缠借,更是在濱河造成了極大的恐慌干毅,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泼返,死亡現(xiàn)場離奇詭異硝逢,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門渠鸽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叫乌,“玉大人,你說我怎么就攤上這事徽缚『┘椋” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵凿试,是天一觀的道長排宰。 經(jīng)常有香客問我,道長那婉,這世上最難降的妖魔是什么板甘? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘本谜。我一直安慰自己,他們只是感情好傲醉,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布蝇闭。 她就那樣靜靜地躺著呻率,像睡著了一般。 火紅的嫁衣襯著肌膚如雪呻引。 梳的紋絲不亂的頭發(fā)上礼仗,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天,我揣著相機與錄音逻悠,去河邊找鬼元践。 笑死,一個胖子當著我的面吹牛童谒,可吹牛的內(nèi)容都是我干的单旁。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼饥伊,長吁一口氣:“原來是場噩夢啊……” “哼象浑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起琅豆,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤愉豺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后茫因,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚪拦,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了驰贷。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盛嘿。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饱苟,靈堂內(nèi)的尸體忽然破棺而出孩擂,到底是詐尸還是另有隱情,我是刑警寧澤箱熬,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布类垦,位于F島的核電站,受9級特大地震影響城须,放射性物質(zhì)發(fā)生泄漏蚤认。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一糕伐、第九天 我趴在偏房一處隱蔽的房頂上張望砰琢。 院中可真熱鬧,春花似錦良瞧、人聲如沸陪汽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挚冤。三九已至,卻和暖如春赞庶,著一層夾襖步出監(jiān)牢的瞬間训挡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工歧强, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留澜薄,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓摊册,卻偏偏與公主長得像肤京,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子茅特,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

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