Solidity撰寫智能合約與注意事項(二)

from:

https://medium.com/taipei-ethereum-meetup/solidity%E6%92%B0%E5%AF%AB%E6%99%BA%E8%83%BD%E5%90%88%E7%B4%84%E8%88%87%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A0%85-%E4%BA%8C-dd915bdeafa0


這篇將介紹以太坊的log資料及event的使用

類似於比特幣的OP_RETURN蜗细,以太坊也提供一個把資料永久寫入?yún)^(qū)塊鏈裡的方法?—?event,event所寫入的資料會被記錄在一個Receipt資料裡酬土。

每一筆transaction都會有一個對應(yīng)的Receipt霸奕,用來記錄這筆transaction的執(zhí)行結(jié)果

eth.getTransaction()

getTransaction可以得到這筆transaction的相關(guān)資料寝志,這些資料在transaction被製作出來的時候就有了,而Receipt則是直到被執(zhí)行完(也就是transaction被放進鏈裡)後才會有。

註:(1)gas是指這次提供的gas總量

(2)input是合約的code(這是一個部署合約的transaction单山,所以input就是整份合約的code)眼溶。

用getTransacitonReceipt("hash")來取得transaction對應(yīng)的Receipt:

eth.getTransactionReceipt()

註:(1)gasUsed是這筆transaction所花費的gas(我們提供了4700000悠砚,只花了118615,剩下的會退還給我們)

(2)logs則是我們這篇介紹的log堂飞,如果有event被觸發(fā)灌旧,資料就會被入在這

那什麼時候會需要用到event呢?

1. 當(dāng)作一個額外的儲存空間绰筛,而且很便宜枢泰。event寫入的成本和用合約變數(shù)來儲存的成本相比之下少了很多,如果你開發(fā)的dapp需要將使用者的使用紀(jì)錄(如付款紀(jì)錄)等記錄下來當(dāng)作證明铝噩,與其用一個陣列儲存宗苍,不如在每次使用時用event寫進log裡。

但要注意的是薄榛,這些寫進log裡的資料是沒辦法被合約所存取的讳窟。

2. 當(dāng)成return value來使用。合約裡函式的回傳值並非總是可以使用敞恋,假設(shè)一個有回傳值的函式:

contract f00{

function foo(int _value) returns (int) {

return _value * _value;

}

}

什麼時候你可以拿到這個回傳值丽啡?只有在你使用call在本地進行模擬的時候才會有回傳值,如下:

var ret = f00.foo.call(25);

console.log(ret);? ? //625

當(dāng)你使用sendTransaction硬猫,真的做出一筆交易的時候补箍,他會回傳你這筆transaction的hash值改执,所以這時候你可以使用event來將回傳值記錄起來:

contract f00{

event retValue(int _value);

function foo(int _value) returns(int) {

return _value * _value;

}

}

這時候在前端便可以利用像javascript那樣監(jiān)聽的功能:

var retValueEvent = f00.retValue();

retValueEvent.watch(function(err, result){

if(err){

console.log(err);

return;

}

console.log(result.args._value);

});

當(dāng)transaction被收入?yún)^(qū)塊鏈裡後,就會觸發(fā)監(jiān)聽器然後按照你設(shè)定的callback函式執(zhí)行對應(yīng)的動作坑雅。如果要結(jié)束監(jiān)聽辈挂,執(zhí)行?retValueEvent.stopWatching()。

3. 最後便是當(dāng)你開發(fā)dapp的時候裹粤,藉由觸發(fā)event寫入log终蒂,再觸發(fā)監(jiān)聽器執(zhí)行對應(yīng)動作,如此完成從 外界->鏈->鏈->外界 一個完整的執(zhí)行過程遥诉。對使用者來說就像一個是對資料庫操作的動作拇泣,只是這個資料庫變成了區(qū)塊鏈。

接下來以簡單的例子來介紹監(jiān)聽器更多的功能

contract depositAccount {

event Deposit(addressindexed_owner, uint _amount, uint _time);

function deposit() payable {

Deposit(msg.sender, msg.value, now);

}

}

首先先介紹第二行的indexed矮锈。

在Receipt裡如果有l(wèi)og霉翔,會寫在logs欄位裡,每筆log其中有兩部分:data和topics苞笨。一般event寫入的資料都會寫在data裡债朵,但如果在event的變數(shù)加入一個indexed屬性,到時候觸發(fā)時這個變數(shù)對應(yīng)寫入的值就會寫在topics裡瀑凝,在topcis裡的值可以用來當(dāng)作監(jiān)聽器的篩選條件序芦。

註:一份Receipt裡面可以有很多筆log(表示一次transaction可以觸發(fā)很多次event),一筆log最多只能儲存四個topics猜丹,而第一個topic必須是這個event的識別值identifier,代表一個event最多只能有三個變數(shù)可以有indexed屬性硅卢。

transaction的logs裡的其中一筆log

上面這張圖是其中某一筆log射窒,這個event沒有加indexed的變數(shù),值都會寫在data欄位裡(32byte為一單位接在一起将塑,圖中為十六進位的9和19)脉顿,topcis裡唯一一個值?0x35bd26...是該event的識別值。

