针对Algorand所使用的密码相关技术细节进行介绍

关键概念

  • VRF: 可验证随机函数。简单来说是:vrf,Proof = VRF(sk,seed),sk为私钥,seed为随机种子;通过Verify(proof,pk,seed)验证vrf的合法性。
  • cryptographic sorition: 根据用户本轮的VRF值,自身的权重以及公开的区块链信息,计算出某用户本轮被选举的sub-users个数,并提供相应的证明
  • committee member: 见证人委员会,即使用cryptographic sortition选举出的用户集合。
  • FINAL共识:全网用户对某一非空块达成了共识。FINAL区块及之前区块所包含的交易均被确认。
  • TENTATIVE共识:其他用户可能对不同的区块达成了共识。TENTATIVE区块的交易需要在对之后的FINAL区块达成共识后得到确认。

基本假设

算法假设

  • 诚实用户运行bug-free的软件。
  • 节点可以自由地随时加入网络,而且不需要申请。网络中的每一个节点通过一个公钥的地址(这个地址同时也是钱包地址)进行表示,对于新加入的节点地址,只有和网络中其余节点发生转账关系之后,才可以参与到网络中的区块共识
  • 攻击者是动态变化的,诚实节点随时可能变为攻击者
  • 诚实节点所持Token的总数占比大于2/3,以避免区块分叉与交易双花。
  • 强同步(strong synchrony)假设:大多数诚实用户(例如95%)发送的信息都能在一定的已知的时间范围内,被大多数诚实的用户接收。
  • 弱同步(weak synchrony)假设:网络在一定的长时间内是异步的(例如完全被恶意方控制)。在异步阶段之后,网络一定会有一段合理时长的强同步阶段,在这一阶段,Algorand可以确保算法安全。在此情况下,算法仍然安全但性能会受较大影响。
  • 强同步时钟:为了在弱同步情况下执行恢复协议,所有节点需要同步本地时钟,即本地时钟应当足够接近,使得所有节点执行恢复协议的步调基本一致。

网络假设

  • 网络消息传播时间上限:固定时间内完成对固定比例的用户的网络传播。
  • 比如,比特币:1KB消息,在1秒钟内完成全网95%的传播,而1MB消息需要1.5分钟完成全网95%的传播。

总体概括

  • Algorand 采用可验证随机函数、POS (账户余额权重)以及新的拜占庭协议议定书(Byzantine Agreement Protocol,BA*)整合方式的共识机制来实现提高TPS的同时,没有牺牲去中心化和隐私性,并且拥有良好的扩展性。

可验证的随机函数:

  • Micali是可验证的随机函数(verifiable random functions:VRF)的发明人之一,VRF是一种随机数产生方式,每一个用户,都能够通过计算他们的私钥和区块链上公共信息的函数(VRF),独立地判断他是否当选委员会的成员。这一过程是非互动的,所以可以有效保证信息的隐私性和防止参与者被攻击的可能性。
  • 由于使用节点私钥作为Input,VRF的结果无法被预测。其他节点只有通过网络接收到随机结果后才能对其合法性进行验证,即攻击者在得知选举结果时,选举人已经做出行动了。
  • VRF的输出值除了随机值外,还包含一个proof,提供了随机值验证的零知识证明,即不必知道某人私钥即可证明该随机值是由某人产生的
  • Algorand 利用 VRF 来选择区块生产者和验证者,保证所有共识参与者都是随机地、公平地被选出的。可验证随机函数(VRF,Verifiable Random Function)是由 Micali 教授等提出的一种伪随机函数,和普通的随机函数一样,对于不同输入,其输出也具有随机性(严格来说是“伪随机”)。其独特之处在于调用者可以提供一个证明,表明这个随机输出确实由该调用者产生。
  • VRF 可以有多种实现方式,Micali 等人在其原始论文中提供了一种较复杂的实现方式。Algorand 利用哈希函数和数字签名的特性,提供了一种较为简单的 VRF 实现。具体实现方式是调用者 i 将输入 m 通过数字签名和哈希函数映射为固定长度的输出 H[SIGi(m)],即 m -> H[SIGi(m)]。
  • 对于任何输入 m,不同的调用者 i 生成的数字签名 SIGi(m) 都是唯一的;而对于不同输入,哈希函数 H 的输出具有随机性,因此上述映射符合 VRF 的”随机性“要求。同时,由于 i 的数字签名 SIGi(m) 可通过其公钥对其身份进行验证,因此其也符合 VRF ”可验证“ 的特性,SIGi(m) 就是 VRF 中提到的”证明“。

具体内容详解

随机选出每一轮的区块生产者(Leader)

  • 每一轮共识开始时,每个节点都可以通过以下 VRF 独立地验证自己是否是潜在的 leader:
  • .H[SIG(r, 1, Q(r-1))] <= 1 / SIZE(PK(r-k))
  • 其中,H 是哈希运算;SIG 是签名运算;r 是目前的轮次;Q(r-1) 为与 r-1 轮的种子;SIZE(PK(r-k)) 是在 r-k 轮所有符合要求的公钥的数量(k 为回溯系数);公式开始的 . 表示将哈希结果转化为小数位,从而保证结果为[0,1)的某个值。
  • 节点通过自己的私钥计算上面签名的哈希值是否符合要求,从而知道自己是否属于候选的 leader,在此过程中无需和其他节点交换信息。由于哈希函数输出的随机性,可以认为符合要求的候选节点都是随机选出的。候选节点随后可以生成新区块,并向全网提供签名证实自己的身份。如果有多个候选 leader,最终上述哈希值最小的 leader 将在后续的共识中成为本轮最终的 leader。Leader 产生的区块 Br 包含了本轮的所有交易和上述的证明信息,由验证组成员进行共识验证。

随机选出每一轮每一阶段的验证组

  • 验证组成员的选择与上述过程类似,在每一轮和每一阶段(step),所有节点都可以独立验证自己是否属于验证组成员:
  • .H[SIG(r, s, Q(r-1))] <= n / SIZE(PK(r-k))
  • 其中 s 为本轮所处的不同阶段,Algorand 在每一轮的各个阶段都有不同的验证组,从而进一步保证安全性;n 为预期的验证组成员数量,可以人为设定;其他参数含义与候选 leader 一样,每一阶段的验证组成员均随机选出,验证节点在证实自己身份后,可以开始参与共识验证过程,揭露自己的签名即可证明其身份。

引入权益证明(Proof-of-Stake,PoS)机制

  • 上述的随机选择过程没有考虑 Token 持有者的权重,恶意节点可能通过大量生成有效私钥从而有极大概率成为区块的生产者和验证者。Algorand 在其公布的实现建议中引入了名为 Honest Majority of Money (HMM)的条件假设,其基本思想来源于 PoS 共识机制,即在上述随机选择过程中引入代币持有量(Stake)作为权重,持有量多的节点被选中的概率较高,而代币持有者往往更倾向于保护网络的安全性。
  • 具体可以表示为如下公式:.H[SIG(r, 1, Q(r-1))] <= (a(i,r) / M) * (1 / SIZE(PK(r-k)))
  • 其中,a(i,r) / M 为节点所持有的币的数量占代币总数 M 的权重。其余过程与前面描述一直。

