與智能合約交互

與智能合約交互

概述

為了與合約交互而向Ethereum網(wǎng)絡(luò)編寫原始請求包斑,那么您很快就會意識到流礁,編寫這些請求是笨重而麻煩的涕俗。
同樣,你可能會發(fā)現(xiàn)管理每個請求的狀態(tài)非常復(fù)雜崇棠。幸運的是咽袜,Truffle 為您解決了這種復(fù)雜性,使得與合約的交互變得輕而易舉枕稀。

讀寫數(shù)據(jù)

Ethereum網(wǎng)絡(luò)對向網(wǎng)絡(luò)寫入數(shù)據(jù)和從網(wǎng)絡(luò)讀取數(shù)據(jù)進行了區(qū)分询刹,這種區(qū)分在如何編寫應(yīng)用程序中起著重要作用。
通常萎坷,寫入數(shù)據(jù)稱為交易( transaction )凹联,而讀取數(shù)據(jù)稱為調(diào)用( call )。事務(wù)和調(diào)用的處理方式非常不同哆档,具有以下特征蔽挠。

交易 (Transactions)

交易從根本上改變了網(wǎng)絡(luò)的狀態(tài)。交易可以是簡單到將以太幣發(fā)送到另一個帳戶瓜浸,也可以是復(fù)雜到執(zhí)行合約函數(shù)或向網(wǎng)絡(luò)添加新合約澳淑。
交易的定義特性是它寫入(或更改)數(shù)據(jù)。交易的運行成本很高插佛,稱為“gas”杠巡,交易的處理需要時間。
當(dāng)您通過交易執(zhí)行合約的功能時雇寇,您不能接收該函數(shù)的返回值氢拥,因為交易沒有立即處理。一般來說锨侯,通過交易執(zhí)行的函數(shù)不會返回值;
它們將返回一個交易id嫩海。所以總的來說,交易(Transactions)特性如下:

  • 消費 gas (以太幣 ether)
  • 修改網(wǎng)絡(luò)狀態(tài)
  • 不能馬上執(zhí)行
  • 不會暴露一個返回值(之返回一個交易id)

調(diào)用 (Calls)

調(diào)用正好相反。調(diào)用可以是在網(wǎng)絡(luò)中執(zhí)行代碼囚痴,不會永久的改變數(shù)據(jù)(狀態(tài))叁怪。調(diào)用是免費的,它的特性就是讀取數(shù)據(jù)深滚。
當(dāng)你使用 call 調(diào)用一個合約中的一份方法時骂束,函數(shù)會馬上返回〕审铮總的來說 Calls 的特性:

  • 免費(不消耗 gas)
  • 不改變網(wǎng)絡(luò)狀態(tài)
  • 馬上執(zhí)行
  • 會暴露一個返回值

選擇使用 Tranaction 或 Call 很簡單展箱,取決于你是讀取數(shù)據(jù)還是寫入數(shù)據(jù)。

合約抽象簡介

合約抽象是使用 Javascript 與 Ethereum 合約交互的 bread 和 butter 蹬昌。
簡而言之混驰,合約抽象是一種包裝代碼,它使與合約的交互變得容易,從而讓你忘記了在引擎下執(zhí)行的許多引擎和齒輪栖榨。
Truffle通過 Truffle-contract 模塊使用它自己的合約抽象昆汹,下面描述的就是這個合約抽象。

為了理解合約抽象的作用婴栽,我們首先需要一個合約例子监署。我們將使用MetaCoin合約合砂,通過 truffle unbox metacoin 提供給您委可。

pragma solidity ^0.4.2;

import "./ConvertLib.sol";

// This is just a simple example of a coin-like contract.
// It is not standards compatible and cannot be expected to talk to other
// coin/token contracts. If you want to create a standards-compliant
// token, see: https://github.com/ConsenSys/Tokens. Cheers!

contract MetaCoin {
    mapping (address => uint) balances;

    event Transfer(address indexed _from, address indexed _to, uint256 _value);

    function MetaCoin() {
        balances[tx.origin] = 10000;
    }

    function sendCoin(address receiver, uint amount) returns(bool sufficient) {
        if (balances[msg.sender] < amount) return false;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Transfer(msg.sender, receiver, amount);
        return true;
    }

    function getBalanceInEth(address addr) returns(uint){
        return ConvertLib.convert(getBalance(addr),2);
    }

    function getBalance(address addr) returns(uint) {
        return balances[addr];
    }
}

除了構(gòu)造函數(shù)(sendCoin访敌、getBalanceInEth和getBalance)之外,該契約還有三個方法轰枝。
這三個方法都可以作為 transaction 或 call 執(zhí)行捅彻。

現(xiàn)在讓我們看看 Truffle 提供給我們的名為 MetaCoin 的 Javascript 對象,
這是在 truffle console 中的:

// Print the deployed version of MetaCoin.
// Note that getting the deployed version requires a promise, hence the .then.
MetaCoin.deployed().then(function(instance) {
  console.log(instance);
});

// outputs:
//
// Contract
// - address: "0xa9f441a487754e6b27ba044a5a8eb2eec77f6b92"
// - allEvents: ()
// - getBalance: ()
// - getBalanceInEth: ()
// - sendCoin: ()
// ...

請注意鞍陨,合約抽象包含與我們的合約中相同的功能步淹。它還包含一個指向MetaCoin合同已部署版本的地址。

執(zhí)行合約方法

使用合約抽象你可以很容易的在以太坊網(wǎng)絡(luò)中調(diào)用合約诚撵。

創(chuàng)建一個交易

MetaCoin 中有三個方法可以執(zhí)行缭裆。如果你自己看你會發(fā)現(xiàn) setCoin 方法是用來在網(wǎng)絡(luò)中發(fā)送幣的。
這個方法需要修改網(wǎng)絡(luò)中的狀態(tài)寿烟。

我們調(diào)用 setCoin 方法時候我們使用 transaction 調(diào)用澈驼。在下面的例子中將會轉(zhuǎn)賬10個 Meta 幣,
就是說要永久的修改網(wǎng)絡(luò)狀態(tài):

var account_one = "0x1234..."; // an address
var account_two = "0xabcd..."; // another address

var meta;
MetaCoin.deployed().then(function(instance) {
  meta = instance;
  return meta.sendCoin(account_two, 10, {from: account_one});
}).then(function(result) {
  // If this callback is called, the transaction was successfully processed.
  alert("Transaction successful!")
}).catch(function(e) {
  // There was an error! Handle it.
})

上面的代碼有一些有趣的地方:

  • 我們直接調(diào)用合約抽象的 setCoin 方法韧衣。這個調(diào)用將會返回一個 transactin 結(jié)果。
  • 當(dāng)交易成功執(zhí)行以后购桑,回調(diào)方法才會執(zhí)行畅铭。這就讓生命周期管理改變的簡單,你不需要自己檢查交易狀態(tài)勃蜘。
  • 我們將對象作為第三個參數(shù)傳遞給sendCoin硕噩。注意,在我們的Solidity合約中缭贡,sendCoin函數(shù)沒有第三個參數(shù)炉擅。
    上面看到的是一個特殊的對象,它總是作為最后一個參數(shù)傳遞給一個函數(shù)阳惹,該函數(shù)允許您編輯交易的特定細(xì)節(jié)谍失。
    在這里,我們設(shè)置了from address確保該交易來自account_one莹汤。

創(chuàng)建一個調(diào)用 call

繼續(xù)使用 MetaCion 例子快鱼,注意 getBalance 函數(shù)是從網(wǎng)絡(luò)讀取數(shù)據(jù)的一個很好的候選函數(shù)。
它不需要做任何更改,因為它只返回傳遞給它的地址的 Meta Coin 余額抹竹。讓我們試一試:

var account_one = "0x1234..."; // an address

var meta;
MetaCoin.deployed().then(function(instance) {
  meta = instance;
  return meta.getBalance.call(account_one, {from: account_one});
}).then(function(balance) {
  // If this callback is called, the call was successfully executed.
  // Note that this returns immediately without any waiting.
  // Let's print the return value.
  console.log(balance.toNumber());
}).catch(function(e) {
  // There was an error! Handle it.
})

這里有意思的地方:

  • 我們執(zhí)行了 call 方法线罕,告訴以太坊網(wǎng)絡(luò)我們不會修改網(wǎng)絡(luò)中的數(shù)據(jù)。
  • 我們接收到了一個返回值窃判,而不是一個交易id钞楼。
警告:
我們把返回值轉(zhuǎn)換為數(shù)字,因為這個demo中數(shù)字很小袄琳。通常給如果如果你要轉(zhuǎn)換一個超大整形需要
使用 JavaScript 提供 ```BigNumber``` 庫询件,否則會報錯或者拋出異常。

捕獲事件

你的合約可以觸發(fā)事件跨蟹,你可以通過這些事件獲得更多的了解你的合約在做什么雳殊。
處理事件的最簡單方法是處理觸發(fā)事件的交易的結(jié)果對象,如下所示:

var account_one = "0x1234..."; // an address
var account_two = "0xabcd..."; // another address

