015:合約結(jié)構(gòu)|《ETH原理與智能合約開發(fā)》筆記

待字閨中開發(fā)了一門區(qū)塊鏈方面的課程:《深入淺出ETH原理與智能合約開發(fā)》,馬良老師講授。此簡書文集記錄我的學(xué)習(xí)筆記。

課程共8節(jié)課。其中,前四課講ETH原理,后四課講智能合約。
第五課分為三部分:

  1. Dapp用例
  2. 合約結(jié)構(gòu)
  3. Solidity語法

這篇文章是第五課第二部分的學(xué)習(xí)筆記:合約結(jié)構(gòu) 。


這節(jié)課主要講解了智能合約結(jié)構(gòu)、ERC20、ERC721規(guī)范。

1、智能合約結(jié)構(gòu)

1.1 智能合約的結(jié)構(gòu)

智能合約的源代碼由以下7個部分組成。

  1. 版本聲明
    在以太坊的solidity編程語言中,各個大版本之間不具有兼容性,所以需要在開頭聲明版本號。不能在之前或之后的版本中運行,如pragma solidity ^0.4.x,不能在0.3或0.5的系統(tǒng)中運行。

  2. 包含其它代碼文件:import
    可以引入其它文件或者庫。

  3. 合約的定義
    使用關(guān)鍵字contract,后面跟上合約的名字。contract 合約名

  4. 存儲狀態(tài)變量
    這部分內(nèi)容需要存儲在Storage Root中。(第3課)

  5. 構(gòu)造函數(shù)
    它是一類很特殊的函數(shù),它在合約被創(chuàng)建的交易中被執(zhí)行一次,函數(shù)名需要與合約名相同。(與C++的構(gòu)造函數(shù)類似)

  6. 調(diào)用接口函數(shù)
    提供給其它賬戶調(diào)用。

  7. 事件
    用于記錄關(guān)鍵這個步驟與信息。

1.2 智能合約的ABI

開發(fā) DApp 時要調(diào)用在區(qū)塊鏈上的 Ethereum 智能合約,就需要智能合約的 ABI。ABI(Application Binary Interface)主要是規(guī)范外部賬戶與合約之間二進(jìn)制數(shù)據(jù)的編碼規(guī)范。

要調(diào)用一個合約特定的接口,首先要有合約的地址。在這個合約眾多的接口中,怎么找到需要調(diào)用的那一個,這就要用到函數(shù)簽名。函數(shù)的簽名由函數(shù)名與所有參數(shù)類型組成(返回值類型不算在內(nèi)),編碼的前四個字節(jié)是函數(shù)簽名的Keccak256 單向散列值的前四字節(jié)。如:function baz(uint32 x, bool y)這個函數(shù),其編碼的前四個字節(jié)是baz(uint32,bool)經(jīng)過Keccak256計算后,再取前四個字節(jié)0xcdcd77c0。從第五字節(jié)開始對輸入的實際調(diào)用參數(shù)進(jìn)行編碼,并補(bǔ)齊32字節(jié)。比如例子中的x, y分別取值0x88,0x1,補(bǔ)齊32字節(jié)。

1.3 通過 remix 介紹合約結(jié)構(gòu)

1.3.1 一個小例子

打開remix網(wǎng)站,自帶一個例子程序。→Remix

remix中的合約例子

此外,老師的例子開頭處,比我的多了兩行,導(dǎo)入其它文件。分別是導(dǎo)入github上的文件,和導(dǎo)入本地的文件。

import "github.com/ethereum/dapp-bin/library/iterable-mapping.sol";
import "./test.sol";

1.3.2 solidity中的注釋

有三種。
/*注釋*/,類似于C語言中的注釋;
//注釋,類似于C++中的注釋;
///注釋,也可以三個斜杠,主要用于函數(shù)前,說明函數(shù)作用。

1.3.3 remix的使用

remix是一個強(qiáng)大的IDE(Integrated Development Environment ,集成開發(fā)環(huán)境)。

中間是代碼區(qū),右邊有六個表單。

  1. Compile
    編譯,可以設(shè)置為自動編譯,修改后自動執(zhí)行。

Detail按鈕可以查看該程序的詳細(xì)信息。點開彈出。其中,METADATA是該程序的元數(shù)據(jù),含有編譯器的版本,和其它的一些數(shù)據(jù)等。這里關(guān)注一下ABI數(shù)據(jù)。它是關(guān)于接口的,點開具體的接口,可以看到接口的名字,輸入和輸出等。

  1. Run
    運行代碼。

它提供了三種運行環(huán)境,自己練習(xí)可以選用JavaScript VM,在本地運行,速度快。它自動提供了5個賬號,每個都含有100ETH。Gas limit是發(fā)起合約的Gas上限;Value是發(fā)送以太幣到一個合約時發(fā)送的數(shù)量。

Deploy布署一個合約。代碼區(qū)的下面,有控制臺可以看到合約執(zhí)行情況。

  1. Settings
    設(shè)置。主要是設(shè)置編譯器的版本。

  2. Analysis
    分析。主要是一些安全性的分析,比如Gas的數(shù)量,使用情況;還有一些雜項。

  3. Debugger
    調(diào)試。后面在具體的例子中再介紹。

  4. Support