纯粹股权证明PurePoS

  • 正如上面所述,一小部分资金的所有者不可能损害整个系统,而且大多数资金的所有者作恶,使自己的资产贬值将是十分愚蠢的。
  • 例如,在PoW或BPoS中,少数用户就可以阻止其他用户进行交易。在Algorand,只有大部分资金的所有者才能阻止其他用户进行交易。但如果他们这样做,声誉将受到极大的损害,资金将不再被普遍接受,其购买力将大大降低。对于大多数资金的所有者来说,这并不是一个好的结果。

PPos如何出块

在Algorand一个新的区块分为两个阶段: 

  • 在第一阶段,随机选择一个Token,其所有者就是下一个块提议者。
  • 在第二阶段,从当前系统中的所有通证中选择1000个Token。
  • 这1000个Token的所有者被选为第2阶段委员会的一部分,该委员会批准第一个用户提出的区块。
  • 因此,委员会的一些成员可以被选择两次或更多次,通常是k次,在这种情况下,该成员将在委员会中拥有k票以批准下一个区块。

第二阶段是十分必要的

  • 在任何社会中,区块链也不例外,总有一小部分坏人被发现;比如1%。也许2%。如果一个人不幸生活在一个非常危险的社会中,那么10%的人可能是坏人,也许甚至20%!但只要大多数成员遵守规定的规则,就会存在一个稳定和谐的社会。
  • 假设Algorand中10%的代币属于不诚实的人。然后在阶段1中,十分之一选择提议块的用户可能是坏演员。因此,他可以告诉一些用户该块是X,而告诉其他用户该块是Y等等,从而产生关于区块的意见分歧。
  • 阶段2消除了这个问题。实际上,如果你选择随机的1000个代币,当最多10%的代币是不诚实的手牌时,大多数所选硬币属于不良参与者的概率,即委员会大多数投票是糟糕的演员的概率是如此之低,以至于可以忽略不计。

谁来进行随机选择委员会

  • Algorand采取的方式:委员会成员选择自己。你可能会想“什么?这是一个糟糕的主意!因为如果我是一个坏人,我会选择自己成为这个委员会的成员。接下来。那之后......“但不是那么快。
  • 要想属于委员会,你的一枚代币必须独立赢得这个机会,像加密地公平的彩票,你可以在你自己的计算机隐私中独立运行 - 也就是说,不与任何其他人交谈。而且由于彩票是加密公平的,你不能改变被选中的机会。(即使是拥有巨大算力资源的民族国家,也无法增加被选中的概率。)
  • 为了在假设10,000,000,000个通证中选择1,000个随机通证,每个代币以概率1,000 /10,000,000,000被选择 - 即,概率为1千万分之一

我可以获得多少票

(如果用户有n个通证,额外的算法技术基本上运行一个整张彩票,而不是n个单独的彩票!)一旦用户运行她的抽奖,就会出现两种情况之一。

  • 要么所有代币都没有赢得彩票,在这种情况下,用户对该区块表达何种意见都将被忽略。
  • 或者其中一些k> 1的代币赢得了彩票,在这种情况下,用户获得了一张中奖彩票,即一个简短的证明,即每个人都可以很容易地证明此用户在委员会中有k票。在后一种情况下,通过网络传播:证明用户有k票的中奖票  以及该用户对该票的意见。

例子

  • 这里具体举例说明一下:假设网络里总共有100万个币,要从中选1000个做委员. 那么每个币被选中的概率是千分之一。 我如果有100个币,等于我参选了100次,每次千分之一。你如果有10000次,就等于参选了10000次。这些次选择都是独立的,所以有可能你有多次被选中,我也有多次被选中,只是我的概率比你低。
  • 但是每次都是千分之一的概率,那么你有100个token被选中的概率是千分之一的100次方 乘以一个二项式的系数,概率极低。

伪代码

入参解释

  • ·sk: 用户私钥
  • ·seed: 选举所用的种子信息
  • ·role: 当前所选举的身份信息
  • ·τ: 期望选举的子用户sub-users数量
  • ·w: 用户的权重
  • ·W: 全网总权重

介绍

  • 为了防止女巫攻击,Algorand使用二项分布作为概率分布函数,原因是B(k1+k2;w1+w2,p) = B(k1;w1,p) + B(k2;w2,p),即从概率上来说,无法通过拆分token来提高被选中子用户的数量。
  • 某用户的子用户数量j数量大于0,即表示该用户被选为committee member(见证人委员会)

选举验证:

  • 选举证明算法如下,用于判断某用户的VRF值是否合法,且在当前轮次与步骤下是否被选举为committee member。该函数在CommitteeVote中被使用到

如何选取种子

  • 在Algorand中,seed作为区块的一个字段,第r轮的seed由第r-1轮区块的seed所决定
  • 计算公式如下:<seed(r),π> = VRF(sk,seed(r−1)||r).
  • 为了限制攻击者操纵选举的能力,选举算法中所用的seed会每隔R轮刷新一次,即seed(r) = seed(r-1-(r mod R))。

选择早先于seed的私钥

  • 上述机制对用户的私钥sk选择提出了新的要求:由于seed在固定R轮中不变,这使得恶意用户可以通过尝试不同私钥来控制VRF值。Algorand要求用户的私钥是在区块r-1-(r mod R)之前生成的,论文中提出的方案是使用距离区块r-1-(r mod R)早b个时间单位的最近区块所使用的密钥对。

 

新的拜占庭协议议定书BA*:

  • BA* 是一种高度可扩展性极强,远超目前拜占庭协议书的链上共识,在这个过程中,每个节点连续性提出出块建议,并且直到权重最高的快被选出为止。
  • 由下图可知,BA* 协议也可以理解为两步骤:第一步,同步确定拥有最大优先级的区块,即验证者对区块运行分级共识协议,选出验证者共识最多的候选区块。第二步,确定该区块是否拥有稳定共识的能力,即验证者对上一阶段选出的候选区块,进行二元拜占庭协议验证,要么接受他,要么接受空的区块。

BA*共识又被细化为两个重要的子算法:

Reduction

  • 在Block Proposal阶段,不同的诚实节点因为网络延迟等因素,会收集到不同优先级的区块,其所观察到的最高优先级区块可能不同。因此,它们传入BA算法的区块也会不同。因此在做拜占庭共识之前,先执行Reduction*,在全网对哪个区块的优先级最高这一问题进行投票并达成共识,将N个潜在的区块收敛为至多1个非空区块

