設計模式是許多開發場景中的首選解決方案,本文將介紹五種經典的智慧型合約設計模式並給出
以太坊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 的正規化理解,意思是那些智慧型合約...