日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

深入理解Solidity 三

發(fā)布時(shí)間:2023/12/13 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解Solidity 三 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Solidity函數(shù)聲明和類型

  • ?函數(shù)的值類型有兩類:內(nèi)部(internal)類型和外部(external)類型
  • 內(nèi)部函數(shù)只可以在當(dāng)前合約內(nèi)部被調(diào)用(即在當(dāng)前代碼塊內(nèi),包括內(nèi)部庫(kù)函數(shù)和繼承函數(shù)),因?yàn)樗麄儾荒茉诋?dāng)前合約的上下文中的外部被執(zhí)行。調(diào)用一個(gè)內(nèi)部函數(shù)是通過(guò)跳轉(zhuǎn)到它的入口標(biāo)簽來(lái)實(shí)現(xiàn)的,就像在當(dāng)前合約的內(nèi)部調(diào)用一個(gè)函數(shù)
  • 外部函數(shù)是由一個(gè)地址和一個(gè)函數(shù)的簽名組成,可以通過(guò)外部函數(shù)調(diào)用傳遞或者返回
  • 調(diào)用內(nèi)部函數(shù),直接使用名字f
  • 調(diào)用外部函數(shù):this.f(當(dāng)前合約),a.f(外部合約)
  • 除了使用外部函數(shù)調(diào)用外,還可以使用繼承機(jī)制

例子(外部函數(shù)調(diào)用)

contract C{uint a;function f() public{} } contract D{function g() public{C c = new C();c.f();} }

例子(繼承機(jī)制)

  • 可以使用internal函數(shù)/public函數(shù),不可以使用private函數(shù)
  • D繼承C合約,只會(huì)把交叉的函數(shù)編譯上傳
contract C{uint a;function f() public{} } contract D is C{function g() public{f();} }

函數(shù)的可見(jiàn)性

  • 函數(shù)的可見(jiàn)性可以指定為external、public、internal或者private;對(duì)于狀態(tài)變量,不可以設(shè)置為external,默認(rèn)是internal
  • external:外部函數(shù)作為合約接口的一部分,意味著我們可以從其他合約和交易中調(diào)用。一個(gè)外部函數(shù)f不可以從內(nèi)部調(diào)用(即f不起作用,但是this.f可以)。當(dāng)接收到大量的數(shù)據(jù)的時(shí)候,外部函數(shù)有時(shí)候會(huì)更有效率
  • public:public函數(shù)是合約接口的一部分,相當(dāng)于定義了一個(gè)view類型的可以返回參數(shù)的函數(shù),可以在內(nèi)部或者通過(guò)消息調(diào)用。對(duì)于public狀態(tài)變量,會(huì)自動(dòng)生成一個(gè)getter函數(shù)

例子

uint public a;//將a聲明為public,就相當(dāng)于為a定義了如下的函數(shù)形式 function a() public view returns (uint){return a; }
  • internal:這些函數(shù)和狀態(tài)變量只能是內(nèi)部訪問(wèn)(即從當(dāng)前合約內(nèi)部或者從其他派生的合約訪問(wèn)),不可以使用this
  • private:private函數(shù)和狀態(tài)變量?jī)H在當(dāng)前定義他們的合約中使用,并且不能被派生合約使用。

函數(shù)狀態(tài)可變性

  • payable:允許從消息調(diào)用中接收以太幣Ether
  • constant:和view相同,一般只修飾狀態(tài)變量,不允許賦值(除了初始化之外)
constructor()public payable{}//創(chuàng)建合約的同時(shí)需要往合約上面轉(zhuǎn)錢
  • pure:純函數(shù),不允許修改或者訪問(wèn)狀態(tài)
  • view:不允許修改狀態(tài)

函數(shù)狀態(tài)可變性

  • 修改狀態(tài)變量
  • 產(chǎn)生事件
  • 創(chuàng)建其他合約
  • 使用selfdestruct(自殺/自毀)
  • 通過(guò)調(diào)用發(fā)送以太幣
  • 調(diào)用任何沒(méi)有標(biāo)記為view或者pure的函數(shù)
  • 使用低級(jí)調(diào)用
  • 使用包含特定操作嗎的內(nèi)聯(lián)匯編

以下是被認(rèn)為從狀態(tài)中進(jìn)行讀取

  • 讀取狀態(tài)變量
  • 訪問(wèn)this.balance或者<address>.balance
  • 訪問(wèn)block、tx、msg中任意成員(除了msg.sig和msg.data之外)
  • 調(diào)用任何未標(biāo)記為pure的函數(shù)
  • 使用包含某些操作碼的內(nèi)聯(lián)匯編

函數(shù)修飾器 modifier

  • 使用修飾器modifier可以輕松改變函數(shù)的行為。例如,他們可以在執(zhí)行函數(shù)之前自動(dòng)檢查某個(gè)條件。修飾器modifier是合約的可繼承屬性,并可能被派生合約覆蓋
  • 如果同一個(gè)函數(shù)有多個(gè)修飾器modifier,他們之間可以使用空格隔開(kāi),修飾器modifier會(huì)依次檢查執(zhí)行。