具体步骤

  • 检查自己是否为committee member,若是则对自己提案的区块投票。
  • 等待λblock + λstep的超时时间,收集网络用户的投票。
  • 一旦某区块的投票数超过了T*τ的阈值,则认为全网大部分诚实节点在该区块达成共识,再对该区块投票;若在执行上一步等待λblock + λstep时间的时候超时,则对空块投票。
  • 等待λstep的超时时间,收集网络用户投票,并返回最终得到的区块。

Q&A

Q:为什么要进行两次投票?

A:第一次投票(步骤2)用于对大多数节点所看到的最高优先级区块达成共识,类似于prepare阶段;第二次投票(步骤3、4)用于对第一次投票的共识结果进行共识,表示大多数节点已经对某新区块达成共识,类似于commit阶段。

Q:CommitteeVote函数中为何要传入不同的step?(REDUCTION_ONE与REDUCTION_TWO)

A:每个用户的vrf值,round和step均为选举算法的随机种子,影响着用户是否能被选举为committee member。这里对Reduction的两次投票引入了一定的随机性,使得两次投票的用户不同。若两次投票用户均为同一批,恶意方可以在两次投票之间的时间间隙,对第一次投票的用户进行攻击(因为第一次投票后已经暴露了投票人是谁),从而危及算法安全性。

 

BinaryBA*

  • BinaryBA* 算法对Reduction过程收敛的区块进行多次投票,在网络状况良好的情况下在第一步即可达成FINAL共识。
  • 1,step=1时,用户对Reduction得到的区块hash进行投票,并收集票数。若超时,则保持原区块hash,进入步骤2;若不超时且投票结果为非空块,则再对该hash投票3次,并投出FINAL步骤的票(意为当前用户已达成FINAL共识),返回该区块hash。
  • 2,继续对上一步骤中得到的区块hash投票并收集票数。若超时,则将hash置为空块hash,并进行步骤3;若得到空块,则连续投票3次并返回空块hash。
  • 3,继续对上一步骤中得到的区块hash投票并收集票数。若超时,则执行“抛硬币”算法,有50%的概率将hash置为原先的区块hash或空块hash。若否,则将hash置为投票结果。最后重复步骤1。

Q&A

Q: 在每轮算法的前两步中达成共识,为何在return之前要连续投票3次?

  • A: 在公网环境下,若有很多诚实节点在某一步达成共识并返回,而其余诚实节点由于网络延迟,在给定时间内没有收集到足够的票数,从而超时进入下一轮。此时在接下来的step中很可能没有足够的committee member进行投票,使得这些节点始终无法对区块达成共识。Algorand对这一问题的解决方案是:在某用户达成共识并结束算法之前,预先对该区块hash进行后三步的投票。在还未达成共识的用户看来,这些已达成共识的节点仍然参与了后三步(后一轮)的投票。

Q: 为何设计CommonCoin抛硬币算法?

  • A: 避免在网络分区的情况下,攻击者有机会给不同的用户发送对不同hash的投票(或故意不投),使它们对不同区块达成共识。同时CommonCoin加速了BBA的收敛过程。根据CommonCoin的算法特性,诚实用户的比例最坏为2/3,经过CommonCoin得到block_hash和empty_hash概率均为为1/2,因此每经过一次CommonCoin,全网达成共识的概率为(2/3)*(1/2) = 1/3。则全网用户在第i轮达成共识的概率为((2/3)^(i-1))*(1/3)。达成共识的期望总轮数为i*((2/3)^(n-1)*(1/3))的无穷级数,即极限为3。因此,通过抛硬币,在最坏情况下,全网达成共识的期望轮数为3,期望步骤数为2+3*3=11

改进的二元拜占庭协议 BBA*

  • Algorand 引入的 BBA* 是一个改进的二元拜占庭协议(所谓二元,即只能达成 0 或 1 两种共识)。BBA* 可以在诚实节点超过 ⅔ 的情况下,快速达成共识。其具体过程是一个 3 步循环,循环中每一步都有 ⅓ 的概率达成共识。
  • 节点之间需要进行 P2P 通信,假设被选中的验证节点中有 t 个恶意节点,验证组总的节点数为 n >= 3t + 1,即恶意节点不超过 ⅓ 。协议过程如下:

  • 所有验证节点i都有一个初始值 bi(bi = 0 或 1),协议开始时,每个验证节点都会向其他验证节点发送各自的初始值,

协议第一步(Step 1)是归 0 过程:

  • 如果某验证节点 i 收到 0 的总数超过总验证节点数的 ⅔ ,输出共识结果为 0,共识结束,不再执行后面所有步骤
  • 如果某验证节点 i 收到 1 的总数超过总验证节点数的 ⅔,则该验证节点把自己的 bi 设为 1
  • 如果收到的 0 或 1 都没超过 ⅔, 则验证节点把自己的 bi 设为 0
  • 第一步结束节点再次向其他节点发送各自的 bi

第二步(Step 2)为归 1 过程:

  • 如果某验证节点 i 收到 1 的总数超过总验证节点数的 ⅔ ,输出共识结果为 1,共识结束,不再执行后面所有步骤
  • 如果某验证节点 i 收到 0 的总数超过总验证节点数的 ⅔,则该验证节点把自己的 bi 设为 0
  • 如果收到的 0 或 1 都没超过 ⅔, 则验证节点把自己的 bi 设为 1
  • 第二步结束节点再次向其他节点发送各自的 bi

第三步(Step 3)为重新设定初始值的过程:

  • 如果某验证节点 i 收到 0 的总数超过总验证节点数的 ⅔,设定 bi = 0
  • 如果某验证节点 i 收到 1 的总数超过总验证节点数的 ⅔,设定 bi = 1
  • 如果收到的 0 或 1 都没超过 ⅔,则每个验证节点会对某个和本轮本阶段相关的信息进行签名,并对签名求哈希。bi 被设置为这些哈希值中最小哈希的最低有效位(仍然是 0 或 1)
  • 之后返回第一步,直到达成共识
  • 在 Algorand 中, BBA* 的结果是对是否接受某个区块达成共识,共识结果只有接受(0)或拒绝(1)两种情况。

分级共识协议 GC

  • 上述 BBA* 只适用于二元情况,当需要对任意值达成共识,需要引入分级共识协议,将任意值问题转化为二元问题:

  • Algorand 采用的 GC 分为两步(上图来自 Algorand 白皮书,为了和文中其他部分对应,将两个步骤命名为 Step 2 和 3),协议开始时,每个验证节点i各自都有一个初始值 vi(在 Algorand 中即候选的新区块的哈希)\
  • 第一步 (Step 2),所有验证节点将各自的 vi 发给其他所有验证节点;
  • 第二步(Step 3),对于某个x值,当且仅当节点收到其他验证节点发来该 x 值的总次数(多次收到同一节点发送的x值,只算一次)超过总验证节点数的 ⅔ 时,这个节点会对其它节点发送值 x:

