W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵(lì)
地址類型有兩種風(fēng)格,它們基本相同:
這種區(qū)別背后的想法是,您可以將 Ether 發(fā)送到一個(gè)地址,而您不應(yīng)該將 Ether 發(fā)送到 plain ,例如,因?yàn)樗赡苁遣皇菫榻邮?Ether 而構(gòu)建的智能合約。address payableaddress
類型轉(zhuǎn)換:
允許從to的隱式轉(zhuǎn)換,而從to的轉(zhuǎn)換 必須通過.address payableaddressaddressaddress payablepayable(<address>)
address允許對uint160、整數(shù)文字 bytes20和合約類型進(jìn)行顯式轉(zhuǎn)換。
只有 typeaddress和 contract-type 的表達(dá)式可以通過顯式轉(zhuǎn)換轉(zhuǎn)換為類型。對于合約類型,只有當(dāng)合約可以接收以太幣時(shí)才允許這種轉(zhuǎn)換,即合約要么具有接收或應(yīng)付回退功能。請注意,這是有效的,并且是此規(guī)則的一個(gè)例外。address payablepayable(...) payable(0)
筆記
如果您需要一個(gè)類型的變量address并計(jì)劃向其發(fā)送 Ether,則聲明其類型以使此要求可見。另外,請嘗試盡早進(jìn)行這種區(qū)分或轉(zhuǎn)換。address payable
運(yùn)營商:
警告
例如,如果將使用較大字節(jié)大小的類型轉(zhuǎn)換address為bytes32,則 將address被截?cái)?。為了減少轉(zhuǎn)換歧義,版本 0.4.24 及更高版本的編譯器強(qiáng)制您在轉(zhuǎn)換中顯式截?cái)?。?32 字節(jié)的值為例0x111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFFCCCC。
您可以使用address(uint160(bytes20(b))), 導(dǎo)致0x111122223333444455556666777788889999aAaa, 或者您可以使用address(uint160(uint256(b))), 導(dǎo)致0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc.
筆記
address和之間的區(qū)別是在 0.5.0 版本中引入的。同樣從該版本開始,合約不是從地址類型派生的,但 如果它們具有接收或應(yīng)付回退功能,仍可以顯式轉(zhuǎn)換為or 。address payableaddressaddress payable
有關(guān)地址的所有成員的快速參考,請參閱地址類型的成員。
balance
和transfer
可以使用該屬性查詢地址的余額,balance
并使用以下函數(shù)將 Ether(以 wei 為單位)發(fā)送到應(yīng)付地址transfer
:
address payable x = payable(0x123); address myAddress = address(this); if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);
transfer
如果當(dāng)前合約的余額不夠大或以太幣轉(zhuǎn)賬被接收賬戶拒絕,則該功能失敗。該transfer
功能在失敗時(shí)恢復(fù)。
筆記
Ifx
是一個(gè)合約地址,它的代碼(更具體地說:它的Receive Ether Function,如果存在,或者它的Fallback Function,如果存在)將與調(diào)用一起執(zhí)行transfer
(這是
EVM 的一個(gè)特性,無法阻止)。如果該執(zhí)行用完 gas 或以任何方式失敗,則 Ether 轉(zhuǎn)移將被恢復(fù),當(dāng)前合約將異常停止。
send
Send 是 的低級對應(yīng)物transfer
。如果執(zhí)行失敗,當(dāng)前合約不會異常停止,而是send
會返回false
。
警告
使用 有一些危險(xiǎn)send
:如果調(diào)用堆棧深度為 1024,則傳輸失?。ㄟ@總是由調(diào)用者強(qiáng)制執(zhí)行的),如果接收者用完 gas,它也會失敗。因此,為了進(jìn)行安全的 Ether 轉(zhuǎn)賬,請始終檢查 的返回值send
,使用transfer
甚至更好:使用收款人取款的模式。
call
,delegatecall
和staticcall
為了與不遵守 ABI 的合約進(jìn)行交互,或者為了更直接地控制編碼,提供了call
和delegatecall
功能staticcall
。它們都采用單個(gè)參數(shù)并返回成功條件(作為 a )和返回的數(shù)據(jù)()。函數(shù)、和可用于對結(jié)構(gòu)化數(shù)據(jù)進(jìn)行編碼 。bytes memory
bool
bytes memory
abi.encode
abi.encodePacked
abi.encodeWithSelector
abi.encodeWithSignature
例子:
bytes memory payload = abi.encodeWithSignature("register(string)", "MyName"); (bool success, bytes memory returnData) = address(nameReg).call(payload); require(success);
警告
所有這些函數(shù)都是低級函數(shù),應(yīng)該小心使用。具體來說,任何未知的合約都可能是惡意的,如果您調(diào)用它,您會將控制權(quán)移交給該合約,該合約可能會反過來回調(diào)您的合約,因此請準(zhǔn)備好在調(diào)用返回時(shí)更改您的狀態(tài)變量。與其他合約交互的常規(guī)方式是調(diào)用合約對象 ( x.f()
) 上的函數(shù)。
筆記
以前版本的 Solidity 允許這些函數(shù)接收任意參數(shù),并且還會以不同的方式處理第一個(gè)類型的參數(shù) bytes4
。這些邊緣情況在 0.5.0 版中被刪除。
可以使用調(diào)節(jié)器調(diào)整供應(yīng)的氣體gas
:
address(nameReg).call{gas: 1000000}(abi.encodeWithSignature("register(string)", "MyName"));
同樣,也可以控制提供的 Ether 值:
address(nameReg).call{value: 1 ether}(abi.encodeWithSignature("register(string)", "MyName"));
最后,可以組合這些修飾符。他們的順序無關(guān)緊要:
address(nameReg).call{gas: 1000000, value: 1 ether}(abi.encodeWithSignature("register(string)", "MyName"));
以類似的方式,delegatecall
可以使用該功能:不同之處在于僅使用給定地址的代碼,所有其他方面(存儲,余額,...)均取自當(dāng)前合約。的目的delegatecall
是使用存儲在另一個(gè)合約中的庫代碼。用戶必須確保兩個(gè)合約中的存儲布局都適合使用委托調(diào)用。
筆記
在宅基地之前,只有一個(gè)名為的有限變體callcode
可用,它不提供對原始值msg.sender
和msg.value
值的訪問。此功能已在 0.5.0 版中刪除。
因?yàn)?code>staticcall也可以使用拜占庭。這與 基本相同call
,但如果被調(diào)用的函數(shù)以任何方式修改狀態(tài),它將恢復(fù)。
這三個(gè)函數(shù)call
和都是非常低級的函數(shù)delegatecall
,staticcall
只能作為最后的手段使用,因?yàn)樗鼈兤茐牧?Solidity 的類型安全。
該gas
選項(xiàng)適用于所有三種方法,而該value
選項(xiàng)僅適用于call
.
筆記
最好避免在智能合約代碼中依賴硬編碼的 gas 值,無論狀態(tài)是讀取還是寫入,因?yàn)檫@可能有很多陷阱。此外,未來天然氣的獲取可能會發(fā)生變化。
code
和codehash
您可以查詢?nèi)魏沃悄芎霞s的部署代碼。用于.code
將 EVM 字節(jié)碼獲取為 ,它可能為空。使用獲取該代碼的 Keccak-256 哈希(作為)。請注意,這比使用便宜。bytes memory
.codehash
bytes32
addr.codehash
keccak256(addr.code)
筆記
所有合約都可以轉(zhuǎn)換為address
類型,因此可以使用 查詢當(dāng)前合約的余額address(this).balance
。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: