Oracle分類按照同步與非同步方式,Oracle大體上可以分為:● 多筆交易,非同步方式例如,user request交易先上鍊,Oracle response 交易再上鍊,最後觸發再出發使用者真的任務執行。比如傳統的Oracle採用回撥方式,Oracle response上鍊後執行使用者的回撥任務。● 多筆交易,同步方式比如,user request先被廣播,但將處於等待狀態,當Oracle節點發出Response交易時,再將request交易放在response後打包上鍊執行。● 一筆交易拓展user request交易,再將Oracle節點請求到的資料,存入到requset交易或區塊的拓展欄位中,再打包上鍊執行。今天我們將介紹一種,使用鏈上條件定時器來實現同步方式的Oracle。條件定時器概念定義● 物件特定的交易才能觸發定時器(指定交易的Sender或交易hash),不像傳統定時器,在區塊鏈上,任務的觸發執行,都需要交易進行觸發。● 條件在特定物件交易中,呼叫時所進行的條件檢查,使用者可以自定義設定檢查條件,如Oracle的response資料閾值條件等。● 任務一個任務即是在條件定時器中註冊的交易,當條件被滿足時,將觸發該交易的執行。一個任務必須在條件定時器中被註冊,可透過在交易的聯合簽名者列表中(Tx.Cosigner)新增條件定時器合約的hash值。該任務(交易)將被當成普通交易打包上鍊,以及被收取費用,但是不會被立刻執行。只有當條件定期器被觸發時,才會被自動執行該交易。一些約束條件● 一個物件只能觸發一個任務執行● 一個任務只能被觸發一次● 在任務執行過程中,不能再觸發別的任務執行● 需要支付一定費用來註冊條件定時器概括之,鏈上條件定時器,註冊在條件定時器的交易(尚未執行),當被後續的某一筆交易滿足其觸發條件時,將觸發之前註冊的交易進行執行。一個條件定時器原生合約定義示例:class ConditionTimerContract: NativeOnctract{ private Map<Task, Object> timers; private List<Task> triggeredTasks; public bool verify(){ // verify the tx.fee >= basic fee } protected registerTimer(task, object){ // Only can use native transaction to register or other native contract } public bool activeTimer(task.hash){ // check object } @override public list<tx> PreExecuteBlock(blockTxs){ // register condition timer... registerTimer(task, object) } @override public void PostExecuteBlock(blockTxs){ // execute tasks which be triggered }}工作原理原生合約作為一種系統內建的合約,具有相對比較大的許可權,可以在區塊執行前後做一些特殊的任務操作。原生交易是一種特殊的交易,交易發起者(Tx.Sender)或聯合簽名者(Tx.Cosigner)包含原生和合約的hash值,即原生交易。然後,我們將介紹透過使用原生合約的條件定時器(ConditionTimerContract)和Oracle(OracleContract)設計方案。Oracle的工作流程
1. 首先,使用者傳送Oracle Request交易,設定OracleContract.hash作為該交易的聯合簽名者, 實際上該交易將作為原生交易。
2. Request交易,將被當成普通交易打包上鍊。
3. 由於是原生合約,區塊執行前,將觸發OracleContract將會呼叫條件定時器合約ConditionTimerContract的註冊方法registerTimer, 完成該Requset交易的註冊,並從待執行交易列表中移除,其意味著該交易不會被當前區塊所執行。
4. 當Oracle nodes檢測到新區塊包含Request請求交易時,開始請求資料,併傳送攜帶資料和簽名的Response交易上鍊。
5. Response交易作為普通交易,上鍊執行時,將會呼叫OracleContract的AddResponse方法,將Oracle節點請求的資料收集起來。
6. 當Oracle的請求閾值條件被滿足時,將之前註冊的Request交易新增到可執行交易列表中,最終完成對使用者發起的Request交易執行,完成資料訪問請求。
鏈上聚合資料
無論我們選擇哪種Oracle的資料聚合方式,都需要將Oracle節點的資料跟簽名上鍊。因此,我們將採用鏈上聚合資料的方式,Oracle節點的Response訊息將被當成普通交易上鍊,將呼叫OracleContract的AddResponse方法。
聚合方式可以有很多種,這裡我們採用的是之前方案簽名閾值方法,詳情可參考:
https://github.com/neo-project/neo/issues/1273
其他處理流程,與普通的Oracle方式類似,就不再做詳細介紹。
優勢
1. 解決了同步等待問題,即使用者的Request交易不必等待Response交易後才能上鍊。
2. 對比起傳統回撥方式,保持了同步方法,對於合約開發者更加便捷。
劣勢
破壞了區塊鏈打包交易上鍊就執行的規則,執行順序具有不可預測性。
* 注意,該方案並非Neo3最終實施方案,而是開發過程中一些發現解決鏈上同步問題的一種可能方式。