经过 GC,每个节点都会输出一个值对 (vi, gi),输出规则:

  • 当收到 x 的总次数超过总验证节点数的 ⅔ 时,设定 vi = x, gi = 2;
  • 当收到 x 的总次数超过总验证节点数的 ⅓ 时,设定 vi = x, gi = 1;
  • 否则,设定 vi = 空, gi = 0;
  • 简单来说,分级共识的作用是从多个可能的候选新区块中选择被大多数认可的一个作为最终候选的区块,再通过上面的 BBA* 最终达成共识。

BA* = GC + BBA*

  • 改进的拜占庭协议 BA*  结合了上述 GC 和 BBA*,先通过 GC 把任意值问题(从多个区块中选择一个候选)转化为二元问题(接收或拒绝新区块?),再利用 BBA* 达成快速二元拜占庭共识,从而可以快速对任意值达成共识,其共识过程如下:

  •  BA* 的第一步,和第二步,所有验证节点 i 执行 分级共识 GC,各自得到一个关于新区块的数值对 (vi, gi),其中 vi 为验证节点 i 认为的候选区块哈希(有可能为空),gi = 0 或 1 或 2 。
  • 第三步,所有验证节点根据各自的 (vi, gi) 设定 BBA* 的初始值,如果 gi = 2,则设定初始值为 0,如果 gi = 0 或 1, 则设定初始值为 1 。之后进行BBA* 共识过程:
  • 若共识结果为 0,则最终输出结果为 vi(非空新区块)
  • 若共识结果为 1, 则最终输出结果为空(即新区块为空)
  • 无论哪种情况,BA* 都可以在验证节点中达成共识,从而确定新区块及其包含的交易(有可能为空区块)。

 Algorand 区块链分叉的可能性

  • Algorand 实际采用的是经典拜占庭共识的升级版 BA*,它和以比特币为代表的中本聪共识的最大区别在于分叉的可能性。后者由于完全去中心化,节点之间无法完全通信,因此可能仅在部分节点间达成共识,容易发生分叉。
  • Algorand 可以通过设定最大可接受的错误概率 F 调整分叉的概率。在 Algorand 提供的两种实现中,其分叉概率分别为 10^-12 和 10^-18,在现实中分叉仅存在理论上的可能,但是这个概率贼低,假设 Algorand 每秒生成一个区块,10^-18 的概率意味着从宇宙大爆炸至今的时间内,只有可能发生一次分叉,可见其概率极低。
  • 即使真的发生分叉,Algorand 仍可以从分叉中恢复:
  1. Algorand 遵守中本聪共识中的最长链法则
  2. 如果有多条最长链,则选择包含非空区块的最长链
  3. 如果仍相同,则可以具体根据区块哈希值进行排序选择

Algorand 如何保证安全性

