溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

solidity 0.5.7簡(jiǎn)明教程

發(fā)布時(shí)間:2020-09-14 00:37:39 來(lái)源:網(wǎng)絡(luò) 閱讀:425 作者:小智123 欄目:開(kāi)發(fā)技術(shù)

以太坊不僅是一種加密數(shù)字貨幣,它更是功能完備的智能合約平臺(tái),solidity就是用來(lái)開(kāi)發(fā)以太坊上的智能合約的原生開(kāi)發(fā)語(yǔ)言。solidity最早發(fā)布于2015年,它是第一種圖靈完備的智能合約專用開(kāi)發(fā)語(yǔ)言。目前除了以太坊之外,在其他區(qū)塊鏈中也逐漸開(kāi)始支持solidity,例如hyperledger fabric、tendermint等。在這個(gè)solidity快速教程中,我們將使用最新0.5.7版的solidity,以一個(gè)具體的案例來(lái)介紹solidity智能合約的開(kāi)發(fā)、部署與交互,希望對(duì)你快速掌握solidity智能合約的開(kāi)發(fā)有所幫助。

如果要高效系統(tǒng)地掌握以太坊智能合約與DApp的開(kāi)發(fā),推薦訪問(wèn)匯智網(wǎng)的在線互動(dòng)課程:

以太坊開(kāi)發(fā)入門(mén) |java以太坊 | python以太坊 | php以太坊 | C#以太坊 | 電商DApp實(shí)戰(zhàn) | ERC721通證實(shí)戰(zhàn)

0、問(wèn)題的背景

有一個(gè)老爺爺,在生命的最后歲月別無(wú)他求,只是希望自己的財(cái)產(chǎn)能夠通過(guò)遺囑順利地傳給其他家庭成員。

在傳統(tǒng)的遺囑中,遺產(chǎn)分配方案是落實(shí)在法律文件上的,然后當(dāng)真正開(kāi)始分配時(shí),法官需要重審文件并做出相應(yīng)的決定。常見(jiàn)的問(wèn)題發(fā)生在家庭成員之間對(duì)分配比例的爭(zhēng)執(zhí)上,甚至因此而導(dǎo)致家庭成員關(guān)系的破裂。在法庭聽(tīng)證階段,這些都會(huì)影響法官最終的裁決,并因此可能導(dǎo)致不公平的結(jié)果,甚至對(duì)家庭關(guān)系造成進(jìn)一步的傷害。

那么,如果我們可以讓遺產(chǎn)分配自動(dòng)進(jìn)行,是否可以避免上述情況的發(fā)生?

如果遺產(chǎn)是一個(gè)智能合約,那么就不需要法官了。老爺爺可以自主地利用合約管理資產(chǎn),然后在他去世后由程序來(lái)分配遺產(chǎn)給家庭成員。合約里的代碼就決定了最終的分配結(jié)果,因此無(wú)需法官的介入。例如薩拉分$10000,本得到$5000,朱麗葉得到$2000。代碼執(zhí)行后,資產(chǎn)以代幣或加密貨幣的形式自動(dòng)分配給這些家庭成員,而無(wú)需人工介入。雖然不能保證每個(gè)成員都對(duì)遺產(chǎn)的分配結(jié)果滿意,但是沒(méi)有人會(huì)和代碼爭(zhēng)執(zhí)。這聽(tīng)起來(lái)還比較可行,對(duì)嗎?

記住這個(gè)案例,在這個(gè)快速教程中,我們將使用solidity,為老爺爺開(kāi)發(fā)一個(gè)簡(jiǎn)單的遺囑合約,來(lái)滿足他最后的愿望。

1、搭建solidity開(kāi)發(fā)環(huán)境

開(kāi)發(fā)solidity智能合約最簡(jiǎn)單的方法,就是使用官方提供的在線集成開(kāi)發(fā)環(huán)境REMIX,你可以點(diǎn)擊這里打開(kāi)remix,在網(wǎng)頁(yè)里就完成solidity智能合約的編寫(xiě)、編譯與部署:

solidity 0.5.7簡(jiǎn)明教程

