Polygon早期名为Matic。
Polygon为一组sidechain 侧链,为公链扩容方案,其基于 Plasma MoreVP 框架——采用的为account模型,而不是UTXO模型。Polygon支持现有所有的以太坊工具,并具有更快、更便宜的交易。Polygon上的gas费约为以太坊主网上的 1 / 100 1/100 1/100。
以太坊主网的资产,如Dapps/Tokens/Protocols都可迁移至Polygon side chain(s)上,同时也可根据需要将资产取回主链上。 Polygon支持DEX(如0x)、Liquidity pools(如Kyber Network)、借款协议(如Dharma Protocol)等。
具体的代码实现参见:
- https://github.com/maticnetwork/bor:其fork自Go Ethereum,并兼容EVM。
- https://github.com/maticnetwork/heimdall:其fork自Tendermint。
Polygon一般可分为四层:
-
Ethereum层:可使用以太坊来host and execute any mission-critical component of their logic。该层由以太坊智能合约来实现,主要功能类似有:
- Finality/checkpointing
- Staking
- Dispute resolving
- Message relaying
-
安全层:为可选层,非强制需要。用于管理一组validators,validators会周期性地检查任何Polygon chain的可用性,并收取一定的费用。安全层是完全抽象的,可由不同的主体实现不同的特征。改成可直接实现在以太坊上,此时,以太坊的矿工承担了validation的工作。该层可 以平行于以太坊的meta-blockchain方式运行,负责的主要功能有:
- Validator management(注册/反注册、激励、shuffuling等)
- Polygon chains validation
-
Polygon networks层:为一群主权区块链网络。这个网络可利用Polygon协议来相互连接并交换任意消息。每个区块链网络服务于其各自的社区,维护一下功能:
- 整理交易
- 本地共识
- 产生区块
-
执行层:该层可解析并运行 已在Polygon网络中达成共识的交易,主要分为2个子层:
- 执行环境(实现可插拔的虚拟机)
- 执行逻辑(某一特定Polygon网络的状态转换函数,通常写成以太坊智能合约)
Polygon(matic)总体架构为: Polygon PoS为a Layer2 commit chain to 以太坊网络。 PoS中实际内容又可划分为3个子层:
- 对于以太坊主网层:部署了一组智能合约。
- 对于Heimdall层:为平行于以太坊运行的一组proof-of-stake Heimdall节点,并会监控以太坊网络中的合约。Heimdall fork自 Tenedermint。
- 对于Bor层:Heimdall节点会shuffle a set of block-producing Bor nodes。Bor fork自Go Ethereum。Bor节点或Block Producer实现本质就是sidechain operator。sidechain VM是以太坊兼容的。当前,其是:基础的Geth实现+对共识算法的自定义调整。未来,将从头开始实现,使其更轻量、更专注。产块者从Validator set中产生,并使用历史Ethereum block hashes来进行shuffle。未来将使用randomness来选举出产块者。
在以太坊主网上的合约中进行质押,Heimdall节点会监听以太坊网络上合约中质押的token,并选择相应的Bor节点来产块。Bor节点会基于Heimdall节点选择的spans轮流产块。spans与以太坊上的质押量大小相关。
Checkpoint有2个作用:
- 1)Provide finality on the Root Chain:以太坊主链根据提交过来的checkpoint来决定侧链上块的最终性。
- 2)Provide proof of burn in withdrawal of assets:在用户提现资产到主链上时,提交燃烧证明。
Polygon与Plasma主要有2处不同:
- Polygon实现的Plasma是基于EVM运行的state-based sidechains。而其它Plasma实现主要基于UTXO——仅支持特定的支付。Polygon具有state-based sidechains,使得Polygon可提供通用的智能合约扩容性。
- Polygon采用的public checkpointing layer,会定期发布checkpoints——不像Plasma Cash在每个区块之后都要发布checkpoints。通过支持checkpoints的批量发布,可支持侧链以更快的速度运行。checkpoints+fraud proofs 机制,可保证Polygon侧链的安全性,同时,任何欺诈行为都可由以太坊主网发现,并通过罚没质押的token来惩罚作弊者。该主链安全性是对侧链PoS协议安全性的补充。
Polygon致力于去中心化扩容。Polygon采用了Plasma架构中周期性的checkpoints和fraud proofs。当用户需要取回资产时:
- 使用checkpoints来证明其在侧链上的资产。
- 使用fraud proofs来挑战fraud or any bad behavior and slash tokens。
Loom也提供L2扩容方案,其提出的Zombiechain与Polygon类似,但有2点不同:
- 关注点不同。Loom主要关注游戏和社交APP,其对去中心化的诉求相对没那么高。而Polygon关注金融交易、游戏等Dapp。同时计划提供全面的金融服务,如借贷Dapp(token swaps,margin trade等等)。
- Loom未来可能会使用的Plasma Cash,由于其需要将侧链的每个区块都推送到主链上,具有的block times要大于以太坊的block times。而Polygon使用的checkpoints for 1-second block times (with PoS layer)。 Plasma Cash+NFT,特别适合用于表示游戏卡和社交状态转换。但是对于普通的token transfers,其需要在plasma cash上进行token swap,用户体验不够好。
POA项目的产块者由Goverment公证确认,Go-Chain则依赖于多个国家的组织。这样的public block producers将有很大概率会受powerful external agencies and self-interest影响。同时侧链的交易仅由侧链的共识来保证,其共识参与者仅由3~25个。 而Polygon中,所有侧链交易的安全性将由侧链以及主链等多重机制保证。
在侧链端,Block producer layer中的任何交易都将通过高度去中心化的checkpointing layer verified and checkpointed to 主链。侧链端的任何欺诈交易都可通过checkpoiting layer来探测和处理。极端情况下,即使block producer layer和checkpoiting layer串通作弊,主链端还有fraud proofs,任何人都可公开来挑战其认为在侧链端是作弊的任何交易,如果挑战成功,colluding parties的质押将slash从而造成巨大的经济惩罚。同时,公开挑战者可获得the slashed stakes of the fraudulent sidechain actors。 此外, Polygon sidechains的容量和TPS要远远高于POA和Go-chain。Polygon tps可达数千,而POA和Go-chain仅有小一两千。理论上,“a single Polygon side chain”的tps可达 ( 2 16 ) (2^{16}) (216),即约6.5万+。Polygon支持多条侧链。
1.4 Polygon VS Celer NetworkPolygon 和 Celer Network 是对同一问题的不同解决方案,即解决当前区块链的低tps问题。二者都采用链下扩容技术,最终都依赖主链来提供final security。二者的目标都是generalized state transitions off-chain。 但是,二者本质有所不同:
- Polygon基于的是a set of Plasma sidechain(s) + PoS共识。Celer Network基于的是状态通道解决方案。
- Polygon致力于构建DApp开发者生态,因为其使用的是account-based Plasma sidechain,且其Polygon VM为兼容EVM的runtime,可以很容易的将以太坊DApp迁移至Polygon。从开发者角度来看,这与Celer Network有所不同。
Polygon支持3种接入方式:
- Polygon PoS chain
- Ethereum + Polygon with PoS bridge
- Ethereum + Polygon with Plasma bridge
其中PoS Bridge和Plasma Bridge对比如下:
PoS Bridge(Recommended)Plasma BridgeShort DescriptionDApp Developer’s looking for flexibility and faster withdrawals with POS system securityDApp Developer’s looking for increased security guarantees with Plasma exit mechanism.StructureHighly flexibleRigid, Less FlexibleDeposit(Ethereum → Polygon)3-5 mins3-5 minsWithdrawal(Polygon → Ethereum)1 checkpoint = ~ 20 mins to 3 hours10080 mins or 7 days (Challenge Period)SecurityProof-of-Stake system, secured by a robust set of external validators.Polygon’s Plasma contracts piggybacks on Ethereum’s security with 7 days challenge period.Support StandardsETH, ERC20, ERC721, ERC1155 and OthersOnly ETH, ERC20, ERC721Polygon采用双共识机制:PoS+Plasma。
bridge本质上为一组合约,用于帮助将资产由root chain移动到child chain。
使用PoS Bridge的详细流程为:
- 1)将Root token和Child token映射在PoS bridge。具体映射申请页面为:https://mapper.matic.today/。
- 2)可直接使用matic.js SDK来直接与合约进行交互。
- 3)为了将资产由以太坊转移到Polygon,再取回到以太坊中,具体的操作为:
- 3.1)部署在以太坊网络的Predicate合约可lock 待存入的token数额。Owner of asset (ERC20/ERC721/ERC115) token需授权Predicate合约来spend要传输的token数额。
- 3.2)一旦完成授权,接下来了存入资产。需调用RootChainManager合约,继而触发部署在Polygon chain上的ChildChainManager合约。
- 3.3)采用state sync机制,部署在Polygon chain上的ChildChainManager内部会调用相应child token合约的
deposit
函数,然后相应的数额的token资产会mint到相应的用户账号中。注意,仅有ChildChainManager合约可调用child token合约的deposit
函数。 - 3.4)一旦Polygon上的用户收到token,其可在Polygon chain上几乎实时地交易,其手续费几乎可忽略。
- 3.5)将Polygon上的资产提回到以太坊上分为2步:首先,需要在Polygon chain上burn相应的token资产;然后,需要将proof of burn交易提交到以太坊主链上。
- 3.6)需要由Proof of Stake validators对burn交易进行checkpoint,用时约需20分钟到3小时,然后再提交到以太坊主链上。
- 3.7)一旦交易被添加到了check point中,则可调用部署在以太坊上的RootChainManager合约的
exit
函数来提交proof of burn交易。调用的exit
函数会验证the checkpoint inclusion,然后出发部署在以太坊上的Predicate合约(之前存入时通过该合约lock了相应token资产)。 - 3.8)最后,部署在以太坊上的Predicate合约会释放the locked tokens,然后将资金重新冲入相应的以太坊用户账号中。
详细参看:
- https://github.com/maticnetwork/matic-docs/blob/master/docs/contribute/state-sync/state-sync-mechamism.md
- https://github.com/maticnetwork/matic-docs/blob/master/docs/contribute/state-sync/state-sync-mechamism.md
State Sync
为native机制,用于从以太坊主链上读取state并发送到Bor链上。 Heimdall层的Validators会监听StateSynced 事件,然后将该事件传输给Bor层。
receiver合约继承了IStateReceiver,自定义逻辑体现在onStateReceive
函数中:
pragma solidity ^0.5.11;
// IStateReceiver represents interface to receive state
interface IStateReceiver {
function onStateReceive(uint256 stateId, bytes calldata data) external;
}
是需要dapps/users按如下流程操作来实现state-sync:
- 1)调用以太坊主链上部署的StateSender合约中的
syncState
函数。 - 2)
syncState
函数会释放event StateSynced( uint256 indexed id, address indexed contractAddress, bytes data );
事件。 - 3)Heimdall chain中的所有Validators将监听到该事件,然后其中的一个想要获得tx fee的Validator将该交易发送到heimdall。
- 4)一旦
state-sync
交易被包含在heimdall上的一个区块中(经过2/3+ validators同意),其即被添加到了pending state-sync list。 - 5)在bor中的每个sprint(当前为64 blocks on Bor)之后,bor节点会通过调用API从heimdall中提取pending state-sync states。详细代码为:【在调用
commitState
时,stateId
和data
为参数。】
func (gc *GenesisContractsClient) CommitState(
event *EventRecordWithTime,
state *state.StateDB,
header *types.Header,
chCtx chainContext,
) error {
eventRecord := event.BuildEventRecord()
recordBytes, err := rlp.EncodeToBytes(eventRecord)
if err != nil {
return err
}
method := "commitState"
t := event.Time.Unix()
data, err := gc.stateReceiverABI.Pack(method, big.NewInt(0).SetInt64(t), recordBytes)
if err != nil {
log.Error("Unable to pack tx for commitState", "error", err)
return err
}
log.Info("→ committing new state", "eventRecord", event.String())
msg := getSystemMessage(common.HexToAddress(gc.StateReceiverContract), data)
if err := applyMessage(msg, state, header, gc.chainConfig, chCtx); err != nil {
return err
}
return nil
}
- 6)部署在Bor链(子链)上的receiver合约继承了IStateReceiver,在
onStateReceive
函数中可实现自定义逻辑来解析data并实现任意action。
详细参看:
- https://github.com/maticnetwork/bor/pull/90
Bor会为client生成新的tx/receipt,包含了all logs for state-sync。Tx hash有block number和block hash(sprint中最后一个区块的block hash)派生而来:
keccak256("matic-bor-receipt-" + block number + block hash)
这并不会影响共识逻辑,仅会影响客户端。eth_getBlockByNumber
,eth_getTransactionReceipt
和 eth_getLogs
会包含派生的state-sync logs。注意,区块中的bloom过滤器不会包含inclusion for state-sync logs,同时也不会在transactionRoot
和receiptRoot
中包含派生的tx。
主网实际部署信息参见:
- https://static.matic.network/network/mainnet/v1/index.json
{
Main: {
NetworkName: "Ethereum",
ChainId: 1,
DaggerEndpoint: "wss://mainnet.dagger.matic.network",
WatcherAPI: "https://sentinel.matic.network/api/v2",
StakingAPI: "https://sentinel.matic.network/api/v2",
Explorer: "https://etherscan.io",
SupportsEIP1559: true,
Contracts: {
BytesLib: "0x1d21fACFC8CaD068eF0cbc87FdaCdFb20D7e2417",
Common: "0x31851aAf1FA4cC6632f45570c2086aDcF8B7BD75",
ECVerify: "0x71d91a8988D81617be53427126ee62471321b7DF",
Merkle: "0x8b90C7633F1f751E19E76433990B1663c625B258",
MerklePatriciaProof: "0x8E51a119E892D3fb324C0410F11f39F61dec9DC8",
PriorityQueue: "0x61AdDcD534Bdc1721c91740Cf711dBEcE936053e",
RLPEncode: "0x021c2Bf4d2941cE3D593e07317EC355937bae495",
RLPReader: "0xD75f1d6A8A7Dc558A65c2f30eBF876DdbeE035a2",
SafeMath: "0x96D358795782a73d90F2ed2d505aB235D197ca05",
Governance: "0x98165b71cdDea047C0A49413350C40571195fd07",
GovernanceProxy: "0x6e7a5820baD6cebA8Ef5ea69c0C92EbbDAc9CE48",
Registry: "0x33a02E6cC863D393d6Bf231B697b82F6e499cA71",
RootChain: "0x536c55cFe4892E581806e10b38dFE8083551bd03",
RootChainProxy: "0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287",
ValidatorShareFactory: "0xc4FA447A0e77Eff9717b09C057B40570813bb642",
StakingInfo: "0xa59C847Bd5aC0172Ff4FE912C5d29E5A71A7512B",
StakingNFT: "0x47Cbe25BbDB40a774cC37E1dA92d10C2C7Ec897F",
StakeManager: "0xd6f5c46d4e1a02f9d145cee41d2f8af30d8d2d76",
StakeManagerProxy: "0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908",
SlashingManager: "0x01F645DcD6C796F6BC6C982159B32fAaaebdC96A",
ValidatorShare: "0x01d5dc56ad4206bb0c132d834644d57f51fed5ec",
StateSender: "0x28e4F3a7f651294B9564800b2D01f35189A5bFbE",
DepositManager: "0xd505C3822C787D51d5C2B1ae9aDB943B2304eB23",
DepositManagerProxy: "0x401F6c983eA34274ec46f84D70b31C151321188b",
WithdrawManager: "0x017C89Ca4Bda3D66cC65E3d20DD95432258201Ca",
WithdrawManagerProxy: "0x2A88696e0fFA76bAA1338F2C74497cC013495922",
ExitNFT: "0xDF74156420Bd57ab387B195ed81EcA36F9fABAca",
ERC20Predicate: "0x158d5fa3ef8e4dda8a5367decf76b94e7effce95",
ERC721Predicate: "0x54150f44c785d412ec262fe895cc3b689c72f49b",
Tokens: {
MaticToken: "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0",
TestToken: "0x3db715989dA05C1D17441683B5b41d4510512722",
RootERC721: "0x96CDDF45C0Cd9a59876A2a29029d7c54f6e54AD3",
MaticWeth: "0xa45b966996374E9e65ab991C6FE4Bfce3a56DDe8"
}
},
POSContracts: {
Merkle: "0x195fe6EE6639665CCeB15BCCeB9980FC445DFa0B",
MerklePatriciaProof: "0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa",
RLPReader: "0xBEFe614A45A8300f2a4A00fb634b7137b6b1Bc47",
SafeERC20: "0xeFfdCB49C2D0EF813764B709Ca3c6fe71f230E3e",
SafeMath: "0x6EBEAC13f6403D19C95b6B75008B12fd21a93Aab",
RootChainManager: "0x7cfa0f105a4922e89666d7d63689d9c9b1ea7a19",
RootChainManagerProxy: "0xA0c68C638235ee32657e8f720a23ceC1bFc77C77",
ERC20Predicate: "0x608669d4914eec1e20408bc4c9efff27bb8cbde5",
ERC20PredicateProxy: "0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf",
ERC721Predicate: "0xb272b6d99858b0efb079946942006727fe105201",
ERC721PredicateProxy: "0xE6F45376f64e1F568BD1404C155e5fFD2F80F7AD",
ERC1155Predicate: "0x62d7e87677ac7e3bd02c198e3fabeffdbc5eb2a3",
ERC1155PredicateProxy: "0x0B9020d4E32990D67559b1317c7BF0C15D6EB88f",
MintableERC20Predicate: "0xFdc26CDA2d2440d0E83CD1DeE8E8bE48405806DC",
MintableERC20PredicateProxy: "0x9923263fA127b3d1484cFD649df8f1831c2A74e4",
MintableERC721Predicate: "0x58adfa7960bf7cf39965b46d796fe66cd8f38283",
MintableERC721PredicateProxy: "0x932532aA4c0174b8453839A6E44eE09Cc615F2b7",
MintableERC1155Predicate: "0x62414d03084eeb269e18c970a21f45d2967f0170",
MintableERC1155PredicateProxy: "0x2d641867411650cd05dB93B59964536b1ED5b1B7",
EtherPredicate: "0x499a865ac595e6167482d2bd5a224876bab85ab4",
EtherPredicateProxy: "0x8484Ef722627bf18ca5Ae6BcF031c23E6e922B30",
DummyStateSender: "0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39",
Tokens: {
DummyERC20: "0xf2F3bD7Ca5746C5fac518f67D1BE87805a2Be82A",
DummyERC721: "0x71B821aa52a49F32EEd535fCA6Eb5aa130085978",
DummyMintableERC721: "0x578360AdF0BbB2F10ec9cEC7EF89Ef495511ED5f",
DummyERC1155: "0x556f501CF8a43216Df5bc9cC57Eb04D4FFAA9e6D"
}
},
FxPortalContracts: {
FxERC20RootTunnel: "0x9194ec72B67ce7AE51074aFdAd44f937CE1dD447"
}
},
Matic: {
NetworkName: "Polygon",
ChainId: 137,
RPC: "https://matic-mainnet.chainstacklabs.com",
DaggerEndpoint: "wss://matic-mainnet.dagger.matic.network",
Explorer: "https://polygonscan.com",
NetworkAPI: "https://apis.matic.network/api/v1/matic",
SupportsEIP1559: false,
Contracts: {
ChildChain: "0xD9c7C4ED4B66858301D0cb28Cc88bf655Fe34861",
Tokens: {
MaticWeth: "0x8cc8538d60901d19692F5ba22684732Bc28F54A3",
MaticToken: "0x0000000000000000000000000000000000001010",
TestToken: "0x5E1DDF2e5a0eCDD923692d4b4429d8603825A8C6",
RootERC721: "0xa35363CFf92980F8268299D0132D5f45834A9527",
WMATIC: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270"
}
},
POSContracts: {
ChildChainManager: "0xa40fc0782bee28dd2cf8cb4ac2ecdb05c537f1b5",
ChildChainManagerProxy: "0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa",
Tokens: {
DummyERC20: "0xeFfdCB49C2D0EF813764B709Ca3c6fe71f230E3e",
DummyERC721: "0x6EBEAC13f6403D19C95b6B75008B12fd21a93Aab",
DummyMintableERC721: "0xD4888faB8bd39A663B63161F5eE1Eae31a25B653",
DummyERC1155: "0xA0c68C638235ee32657e8f720a23ceC1bFc77C77",
MaticWETH: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619"
}
},
FxPortalContracts: {
FxERC20ChildTunnel: "0x918cc10cf2393bb9803f9d9D3219539a1e736dd9"
},
GenesisContracts: {
BorValidatorSet: "0000000000000000000000000000000000001000",
StateReceiver: "0000000000000000000000000000000000001001"
}
},
Heimdall: {
ChainId: "heimdall-137",
API: "https://heimdall.api.matic.network"
}
}
参考资料
[1] maticnetwork 白皮书 [2] polygon lightpaper [3] Polygon technology [4] Polygon PoS [5] Polygon docs