种子Q(r)

  • Algorand 中的随机性主要靠 VRF 保证,每轮随机的选出 leader 及验证组。一个比较直接的想法是把上一区块 B(r-1) 作为随机函数的输入。但这种方法将给恶意节点带来一定的优势:因为区块和其包含的交易高度相关,恶意节点可以通过调整区块中包含的交易集,获得多个输出,并选择对其最有利的交易集产生新区块,从而提高自己在下一轮中成为 leader 或验证组的概率。
  • 为解决这一问题,Algorand 引入了一个随机的、不断更新的种子参数 Q(r),Q(r) 与交易集本身相互独立,因此恶意节点无法通过调整交易集而获利。当区块非空时,Q(r) = H(SIG(Q(r-1),r) (其中,SIG 为 本轮 leader 的签名); 当区块为空时,Q(r) = H(Q(r-1),r)
  • 可以看出,Q(r) 在每一轮都发生变化,且与交易本身无关。可以证明,当 Q(r-1) 是随机的,则 Q(r) 也是随机的。因此恶意节点无法通过改变交易集影响下一个种子的生成。其中,Q(1)的定义没有在相关文献中找到。

回溯系数K

  • 种子参数降低了恶意节点预测 leader 的可能性,但拥有多个潜在 leader 的恶意节点仍可以有比普通节点更高的概率成为下一个区块的 leader,但这个概率会随着区块的变多而逐渐变小。因此,Algorand 引入了一个回溯系数 k,第 r 轮的候选组只从 r-k 轮已存在的候选组中选取,恶意节点在 r-k 轮能够影响第 r 轮候选组的概率极低。

一次性公钥

  • Algorand 从协议层面的分叉仅在理论上可能发生。在实际中,如果恶意节点可以挟持其他节点,仍可以在验证组被公开的瞬间,强制这些节点重新签名新的区块,从而产生短暂的分叉。Algorand 引入了一种一次性公钥的机制,以杜绝这种可能性。
  • 具体原理是所有节点在加入 Algorand 网络时(即发生第一笔交易时),都生成足够多的一次性公钥,并公布。这些公钥将用作后续所有轮次的签名验证,并且每个公钥只使用一次,一旦被使用后就销毁。一次性公钥的生成过程需要一定的时间,在 Algorand 的典型实现中,每个新节点需要约 1 小时来生成未来 10^6 轮的所有公钥(约 180 MB 数据)。虽然这增加了节点加入时的门槛,但可以从根本上杜绝上述分叉攻击:因为一旦签名完成,公钥即被销毁,即使被恶意节点劫持,也无法再次签名产生分叉。

Algorand 的可扩展性

  • 对于目前大多数去中心化区块链,如比特币,以太坊以及 Qtum 等,可扩展性的主要瓶颈在于所有链上计算都要进行全网验证,而达成全网共识往往需要一定的时间。Algorand 采用 PoS+VRF 机制进行随机选择区块生产者和验证者,无论网络中有多少节点,每一轮都只需要在少数节点上进行验证,大大提高了共识速度,提高可扩展性。同时,Algorand 还采用了改进的拜占庭共识 BA*,该协议可以减少共识节点之间的通信量,从而进一步提高共识速度。
  • 此前 Algorand 发布了其性能测试数据,结果表明,在 1000 台 EC2 服务器(AWS 虚拟云服务器)、500,000 用户场景下,Algorand 网络确认时间稳定为 1 分钟,吞吐量约为比特币网络的 125 倍。(比特币约为 7 TPS)且吞吐量不会随着节点数的变多而明显下降。

 

账户余额权重:

  • Algorand算法中的节点都有权重(weight),该权重和账户的余额成正比。

  • 上图中的t是选中的账户余额阀值,w=账户余额/账户余额阀值,也就是说w是账户中可以分割成多少个账户余额阀值。利用多项式分布B(k;w,p),计算出hash对应的比例在哪个区间内,则最后选中的次数就是多少,也就是最后的j的数值。

加密抽签算法:

  • 在百万级别使用用户的量级下,如何依然能维持快速有效的的拜占庭共识,其主要手段是避免所有用户参与验证,那么减少验证者同样可能带来安全性的不足,如何平衡两者使得在大量节点中提取可靠维持共识效率的验证人是关键。加密抽签算法就是用来解决这个随机选择问题的,他提供了一种私密随机并可验证的验证人筛选方法。
  • 抽签其实是一种随机方式,在整个网络中,节点之间如何不存在事先商议的情况下自动产生随机验证人是需要用心构思的技巧。
  • Algorand的解决方式中,主要有两点:1、用户私钥参与运算的随机特征值产生算法函数,该函数产生与上一区块相关,私钥的保密性,使得参与随机运算后的结果存在不可预测性;2、将运算后的特征值映射到(0,1)数值区间内,对比特征值数值最小的作为提块人,按照特定规则从特征值中选取出验证群体,并且在此时验证人的选取是在其不可知的情况下被选择的,只有当区块组装完成后,验证人会同时将自己生成的验证凭证(用来证明自己是在秘密抽签中被合法选中的验证人)一并广播出去,在这之后其他用户可验证当前验证人是否合法。
  • Algorand采用了VRF函数,并结合账户的余额比例,随机确定区块生成以及投票人角色。根据论文中的模拟数据,比特币的POW共识换成Algorand共识后,TPS增长125倍。和DPOS+BFT相比,Algorand的安全性更强,只要超过2/3的账户余额是诚实节点,Algorand即安全。不过Algorand共识只是进行了小范围的测试,还没有经过大规模的市场验证。

算法细节解析

算法辅助函数

CommonCoin

  • CommonCoin算法用于模拟1/2概率,俗称”抛硬币“,但该”抛硬币“算法有以下两个特点:
  • 1. 结果只有2个,且每个结果的概率为50%。
  • 2. 使用相同参数作为种子,获得的结果相同。
  • 在Algorand中,CommonCoin使用全网的投票信息作为种子,对于强同步的大多数诚实节点来说,得到相同结果的概率为h(h即为诚实节点所占比例,h > 2/3)。故每经过一次CommonCoin可以h的概率让大多数诚实节点达成共识。

CountVotes

  • CountVotes算法用于在给定时间内统计票数,并选出超过票数阈值的合法区块。每个投票消息的票数实际为该用户在当前上下文中所选举的子用户数量。

ProcessMsg

  • ProcessMsg用于接收投票信息,验证并统计票数。

 AIgorand的区块链的种类的分类

ALGORAND 非许可区块链

  • Algorand 提供真正去中心化、可扩展和安全的非许可区块链。它具备真正去中心化的特点:每个代币都可以参与共识协议,与任何其他代币具有相同的权力。它具有可伸缩性,因为它只需使用少量的运算,即可支持数十亿用户在几秒之内生成一个区块。而且它很安全,因为它不可能被少数矿工或受托人或者一小部分代币的所有者破坏。事实上,只要 Algorand 区块链的大多数代币掌握在可靠的人手中,它就能保证正常工作。
  • Algorand 协议依赖于全新的技术,例如其独特的密码抽签和超高效的拜占庭协议

除了完全的去中心化、可扩展性和安全性之外,Algorand 非许可区块链还具有以下显著特性:

  • 无分叉和即时交易确认。Algorand 区块链不会分叉。每个新区块都是单独商定的,并且保证永远留在 Algorand 链上。因此,用户可以立即信赖新区块中包含的交易,而不必等待区块在链中具有足够的深度。
  •  Layer 1 处理标准资产和智能合约。区块链在不同的层面上处理不同的交易。第 1 层是最直接和最安全的一层。传统意义上来说,第 1 层只处理普通支付和共识协议本身,新资产的发行、智能合约和其他的所有事务都在第 2 层处理。但众所周知,第 2 层的协议速度慢、成本高并且容易出错。相比之下,Algorand 在第 1 层还会处理标准资产和大量智能合约的发行,包括资产代币化、原子交易抵押借贷,并且能够在必要时隔离和收回有争议的交易。事实上,Algorand 在第 1 层就满足了智能合约的大多数当前用例,并且具有与普通支付手段相同的安全性和效率。

ALGORAND许可链版本

  • 许可型区块链的主要优点是能够保护交易不受外界干扰。
  • 在 Algorand 的非许可链版本中,每个原生代币(除了作为本地货币 (Algo) 的计量单位之外)都可以参与共识协议,并具有与其他代币相同的权力。但是,在 Algorand 的许可链版本中,企业 E 只能将给定的 10M 代币池用于共识协议,并以任何方式将其划分到自己选择的验证节点集合 V 中。例如,E 可以选择 V 仅包含 5 个验证节点,并为每个验证节点分配 2M 共识代币。这样做的结果是,E 为五个验证节点中的每一个提供了生成新区块的相同能力。另举一例,E 可以选择 55 个验证节点,为前 5 个验证节点每个分配 1M 代币,并为另外 50 个验证节点每个分配 100K 代币。这样的话,E 为前 5 个验证节点分配的区块生成能力就是其他 50 个验证节点的 10 倍。
  • Algorand 的许可型版本具有极细的颗粒度级别,可以为不同的验证节点分配不同的权重。

通过Algorand 许可区块链,而不是从头开始构建自己的许可链或采用另一个许可链,E 获得了以下主要优势:

  • a) 按需分配的加权去中心化。选择任意数量(任意权重)的验证节点是至关重要的。实际上,E 可能想做出这种选择来提高自己区块链的安全性,或者扩大它所服务的社区。最初为少量金融机构服务的区块链可以从少量的验证节点开始。但是,如果以后它想要为中小型银行和信用合作社服务,而所有这些机构都希望参与区块生成,该怎么办?适用于少数参与者的共识算法可能无法有效地适用于成百上千的参与者。而中途改变策略可能相当具有挑战性!通过允许共识协议扩展到数十亿个验证节点,E 能够保证在任何时候毫无问题地扩大验证节点集。缩小规模容易,扩大规模就难了。
  • b) 交易最终性和第 1 层智能合约。无论是私有还是公有区块链,许可型还是非许可型区块链,对于任何区块链来说,交易最终性都是一个至关重要的属性。在第 1 层处理大多数智能合约需求的能力也是如此。通过在 Algorand 中增加权限控制特性,E 从而获得一个许可型区块链,该区块链会自动继承这些至关重要并且很难拥有的属性。
  • c) 可升级性和持续创新。无论何时将升级改进和创新添加到核心的无许可型 Algorand 主链,使用许可型版本的 Algorand 协议均会自动为 E 提供未来的升级改进和创新。

ALGORAND Co-Chain:定义和挑战