在你打開(kāi)remix頁(yè)面后,注意在右側(cè)的run選項(xiàng)頁(yè),environment下拉框中,要選中JavaScript VM。這個(gè)選項(xiàng)的意思是使用一個(gè)內(nèi)存仿真以太坊節(jié)點(diǎn)作為你的solidity智能合約的運(yùn)行平臺(tái),這樣就不用考慮與實(shí)際的以太坊主網(wǎng)交互所需要的賬號(hào)、資金、計(jì)算費(fèi)用等問(wèn)題,而可以先把精力聚焦在學(xué)習(xí)如何使用solidity表達(dá)你的業(yè)務(wù)邏輯上。

點(diǎn)擊remix頁(yè)面左上方的+圖標(biāo),就可以創(chuàng)建一個(gè)新的代碼文件,我們將其命名為will.sol。在remix頁(yè)面中間的編輯區(qū)域可以同時(shí)顯示多個(gè)文件,當(dāng)前正在編輯的文件,則以活動(dòng)選項(xiàng)頁(yè)的形式顯示文件名稱。

2、聲明solidity編譯器版本

solidity還是很早期階段的語(yǔ)言,從語(yǔ)法到編譯器都在不斷地演化,所以在solidity代碼的第一行,一定要用pragma關(guān)鍵字聲明這個(gè)文件中的solidity代碼需要哪個(gè)版本的編譯器。例如:

solidity 0.5.7簡(jiǎn)明教程

注意在solidity中,末尾的分號(hào)不可省略。

3、編寫(xiě)第一個(gè)solidity合約

接下來(lái)就可以定義我們的第一個(gè)合約:

solidity 0.5.7簡(jiǎn)明教程

使用contract關(guān)鍵字來(lái)定義一個(gè)合約,solidity的合約類(lèi)似于我們熟悉的OOP中的類(lèi),因此通常合約的名稱首字母也會(huì)大寫(xiě),例如Will。一對(duì)大括號(hào)用來(lái)定義合約的實(shí)現(xiàn)邏輯,單行注釋也使用//,這和很多開(kāi)發(fā)語(yǔ)言都類(lèi)似。

4、solidity中的全局變量和構(gòu)造函數(shù)

在我們開(kāi)始寫(xiě)代碼之前,應(yīng)當(dāng)首先明確遺囑的條款。假設(shè)老爺爺?shù)倪z產(chǎn)是50個(gè)以太幣,其中20個(gè)留給他的兒子康萊德,剩下的30個(gè)留給他的妻子麗莎。在真實(shí)的環(huán)境中,當(dāng)老爺爺去世后,應(yīng)當(dāng)有一個(gè)外部的程序?qū)⒄{(diào)用合約中定義的方法來(lái)分配遺產(chǎn),但是我們?yōu)榱吮阌趯W(xué)習(xí)將自己完成這個(gè)調(diào)用。

現(xiàn)在,讓我們先完成如下代碼:

  • 表征合約所有者的變量
  • 表征遺產(chǎn)數(shù)量的變量
  • 表征老爺爺是否還健在的變量
  • 設(shè)置上述變量初始值的構(gòu)造函數(shù)

solidity 0.5.7簡(jiǎn)明教程

第5行代碼定義了合約的所有者。當(dāng)我們?cè)趕olidity中定義變量時(shí),必須先聲明其類(lèi)型。address是solidity中一種特殊的類(lèi)型,它表示一個(gè)以太坊地址。address類(lèi)型的變量有一些特殊的方法,我們?cè)诤竺鏁?huì)進(jìn)一步了解。

第6行代碼定義的fortune變量用來(lái)保存老爺爺?shù)倪z產(chǎn)數(shù)量,它的類(lèi)型是uintunsigned int,意思是這個(gè)變量是0或正整數(shù)。solidity中有很多數(shù)據(jù)類(lèi)型,但我們不會(huì)在這里一一介紹,你可以在官方文檔中深入了解solidity的數(shù)據(jù)類(lèi)型。

第7行代碼定義的isDeceased變量用來(lái)標(biāo)識(shí)老爺爺是否已經(jīng)去世,這是一個(gè)開(kāi)關(guān)量,因此其類(lèi)型為boolean,可能的值只有兩個(gè):true或false,默認(rèn)值為false。

第9~13行代碼是合約的構(gòu)造函數(shù),這個(gè)特殊的函數(shù)將在合約部署的時(shí)候自動(dòng)執(zhí)行。