代碼

contract Purchase{address public seller;constructor() public{seller = msg.sender;}modifier onlySeller(){require(msg.sender == seller,"Only seller");_;}function f() public view onlySeller returns(uint){return 200;} }

效果展示

  • msg.sender是合約的部署者,只有合約的部署者調(diào)用f函數(shù),返回200,剩余的人會(huì)返回錯(cuò)誤信息,only seller
  • require(msg.sender == seller,"Only seller");逗號(hào)之前是檢查條件,之后是返回報(bào)錯(cuò)信息,檢查條件在代碼流程之前執(zhí)行
  • _;將代碼流程嵌套到這里,指代檢查條件執(zhí)行之后,執(zhí)行代碼的邏輯。(函數(shù)體)

回退函數(shù)(fallback)

  • 回退函數(shù)(fallback function)是合約中的特殊函數(shù);沒(méi)有名字,不能有參數(shù)也不能有返回值
  • 如果在一個(gè)到合約的調(diào)用中,沒(méi)有其他函數(shù)與給定的函數(shù)標(biāo)示符匹配(或者沒(méi)有提供調(diào)用函數(shù)),你們這個(gè)函數(shù)(fallbacj函數(shù))會(huì)被執(zhí)行
  • 每當(dāng)合約收到以太幣(沒(méi)有任何數(shù)據(jù)),回退函數(shù)就會(huì)執(zhí)行。此外,為了接收以太幣,fallback函數(shù)必須標(biāo)記為payable。如果不存在這樣的函數(shù),則合約不能通過(guò)常規(guī)交易接收以太幣
  • 在上下文中只有很少的gas可以用來(lái)完成回退函數(shù)的調(diào)用,所以使fallback函數(shù)的調(diào)用盡量廉價(jià)很重要

代碼

pragma solidity >0.4.99 <0.6.0; contract Sink{function() external payable{} } contract Test{function() external {x=1;}uint x; }contract Caller{function calllTest(Test test)public returns(bool){(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));require(success);address payable testPayable = address(uint160(address(test)));return testPayable.send(2 ether);} }

注解

  • 調(diào)用合約中不存在的函數(shù)和轉(zhuǎn)錢的時(shí)候會(huì)調(diào)用回退函數(shù)
  • 回退函數(shù)適用在合約5.0版本以上

事件(event)

  • 事件是以太坊EVM提供的一種日志基礎(chǔ)設(shè)施。事件可以用來(lái)做操作記錄,存儲(chǔ)為日志。也可以用來(lái)實(shí)現(xiàn)一些交互功能,比如通知UI,返回函數(shù)的調(diào)用結(jié)果
  • 當(dāng)定義的事件被觸發(fā)時(shí),可以將事件存儲(chǔ)到EVM的交易日志中,日志是區(qū)塊鏈中的一種特殊的數(shù)據(jù)結(jié)構(gòu);日志和合約相互關(guān)聯(lián),與合約的存儲(chǔ)合并存入到區(qū)塊鏈條中,只要某個(gè)區(qū)塊可以訪問(wèn),其相關(guān)的日志就可以訪問(wèn),但是在合約中是不可以之間訪問(wèn)日志和事件數(shù)據(jù)
  • 可以通過(guò)日志實(shí)現(xiàn)簡(jiǎn)單支付驗(yàn)證SPV,如果一個(gè)外部實(shí)體提供了一個(gè)帶有這種證明的合約,它可以檢查日志是否真實(shí)存在于區(qū)塊鏈中

異常處理

  • 適用狀態(tài)恢復(fù)異常來(lái)處理異常。這樣的異常將會(huì)撤銷對(duì)于當(dāng)前的調(diào)用(及其所有的子調(diào)用)中的狀態(tài)所做的所有的更改,并且向調(diào)用者返回錯(cuò)誤
  • 函數(shù)的assert和require用于判斷條件,并且在不滿足條件的時(shí)候拋出異常
  • assert()一般只應(yīng)用于測(cè)試內(nèi)部的錯(cuò)誤,并且檢查異常
  • require()應(yīng)用于確保滿足有效的條件(如輸入或合約的狀態(tài)變量),或者驗(yàn)證調(diào)用外部合約的返回值
  • revert()用于拋出異常,它可以標(biāo)記一個(gè)錯(cuò)誤并且將當(dāng)前調(diào)用回退

單位

  • 以太幣單位之間的換算就是在數(shù)字后邊加上wei、finney、szabo或者ether來(lái)實(shí)現(xiàn),如果沒(méi)有單位,缺省為wei

時(shí)間

  • 秒是缺省單位,在時(shí)間單位之間,數(shù)字后面帶有seconds、minutes、hours、days、weeks和years的可以進(jìn)行換算?但是這些后綴不可以直接用在變量的后邊,如果需要使用到時(shí)間單位(例如days)來(lái)將輸入變量轉(zhuǎn)換為時(shí)間,可以使用如下方式
function f(uint start,uint daysAfter)public{if (now >= start + daysAfter * 1 days) }

?

總結(jié)

以上是生活随笔為你收集整理的深入理解Solidity 三的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。