定义

  • Algorand Co-Chain是特殊的 Algorand 许可链版本。因此,它是一个可扩展的许可链框架,可按需实现去中心化,具有交易即时确认和第 1 层智能合约等特性。它还满足一个额外的关键特性:
  • 与其他Co-Chain的互操作性许可型区块链能让给定范围内的用户安全地进行互动。但它可能不允许他们与其他实体和个人进行互动。这是一个很大的限制,因为“外部”的世界比“内部”的世界更大,我们可能想要与更大的世界互动。一组金融机构可能想建立他们自己的许可链。但是一些医疗机构可能也想这样做。由于医疗保健是经济的重要组成部分,所以金融机构链想必希望与医疗机构链进行交互和资产交换。如果没有外部的互操作性,许可链的成员就可能被困在自己的链中。

Co-Chain Algorand 许可链,它能保证 Algorand 无许可链与其他Co-Chain之间高效和安全的互操作性。

挑战

第一个挑战:安全性

  • 许可链之间的互操作性很容易声明,但很难得到保证。考虑一个简单的例子。用户a拥有资产 x,他希望与拥有资产 y的另一用户 b进行交换。
  • 如果 a和 b属于 Algorand 无许可链或同一个 Algorand Co-Chain,此问题可以在 5 秒内解决,并且具有最终性和安全性。实际上,他们可以使用原子交换,这是 Algorand 中作为第 1 层交易可用的主要工具之一。但是,如果 a是Co-Chain A 的成员,b是另一个Co-Chain B 的成员,该怎么办?
  • 不同链间的资产交换通常通过哈希锁定协议来实现的。但是这种方法存在相当大的问题。除了需要多个逻辑复杂的步骤之外,它还容易受到拒绝服务攻击。这样的攻击可以使欺骗一方保留自己的资产,同时获得另一方的资产。为了避免这种情况,协议可能需要持续很长一段时间,这可能使拒绝服务的成本高于相关资产的价值。

第二个挑战:明确所有权

  • 但是,这又会产生另一个问题,并且该问题适用于仅涉及xy及其各自区块链AB的任何协议。也就是说,由于B是许可型的私有链,最多只有它们的成员知道xy交换了原始资产,因此,b现在由链A的成员拥有。如果链损坏,没有什么能够阻止y多次向其他区块链的成员出售b或用其交换其他资产!从本质上讲,这相当于资产交换的双重支付。
  • 如果许可链的大多数验证节点是恶意的,或者其密钥已泄露,那么该许可链就算是腐败了。在腐败的链中,原始区块可以被替换为假区块,这样就再也无法弄清楚谁拥有哪些资产。(这就是去中心化对安全来说至关重要,以及几百个验证节点比几十个更好的原因!)许可链的损坏具有很强的隐匿性,因为它的私密性可以防止外部人员注意到这种腐败。链的损坏是比较罕见的事件,但当它发生时,应该只影响链的成员,而不应该影响诚实链!没人能够保证另一条链可以保持诚实。
  • 链的互操作性应该保证诚实链的成员所获得的任何资产都有明确的所有权。即便从腐败的链的成员处获得的资产也是如此。

ALGORAND(简化版)Co-Chain体系结构

现在,我们来概述一下 Algorand Co-Chain如何互操作。为简明起见,先忽略隐私特性。

序言

我们用 MAIN来表示 Algorand 的主网,它是无许可并且公开的。相应地,每个Co-Chain监控 MAIN的区块。对于每个Co-Chain CMAIN都需要维护

  • Co-Chain的验证节点的最新列表VALIDATORSC
  • 以及Co-Chain的成员拥有的,可以转让给其他链的所有资产的最新列表ASSETSC

过程

  • 最初,当一个Co-Chain形成时,这两个列表都可能被包含在本质上是Co-Chain C在“MAIN中的创世区块”。(这个创世区块与Co-Chain C的原始创世区块不同,它指示哪些是Co-Chain C的初始公钥,以及这些密钥最初拥有哪些资产。)
  • 随着时间的推移,VALIDATORSC和 ASSETSC都通过Co-Chain C在 MAIN中发布由Co-Chain C的最新验证节点列表(适当多数)签署的适当交易进行更新。
  • 需要强调的是,MAIN不仅对Co-Chain C 中发生的交易一无所知,而且也不知道Co-Chain C的实际公钥,更不用说使用这些密钥的实际用户了!事实上,ASSETSC不会透露有关Co-Chain C中控制 ASSETS中资产的公钥的任何信息。

 Algorand Co-Chain 到主链的资产转移

  • Algorand Co-Chain A 的用户 x可能想要通过公钥 tx将他拥有的资产 a转移到 MAIN。用户 x这样做可能出于多种原因。例如,x可能想拍卖 a,而“出价的人越多,价格就越高”。因此,与其在 A上拍卖 a,用户 x可能更愿意在 MAIN上拍卖,这样不仅有 A的成员报价,还有 MAIN或其他Co-Chain的成员报价。事实上,Co-Chain的任何成员都可以轻松地向 MAIN转移稳定币,唯一的目的就是参加拍卖。
  • 与Co-Chain A 中普通的转移相同,将 a从 tx转移到 MAIN的操作由 tx 的数字签名授权,用符号表示为 SIGx(tx, a, MAIN)。由于 tx拥有 ,并且转移得到了适当的授权,SIGx(tx, a, MAIN)会进入经 A的验证节点适当认证的 A的一个新区块 X。此时,Co-Chain A 的所有成员意识到 tx和 A中的任何其他公钥均不拥有资产 a。因此(除非 A已损坏),tx不能再授权 a在 A内或 A外的转移。
  • 与 A的所有其他区块相同,X的结构是为了便于将 SIGx (tx,a, MAIN)和转到 MAIN的所有其他资产转移与所有其他信息隔离开来,这些信息必须仅对 A的成员保持可见。从概念上来说,表示方式如下:

X= (SIGx (tx, a, MAIN), other transfers to MAIN, H)

  • 其中HA中所有交易的单向哈希(通常长度为 256 位),必须在A中保持私密。需要注意的是,X的格式非常紧凑。实际上,除了打算传递给 Algorand 主链的信息外,它只包含 256 个字节。
  • 此格式的区块X以及它在A中的证书会传播到MAIN的节点。

由于Co-Chain A运行与MAIN相同的共识算法,并且MAIN知道 A 的验证节点,因此MAIN的验证节点可以解析X的证书,并了解到

  • txA拥有资产a的密钥

  • 密钥tx的所有者希望将 a转移到 Algorand 的主链。

相应地,

  • 资产a会从 ASSETSA中移除,并且

  • 密钥tx会被记录为MAIN拥有(在MAIN中!)资产a的(可能为新的)密钥。

注意:步骤 1 中使用的MAIN既是公有的,也是非许可的。具体来说,MAIN为非许可型这一事实能够保证tx成为MAIN中的密钥,不会出现任何问题。并且MAIN是公有的这一事实能够保证所有人意识到资产a现在位于MAIN中。这能够保证y将(在下一个步骤中)获得a的明确所有权。事实上,无论Co-Chain A 是否损坏,x和A中的任何其他成员均无法将a转移给任何其他Co-Chain的任何成员。