public關(guān)鍵字被稱為可見(jiàn)性修飾符,它的作用是聲明被修飾的方法是否允許外部調(diào)用。public意味著在合約內(nèi)部或外部(由其他合約或其他人)都可以調(diào)用該方法。

payable關(guān)鍵字是solidity的特色之一,它使得被修飾的方法可以發(fā)送或接收以太幣。為構(gòu)造函數(shù)聲明payable關(guān)鍵字意味著當(dāng)我們部署合約的時(shí)候,可以直接向合約存入以太幣,例如,作為遺產(chǎn)的50個(gè)以太幣。當(dāng)合約接收到以太幣后,這些幣就保存在合約地址上了。

在構(gòu)造函數(shù)內(nèi)部,我們將owner變量的值設(shè)置為msg.sender,這是一個(gè)以太坊平臺(tái)預(yù)置的全局變量,表示調(diào)用合約方法的賬號(hào)地址,在我們的案例中,這的地址是老爺爺?shù)摹?/p>

同時(shí)我們將fortune變量的值設(shè)置為msg.value,這是另一個(gè)全局變量,它表示被調(diào)用的方法接收到的以太幣的數(shù)量。

雖然變量isDeceased被自動(dòng)初始化為默認(rèn)值false,但為了清晰起見(jiàn),我們將其顯式地設(shè)置為false。

5、使用solidity修飾符

在solidity中,修飾符(Modifier)可以為函數(shù)附加額外的條件邏輯。例如,假設(shè)我有一個(gè)用來(lái)關(guān)燈的方法,同時(shí)有一個(gè)修飾符要求燈開(kāi)關(guān)必須處于on狀態(tài),那么
我們就可以在方法上附加聲明這個(gè)修飾符,以便確保只有在燈開(kāi)關(guān)處于on狀態(tài)時(shí),才可以調(diào)用這個(gè)方法,否則就拋出異常。

solidity 0.5.7簡(jiǎn)明教程

第15行代碼定義了onlyOwner修飾符。如果一個(gè)方法附加聲明了這個(gè)修飾符,那么就要求調(diào)用方法的賬號(hào)(msg.sender)必須與owner變量的值一致(別忘了我們?cè)跇?gòu)造函數(shù)中設(shè)置了owner的值)。這個(gè)調(diào)用條件有助于遺產(chǎn)的分配,我們將在后面看到這一點(diǎn)。

require關(guān)鍵字的意思是,括號(hào)里的表達(dá)式的值必須為真(true),否則就會(huì)拋出異常,不再繼續(xù)執(zhí)行代碼。

_;起到占位符的作用,在執(zhí)行過(guò)程中,以太坊虛擬機(jī)會(huì)用被修飾的方法代碼來(lái)替換它。

第20行代碼定義了mustBeDeceased修飾符。如果一個(gè)方法附加聲明了這個(gè)修飾符,那么就只有在isDeceased變量值為true時(shí),才可以調(diào)用該方法,否則就拋出異常。

在上面的代碼中,我們使用修飾符來(lái)限定方法的執(zhí)行條件,當(dāng)然也可以不使用修飾符,而直接在方法實(shí)現(xiàn)代碼中使用require,不過(guò)修飾符看起來(lái)更高級(jí)一些,也更容易實(shí)現(xiàn)代碼的復(fù)用。

6、設(shè)定遺產(chǎn)分配方案

現(xiàn)在我們要繼續(xù)完成遺產(chǎn)在家庭成員之間的分配任務(wù),這需要他們的錢(qián)包地址和分配數(shù)量。

正如我們之前所述,康萊德將收到20個(gè)以太幣而麗莎將繼承30個(gè)。讓我們創(chuàng)建一個(gè)數(shù)組來(lái)保存他們的錢(qián)包地址,然后寫(xiě)一個(gè)方法來(lái)分配遺產(chǎn)。

solidity 0.5.7簡(jiǎn)明教程

第25行代碼定義了一個(gè)空數(shù)組familyWallets,用來(lái)保存所有家庭成員的錢(qián)包地址。和其他語(yǔ)言一樣,在solidity中數(shù)組是順序存放并且可以使用序號(hào)來(lái)存取。注意方括號(hào)之前的關(guān)鍵字paybale,只有address payable類(lèi)型的變量,才可以接收以太幣,這是0.5版本的solidity與之前版本的區(qū)別之一。

