在之前我們已經(jīng)看到過(guò),使用interface、library的方式調(diào)用外部合約的代碼。
接下來(lái),我們將為大家補(bǔ)充第三種形式:
在下面的代碼中,部署cat合約之后,例如地址為 0x345678..
在部署animal合約時(shí),傳遞此cat合約地址。從而能夠存儲(chǔ)合約的引用。調(diào)用test方法即可調(diào)用到外部合約的方法。
1 | pragma solidity ^0.4.23; |
不管是interface、library還是上面看到的形式,要調(diào)用外部代碼,都是底層調(diào)用了call或者是delecall函數(shù)。
call函數(shù)的使用方法,首先需要外部合約的地址。如下例中的animalCall合約,在部署合約時(shí),傳遞了外部合約cat的地址 0x345678..
,存儲(chǔ)在address c當(dāng)中。
通過(guò)合約地址.call(函數(shù)標(biāo)志符)的方式來(lái)調(diào)用合約。函數(shù)標(biāo)志符是對(duì)于函數(shù)聲明哈希之后的前4個(gè)字節(jié)的數(shù)據(jù)。
如下例中,c.call(bytes4(keccak256(“eat()”)))將調(diào)用cat合約中的eat方法
1 | contract cat{ |
call函數(shù)的返回值為true或者false。只有當(dāng)能夠找到此方法并執(zhí)行成功后,會(huì)返回true,而如果不能夠找到此函數(shù)或執(zhí)行失則會(huì)返回false。因此調(diào)用test1方法會(huì)返回true,調(diào)用test2方法會(huì)返回false,因?yàn)檎也坏胶瘮?shù)。
call函數(shù)如果找不到函數(shù),默認(rèn)會(huì)調(diào)用回調(diào)函數(shù)。
回調(diào)函數(shù)是特殊的函數(shù),其沒(méi)有函數(shù)名。
其形式為:
1 | function(){ |
對(duì)于如下的cat合約。書(shū)寫(xiě)了回調(diào)函數(shù)。假設(shè)合約地址為c.那么在外部調(diào)用c.call(“abc”);會(huì)找不到此函數(shù),默認(rèn)會(huì)執(zhí)行回調(diào)函數(shù).因此在外部調(diào)用的c.call(“abc”) 會(huì)使得cat合約的狀態(tài)變量變?yōu)?99。而且call函數(shù)會(huì)返回true。
1 | contract cat{ |
回調(diào)函數(shù)是非常有用的,例如我們可以在外部調(diào)用失敗的時(shí)候,執(zhí)行某一些操作。
對(duì)于如下的cat合約。書(shū)寫(xiě)了回調(diào)函數(shù)。假設(shè)合約地址為c.那么在外部調(diào)用c.call(“abc”);會(huì)找不到此函數(shù),默認(rèn)會(huì)執(zhí)行回調(diào)函數(shù).回調(diào)函數(shù)中,將msg.data的值賦值給了fail變量。通過(guò)getfail函數(shù)可查看call函數(shù)傳遞過(guò)來(lái)的完整數(shù)據(jù)。fail變量的值為32個(gè)字節(jié)0x6162630000000000000000000000000000000000000000000000000000000000
,前3個(gè)字節(jié)是參數(shù)字母a、b、c的ASCII碼。61、62、63.
1 | pragma solidity ^0.4.23; |
在下例中,cat合約與animalcall合約中都有狀態(tài)變量我們首先部署cat合約,得到地址0x3456..
, 接下來(lái),將合約地址作為參數(shù)部署anumalCall合約。
調(diào)用test2方法,其調(diào)用了cat合約的eat方法,修改了cat合約中a的值為256. call函數(shù)調(diào)用外部合約,修改外部合約中的狀態(tài)變量。
1 | pragma solidity ^0.4.23; |
delegatecall函數(shù)的使用方法和call函數(shù)一樣,通過(guò)合約地址.delegatecall(函數(shù)標(biāo)志符)的方式來(lái)調(diào)用合約。函數(shù)標(biāo)志符是對(duì)于函數(shù)聲明哈希之后的前4個(gè)字節(jié)的數(shù)據(jù)。
library庫(kù)的遠(yuǎn)程調(diào)用正是使用了delegatecall函數(shù)。delegatecall與call不同之處在于,delegatecall不會(huì)修改外部合約中的狀態(tài)變量,其好像是將外部函數(shù)的代碼加載到了本地合約中執(zhí)行。會(huì)修改本地合約狀態(tài)變量的值。
例如下面的代碼,首先部署cat合約,得到地址0x3456..
, 接下來(lái),將合約地址作為參數(shù)部署anumalCall合約。
調(diào)用test2方法,其調(diào)用了cat合約的eat方法,但是卻是修改了animalcall合約中的狀態(tài)變量a。因此當(dāng)查詢后發(fā)現(xiàn),cat合約中的a并沒(méi)有變化,animalCall合約變量a變?yōu)榱肆?56。
1 | pragma solidity ^0.4.23; |
call函數(shù)可以進(jìn)行轉(zhuǎn)賬,并且是transfer與send的底層函數(shù)。call函數(shù)轉(zhuǎn)賬的使用方法是地址.call.value(轉(zhuǎn)賬金額)()
要注意的是,執(zhí)行轉(zhuǎn)賬的時(shí)候,如果轉(zhuǎn)賬的地址為合約,并且轉(zhuǎn)賬合約中有回調(diào)函數(shù)。那么將默認(rèn)會(huì)執(zhí)行回調(diào)函數(shù)。
但是以太坊為了避免重入***,對(duì)于transfer與send函數(shù)進(jìn)行了限制。當(dāng)使用transfer與send函數(shù),回調(diào)函數(shù)中執(zhí)行的操作最多不能夠超過(guò)2300gas。這也就意味著不能夠執(zhí)行轉(zhuǎn)賬、賦值等操作,而只能夠執(zhí)行事件觸發(fā)等操作。
例如下面的代碼: 首先部署Receiver合約,得到地址0x3456..
,再傳遞Receiver的地址部署Sender合約。當(dāng)調(diào)用sendMoney方法的時(shí)候,為合約地址0x3456..
轉(zhuǎn)賬的操作會(huì)觸發(fā)回調(diào)函數(shù),將狀態(tài)變量balance的數(shù)量增加。但是由于修改狀態(tài)變量的操作超過(guò)了大2300gas的限制,所以下面的操作不會(huì)成功。
1 | pragma solidity ^0.4.23; |
call函數(shù)能夠讓上面的操作成功。call函數(shù)能夠指定gas的限制,超過(guò)2300gas限制的約束。
如下例所示:
首先部署Receiver合約,得到地址0x3456..
,再傳遞Receiver的地址部署Sender合約。當(dāng)調(diào)用sendMoney方法轉(zhuǎn)移100wei的時(shí)候,為合約地址0x3456..
轉(zhuǎn)賬的操作會(huì)觸發(fā)回調(diào)函數(shù),將狀態(tài)變量balance的數(shù)量增加。由于call函數(shù)指定的大gas限制為20317,所以觸發(fā)回調(diào)函數(shù)可以將balance的金額修改為100.但是要注意,正因?yàn)榇?,call函數(shù)是危險(xiǎn)的底層函數(shù),不能夠避免重入***的問(wèn)題。
1 | pragma solidity ^0.4.23; |
本文鏈接: https://dreamerjonson.com/2018/11/23/solidity-48-call/
版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 CC BY 4.0 CN協(xié)議 許可協(xié)議。轉(zhuǎn)載請(qǐng)注明出處!
創(chuàng)新互聯(lián)www.cdcxhl.cn,專(zhuān)業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。
網(wǎng)站欄目:solidity[48]-call函數(shù)-創(chuàng)新互聯(lián)
分享網(wǎng)址:http://m.rwnh.cn/article42/ddocec.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、服務(wù)器托管、網(wǎng)站收錄、品牌網(wǎng)站建設(shè)、微信公眾號(hào)、定制開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容
全網(wǎng)營(yíng)銷(xiāo)推廣知識(shí)