内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

solidity[48]-call函數(shù)-創(chuàng)新互聯(lián)

調(diào)用外部合約的代碼

在之前我們已經(jīng)看到過(guò),使用interface、library的方式調(diào)用外部合約的代碼。
接下來(lái),我們將為大家補(bǔ)充第三種形式:
在下面的代碼中,部署cat合約之后,例如地址為 0x345678.. 在部署animal合約時(shí),傳遞此cat合約地址。從而能夠存儲(chǔ)合約的引用。調(diào)用test方法即可調(diào)用到外部合約的方法。

汕頭ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)公司的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書(shū)合作)期待與您的合作!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pragma solidity ^0.4.23;

contract cat{

   uint public a=5;
   function eat() public returns(uint){
       a = 256;
       return a;
   }
}

contract animal{
   cat c;

   constructor(address _addr){
       c = cat(_addr);
   }

   function test() public returns(uint){

       return c.eat();
   }
}

call函數(shù)

不管是interface、library還是上面看到的形式,要調(diào)用外部代碼,都是底層調(diào)用了call或者是delecall函數(shù)。

call函數(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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
contract cat{

   uint public a=5;
   function eat() public returns(uint){
       a = 256;
       return a;
   }
}
contract animalCall{
   address c;
   constructor(address _addr){
       c = _addr;
   }

   function test1() public returns(bool){
       return c.call(bytes4(keccak256("eat()")));
   }
   function test2() public returns(bool){
       return c.call(bytes4(keccak256("eat")));
   }
}

call函數(shù)返回值

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ù)與回調(diào)函數(shù)

call函數(shù)如果找不到函數(shù),默認(rèn)會(huì)調(diào)用回調(diào)函數(shù)。
回調(diào)函數(shù)是特殊的函數(shù),其沒(méi)有函數(shù)名。
其形式為:

1
2
3
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
2
3
4
5
6
7
8
9
10
11
12
13
14
contract cat{

   uint public a=5;

   function eat() public returns(uint){
       a = 256;
       return a;
   }

   function (){
       a=999;
   }

}

call函數(shù)與msg.data

回調(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
2
3
4
5
6
7
8
9
10
11
12
13
14
pragma solidity ^0.4.23;

contract cat{

   bytes fail;
   function (){
       fail = msg.data;
   }

   function getfail() returns(bytes){
       return fail;
   }

}

call函數(shù)修改外部合約的狀態(tài)變量

在下例中,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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pragma solidity ^0.4.23;
contract cat{
   uint public a=5;
   function eat() public returns(uint){
       a = 256;
       return a;
   }
}

contract animalCall{
    uint public a=4;
   address c;

   constructor(address _addr){
       c = _addr;
   }

     function test2() public returns(bool){
       return c.call(bytes4(keccak256("eat()")));
     }
}

delegatecall

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pragma solidity ^0.4.23;
contract cat{
   uint public a=5;
   function eat() public returns(uint){
       a = 256;
       return a;
   }
}

contract animalCall{
    uint public a=4;
   address c;

   constructor(address _addr){
       c = _addr;
   }

     function test2() public returns(bool){
       return c.delegatecall(bytes4(keccak256("eat()")));
     }
}

call函數(shù)轉(zhuǎn)賬與回調(diào)函數(shù)細(xì)節(jié)

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
pragma solidity ^0.4.23;

contract Sender {
 function sendMoney(address _receiver) payable {
   _receiver.send(msg.value);
 }
}



contract Receiver {
 uint public balance = 0;

 function () payable {
   balance += msg.value;
 }
}

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pragma solidity ^0.4.23;

contract Sender {
 function send(address _receiver) payable {
   _receiver.call.value(msg.value).gas(20317)();
 }
}

contract Receiver {
 uint public balance = 0;

 function () payable {
   balance += msg.value;
 }
}
  • 本文鏈接: https://dreamerjonson.com/2018/11/23/solidity-48-call/

  • 版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 CC BY 4.0 CN協(xié)議 許可協(xié)議。轉(zhuǎn)載請(qǐng)注明出處!

solidity[48]-call函數(shù)

創(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)

營(yíng)銷(xiāo)型網(wǎng)站建設(shè)
珠海市| 博湖县| 天门市| 荥经县| 萨嘎县| 安泽县| 奎屯市| 郯城县| 石狮市| 方正县| 读书| 永年县| 黔西县| 大冶市| 安陆市| 额济纳旗| 赤水市| 攀枝花市| 福贡县| 中牟县| 清河县| 南雄市| 健康| 疏勒县| 北川| 蛟河市| 九龙县| 沅陵县| 古浪县| 龙川县| 伊春市| 普格县| 洛隆县| 大新县| 固原市| 鄢陵县| 涿鹿县| 揭西县| 成安县| 临汾市| 香格里拉县|