从主链转回Co-Chain的资产转移

  • 在 MAIN中出售 a后,tx可能会想将拍卖所得的稳定币转移给 A
  • 更普遍的情况下,如果 tx是 MAIN和 A两者的公钥,tx可能会想将它在 MAIN中拥有的资产 b转移到 A。同样,这样的转移可能是由 tx的数字签名授权的,用符号表示为 SIGx (tx,b, A),它会进入 MAIN的一个新区块。由于 MAIN为非许可型,A的验证节点可能会看到 SIGx (tx,a, A)出现在 MAIN的区块中,或者它们可以通过 tx本身看到这种出现的适当紧凑证明。无论哪种情况,A的验证节点都将导致 tx成为 A中资产 b的当前所有者,因为它已经是 A中的一个密钥。同时,只要 SIGx(tx, a, A)出现在 MAIN的区块中,tx便不再拥有 MAIN中的 b,并且 ASSETS A将更新为包含资产 b

Co-Chain互操作性

  • 接下来,我们使用上面提到的相同资产交换示例来说明Co-Chain是如何互操作的。现在,A和 B是不同的 Algorand Co-Chain。具体来说,资产 a在 A中由公钥 tx控制,其私钥为 x所知,而资产 b在 B中由公钥 ty控制,其密钥为 y所知。

要交换它们的资产,xy通过以下概念步骤利用MAIN

  1. 在链A中,tx“将a转移到MAIN”,并向MAIN提供转移证明。在链B中,ty“将b转移到MAIN”,并向MAIN提供转移证明。
  2. MAIN中,tx和 ty通过原子互换交换ab
  3. MAIN中,txb转移到A,并且 tya转移到B。链B都能看到这两项转移

步骤 1 的说明

步骤 1 可以通过txMAIN的区块中发布 SIGx (tx, a, A) 来实现,如上所述。相应地,在MAIN中,

  • 资产a会从 ASSETA中移除,并且资产b会从 ASSETB中移除。

  • 密钥tx不再拥有a

类似地,对于ty来说也是如此。

步骤 2 的说明

  • 从现在开始,在 MAIN中,tx 拥有a,并且ty拥有b,它们可以在几秒钟之内以超级安全的方式交换这些资产。实际上,所采取的方式是第 1 层原子交易,这是 Algorand 非许可链的主要功能特性之一。

步骤 3 的说明

  • 如前所述,在 MAIN中,tx b转移给 A 中的自己,因为tx仍然是A的批准密钥。类似地,对于ty来说也是如此。

附加说明

  • 我们可以注意到,整个过程非常快。实际上,以上三个步骤中的每一步都可以在生成新区块所需的时间内执行。这一时间在 Algorand 的主链中不超过 5 秒。但是在 Algorand Co-Chain中生成区块可能会快很多。实际上,在 Algorand 协议中,可以在确保大多数验证节点看到区块所需的时间内生成一个区块。在网络速度很快的Co-Chain中,这一时间可以忽略不计。
  • 还注意到,整个过程发生在第 1 层,因此无论是在主链中还是在Co-Chain中,都具有更高的安全性。

  • 最后请注意,给定Co-Chain的资产累计价值可能超过 Algorand 主链的估值。然而,Algorand 的主链并不用于保护任何Co-Chain的资产。在给定的时间点,它仅用于处理给定Co-Chain的少量资产,并且仅持续几秒钟。也就是说,它用于处理Co-Chain想与另一个链交换的资产。

增强私密性

  • Algorand Co-Chain之间资产交换的隐私性可以大幅增强。
  • 具体而言,tx和 ty可以是临时密钥,仅供 x和 y在本次资产交换中使用。也就是说,在开始上述的三步流程之前,x生成临时公钥 tx 并将资产 a从之前持有a的任何公钥转移到 tx。完成步骤 3,并且 tx 在 A中拥有资产 b后,x可以将 b从 tx 转移到他选择的任何其他公钥。通过这样的方式,Algorand 的主链永远不知道 A中的哪个公钥最初拥有资产 a,以及哪个公钥最终会拥有 b

Co-Chain主要有以下几个特点

  • 完全独立于公有区块链,保护其交易不被外部人员所看到,可以自行选择验证者节点,并自行来运行Algorand共识协议;
  • 通过与Algorand主链交互从而和其他Co-Chains以及其他方之间进行交易,并且确保该过程和在Algorand无需许可的公链内进行资产交换,拥有相同程度的安全性和便利性;
  • Co-Chain能够使用原子交换(Atomic Transfers),智能合约(ASC)等所有Algorand公链原生拥有的工具和特性;实际上,Co-Chain能够自动享受到Algorand公链上所有的升级以及性能提升。

Algorand网络节点分为两种

  • Relay Node(中继节点)和 Non-Relay Node(非中继节点)。其中中继节点承担 Algorand 网络枢纽的作用,执行重复数据删除,签名检查和其他验证步骤,最终向其他节点重新传播有效消息。非中继节点则又称为参选节点,通过配置有效账户并连接到中继节点参与网络选举。作为一个开放性的网络,任何人都可以下载安装跑一个Algorand节点。参选节点可以设置为全节点模式和非全节点模式。在非全节点模式下,节点只需要保留大约1天的区块数据,能有效降低存储要求。Algorand 所固有的高速、可扩展性和安全性等特点将被其上发行的 USDT 所继承。

小结

[1]Algorand 共识不是一个漫长的过程。随着越来越多的区块被附加到给定的区块 B 上,人们越来越有可能对 B 达成共识。Algorand 单独对新的区块达成协议,这一过程完成后,再对下一个区块达成协议,以此类推。

[2]原子交易让多名用户能够通过单笔交易交换资产,或者以多种货币执行多笔支付。因此,原子交易中的任何参与者都无法欺骗其他参与者,并且没有人害怕自己是第一个尝试的人。

[3]另一个经常提到的选择许可型区块链的原因是安全。然而,这个理由忽略了一点,即去中心化本身就是安全性的主要来源。

 

参考链接

  • AIgorand:兼顾高性能、去中心和安全的公有链 | ONETOP评级
  • AIgorand加密共识算法主要解决了什么问题?
  • 必读| Algorand PPoS共识协议绝对核心优势在哪?PurePoS轻松速懂精华总结版
  • Algorand Co-Chain技术解读
  • 专题研究九:区块链项目Algorand
  • 可验证随机函数VRF之Algorand算法

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447082.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对于Algorand的介绍

