以太坊solidity智慧型合約設計模式

2021-08-19 15:35:25 字數 3552 閱讀 2476

設計模式是許多開發場景中的首選解決方案,本文將介紹五種經典的智慧型合約設計模式並給出

以太坊solidity實現**:自毀合約、工廠合約、名稱登錄檔、對映表迭代器和提款模式。

合約自毀模式用於終止乙個合約,這意味著將從區塊鏈上永久刪除這個合約。 一旦被銷毀,就不可能呼叫合約的功能,也不會在賬本中記錄交易。

現在的問題是:「為什麼我要銷毀合約?」。

有很多原因,比如某些定時合約,或者那些一旦達到里程碑就必須終止的合約。 乙個典型的案例

是貸款合約,它應當在貸款還清後自動銷毀;另乙個案例是基於時間的拍賣合約,它應當在拍賣結束後終止 —— 假設我們不需要在鏈上儲存拍賣的歷史記錄。

在處理乙個被銷毀的合約時,有一些需要注意的問題:

為避免資金損失,應當在傳送資金前確保目標合約仍然存在,移除所有對已銷毀合約的引用。

現在我們來看看**:

contract selfdesctructioncontract  

// constructor

function

selfdesctructioncontract

() // a ****** setter function

function

setsomevalue

(string value)

// you can call it anything you want

function

destroycontract

()ownerrestricted

}

正如你所看到的,destroycontract()方法負責銷毀合約。

請注意,我們使用自定義的ownerrestricted修飾符來顯示該方法的呼叫者,即僅允許合約的擁有者銷毀合約。

工廠合約用於建立和部署「子」合約。 這些子合約可以被稱為「資產」,可以表示現實生活中的房子或汽車。

工廠用於儲存子合約的位址,以便在必要時提取使用。 你可能會問,為什麼不把它們存在web應用資料庫裡? 這是因為將這些位址資料存在工廠合約裡,就意味著是存在區塊鏈上,因此更加安全,而資料庫的損壞可能會造成資產位址的丟失,從而導致丟失對這些資產合約的引用。 除此之外,你還需要跟蹤所有新建立的子合約以便同步更新資料庫。

工廠合約的乙個常見用例是銷售資產並跟蹤這些資產(例如,誰是資產的所有者)。 需要向負責部署資產的函式新增payable修飾符以便銷售資產。 **如下:

contract carshop 

function getdeployedchildcontracts() public view returns (address)

}contract carasset

}

**address newcarasset = new carasset(...)將觸發乙個交易來部署子合約並返回該合約的位址。 由於工廠合約和資產合約之間唯一的聯絡是變數address carassets,所以一定要正確儲存子合約的位址。

現在想象一下,將所有這些合約的位址寫在你的應用**中。 如果這些合約的位址隨著時間的推移而變化,那該怎麼辦?

**如下:

contract nameregistry 

function

registername

(string name, address addr, uint16 ver)

returns

(bool) );

} else

// update record in the registry

registry[name] = info;

return

true;

}function

getcontractdetails

(string name)

constant

returns

(address, uint16)

}

很多時候我們需要對乙個對映表進行迭代操作 ,但由於solidity中的對映表只能儲存值,

並不支援迭代,因此對映表迭代器模式非常有用。 需要指出的是,隨著成員數量的增加,

迭代操作的複雜性會增加,儲存成本也會增加,因此請盡可能地避免迭代。

實現**如下:

string keys;

function

put(string key, address addr)

returns

(bool)

elements[key] = addr;

return true;

}function

getkeycount

()constant

returns

(uint)

function

getelementatindex

(uint index)

returns

(address)

function

getelement

(string name)

returns

(address) }

實現put()函式的乙個常見錯誤,是通過遍歷來檢查指定的鍵是否存在。正確的做法是

elements[key] == address(0)。雖然遍歷檢查的做法不完全是乙個錯誤,但它並不可取,

因為隨著keys陣列的增長,迭代成本越來越高,因此應該盡可能避免迭代。

假設你銷售汽車輪胎,不幸的是賣出的所有輪胎出問題了,於是你決定向所有的買家退款。

假設你跟蹤記錄了合約中的所有買家,並且合約有乙個refund()函式,該函式會遍歷所有買家

並將錢一一返還。

你可以選擇 - 使用buyeraddress.transfer()或buyeraddress.send() 。 這兩個函式的區別在於,

在交易異常時,send()不會丟擲異常,而只是返回布林值false ,而transfer()則會丟擲異常。

為什麼這一點很重要?

假設大多數買家是外部賬戶(即個人),但一些買家是其他合約(也許是商業)。 假設在這些買方合約中,有乙個合約,其開發者在其fallback函式中犯了乙個錯誤,並且在被呼叫時丟擲乙個異常,fallback()函式是合約中的預設函式,如果將交易傳送到合同但沒有指定任何方法,將呼叫合約的fallback()函式。 現在,只要我們在refund函式中呼叫contractwitherror.transfer() ,就會丟擲異常並停止迭代遍歷。 因此,任何乙個買家合約的fallback()異常都將導致整個退款交易被回滾,導致沒有乙個買家可以得到退款。

雖然在一次呼叫中退款所有買家可以使用send()來實現,但是更好的方式是提供withdrawfunds()方法,它將單獨按需要退款給呼叫者。 因此,錯誤的合約不會應用其他買家拿到退款。

實現**如下:

contract withdrawalcontract 

function

withdraw

() }

原文:5種經典的智慧型合約設計模式

智慧型合約 以太坊

智慧型合約是執行在可複製 共享的賬本上的電腦程式,可以處理資訊,接收 儲存和傳送價值。2.1 什麼是以太坊 以太坊 ethereum 是乙個分布式計算機,有許多的節點,其中的每乙個節點都會執行智慧型合約,然後把結果存在區塊鏈上。由於整個網路是分布式的,且應用就是乙個個的狀態組成,儲存了狀態就有了服務...

以太坊和智慧型合約

1 什麼是以太坊?以太坊的官方 告訴我們 以太坊是乙個執行著智慧型合約的分布式平台 應用程式完全按照程式執行,不存在故障 審查 欺詐或第三方干預的可能性 2 智慧型合約就是可以處理資金的指令碼。開發語言 solidity 整合開發工具ide remix,乙個基於瀏覽器的整合開發環境 開發框架 tru...

以太坊智慧型合約安全

智慧型合約就是自主執行的合約,其條款是用 規定的。雖然這個概念已經存在一段時間了,但至少從1996年nick szabo提出了這一概念以來,直到圖靈完備的以太坊區塊鏈來臨,智慧型合約的使用才變得普遍。對智慧型合約理念的字面解釋造成了 即法律 code is law 的正規化理解,意思是那些智慧型合約...