下面這張圖是變數(shù)都加上indexed的event的log記錄:

event有indexed

因為所有變數(shù)都加上indexed点寥,所以data裡沒有值艾疟,值都寫在topics裡(十六進位的102和abcde)。

接下來在前端加入監(jiān)聽器:

var depositEvent = depositAccount.Deposit({_owner:null},{fromBlock: 5000, toBlock: ‘latest’});

depositEvent.watch(function(err, results) {

if (err) {

console.log(err);

return;

}

console.log(results.blockNumber);

});

第一行的{fromBlock: 5000, toBlock: ‘latest’}是加入的篩選條件敢辩,表示監(jiān)聽從第5000個區(qū)塊開始到最新的區(qū)塊蔽莱。如果event被觸發(fā),那callback函式就會印出是發(fā)生在第幾個區(qū)塊( result.blockNumber )戚长。

如果我們要用有加上indexed的變數(shù)(_owner變數(shù))來當(dāng)篩選條件的話盗冷,就指定_owner應(yīng)該要是多少,如果給null(像上面的例子)同廉,那就是任何address都可以的意思:

var depositEvent = depositaccount.Deposit({_owner:'0xbd7255b64eeb594ca57652c94249da6a9b37cd2f'});

depositEvent.watch(function(err, results) {

if (err) {

console.log(err);

return;

}

if(results.args._amount > web3.toWei(0.05,"ether")){

console.log("User: " + results.args._owner +

" deposits: " + results.args._amount +

" on: " +

JSON.stringify(new Date((parseInt(results.args._time)+28800)*1000))

);

}

});

這個callback會在"0xbd7255b64eeb594ca57652c94249da6a9b37cd2f"這個address存錢的時候被觸發(fā)仪糖,存入超過0.05 ether的時候會印出存入的金額和存入時間柑司。

References:

[1]https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e#.u7l9ejta3

[2]https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-events

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市锅劝,隨后出現(xiàn)的幾起案子攒驰,更是在濱河造成了極大的恐慌,老刑警劉巖故爵,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玻粪,死亡現(xiàn)場離奇詭異,居然都是意外死亡稠集,警方通過查閱死者的電腦和手機奶段,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剥纷,“玉大人痹籍,你說我怎么就攤上這事』扌” “怎么了蹲缠?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長悠垛。 經(jīng)常有香客問我线定,道長,這世上最難降的妖魔是什么确买? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任斤讥,我火速辦了婚禮,結(jié)果婚禮上湾趾,老公的妹妹穿的比我還像新娘芭商。我一直安慰自己,他們只是感情好搀缠,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布铛楣。 她就那樣靜靜地躺著,像睡著了一般艺普。 火紅的嫁衣襯著肌膚如雪簸州。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天歧譬,我揣著相機與錄音岸浑,去河邊找鬼。 笑死瑰步,一個胖子當(dāng)著我的面吹牛助琐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播面氓,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼兵钮,長吁一口氣:“原來是場噩夢啊……” “哼蛆橡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掘譬,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤泰演,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后葱轩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睦焕,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年靴拱,在試婚紗的時候發(fā)現(xiàn)自己被綠了垃喊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡袜炕,死狀恐怖本谜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情偎窘,我是刑警寧澤乌助,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站陌知,受9級特大地震影響他托,放射性物質(zhì)發(fā)生泄漏焚廊。R本人自食惡果不足惜虐急,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望讯蒲。 院中可真熱鬧沿盅,春花似錦把篓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽皇耗。三九已至南窗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間郎楼,已是汗流浹背万伤。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留呜袁,地道東北人敌买。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像阶界,于是被迫代替她去往敵國和親虹钮。 傳聞我的和親對象是個殘疾皇子聋庵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

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

  • 一一與旋轉(zhuǎn)屋 徐空文 (這是十幾年前創(chuàng)作的第一個劇本,雖然幼稚芙粱,但現(xiàn)在看來竟是我最喜歡的劇本之一祭玉,雖然之後曾以寫劇...
    徐空文閱讀 522評論 0 5
  • 為何叫做 shell ? shell prompt(PS1) 與 Carriage Return(CR) 的關(guān)系春畔?...
    Zero___閱讀 3,141評論 3 49
  • 每一個孩子都是各自家庭里的寶,每一個父母都希望給孩子創(chuàng)造最好的生活環(huán)境择份,讓孩子享受到最好的教育資源扣孟,給孩子一片明媚...
    橡樹心閱讀 505評論 0 2
  • 1 文件目錄文件普通文件: 純文本文件 (簡歷.日志,word文檔) 二進制文件(.exe文...
    我本無邪閱讀 224評論 0 0
  • 前一秒,嘰嘰喳喳的聲音掩蓋了我的落寞缓淹。 下一秒哈打,猝不及防的淚水出賣了我的脆弱。 只因為——這一秒讯壶,你的容顏倒映在我...
    莫負青檸閱讀 194評論 2 2