第27行代碼創(chuàng)建了一個(gè)從address類(lèi)型到uint類(lèi)型的映射表變量inheritance,用來(lái)保存每個(gè)錢(qián)包地址的遺產(chǎn)數(shù)量。這是一個(gè)鍵/值對(duì)數(shù)據(jù)結(jié)構(gòu),類(lèi)似于其他語(yǔ)言中的字典或哈希表,可以用鍵來(lái)存取值。

第29行代碼定義了一個(gè)方法,它的功能是將一個(gè)錢(qián)包地址添加到familyWallets數(shù)組,然后設(shè)置該地址在inheritance映射表中的遺產(chǎn)數(shù)量。注意附加的onlyOwner修飾符,猜一下為什么我們要在這里聲明這個(gè)修飾符?

第30行代碼將傳入方法的錢(qián)包地址追加到familyWallets數(shù)組的末尾。

第31行代碼將傳入方法的遺產(chǎn)繼承數(shù)量設(shè)置為映射表inheritance的指定地址(傳入方法的另一個(gè)參數(shù))的值。

7、實(shí)現(xiàn)遺產(chǎn)自動(dòng)分配

讓我們總結(jié)一下。到目前為止,我們已經(jīng)學(xué)習(xí)了全局變量、數(shù)據(jù)類(lèi)型、構(gòu)造函數(shù)、特殊的關(guān)鍵字例如payablepublic、內(nèi)置的全局變量例如msg.sendermsg.value、修飾符和require、數(shù)組、映射表和方法。我們已經(jīng)搭好了合約的框架,現(xiàn)在讓我們把各部分整合起來(lái)最終完成合約。

作為這個(gè)教程最后一部分的代碼,我們將實(shí)現(xiàn)家庭成員遺產(chǎn)的自動(dòng)分配。

solidity 0.5.7簡(jiǎn)明教程

第34行定義了payout()方法,注意private關(guān)鍵字,這個(gè)可視性修飾符public的反義詞,它只允許被修飾的方法在合約內(nèi)部調(diào)用,就像在第42行的代碼那樣。之所以在這里使用private,主要是考慮到安全性,因?yàn)槲覀儾幌M魏蝸?lái)自合約外部的調(diào)用。注意最后的mustBeDeceased修飾符,目前我們依然不能滿足這個(gè)修飾符要求的條件來(lái)執(zhí)行payout()方法。

第35行代碼是一個(gè)for循環(huán),用來(lái)遍歷familyWallets數(shù)組。語(yǔ)法如下:

  • 定義一個(gè)計(jì)數(shù)器變量i,
  • 聲明循環(huán)的執(zhí)行條件
  • 每個(gè)周期計(jì)數(shù)器變量i加1

第36行代碼是整個(gè)合約的核心,我們調(diào)用address類(lèi)型的地址對(duì)象的transfer()方法,向該地址轉(zhuǎn)賬預(yù)定的遺產(chǎn)繼承數(shù)量,inheritance[familyWallets[i]]表示在inheritance映射表中,鍵familyWallets[i]的值,也就是第i個(gè)家庭成員的遺產(chǎn)繼承數(shù)量。

第40~42行代碼定義了一個(gè)方法,當(dāng)老爺爺去世后將調(diào)用這個(gè)方法來(lái)觸發(fā)遺產(chǎn)的分配。在這里我們將變量isDeceased的值設(shè)置為true。

現(xiàn)在我們完成了嗎?

實(shí)際上,還不完全是...

這個(gè)智能合約的代碼是寫(xiě)完了,但是我們?cè)趺从盟??現(xiàn)在是收獲果實(shí)的時(shí)候了。

8、solidity合約部署與交互

你的remix頁(yè)面看起來(lái)應(yīng)該像這樣:

solidity 0.5.7簡(jiǎn)明教程

在remix頁(yè)面右邊切換到compile選項(xiàng)頁(yè),確認(rèn)按下圖選中編譯器的版本,然后點(diǎn)擊[start to compile]:

