1 系統(tǒng)合約
BSC 的核心在于 系統(tǒng)合約(solidity)拇勃,在 【BSC詳解】2——bsc relayer
分析可知伊滋,所有的跨鏈行為都是通過調(diào)用系統(tǒng)合約實現(xiàn)的,所以首先介紹一下部署在 BSC 上的系統(tǒng)合約狂巢。
system contract name | solidity | Address |
---|---|---|
ValidatorContract | BSCValidatorSet.sol | 0x0000000000000000000000000000000000001000 |
SlashContract | SlashIndicator.sol | 0x0000000000000000000000000000000000001001 |
SystemRewardContract | SystemReward.sol | 0x0000000000000000000000000000000000001002 |
LightClientContract | TendermintLightClient.sol | 0x0000000000000000000000000000000000001003 |
TokenHubContract | TokenHub.sol | 0x0000000000000000000000000000000000001004 |
RelayerIncentivizeContract | RelayerIncentivize.sol | 0x0000000000000000000000000000000000001005 |
RelayerHubContract | RelayerHub.sol | 0x0000000000000000000000000000000000001006 |
GovHubContract | GovHub.sol | 0x0000000000000000000000000000000000001007 |
TokenManagerContract | TokenManager.sol | 0x0000000000000000000000000000000000001008 |
CrossChainContract | CrossChain.sol | 0x0000000000000000000000000000000000001009 |
在 BSC 中系統(tǒng)合約直接通過 solidity 的 Hex code 進行部署。
1.1 預(yù)編譯合約
在介紹上述系統(tǒng)合約之前,首先需要介紹一下 預(yù)編譯合約澡谭。
預(yù)編譯合約是 EVM 中用于提供更復(fù)雜庫函數(shù)(通常用于加密纯命、散列等復(fù)雜操作)的一種折衷方法西剥,這些函數(shù)不適合編寫操作碼。 它們適用于簡單但經(jīng)常調(diào)用的合約亿汞,或邏輯上固定但計算量很大的合約瞭空。預(yù)編譯合約是在使用節(jié)點客戶端代碼實現(xiàn)的,因為它們不需要 EVM疗我,所以運行速度很快咆畏。 與使用直接在 EVM 中運行的函數(shù)相比,它對開發(fā)人員來說成本也更低吴裤。
在 Etheruem 中已經(jīng)實現(xiàn)了不少預(yù)編譯合約了旧找,比如下面這些:
Precompiled contract name | Features | Address |
---|---|---|
ecrecover() | Recovery of ECDSA signature | 0x1 |
sha256hash() | Hash function SHA256 | 0x2 |
ripemd160hash() | Hash function RIPEMD160 | 0x3 |
dataCopy() | Identify | 0x4 |
bigModeExp() | Modular exponentiation | 0x5 |
bn256Add() | Addition on elliptic curve alt_bn128 | 0x6 |
bn256ScalarMul() | Scalar multiplication on elliptic curve alt_bn128 | 0x7 |
bn256Pairing() | Checking a pairing equation on curve alt_bn128 | 0x8 |
在代碼層面,所謂的地址實際上是合約數(shù)組的索引麦牺,每一個索引唯一對應(yīng)一個預(yù)編一個合約钮蛛。在智能合約代碼中,可以像普通合約一樣在合約文件中直接調(diào)用預(yù)編譯合約剖膳,但調(diào)用方式有所不同:
assembly {
if iszero(call(gasLimit, contractAddress, value, input, inputLength, output, outputLength)) {
revert(0, 0)
}
}
總結(jié)來說魏颓,預(yù)編譯合約效率更高,成本更低吱晒,它們是無狀態(tài)的甸饱,而 solidity 智能合約是有狀態(tài)的,所以 BSC 使用智能合約保存數(shù)據(jù)仑濒,使用預(yù)編譯合約進行數(shù)據(jù)的處理和計算叹话。
BSC 中的預(yù)編譯合約定義如下:
// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
// contracts used in the Istanbul release.
var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{100}): &tmHeaderValidate{},
common.BytesToAddress([]byte{101}): &iavlMerkleProofValidate{},
}
BSC 新增了 tmHeaderValidate
合約和 iavlMerkleProofValidate
合約。
1.1.1 tmHeaderValidate
該合約主要用于驗證 BC 塊頭是否合法躏精,被 LightClientContract
系統(tǒng)合約調(diào)用渣刷,在后文一同進行講解。
1.1.2 iavlMerkleProofValidate
該合約主要用于驗證 BC 跨鏈數(shù)據(jù)包是否合法矗烛,被 CrossChainContract
系統(tǒng)合約調(diào)用辅柴,在后文一同進行講解箩溃。
1.2 系統(tǒng)合約
1.2.1 LightClientContract(TendermintLightClient.sol)
負(fù)責(zé)執(zhí)行 bsc-relayer 發(fā)送過來的“同步塊頭”的交易,和 tmHeaderValidate
預(yù)編譯合約一同工作:
-
LightClientContract
用于保存狀態(tài)數(shù)據(jù)
狀態(tài)數(shù)據(jù)如下碌嘀,其中涣旨,appHash
字段即為 BC 的根哈希。
type ConsensusState struct {
chainID string
height int64
appHash []byte
curValidatorSetHash []byte
nextValidatorSet *tmtypes.ValidatorSet
}
-
tmHeaderValidate
用于塊頭的校驗
LightClientContract
調(diào)用tmHeaderValidate
時股冗,將ConsensusState
和塊頭作為參數(shù)(這里的塊頭包括塊頭霹陡、當(dāng)前工作的 bc-validator 集合信息、下一輪更新的 bc
-validator 集合信息止状,可參考 【BSC詳解】2——bsc relayer)烹棉,tmHeaderValidate
通過ConsensusState
中的nextValidatorSet
校驗塊頭中的 BLS 簽名以及投票是否正確,若正確則使用塊頭的數(shù)據(jù)更新ConsensusState
怯疤,返回給LightClientContract
進行更新保存浆洗。
1.2.2 CrossChainContract(CrossChain.sol)
負(fù)責(zé)執(zhí)行 bsc-relayer 發(fā)送過來的“同步跨鏈數(shù)據(jù)包”的交易,和 iavlMerkleProofValidate
預(yù)編譯合約一同工作:
iavlMerkleProofValidate
用于跨鏈數(shù)據(jù)包的校驗
跨鏈數(shù)據(jù)包中包含兩個內(nèi)容:msg
和merkle proof
集峦,CrossChainContract
調(diào)用iavlMerkleProofValidate
時伏社,將 1.2.1 中的appHash
、msg
塔淤、merkle proof
摘昌,通過默克爾證明算法驗證這個msg
時合法的。
這里也說通了為什么在 【BSC詳解】2——bsc relayer
中同步跨鏈數(shù)據(jù)包前需要先同步塊頭高蜂,因為需要更新appHash
聪黎,只有高度 H+1的appHash
才能進行完成高度 H 的msg
的默克爾證明。CrossChainContract
用于調(diào)用相關(guān)的業(yè)務(wù)合約
在校驗完成后妨马,根據(jù)msg
的類型挺举,分別進行其它不同的系統(tǒng)合約的調(diào)用,完成相應(yīng)的業(yè)務(wù)烘跺。
1.2.3 ValidatorContract(BSCValidatorSet.sol)
用于 BC 更新 bsc-validator 集合。
1.2.4 SlashContract(SlashIndicator.sol)
用于懲罰違規(guī)操作的 bsc-validator脂崔。
1.2.5 SystemRewardContract(SystemReward.sol)
記錄 bsc-relayer 的 reward 數(shù)據(jù)滤淳。
1.2.6 TokenHubContract(TokenHub.sol)
用于 BC 與 BSC 的跨鏈 token transfer。
1.2.7 RelayerIncentivizeContract(RelayerIncentivize.sol)
用于 bsc-relayer claim reward砌左。而 bsc-validator 的 reward 為打包出塊的 tx 的 gas脖咐。
1.2.8 RelayerHubContract(RelayerHub.sol)
用于記錄 bsc-relayer 的注冊信息。
1.2.9 GovHubContract(GovHub.sol)
處理來自 BC 上的鏈上治理數(shù)據(jù)汇歹。
1.2.10 TokenManagerContract(TokenManager.sol)
用于 BC 和 BSC 兩邊 token 的綁定屁擅。
1.2.11 總結(jié)
- 對于跨鏈來說只需要
LightClientContract
和CrossChainContract
兩個合約的調(diào)用即可,其它的業(yè)務(wù)操作都是通過CrossChainContract
調(diào)用其它的合約實現(xiàn)的产弹。 -
BSC 完全受 BC 管理派歌,bsc-relayer 完全受 BSC 管理。
2 共識
2.1 Parlia
BSC 采用的 PoSA(Proof of Stake Authority) 共識算法。bsc-validator 節(jié)點輪流出塊胶果,如果出塊時間不符合預(yù)期或者不符合出塊順序匾嘱,則相應(yīng)的節(jié)點將會被懲罰。
對于安全性的考量早抠,官方解釋如下
Given there are more than 1/2*N+1 validators are honest, PoA based networks usually work securely and properly. However, there are still cases where certain amount Byzantine validators may still manage to attack the network, e.g. through the “Clone Attack”. To secure as much as BC, BSC users are encouraged to wait until receiving blocks sealed by more than 2/3*N+1 different validators. In that way, the BSC can be trusted at a similar security level to BC and can tolerate less than 1/3*N Byzantine validators.
With 21 validators, if the block time is 5 seconds, the 2/3*N+1 different validator seals will need a time period of (2/3*21+1)*5 = 75 seconds. Any critical applications for BSC may have to wait for 2/3*N+1 to ensure a relatively secure finality. However, besides such an arrangement, BSC does introduce Slashing logic to penalize Byzantine validators for double signing or instability. This Slashing logic will expose the malicious validators in a very short time and make the Clone Attack very hard or extremely non-economic to execute. With this enhancement, 1/2*N+1 or even fewer blocks are enough as confirmation for most transactions.
總結(jié)來說霎烙,對于 輕客戶端 無法驗證執(zhí)行塊的驗證操作,只能被動接收 全節(jié)點 的數(shù)據(jù)蕊连,為了避免遭受攻擊悬垃,只有當(dāng)一個塊后面的 2/3*N+1 個塊都接收到了(N 為 bsc-validator 的數(shù)量),才能基本保證當(dāng)前這個塊是被確認(rèn)的甘苍、有效的趣席,而 全節(jié)點 可以對塊進行計算驗證孝扛,并選擇正確的最長鏈進行延申出塊。這個實質(zhì)上就是 PoW 的最長合法鏈原則。
2.2 Epoch
Epoch 為更換共識節(jié)點的間隔椒惨,當(dāng)前值為 200,也就是說每 200 個 block 會生成 1 個 epoch block刻炒。每個 epoch block 出塊時堤框,會查詢保存在 1.2.3 中 ValidatorContract
合約最新的 bsc-validator 集合信息,并寫入 bsc 塊頭中的 extra_data
字段中靡挥。
與 2.1 中對于安全性的考量類似序矩,需要等待一段時間,直到 Epoch block 確認(rèn)后跋破,才會真正更新全局的 bsc-validator 集合簸淀。在 BSC 中,這個等待為 epoch+N/2 個 blocks(N 為 bsc-validator 的數(shù)量)毒返,在此之后租幕,epoch block 中新的 bsc-validator 集合才會正式變更生效。
參考
https://github.com/bnb-chain/bsc
https://github.com/bnb-chain/bsc-genesis-contract