介绍 Algorand具有能耗低、效率高、民主化、分叉概率极低、可拓展性好等优点&#xff0c;旨在解决现有区块链项目存在的“不可能三角”&#xff08;高度可扩展的、安全的、去中心化&#xff09;问题。Algorand由MIT教授、图灵奖得主Silvio Micali发起&#xff0c;拥有MIT区块链…

C++学习 高级编程

C 文件和流 到目前为止&#xff0c;目前使用最为广泛的是 iostream 标准库&#xff0c;它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流。以下将介绍从文件读取流和向文件写入流。这就需要用到 C 中另一个标准库 fstream&#xff0c;它定义了三个新的数…

内存池中的嵌入式指针

嵌入式指针 可以union改struct 内存分配后 next指针就没用了 直接作为数据空间比较省内存 因为对指针指向的内存存储的时候 编译器是不管你是什么类型的 &#xff0c;这里有道练习题可以对指针的概念稍微理解一下&#xff1a; #include <iostream> using std::cout; us…

内存池的实现4 alloc内存池

alloc 内存池 优点: &#xff1a;本质是定长内存池的改进&#xff0c;分配和释放的效率高。可以解决一定长度内存分配的问题。 缺点 &#xff1a;存在内碎片的问题&#xff0c;且将一块大内存切小以后&#xff0c;申请大内存无法使用&#xff0c;别的FreeList挂了很多空闲的内存…

c语音的一些特殊关键字

PRETTY_FUNCTION C语言中获取函数名 C语言中的__LINE__用以指示本行语句在源文件中的位置信息

vim 不常见但好用的命令

● 跳跃 ○ 向前跳跃是 f ○ 向后跳跃是 F ● 继续 ○ 保持方向是 ; ○ 改变方向是 , ● 可以加上 [count] 来加速 ● ^ 是到本行第一个非空字符 ● 0 是到本行第一个字符&#xff0c;不管是不是空格 ● g_ 是到本行最后一个非空字符 ● 两个按键要依次按下 ● $ 跳到本行最后…

加密机组会 会议纪要

2020年9月28日 1&#xff0c;使用基类继承的机制&#xff0c;调用写好的函数接口 1&#xff0c;不要 使用Content&#xff08;封装数据&#xff0c;本质是一个json字符串&#xff09;&#xff0c;1&#xff0c;因为每次使用这个需要对里面的内容进行序列化&#xff0c;转化成…

演示IPFS的一个完整的流程以及针对部分概念的详解

整体的流程 1&#xff0c;创建ipfs节点 通过ipfs init在本地计算机建立一个IPFS节点本文有些命令已经执行过了&#xff0c;就没有重新初始化。部分图片拷贝自先前文档&#xff0c;具体信息应以实物为准 $ ipfs init initializing IPFS node at /Users/CHY/.ipfs generating 2…

TDengine安装教程

TDengine安装教程 前言 TDengine的安装十分简单&#xff0c;可以有以下三种安装方式&#xff0c;源码安装、通过Docker容器进行安装、通过安装包进行安装。但是使用源码安装较为复杂&#xff0c;通过docker的方式最为简单&#xff0c;但是需要一定docker相关的知识&#xff0…

android 软件首次运行时引导页左右滑动效果

很多手机软件在安装后首次运行都会进入到引导页面&#xff0c;再次运行时会进入到主页面。 多了不说了&#xff0c;先看效果图&#xff1a; 代码如下&#xff1a; main.xml <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:an…

dex分包之--------multidex包的配置使用

目录&#xff1a;一、前言二、产生原因三、MultiDex的简要原理四、MultiDex的使用 一、前言 首先说一下我遇到的情况&#xff0c;最近接手了一个项目是在已有的项目里进行更新添加一些功能&#xff0c;然后该项目导了N多的包&#xff0c;在我使用Android Studio的run”App”直…

Android Studio打包和引用aar

一、简介 Android 库在结构上与 Android 应用模块相同。它可以提供构建应用所需的一切内容&#xff0c;包括源代码、资源文件和 Android 清单。不过&#xff0c;Android 库将编译到您可以用作 Android 应用模块依赖项的 Android 归档 (AAR) 文件&#xff0c;而不是在设备上运行…

C++有限状态机的实现

//待完善 有限状态机是一个很常用的技术&#xff0c;在流程控制和游戏AI中都比较实用&#xff0c;因为状态机编程简单又很符合直觉。与有限状态机类似的是设计模式中的状态模式。本文是参考《Programming Game AI by Example》 一、 记得最开始工作时候也接触过有限状态机&…

C++ unsigned char*转化为string的形式

unsigned char*转化为string int main(int argc,char **argv){//unsigned char * 转化为string//参考链接 https://www.itdaan.com/tw/4ff531a5e6651468a5b7c6d95927ba3dunsigned char *foo;unsigned char str[] "Hello world";string strHH;foo str;strHH.append…

我的职业生涯规划(软件工程)

以后笔记先在语雀整理 方便一点https://www.yuque.com/juhao-pqdor/goeie3 整理一下自己的笔记 弥补一下以前没写博客的遗憾吧 二十载求学路将尽&#xff0c;行文至此&#xff0c;思绪万千。求学之路始于家乡&#xff0c;竿转热河&#xff0c;而今终于石门。一路行之如人饮水…

Android设计模式之——Builder模式

一、介绍 Builder模式是一步一步创建一个复杂对象的创建型模式&#xff0c;它允许用户在不知道内部构建细节的情况下&#xff0c;可以更精细的控制对象的构造流程。该模式是为了将构建复杂对象的过程和它的部件解耦&#xff0c;使得构建过程和部件的表示隔离开来。 因为一个复…

Android设计模式之——原型模式

一、介绍 原型模式是一个创建型的模式。原型二字表明了该模型应该有一个样板实例&#xff0c;用户从这个样板对象中复制出一个内部属性一致的对象&#xff0c;这个过程也就是我们俗称的“克隆”。被复制的实例就是我们所称的“原型”&#xff0c;这个原型也是可定制的。原型模…

针对C++异常的学习

源码 头文件 sdf_exception.h #pragma once#include <exception> #include <string>namespace sdf {namespace common{using sdf_error_code_t uint32_t;class SdfException : std::exception{public:explicit SdfException(sdf_error_code_t errorCode) : erro…

Android设计模式之——抽象工厂模式

一、介绍 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;&#xff0c;也是创建型设计模式之一。前一节我们已经了解了工厂方法模式&#xff0c;那么这个抽象工厂又是怎么一回事呢&#xff1f;大家联想一下现实生活中的工厂肯定都是具体的&#xff0c;也就是说…

Android设计模式之——策略模式

一、介绍 在软件开发中也常常遇到这样的情况&#xff1a;实现某一个功能可以有多种算法或者策略&#xff0c;我们根据实际情况选择不同的算法或者策略来完成该功能。例如&#xff0c;排序算法&#xff0c;可以使用插入排序、归并排序、冒泡排序等。 针对这种情况&#xff0c;…