2、ERC 20 規(guī)范

前面介紹的DApp例子中,大部分使用了ERC 20 規(guī)范。
官方文檔:ERC20規(guī)范

這個規(guī)范有六個接口是強(qiáng)制必須實施的。

  1. totalSupply()總的供給量
  2. balanceOf(address tokenOwner)查詢某一地址的余額
  3. approve(address spender, uint tokens) 代幣擁有者授權(quán)某地址,可以在未來多次從擁有者的賬戶使用代幣。它有一點安全問題,即授權(quán)數(shù)量要改變時,需要先改為零,再改為更改的值。
  4. allowance(address tokenOwner,address spender)查詢操作,查詢一個代幣的擁有者,還可以允許支出者花費多少代幣。這個跟前面的approve有關(guān)。
  5. transferFrom(address from, address to,uint tokens) 授權(quán)的地址從擁有者那里花費代幣,也和approve結(jié)合使用?;ㄙM的數(shù)量要小于授權(quán)的數(shù)量,如果大于則失??;地址輸入錯誤,也會失敗。
  6. transfer(address to, uint tokens) 轉(zhuǎn)移代幣,把自己的代幣移給目標(biāo)地址。

還有三個可選操作。name() , symbol(), decimals(),分別是名稱,符號,可以分割的程度,如18,1ETH可以分割為10^18份。

還有兩個事件。event Transfer(address from, address to, uint256 value),event Approval(address owner, address spender, uint256 value),分別是記錄Transfer和Approval的操作。

ERC20本質(zhì)說明

說明一下ERC20規(guī)范的本質(zhì)。它其實是維護(hù)了兩張表。

一張是每個地址對應(yīng)了多少代幣,如左圖。所有余額加起來就是總的供給量。轉(zhuǎn)移代幣是把一個地址的余額減少一定的數(shù)值,另一個地址增加相應(yīng)的數(shù)值。查詢余額就是從這張表中查詢。

另一張表是如右圖的樣子,包含了許可的賬戶及許可額。再說明一下許可(Approval)的意義。假如合約A調(diào)用合約B,如果在調(diào)用前直接把代幣打到B,B收到幣后會有不執(zhí)行合約的風(fēng)險,因此不能先直接給B轉(zhuǎn)移代幣。ERC20的做法是分為兩步,先授權(quán)B一定額度的代幣,B執(zhí)行時,從A那里支取代幣。因為額度預(yù)先分配了,所以轉(zhuǎn)移會成功。

3、ERC 721 規(guī)范

官方文檔:ERC721規(guī)范

ERC 20 和ERC 721 的不同,可以做一個類比。ERC 20 可以類比為現(xiàn)實中的錢幣,你的5塊錢和我的5塊錢是等價的,沒有什么不同。我們的錢還都可以再細(xì)分。而ERC 721,主要是用在游戲中的道具,比如以太坊中的加密貓游戲,你的貓和我的貓是不一樣的。我們的貓也不能分割為半只貓。每只貓都有不同的特性,是非同質(zhì)的。

在數(shù)據(jù)結(jié)構(gòu)上,其本質(zhì)與ERC 20 沒有太大的區(qū)別,也是維護(hù)兩張表。具體內(nèi)容如下。

  1. balanceOf(address tokenOwner) 一個地址下的余額;
  2. ownerOf(uint256 tokenId) 從一個ID查詢其主人是誰;
  3. safeTransferFrom(address from, address to, uint256 tokenId, bytes data) 轉(zhuǎn)換操作,把代幣轉(zhuǎn)移到合約;
  4. safeTransferFrom(address from, address to, uint256 tokenId) 轉(zhuǎn)換操作,把代幣轉(zhuǎn)移到地址;
  5. transferFrom(address from, address to, uint256 tokenId) 傳統(tǒng)的轉(zhuǎn)移方式;

3、4和5兩種方式的區(qū)別,5不檢查接收者是否為一個合約地址,而3和4會檢查接收者是否為合約地址,還會校驗地址。

  1. approve(address approved, uint256 tokenId) 授權(quán)某一地址一定的代幣;

  2. METADATA (Name, SYM, URI) 元數(shù)據(jù):名稱,符號,超鏈接。鏈接可以指向一張圖片,如加密貓的外觀圖。

  3. setApprovalForAll(address operator, bool approved) external; 允許一個地址完全控制自己的代幣;

  4. getApproved(uint256 tokenId) 查詢哪個賬戶有一個ID的許可權(quán);

  5. isApprovedForAll(address owner, address operator) 查詢一個地址是否擁有一個地址所有的操作權(quán)。

還有三個事件,對應(yīng)操作發(fā)生時負(fù)責(zé)記錄下日志。

  1. event Transfer(address indexed from, address indexed to, uint256 tokenId)
  2. event Approval(address owner, address _approved, uint256 _tokenId)
  3. evnet ApprovalForAll(address owner, address operator, bool approved)

總結(jié)一下,這節(jié)課主要介紹了智能合約結(jié)構(gòu)、ERC20、ERC721規(guī)范,還簡要介紹了Remix的使用。


不足之處,請批評指正,感謝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容