地址

2022-05-11 18:06 更新

地址類型有兩種風(fēng)格,它們基本相同:

  • address:保存一個(gè) 20 字節(jié)的值(以太坊地址的大?。?。
  • address payable:與 相同address,但具有附加成員transfer和send。

這種區(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)地址的所有成員的快速參考,請參閱地址類型的成員

  • balancetransfer

可以使用該屬性查詢地址的余額,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,delegatecallstaticcall

為了與不遵守 ABI 的合約進(jìn)行交互,或者為了更直接地控制編碼,提供了calldelegatecall功能staticcall。它們都采用單個(gè)參數(shù)并返回成功條件(作為 a )和返回的數(shù)據(jù)()。函數(shù)、和可用于對結(jié)構(gòu)化數(shù)據(jù)進(jìn)行編碼 。bytes memoryboolbytes memoryabi.encodeabi.encodePackedabi.encodeWithSelectorabi.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.sendermsg.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ā)生變化。

  • codecodehash

您可以查詢?nèi)魏沃悄芎霞s的部署代碼。用于.code將 EVM 字節(jié)碼獲取為 ,它可能為空。使用獲取該代碼的 Keccak-256 哈希(作為)。請注意,這比使用便宜。bytes memory.codehashbytes32addr.codehashkeccak256(addr.code)

筆記

所有合約都可以轉(zhuǎn)換為address類型,因此可以使用 查詢當(dāng)前合約的余額address(this).balance


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號