DPoS 及其在 Plasma Cash 中的实现





1.00/5 (3投票s)
基于 DPoS 的 Plasma 是一种革命性的解决方案,它提供了去中心化,并显著提高了区块链每秒处理的交易数量。
引言
如今,很少有人不知道加密货币及其对等技术——区块链。
在未开化的人眼中,区块链主要与金融领域相关联,但这种创新技术实际上可以用于广泛的应用,例如
- 旅游
- 物流
- 银行
- 法律
- 建筑
- 保险
- 能源
- 医疗
- 以及许多其他领域
是什么让区块链如此有用?首先,它阻止了黑客入侵计算机系统和网络本身。区块链所包含的逻辑是不可违背的。存储在那里的数据由所有节点共享,并且永远无法删除。
区块链的不可篡改性只能通过在分布式网络中实现共识算法来实现。有很多这类算法,但最常见的是中本聪在 2008 年发明的“工作量证明”(PoW)算法,它在加密经济学领域引发了一场革命。
拜占庭将军问题(BGP)是分布式计算机系统网络面临的一个寓言,其中所有参与方必须就一个单一的策略达成一致,以避免完全失败,但其中一些参与方可能腐败且不可靠。BGP 已被用于形式化共识算法,并且已经存在了一段时间,但 Satoshi 的 PoW 算法提供了一个更优雅的解决方案。
拜占庭军队由许多远距离分布的军团组成,每个军团都有自己的将军,将军又服从于主将。在战前,主将会向所有其他将军发出命令,是进攻还是撤退。但有人怀疑一些将军是叛徒,他们故意收到不同的命令。其想法是
- 如果所有忠诚的将军都进攻,军队就会获胜
- 如果所有忠诚的将军都撤退,军队就会安全
- 如果任何一位将军独立行动,军队就会被击败
拜占庭将军的任务是找出叛徒,将他们排除在决策系统之外,并达成共识。当应用于分布式网络时,BGP 确保系统中的所有节点都达成共识。
在比特币中,当我们着手寻找区块哈希的挑战时,我们可以提供证据表明已进行了复杂的操作,大大增加了解决方案的重要性。通过从足够多的证明中累积链,有可能获得系统和网络的可靠一致状态。这就是共识算法的本质。
去中心化网络使用各种算法或逻辑方案来达成共识。按流行度降序排列的三个主要区块链共识算法是:工作量证明(PoW)、权益证明(PoS)和委托权益证明(DPoS)。工作量证明是最古老、最被证明且在区块链中最常用的共识算法。
工作量证明算法早已证明了其巨大的可靠性和重要性。同时,它有一个显著的缺点——它需要大量的电力和资源来运行。因此,通过货币获取获得的利润不足以抵消损失。
理论上,可以发明一种甚至能更快找到哈希并执行工作量证明的程序,从而有可能破解共识,使网络更加中心化。
第二个算法——权益证明,要求相关方必须投票给下一个区块以达成共识。用户因参与网络而获得更多的币作为奖励。这种方法与 PoW 矿工因其努力而获得奖励的方式非常相似。
权益证明算法仍然是去中心化的,但它不需要大量的电力和资源。您可以简单地购买一定数量的代币。
PoS 的主要缺点可以被描述为“无风险”。投资是在消耗能量时发生的,但在 PoS 的情况下,没有什么风险,可以生成任意数量的链。
另一个问题是,越来越多的代币被最大的代币持有者累积,导致中心化风险很高。可以开发一种算法来公平地选择共识参与者,但这将非常复杂。
在工作量证明和权益证明被实施到各种加密货币中后不久,就推出了委托权益证明(DPoS)。对于传统的 PoS,任何人都可以充当权益节点。然而,DPoS 有选举出的代表,由他们的同僚选择来执行特定角色。在 DPoS 环境中,只有当选的节点才能选择区块并为共识做出贡献。
DPoS 的主要优势在于,该算法鼓励用户诚实行为,仅仅因为这样做对他们有利。
另一个很大的优势是 DPoS 提供了更高的可扩展性。如果节点代表集是已知的,那么许多参数都可以进行优化。然后就可以快速达成共识。
然而,中心化程度的提高是一个缺点。
尽管存在缺点,DPoS 为 Plasma Cash 的实现提供了一个完美的解决方案!需要一个子链来提高吞吐量,而子链并不需要完全去中心化。
理想情况下,Plasma Cash 可以作为一个庞大的运营商运行,但数量更多的代表可以提高网络的可靠性,并且它们可以由各种组织控制。这大大增加了信任度。
DPoS 回答了“谁将参与共识?”这个问题。
为此,在 Plasma 链中引入了新的交易:投票/取消投票给代表。这使参与者有机会提名代表候选人。然后,在共识阶段,所有代表都根据投票数和他们的权益进行排序。
查看 Opporty 公司为实现 Plasma 和 DPoS 编写的代码
DPoS 共识算法的每项操作都有其自己的交易类型。已实现的交易类型如下
- vote - 为候选验证人投票
- unvote - 取消投票
- pay - 将代币转移给另一个成员
- candidate - 将地址添加到候选人列表
- resignation - 从候选人列表中删除地址
进入子链后,所有这些交易都必须经过强制验证
async function validatePayTx(transaction) {
checkTransactionFields(transaction)
const tokenOwner = await getSignatureOwner(transaction)
if (tokenOwner != config.plasmaNodeAddress) {
const utxos = await getUtxosForAddress(tokenOwner)
let tokenId = transaction.tokenId.toString()
checkUtxoFieldsAndFindToken(utxos, tokenId, tokenOwner)
}
return {success: true}
}
const validateVoteTx = async (transaction) => {
await validatePayTx(transaction)
return {success: true}
}
const validateUnvoteTx = async (transaction) => {
checkTransactionFields(transaction)
let addsTransaction = await checkAndGetAddsHistoryTx(transaction)
if (ethUtil.addHexPrefix(addsTransaction.newOwner.toString('hex'))
!= ethUtil.addHexPrefix(transaction.newOwner.toString('hex'))) {
throw new Error(rejectCauses.failHistory)
}
return {success: true}
}
const validateCandidateTx = async (transaction) => {
await validatePayTx(transaction)
return {success: true}
}
const validateResignationTx = async (transaction) => {
checkTransactionFields(transaction)
await checkAndGetAddsHistoryTx(transaction)
return {success: true}
}
执行“unvote”或“resignation”类型的交易时,需要检查历史记录和是否存在具有特定投票数和特定代币的验证人。这由 checkAndGetAddsHistoryTx
函数完成。它验证来自特定用户的投票是否存在于交易历史记录中。如果投票存在,则可以取消投票,或者用户可以从验证人列表中删除(交易类型“resignation
”)。
const checkUtxoFieldsAndFindToken = (utxos, tokenId, tokenOwner) => {
for (let i = 0; i < utxos.length; i++) {
if (!utxos[i].owner ||
!utxos[i].tokenId ||
!utxos[i].amount ||
!(utxos[i].blockNumber > -1)) {
continue
}
if ((utxos[i].tokenId === tokenId) &&
(utxos[i].owner === tokenOwner)) {
return {success: true}
}
}
throw new Error(rejectCauses.noUtxo)
}
验证后,状态会发生变化,验证人将被添加到/从验证人列表中删除。
const checkAndGetAddsHistoryTx = async (transaction) => {
const faceThatRemoves = await getSignatureOwner(transaction)
let blockKey = 'block' + transaction.prevBlock
let block = (new Block(await redis.getAsync(Buffer.from(blockKey))))
if (!block) {
throw new Error(rejectCauses.failHistory)
}
let addsTransaction = block.getTxByTokenId(transaction.tokenId)
if (!addsTransaction) {
throw new Error(rejectCauses.failHistory)
}
let faceThatAdds = await getSignatureOwner(addsTransaction)
if (faceThatAdds != faceThatRemoves) {
throw new Error(rejectCauses.failHistory)
}
return addsTransaction
}
对于“vote
”交易,会将权益添加到列表中的特定代表——stateValidators.addStake(stake)
。
const unvoteTxExecute = async (transaction, blockNumber) => {
const newOwner = await getSignatureOwner(transaction)
let oldOwner = ethUtil.addHexPrefix(transaction.newOwner.toString('hex'))
let stake = {
voter: newOwner,
candidate: JSON.parse(transaction.data.toString()).candidate,
value: 1,
}
await stateValidators.toLowerStake(stake)
await utxoTransition(transaction, blockNumber, newOwner, oldOwner)
return {success: true}
}
对于“unvote
”交易,则发生相反的情况——等待提取权益:stateValidators.toLowerStake(stake)
。
const candidateTxExecute = async (transaction, blockNumber) => {
const oldOwner = await getSignatureOwner(transaction)
await stateValidators.addCandidate(oldOwner)
let newOwner = ethUtil.addHexPrefix(transaction.newOwner.toString('hex'))
await utxoTransition(transaction, blockNumber, newOwner, oldOwner)
return {success: true}
}
当执行“candidate
”交易时,代表只需添加到列表中——stateValidators.addCandidate(oldOwner)
。
const resignationTxExecute = async (transaction, blockNumber) => {
const newOwner = await getSignatureOwner(transaction)
let oldOwner = ethUtil.addHexPrefix(transaction.newOwner.toString('hex'))
await stateValidators.removeCandidate(newOwner)
await utxoTransition(transaction, blockNumber, newOwner, oldOwner)
return {success: true}
}
或者在“resignation
”交易的情况下被删除。
在所有情况下,都会发生状态转换,并且代币会被花费。它会被发送到主 Plasma 地址或返回给前所有者。使用 utxoTransition
函数。
需要明白的是,所有阶段都根据区块提交时间分成相等的几部分。代表在列表中的顺序在每个阶段都以伪随机的方式改变。
所有这些都是以严格确定性的方式发生的
async prepareValidators() {
let seedData = Math.floor(Date.now()/config.roundInterval)
this.hungValidators = Object.assign([], this.validators)
let seedSource = crypto.createHash('sha256')
.update(String(seedData), 'utf8').digest()
for (let i = 0, delCount = this.hungValidators.length; i < delCount; i++) {
for (let x = 0; x < 4 && i < delCount; i++, x++) {
let newIndex = seedSource[x] % delCount
let b = this.hungValidators[newIndex]
this.hungValidators[newIndex] = this.hungValidators[i]
this.hungValidators[i] = b
}
}
return 'ok'
}
验证人代表根据当前轮次(轮次根据当前日期计算)进行排序。在任何时候都可以识别出当前验证人
async getCurrentValidator() {
let dateStamp = Date.now()
let index = Math.floor((dateStamp / config.blockTime) %
(this.hungValidators.length))
return this.hungValidators[index]
}
在任何单一时刻,可能只有一个所有人都知道的代表,而这个代表就是当前的验证人。只有这个参与方可以添加一个有效的区块。所有其他矿工都必须等待轮到他们。
如果代表行为不端,他们可以被简单地从列表中排除。
委托权益证明的想法实际上非常简单。尽管如此,该算法相当快且完全去中心化。
Opporty 公司引入了一种新的 DPoS 共识——Plasma,它在适当的中心化程度下提供了最高级别的安全性。
事实上,子链是区块链经典形式的完整实现
- 区块链
- 分布式数据库
- 用于协调的 DPoS 共识算法
- 压缩的 Patricia 树用于保存状态
通过 Plasma,两个区块链能够完全同步地工作,互为补充。
以太坊提供最大的稳定性和可靠性。基于 DPoS 的 Plasma 能够在主网络之外实现去中心化,并显著提高区块链每秒处理的交易数量。
有用链接
- Plasma 白皮书
- DPoS
- 以太坊区块链的隐私和可扩展性解决方案
- 共识
- 拜占庭容错
- 侧链 vs Plasma vs Sharding
- Vitalik Buterin 谈 DPoS
- Slasher Ghost 和其他权益证明方面的进展
- 以太坊中的 Merkle 化
历史
- 2019 年 7 月 18 日:初始版本