solidity 0.5.7簡(jiǎn)明教程

你可能會(huì)看到靜態(tài)分析生成的一個(gè)藍(lán)色文本框,我們暫時(shí)忽略它的提醒,切換到run選項(xiàng)頁(yè):

solidity 0.5.7簡(jiǎn)明教程

確保Environment下拉框中選中了Javascript VM,點(diǎn)擊account的下拉菜單將顯示5個(gè)測(cè)試賬戶,每個(gè)賬戶都有100個(gè)以太幣,讓我們選擇第一個(gè)。

向以太坊區(qū)塊鏈部署合約并不是免費(fèi)的,部署者需要支付手續(xù)費(fèi),通常被稱為gas。引入這一機(jī)制的目的是避免區(qū)塊鏈計(jì)算資源被惡意濫用,要進(jìn)一步了解gas,可以查看這篇文章:1分鐘搞清Gas/ Gas Price/ Gas Limit。

gas limit字段使用默認(rèn)值就可以了,我們先不修改它。

value字段表示我們?cè)诓渴鸷霞s時(shí)要發(fā)送給合約的以太幣數(shù)量。輸入50,還記得我們?cè)诙x構(gòu)造函數(shù)時(shí)附加的payable關(guān)鍵字嗎?

現(xiàn)在繼續(xù),點(diǎn)擊[deploy]。

你可能立刻會(huì)注意到3件事。首先,選中的賬戶余額現(xiàn)在變成了49.9999… ,這是因?yàn)槲覀冝D(zhuǎn)給合約50個(gè)以太幣,還要扣除一點(diǎn)部署手續(xù)費(fèi)。頁(yè)面底部的控制臺(tái)也會(huì)提供關(guān)于部署過(guò)程的詳細(xì)信息,你可以查看一下。現(xiàn)在看起來(lái)是這樣:

solidity 0.5.7簡(jiǎn)明教程

我們的合約已經(jīng)成功部署了!它生成了自己的地址,并且顯示出我們定義的兩個(gè)合約方法。作為合約的持有者,我們要做的第一件事,是設(shè)置家庭成員的繼承數(shù)量:康萊德(20)、麗莎(30)。假設(shè)我們用account下拉菜單中的第二個(gè)作為康萊德的賬號(hào),麗莎的用第三個(gè)。

選擇第二個(gè)賬號(hào),點(diǎn)擊[拷貝到剪切板]圖標(biāo),然后輸入上圖中的setInheritance后面的文本輸入框。

在我們執(zhí)行setInheritance方法之前,有幾件事情要記住。

傳入合約的以太幣數(shù)量的單位是wei而不是以太幣,1 ETH = 1,000,000,000,000,000,000 WEI,這是非常小的單位,因此我們需要將以太幣表示的遺產(chǎn)數(shù)量先轉(zhuǎn)換為以WEI為單位的值。

在將遺產(chǎn)數(shù)量換算后,在將其寫(xiě)入上圖中的setInheritance后面的文本輸入框中,之前輸入的地址后面,這兩個(gè)值之間注意要用逗號(hào)隔開(kāi)。

還有,別忘了在account下拉框選中第一個(gè)賬號(hào),還記得onlyOwner修飾符嗎?只有合約的持有人才可以調(diào)用setInheritance方法!

現(xiàn)在讓我們依次為康萊德和麗莎執(zhí)行setInheritance方法。你應(yīng)當(dāng)可以看到控制臺(tái)輸出的成功信息。看一下其中的decoded input

solidity 0.5.7簡(jiǎn)明教程

你看,它顯示的就是我們輸入的數(shù)據(jù)。

遺產(chǎn)分配好了,但是壞消息來(lái)了。老爺爺在73歲時(shí),在一次北極探險(xiǎn)中不幸因心臟病突發(fā)去世。他總是這么充滿激情與活力。

當(dāng)我們紀(jì)念這位老爺爺?shù)耐瑫r(shí),我們同時(shí)調(diào)用遺囑合約的deceased()方法,完成老爺爺?shù)淖詈蟮脑竿?。。?/p>


原文: solidity 0.5.7簡(jiǎn)明教程

匯智網(wǎng)翻譯整理,轉(zhuǎn)載請(qǐng)標(biāo)明出處

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI