因為設計的目標是想盡可能的減少對於evm的更改,並且讓ethereum現有支援盡可能的可以support(如web3,solc之類的),所以除了研究ethereum smartcontract本身之外,我們還研究了babble的專案,babble是一個基於hash graph共識的拜占庭容錯系統,它提供了一個模組話的情境,去除掉ethereum有關於pow共識的部份改為使用hash graph來達成共識,它的共識保證了全部的節點會以一樣的順序處理相同的交易(透過hashgraph).
以下為其架構圖:
我們想解決的是在於物連網上的邏輯運算和微型支付會遇上的問題
我們知道iot可以收集資料,可以有簡單的邏輯運算
但是沒辦法追蹤資料的走向,來源,(可以中央式的解決這個問題),買賣資料(手續費成本的問題).
綜合以上兩點,我們希望能讓iot裝置處理支付時手續費低廉,又希望能提供一定的邏輯運算因此我們決定
採用tangle帳本上零手續費的特性,和選擇現階段比較成熟的ethereum smart contract為我們研究的目標
我們要解決的就是iota順序問題,對於合約,交易的順序是最為重要的合約的指令順序都是基於此,但是在iota的架構上,現階段並不強調交易的順序.
上一個章結題到iota本身並不在意交易的先後順序,但是我們要提供出一個方法可以讓各個節點之間共識一組順序,在開始介紹我們的架構之前,需要了解iota的milestone是如何運作的.
相關研究:iota的timestamp––->無法使用在這邊
iota現階段為了保護網路的健康狀態(ledger revert),使用了milestone來幫助帳本的finality,透過全部的節點紀錄著coordinator(hosted by iota fundation)的address(ISS+merkle root signature),持續追綜該地址所發出來的交易,此交易稱為milestone,節點們以milestone直接或者間接reference到的交易為帳本finality的基準.
節點間同步milestone的問題,每個節點都會記載著兩個變數lastmilestone_index和last_sub_tangle_milestone_index,分別代表著該節點最近接到最新的milestone,跟節點除了有這筆milestone之外還有他直接或間接reference到的交易,當這節點兩個數值不同時,便會開始同步(跟鄰居request他所欠缺的交易),讓last_sub_tangle_milestone_index追上lastmilestone_index.這是一個重構帳本的動作
我們的目的是讓節點們可以透過milestone算出一組順序,因為milestone是大家有共識的東西,所以這組順序也是有共識的.
1.首先在我們這個研究裡,coordinator是由我們所控制的,我們必須定義好coordinator在執行mcmc(markov chain monte carlo iota用來挑選驗證tip的演算法)時的起點必須是上一個index的milestone.並且必須是設在其trunktransaction的位置.
2.接下來看到節點同步的部分,當節點開始同步時,透過我們的算法,我們就可以訂出last_sub_tangle_milestone_index和lastmilestone_index之間的交易.
3.我們先沿著milestone的trunktransaction(優先)建立出樹的左子樹,其他的branchtransaction放在右子樹,接下來在透過dfs來經歷這棵樹,我們就可以得到一組順序,這邊有考慮到一個情境,就是每個節點的同步index並不一定,下面舉個例子來說明.
下圖是模擬出來的tangle網路狀況,綠色的交易是milestone,其他的為普通交易,我們假設交易0的milestone index是0,交易4的index是1,交易8的index是2,因為網路的狀況不穩定,可能會掉包,導致以下的情境,nodeA跟nodeB的last_sub_tangle_milestone_index都是index0,因為網路的關係,nodeA先接到index1,nodeB先接到index2,在這個情況下他們算出來的順序交集的部分必須是一樣,這個例子的交集就是(0,1,4)三筆交易,就是因為這個需求我們才制定了第二點關於coordinator的行為,因為milestone交易都是coordinator發出的,他本身並不存在掉包的問題,所以我們沿著trunktransaction一定能走回上一個index的milestone,所以即使節點們在同步時並沒有照著順序我們也可以保證結果的正確性.
iota的地址因為不能重用,所以很難紀錄著一個身份,所以我們設計了一個可以給地址另一個別名的系統架構,來達到我們的目的.
這個概念就是在iota的地址上面附加上一個可以辨別身份的別名:
1.首先這個別名在iota的系統上必須是獨一無二的,在系統裡不該有重複的別名.
2.這個別名要跟seed或address沒有關係.別名不能是seed或者address做任何運算的產物,因為都會有洩漏私鑰的風險
3.不能透過第三方來處理,我們不會希望在加入一個centralized的機制在我們的架構裡
所以我們是透過交易來附加別名上去的,每個節點在db會有新的欄位來儲存相關資訊,為了第一點交易必須有明確的順序(才可以辨別出誰先提出申請的),可以透過我們上面提到的方法來取得交易順序.
各節點執行完合約之後會有一vm state,如何保證vm state的finality會是一個問題
要跟別人比對自己執行完的hash很困難
iota的節點狀態,沒有辦法跟其他大多數的節點溝通
為了速度才這樣設計的,是他的優勢,允許subtangle的存在
在這個架構裡面,各節點的block大小是不一致的,取決於他收到哪個milestone和同步到哪個milestone
要如何保證我們的執行結果是對的
輸入evm的tx是被iota的consensus保證的
我們是一個非同步的網路,因此節點並不會看到一樣的交易集合
但是透過milestone各節點承認的交易集合是唯一的
問題在於根據這些交易為輸入,節點執行完的合約狀態是否要比較
先討論會在同樣的輸入同樣的環境之下合約執行狀態會不一致的情況,
惡意節點,改變了合約狀態,但是他無法說服正常節點跟他一樣就沒意義
自己的節點出錯,確保evm真的是沙盒,這部分不討論
規定coordinator的行為,發初milestone時必須附上執行到該輪的vmstate hash
其他node接收到milestone時會去跟這個結果做比對
分兩種情形做討論
一致
不一致
雖然會有太依賴coo的問題,但是現在的系統是會work的,其他潛在風險不在這邊討論
在節點同步的過程中我們會得到交易的順序,把跟contract有關的交易挑出來打包成區塊,再丟進去evm,詳細的架構圖如下:
保留ethereum大部分的原行,抽換掉了原本依靠pow出塊的部分,根據iota的milestone來給予區塊,ethereum角色為執行合約的環境,所以裡面的帳本狀態跟iota不會一致
iota好的節點只要做好自己的事,就能得到跟大家有共識的結果,壞的節點沒辦法說服好的節點,所以合約的結果並不需要比較,這是跟ethereum本質上的不同
ethereum internal transaction的分析方式,有可以透過分析process block之後的狀態來訂出來,比較直接的方式是在evm裡面加入紀錄點,監控以下幾個op code來構建internal transaction
CREATE
CALL
CALLCODE
DELAGATECALL
SUICIDE
部屬合約
1.deploy contract for 100000wei
觸發合約
2.Contribute 499 wei from
3.檢查結果
curl -H "Content-Type:application/json" -X POST http://127.0.0.1:8080/call -d '{"from":"0xea95c7dce6c1362ccbdd959077fb60e17282b117","value":0,"to":"0xaa5a69fa1ff5c282ca808f145941c2da90c39526","data":"0x01cb3b20"}'
取錢
當以後iota的網路沒有coodinator之後,
可以留著當作輔助這套系統運作的基準
如何產生internal transaction
為何不需要比對
講一下snapshotindex的事情
關於EVM保留的行為
關於contract creation:
因為創造合約地址的交易是iota共識時就已定下來
所以使用一個新的boolean值來表明contractcreation的意願
doi:10.6342/NTU201802130