Gravity bridge——IBC Bridge to Ethereum
1. 引言
前序博客有:
- Cosmos IBC
- The Interblockchain Communication Protocol: An Overview
- Cosmos IBC如何異構跨鏈
Gravity由Osmosis network開發,為以太坊 與 Cosmos生態鏈 之間的bridge,可實現token之間的相互轉換。不同于其它bridge,Gravity采用IBC協議,為完全非監管的,僅需要信任Cosmos chain的安全性,而不需要信任任何第三方的bridge管理員,這些bridge管理員存在攜款潛逃的可能。【Osmosis采用Cosmos SDK中標準的DPoS staking 機制。為了便于表達,后續將Osmosis統稱為Cosmos。】
Gravity相關代碼見:
- https://github.com/Gravity-Bridge/Gravity-Bridge(更新)
- https://github.com/cosmos/gravity-bridge(old)
其中在全節點端運行的orchestrator代碼實現有:
- https://github.com/InjectiveLabs/peggo(Injective Chain)
- https://github.com/umee-network/peggo( Umee network)
- https://github.com/celestiaorg/quantum-gravity-bridge(Celestia)
借助Gravity,為:
- 給以太坊上的Gravity合約發送25 DAI,指定接收的Cosmos地址。
- Cosmos鏈上的Validators看到你確實已往以太坊的Gravity合約中發送了25 DAI,在Cosmos接收地址mint 25 DAI。
- DAI可發送給Cosmos中的其他賬號,用于Cosmos應用、或者通過IBC發送給其它Cosmos鏈等等。
- 為了返回以太坊,可將25 DAI發送給Cosmos鏈上的Gravity module,指定接收的以太坊地址。
- Cosmos validators會burn掉Cosmos鏈上的這25 DAI,然后向以太坊上的Gravity.sol合約發起交易,將25 DAI發送給以太坊接收地址。
2. Gravity
Gravity由4部分組成:
- 以太坊上的 Gravity.sol 合約
- Cosmos上的 Gravity module
- 由Cosmos validators 運行 的隨Cosmos區塊鏈代碼一起運行的orchestrator(編配)程序
- a market of relayers:這些relayers會競爭,代替Cosmos validators來向以太坊提交交易。
2.1 以太坊端的Gravity.sol合約
Gravity.sol合約的主要作用為鎖定以太坊鏈上的ERC20 token,使得其可在Cosmos上mint出來。
當前的Cosmos validators 控制Gravity.sol,具體控制比例取決于其在Cosmos鏈上的validation power。
Gravity.sol中存儲了a checkpoint——對應為the active validator set on the Cosmos side at a given moment in time。
a checkpoint為a set of addresses and their validation power。The more validation power an address has, the more its vote counts。
Gravity.sol中的method為public的,可由任意relayer調用,但是必須包含超過2/3+的當前checkpoint的validator set的簽名。
2.1.1 updateValset
由于Osmosis上的validator set總是在變化,隨著Osmosis token持有者將其token委托給不同的validator,validator的power會變化。Cosmos validators會調用Gravity.sol合約中的updateValset方法來更新its stored checkpoint to the latest validator set。若某validator未對an update進行簽名,或者更糟的是,對欺詐update進行簽名,則會被slash掉,損失其在Cosmos鏈上的資產。
2.1.2 sendToCosmos
用戶會調用Gravity.sol合約的sendToCosmos方法來將以太坊的token轉移至Cosmos。該方法會從用戶那接收一定數量的ERC20 token然后鎖定在Gravity.sol合約內,同時會釋放an event,使得Cosmos validators知道其應在Cosmos端為該用戶mint相應數量的token。
2.1.3 submitBatch
當用戶將Cosmos鏈上的token發送給Gravity module,并指定了以太坊端的接收地址。
用戶可attach a fee to compensate whoever relays their transaction。
為了節約gas費,由Cosmos發往以太坊的token是以批量進行的。
Gravity module會創建batches of transactions of one type of token,然后validators對這些batches進行簽名。
Relayers會調用Gravity.sol合約的submitBatch方法來提交batches:
- 首先檢查該batch has signatures from 2/3+ of the validator set in the current checkpoint。
- 然后檢查該batch具有a nonce that is higher than any other batch of the same token type that was already submitted。
- 然后send ERC20 Ethereum transactions transferring the tokens to their destinations。Gravity.sol也可send the fees on the transactions to msg.sender(即發起該交易的relayer)。
2.2 Cosmos端的Gravity module和orchestrator程序
Gravity module為基于Cosmos SDK構建的module,Cosmos鏈上包含了大量類似的module,由其validators同步運行。
每個validator 與 其它validators 運行的都是完全一樣并確定性的邏輯。這些validators對a key-value store的狀態達成共識,不同的的modules可具有狀態的不同部分。
Gravity module負責在Cosmos鏈上mint代表以太坊ERC20 token的Cosmos token。
Gravity module會與orchestrator緊密合作。orchestrator會在每個validator上,與Cosmos代碼一起運行。由于每個validator的cosmos module都是以相同的邏輯同步運行,因此,無法sign messages or transactions with a validator’s unique key。但是,安裝了Gravity module的validators借助orchestrator,可實現簽名操作。
2.2.1 Ethereum oracle
Gravity module必須知道what is going on on the Ethereum chain,從而才可mint tokens on Cosmos for people when they send tokens to the Gravity.sol contract on Ethereum,同時可see when a batch of transactions going from Cosmos to Ethereum has been successfully processed。
Cosmos鏈上具有Gravity module的每個validator都必須運行一個以太坊全節點。每個validator的orchestrator會監聽該全節點的以太坊event。有一個名為EthBlockDelay的參數,orchestrator會監聽以太坊鏈上EthBlockDelay之前的事件。EthBlockDelay參數可讓validators放心該事件已在以太坊鏈上完全固化,當orchestrator看到來自于Gravity.sol合約的事件時,會將該事件放入a Cosmos message,簽名并廣播到Cosmos鏈上。
Gravity module會接收這些messages,并跟蹤哪些validators已對各個以太坊event進行了投票。當event收到了超過2/3的validation power選票時,可認為其是“observed”,然后可修改Cosmos state。
當a SendToCosmosEvent is observed,Gravity module會為目標地址mint tokens。
當 a TransactionBatchExecutedEvent is observed,Gravity module會從batch pool中移除該batch,并取消該token type的任何earlier batches。
2.2.2 Transaction batching
由Cosmos到以太坊的交易,在發送到以太坊鏈上之前,會打包為batches。主要原因在于以太坊鏈上交易費昂貴,通過批量操作可將交易費分攤至該batch內的所有交易。
當用戶想要將token由Cosmos發送到以太坊上某地址,用戶先將token發送到Gravity module。Gravity module會從用戶賬戶中扣除token,然后將一筆交易放入交易池中。交易池中存儲了所有由Cosmos到以太坊的待打包的交易。
任何人都可向Gravity module發送a transaction request來收集a batch of a particular token type。通常由relayers來發起,relayers可relay a batch of tokens for profit。當Gravity module收到該message時,其會按如下流程收集batch:
- Find all transactions for the token
- Choose the 100 transactions with the highest fee and put them in a batch. The number of transactions may not be 100 in future. It may be configurable, or even dynamic。
- If there is a batch in the batch pool with a higher sum of fees than the newly assembled batch, discard the new batch. If not, include it in the batch pool. More on this later.
然后Gravity module會將batch放入batch pool中。一旦某batch加入到batch pool中,所有validator的orchestrqtors都會對該batch進行簽名,并在Cosmos messages中提交簽名。每個簽名都會與其相應的batch一起存儲。
relayers會持續監測batch pool中的batches,一旦某batch的簽名數達到了Gravity.sol中當前checkpoint的validator set的2/3+,relayer就會將該batch提交到Gravity.sol。Relayers自身也可判斷提交某特定batch是否可獲利,然后選擇提交可獲利的batch。若batch中包含的 fee高于提交到以太坊所需的gas,則是可獲利batch。當然,這是一個非常微妙的計算,它考慮了以太坊鏈上當前的平均gas price、鏈上的擁堵以及代幣和以太坊gas之間的匯率。這就是為什么我們有一個自由的relayers市場。
一旦某batch在以太坊鏈上執行,Gravity.sol會釋放TransactionBatchExecutedEvent事件。以太坊EthBlockDelay個區塊之后,Cosmos validators會將該事件提交到Gravity module。當該event被fully observed(如上所述,即達到2/3+簽名),該batch將從batch pool中移除,因為該batch已處理完畢。同時,會將batch pool中具有更低batch nonce的該token類型batches也都移除。原因在于,我們確認這些更低batch nonce的batches將無法提交,因為其batch nonces are two low。這種機制支持被打包進unprofitable batches的交易 有機會再次打包進 profitable batch中。
如上所述,Gravity module僅打包a new batch if there are no batches already in the batch pool with a higher sum of fees。這可防止以下場景:
- 當交易池中有大量unprofitably low fee交易,隨后每個區塊來了少量具有high fee的交易,在每個batch中包含一筆high fee交易 和一堆unprofitable交易。
這樣的batch可能是unprofitable to submit,使得這些profitable交易因被打包進了unprofitable batches,而不被提交。
因此,要求每個new batch必須比現有待提交任何batch都更profitable,會給這種每個區塊中少量的profitable交易機會,可被打包進一個足夠profitable的batch中從而被提交。
3. Validator set updates
更新Gravity.sol中的validator set,與Cosmos當前的validator set一致。這一點很重要。
因為Gravity的trust model 要求 trusting Gravity.sol is the same as trusting the Cosmos chain running it。
valdiator set update必須有Gravity.sol中存儲的checkpoint中的當前validator set的2/3+簽名。
任何人都可發送a Cosmos message requesting a validator set update。當收到相應的request時,Gravity module會存儲當前validator set的snapshot。然后validators對該snapshot進行簽名。一旦達到Gravity.sol中當前checkpoint validator set的2/3+簽名,relayer即可將它提交到以太坊鏈上。需要注意以下幾點:
- Gravity module并不知道Gravity.sol中存儲的當前checkpoint。因為EthBlockDelay,Gravity module中所有關于以太坊的信息都是過時的。因此,需要依賴relayers來判斷某validator set update是否有足夠的簽名可提交。
- relayers提交validator set update并沒有激勵。不像transaction batch,此時沒有fees。后續更新可能會解決。有很多種方式可解決,在Cosmos端或以太坊端。但是目前,Cosmos鏈上運行Gravity的validators會設立一個無私的relayer,用于負責提交validator set updates。
- Gravity.sol不是Cosmos light client,其并不知道完整的Cosmos共識和質押流程。其本質是個多簽,其簽署中為某特定Cosmos鏈的validator set。我們在Cosmos端采用slash策略來保證正確性。
4. Slashing
Slashing為Gravity安全性的重要組成部分。Validators在Cosmos端或以太坊端若表現不正常,都會在Cosmos端進行Slash操作。This is what links the security of the Gravity bridge to the security of the Cosmos chain it is run on.
4.1 Liveness slashing for batches and validator sets
通過參與Cosmos共識流程,a validator隱式地聲明該流程生成的所有validator set update和batches都是正確的。若某validator未對validator sets和batches簽名,則該validator運行不正確。After a grace period,這種未簽名行為將被slash。
4.2 Slashing for fake batches and validator sets
可能會存在向Gravity.sol合約提交 不是由Cosmos鏈生成的 batches和validator sets,只要這些batches和validator sets達到Gravity.sol合約中當前checkpoint validator set 2/3+的簽名。為了防止惡意validators組成聯盟,通過偽造transaction batch或validator set update從Gravity bridge中竊取,Gravity會Slash簽名出現在(這些從未在鏈上生成的)batches和validator set updates中的validator。這是通過evidence機制實現的,任何人都可以在偽造的batch或valset上提交evidence of a signature,該鏈將slash相應的validator。
參考資料
[1] How Gravity works
[2] About Staking on Osmosis
總結
以上是生活随笔為你收集整理的Gravity bridge——IBC Bridge to Ethereum的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32单片机硬件I2C读取AHT10
- 下一篇: iOS 组件中设置文件支持MRC