var meta;
MetaCoin.deployed().then(function(instance) {
  meta = instance;  
  return meta.sendCoin(account_two, 10, {from: account_one});
}).then(function(result) {
  // result is an object with the following values:
  //
  // result.tx      => transaction hash, string
  // result.logs    => array of decoded events that were triggered within this transaction
  // result.receipt => transaction receipt object, which includes gas used

  // We can loop through result.logs to see if we triggered the Transfer event.
  for (var i = 0; i < result.logs.length; i++) {
    var log = result.logs[i];

    if (log.event == "Transfer") {
      // We found the event!
      break;
    }
  }
}).catch(function(err) {
  // There was an error! Handle it.
});

處理交易結(jié)果

當(dāng)我們創(chuàng)建交易時窗轩,將獲得一個結(jié)果對象夯秃,該對象將提供關(guān)于交易的大量信息。
具體來說痢艺,有以下信息:

  • result.tx (string) - 交易哈希值
  • result.log (array) - 解碼后的事件
  • result.receipt (object)- 交易收據(jù)

更多信息請查看 truffle-contract說明仓洼。

向網(wǎng)絡(luò)中添加一個新的合約

如果您已經(jīng)有一個合約地址,您可以創(chuàng)建一個新的合約抽象來表示該地址的合約堤舒。

var instance = MetaCoin.at("0x1234....");

給合約轉(zhuǎn)賬

你可能只想直接發(fā)送以太幣 ether 到合約色建,或者觸發(fā)合約的回退功能。
你可以使用以下兩個選項之一來實現(xiàn)這一點:

方式一:
直接向合約發(fā)送一個交易使用 instance.sendTransaction() 舌缤。這就像所有可用的合約實例函數(shù)一樣箕戳,
web3.eth.sendTransaction 方法相同,但是 web3.eth.sendTransaction 沒有回調(diào)国撵。
如果你沒有申明 to 陵吸,它將會被自動填充。

instance.sendTransaction({...}).then(function(result){
    // same transction result object as above.
});

方式二:
直接發(fā)送以太幣也有簡寫:

instance.send(web3.toWei(1, "ether")).then(function(result){
    // some result oject as above
});
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末介牙,一起剝皮案震驚了整個濱河市壮虫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌环础,老刑警劉巖囚似,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異线得,居然都是意外死亡饶唤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門贯钩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搬素,“玉大人呵晨,你說我怎么就攤上這事“境撸” “怎么了摸屠?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長粱哼。 經(jīng)常有香客問我季二,道長,這世上最難降的妖魔是什么揭措? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任胯舷,我火速辦了婚禮,結(jié)果婚禮上绊含,老公的妹妹穿的比我還像新娘桑嘶。我一直安慰自己,他們只是感情好躬充,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布逃顶。 她就那樣靜靜地躺著,像睡著了一般充甚。 火紅的嫁衣襯著肌膚如雪以政。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天伴找,我揣著相機與錄音盈蛮,去河邊找鬼。 笑死技矮,一個胖子當(dāng)著我的面吹牛抖誉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衰倦,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼袒炉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耿币?” 一聲冷哼從身側(cè)響起梳杏,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤韧拒,失蹤者是張志新(化名)和其女友劉穎淹接,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叛溢,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡塑悼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了楷掉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厢蒜。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出斑鸦,到底是詐尸還是另有隱情愕贡,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布巷屿,位于F島的核電站固以,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏嘱巾。R本人自食惡果不足惜憨琳,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望旬昭。 院中可真熱鬧篙螟,春花似錦、人聲如沸问拘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽场梆。三九已至墅冷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間或油,已是汗流浹背寞忿。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顶岸,地道東北人腔彰。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像辖佣,于是被迫代替她去往敵國和親霹抛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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

  • 小組人員:張佳卷谈、陸晶杯拐、陸春杏、湯惠穎 哀江頭 唐 · 杜甫 少陵野老吞聲哭世蔗,春日潛行曲江曲端逼。 江頭宮殿鎖千門,細(xì)柳...
    凝蜜糖閱讀 340評論 0 2
  • 我是八音盒上獨腳的小人污淋, 聲音來了顶滩, 走了, 我獨腳跳了個舞寸爆, 還在那里礁鲁。
    葡萄美酒閱讀 244評論 0 1
  • 遇見很重要盐欺! 什么時候遇見? 遇見誰仅醇? 皆是遇見的重要因子
    吳瀟旎閱讀 125評論 0 0
  • 老樹新苔冗美,小城春色歸飛燕。 東門翠柳繞長灣析二,日落西山遠(yuǎn)墩衙。 打點胭紅細(xì)看,約黃昏甲抖、酡紅若見漆改。 月溟天暗,收斂心神准谚,纏...
    劉小地閱讀 679評論 20 69
  • 女子顫聲說:“待我稟明教主挫剑,自會留下他性命≈危” 男子哼道:“情形有變樊破,我不得不提前動手。對了唆铐,君海棠身份特殊哲戚,若無...
    十一鸞閱讀 291評論 0 2