需求分析可以支持多条链，只要链支持Solidity智能合约即可可以支持多个代币，需要符合ERC20标准的代币由去中心化的中继节点采用投票方式来完成跨链请求的确认每个中继节点需要质押保证金，每成功一笔跨链交易可获取奖励引入惩罚机制，中继节点每次作恶都会被罚没，保证金低于一定值时被封禁，重新充入保证金可解封引入黑名单管理机制，符合监管需求，禁止名单内账户使用跨链桥功能引入中继节点准入机制，维持中继节点集群稳定，保障跨链桥的稳定工作跨链交易规则跨链有最低金额限制（比如100USDT）每笔收取总金额的一定比例作为手续费（比如万分之五）一定比例的手续费平分给参与投票的中继节点（比如70%）剩下比例的手续费发给平台（比如30%）用户需手动去领取跨链资产，也可以在指定一个帮忙自动提取的中继节点（需额外付费）中继节点规则中继节点列表由平台进行管理维护，需保持稳定（避免在短时间内大量增加或减少）保证金由中继节点自行维护，存入自由，取出需要限制（比如每隔24小时可取一次）中继节点数量需保持一定合适的数量，至少也得3个，太多中继节点也不好（浪费机器资源，也拖慢投票速度）投票罚没规则中继节点需保证金大于指定门槛的才可以参与投票（比如10万），低于的处于封禁状态中继节点的投票权重都一样，和保证金大小无关每次跨链请求需要大于2/3的中继节点（所有的包括封禁的）投票才算通过投票时需要附带中继节点的签名（合约可以验证签名来核查投票结果并允许用户提取对应资产）每次作恶罚没一定比例的保证金（比如5万），罚没的保证金转给平台地址如果某个节点持续作恶，会不断损失保证金，平台也可以将其从中继节点列表中移除跨链通道要进行跨链交易，需要在两条链之间创建一个通道通道是有方向的，一般情况要添加双向的：A链->B链和B链->A链通道需指定两条链关联的代币地址相同的两条链可添加多对代币地址参与角色普通用户-web前端：发起跨链请求、领取跨链资产、查看交易记录（历史的和进行中的）中继节点-后台服务：跨链交易投票、帮用户自动领取跨链资产中继节点-web前端：查看管理保证金、查看收益、查看投票记录平台管理-web前端：查看管理中继节点、查看保证金、查看收益列表、查看修改黑名单、查看交易记录数据分析与监控：交易汇总分析、中继节点收益分析、资金流动分析、跨链桥异常预警合约设计核心流程：用户在A链存入（冻结）资产、中继节点投票（签名）确认、使用超2/3的签名在B链取出（解冻）资产引入一个廉价的链来存储投票过程，而不是中继节点自行共识，投票过程更安全，也可追溯，提高系统的可用性、安全性用来投票的链这里称为桥链（bridge chain），它还可用来存储一些其它数据或运行一些服务使用签名技术减少合约调用次数，简化设计与节省交易gas费为了节省交易gas费，所有投票在桥链上完成，其它功能也尽量在桥链上实现投票就是签名，用户投票则是将签名写入到桥链合约中跨链通道定义：通道id=keccak256(来源链id,来源链代币地址,目标链id,目标链代币地址)跨链交易定义：交易id=keccak256(通道id,时间戳,接收者,金额,手续费)跨链交易记为KR，投票就是对KR进行签名，记为：KS，有效投票需满足数据无篡改和签名可验证架构桥核心合约（资产）：跨链资金出入口、中继成员列表、黑名单列表桥治理合约（投票）：签名存储与验证、保证金管理、惩罚机制、手续费分发桥链部署：治理合约A链部署：资产合约B链部署：资产合约C链部署：资产合约桥核心合约接口-添加中继节点接口-移除中继节点接口-将账户地址加入黑名单接口-将账户地址从黑名单删除接口-添加跨链通道接口-移除跨链通道接口-跨链转入资产（用户资产充足且未在黑名单内）接口-跨链取出资产（需通过2/3的中继节点签名验证）事件-中继节点变更、黑名单变更、资产转入、资产转出、资产解冻、交易取消查询-中继节点、黑名单、跨链USDT额度（到不同链上的额度）变量-跨链USDT额度列表、中继节点列表、黑名单列表桥治理合约接口-增加保证金接口-减少保证金接口-上传签名（验证签名，作恶罚没）事件-保证金变更、签名提交、投票结果、罚没查询-保证金、签名、罚没次数、罚没金额变量-保证金余额列表、签名列表、跨链交易列表、惩罚记录表合约执行以以太坊和波场为例，以稳定币USDT为例初始化两条链的桥核心合约设置相同的10个中继节点地址和黑名单列表在桥链的桥治理合约中为10个中继节点地址冲入20万保证金平台往两条链的桥核心合约中存入10万USDT作为流动资金Ethereum >>> Tron 跨链用户调用Ethereum链资产合约的跨链转入接口检查用户不在黑名单内，黑名单用户交易直接失败将用户的1万个USDT转到资产合约地址名下更新变量：到Tron链的跨链USDT额度减少1万发出事件：跨链转入（起始链ID + 目标链ID + 金额 + 目标链代币合约地址）中继节点调用桥链上的桥治理合约上传签名接口接收用户的跨链请求事件，可以等待N个区块确认（避免区块分叉导致交易失效）对此跨链事件进行签名并提交到投票合约中（如果不认可则可以忽略）在签名满7个时检查投票结果，如果有超2/3的有效票则进行以下操作：对此次跨链请求作恶的中继节点执行罚没分发跨链交易手续费发出事件：投票完成（跨链请求交易哈希 + 可提取代币地址 + 可提取金额 + 7个签名）中继节点调用Tron链桥核心合约的跨链转出接口检查合约持有的USDT是否足够检查7个签名是否有效，且签名地址在中继节点列表中给用户指定的接收地址转9995个USDT（从桥核心合约地址名下）更新变量：Ethereum链的跨链USDT额度增加1万发出事件：跨链取出（跨链请求交易哈希 + 代币地址 + 金额）状态变更总结Ethereum链的资产合约:持有的USDT数量：10万 -> 11万桥链的投票合约：签名列表：+ 跨链请求的7个有效签名Tron链的资产合约：持有的USDT数量：10万 -> 9万用户在Ethereum上的USDT减少1万，在Tron链上获得9995个7个中继节点在桥链上获得3.5/7个USDT平台获得1.5个USDTTron >>> Ethereum 跨链此操作和Ethereum >>> Tron跨链操作流程一样跨链手续费同样在桥治理合约中分发一开始只有两条链上的USDT很少，后期会随着交易量增长用户兑换时可检查目标链上是否有充足的币来决定是否发起交易如果用户一时提取不到资产，待桥核心合约有足够的资金再重试跨链桥特点同一笔跨链交易需按顺序执行：A链转入、投票、B链转出需要2/3的中继节点投票，确保每一笔交易都是有效的不同跨链交易可异步执行，桥链的TPS高，速度快使用相对廉价的链合约来处理投票过程，安全性高，透明度高惩罚机制，提高相同的稳定性多链多币支持，拓展性强平台只是审查中继节点列表，跨链交易由中继节点共识投票确认，去中心化程度高
与以太坊的账户模型不同，比特币是没有余额概念的，使用的是UTXO模型。所以在比特币网络中，存储比特币的是交易输出，准确点说就是未使用过的交易输出。UTXOUTXO是Unspent Transaction Outputs的缩写（Transaction可简写为TX），即未使用过的交易输出。比特币节点会追踪UTXO集合，从而确定哪些代币未被花费，以及哪些人可以花费它们。最初的比特币是通过铸币交易创造的，它是用来奖励矿工的一种特殊交易，因为是凭空创造的，所以它没有输入的。新的UTXO是通过花费现有UTXO创建的，UTXO包含了接收地址和金额。每个比特币交易都由输入和输出组成。输入花费已有UTXO，输出则创建新的UTXO，UTXO只要被用一次，就不存在“未花费”了，以后就不会再被引用，这样就解决双花（双重支付）问题。当我们要使用一个UTXO时，需要对UTXO进行解锁（一般是用私钥对UTXO进行签名），虽然UTXO是公开的，但是如果没有私钥去解锁，则不能花费UTXO。交易结构交易是比特币的核心数据结构，包括区块在内的数据结构都是在为交易服务。交易主要由未花费的输入和输出组成，输出总金额不能大于输入的总金额，多余的部分为交易矿工费有三种类型交易铸币交易（Generation TX），有额外的Coinbase字段，矿工可以随意填写一些信息，因为是挖矿所得，所以这种交易类型没有输入，输出数量就是矿工所得，地址是矿工的地址。普通交易（Pubkey Hash TX），转账交易，一个或多个输入，一个或两个输出，第一个输出称为支付，第二个输出称为找零脚本交易（Script Hash TX），一般为多签脚本，为普通交易升级版本，可以生成灵活的锁定脚本，然后使用特定的解锁脚本去花费比特币字段表数据项大小(Byte)数据类型描述nVersion4int32_t交易版本vin不定CTxIn列表交易输入vout不定CTxOut列表交易输出nLockTime4uint32_t交易锁定时间交易输入CTxIn数据项大小(Byte)数据类型描述prevout不定COutPoint上一个交易的输出，由交易哈希和索引值确定scriptSig不定char[]解锁脚本nSequence4uint32_t序列号，可用于相对时间锁定交易输出CTxOut数据项大小(Byte)数据类型描述nValue8int64_t交易输出金额，单位为SatoshisscriptPubKey不定char[]锁定脚本，定义花费须满足的条件创币交易CoinbaseTransaction每一个区块内包含的第一条交易为CoinbaseTransaction，它作为对挖出该区块的矿工的比特币奖励交易。没有交易输入交易哈希为0输出的索引值固定，为0xffffffffBIP34规定增加一个4字节的height的字段，这个参数是必须的源码参考代码路径：https://github.com/bitcoin/bitcoin/blob/master/src/primitives/transaction.hCOutPut/** An outpoint - a combination of a transaction hash and an index n into its vout * ** 一个交易哈希值与输出下标的集合 */ class COutPoint { public: uint256 hash; //交易哈西 uint32_t n; //对应序列号 COutPoint(): n((uint32_t) -1) { } COutPoint(const uint256& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { } ADD_SERIALIZE_METHODS; //用来序列化数据结构，方便存储和传输 template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(hash); READWRITE(n); } void SetNull() { hash.SetNull(); n = (uint32_t) -1; } bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); } //小于号<重载函数 friend bool operator<(const COutPoint& a, const COutPoint& b) { int cmp = a.hash.Compare(b.hash); return cmp < 0 || (cmp == 0 && a.n < b.n); } //==重载函数 friend bool operator==(const COutPoint& a, const COutPoint& b) { return (a.hash == b.hash && a.n == b.n); } //!=重载函数 friend bool operator!=(const COutPoint& a, const COutPoint& b) { return !(a == b); } std::string ToString() const; };CTxIn/** An input of a transaction. It contains the location of the previous * transaction's output that it claims and a signature that matches the * output's public key. * **交易的输入，包括当前输入所对应上一笔交易的输出位置， *并且还包括上一笔输出所需要的签名脚本 */ class CTxIn { public: COutPoint prevout; //上一笔交易输出位置 CScript scriptSig; //解锁脚本 uint32_t nSequence; /**序列号，可用于交易的锁定 nSequence字段的设计初心是想让交易能在在内存中修改，可惜后面从未运用过 对于具有nLocktime或CHECKLOCKTIMEVERIFY的交易， nSequence值必须设置为小于2^32，以使时间锁定器有效。通常设置为2^32-1 由于BIP-68的激活，新的共识规则适用于任何包含nSequence值小于2^31的输入的交易（bit 1<<31 is not set）。 以编程方式，这意味着如果没有设置最高有效（bit 1<<31），它是一个表示“相对锁定时间”的标志。 否则（bit 1<<31set），nSequence值被保留用于其他用途， 例如启用CHECKLOCKTIMEVERIFY，nLocktime，Opt-In-Replace-By-Fee以及其他未来的新产品。 一笔输入交易，当输入脚本中的nSequence值小于2^31时，就是相对时间锁定的输入交易。 这种交易只有到了相对锁定时间后才生效。例如， 具有30个区块的nSequence相对时间锁的一个输入的交易 只有在从输入中引用的UTXO开始的时间起至少有30个块时才有效。 由于nSequence是每个输入字段，因此交易可能包含任何数量的时间锁定输入， 所有这些都必须具有足够的时间以使交易有效。 */ CScriptWitness scriptWitness; //! Only serialized through CTransaction /* Setting nSequence to this value for every input in a transaction * disables nLockTime. * * 规则1:如果一笔交易中所有的SEQUENCE_FINAL都被赋值了相应的nSequence，那么nLockTime就会被禁用 */ static const uint32_t SEQUENCE_FINAL = 0xffffffff; /* Below flags apply in the context of BIP 68*/ /* If this flag set, CTxIn::nSequence is NOT interpreted as a * relative lock-time. * * 规则2:如果设置了该值，nSequence不被用于相对时间锁定。规则1失效 */ static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31); /* If CTxIn::nSequence encodes a relative lock-time and this flag * is set, the relative lock-time has units of 512 seconds, * otherwise it specifies blocks with a granularity of 1. * * 规则3：如果规则1有效并且设置了此变量，那么相对锁定时间单位为512秒，否则锁定时间就为1个区块 */ static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22); /* If CTxIn::nSequence encodes a relative lock-time, this mask is * applied to extract that lock-time from the sequence field. * * 规则4：如果nSequence用于相对时间锁，即规则1有效，那么这个变量就用来从nSequence计算对应的锁定时间 */ static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff; /* In order to use the same number of bits to encode roughly the * same wall-clock duration, and because blocks are naturally * limited to occur every 600s on average, the minimum granularity * for time-based relative lock-time is fixed at 512 seconds. * Converting from CTxIn::nSequence to seconds is performed by * multiplying by 512 = 2^9, or equivalently shifting up by * 9 bits. * * 相对时间锁粒度 * 为了使用相同的位数来粗略地编码相同的挂钟时间， * 因为区块的产生限制于每600s产生一个， * 相对时间锁定的最小单位为512是，512 = 2^9 * 所以相对时间锁定的时间转化为相当于当前值左移9位 */ static const int SEQUENCE_LOCKTIME_GRANULARITY = 9; CTxIn() { nSequence = SEQUENCE_FINAL; } explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL); CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL); ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(prevout); READWRITE(scriptSig); READWRITE(nSequence); } friend bool operator==(const CTxIn& a, const CTxIn& b) { return (a.prevout == b.prevout && a.scriptSig == b.scriptSig && a.nSequence == b.nSequence); } friend bool operator!=(const CTxIn& a, const CTxIn& b) { return !(a == b); } std::string ToString() const; };CTxOut/** An output of a transaction. It contains the public key that the next input * must be able to sign with to claim it. * **交易输出，包含输出金额和锁定脚本 */ class CTxOut { public: CAmount nValue; //输出金额 CScript scriptPubKey; //锁定脚本 CTxOut() { SetNull(); } CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn); ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nValue); READWRITE(scriptPubKey); } void SetNull() { nValue = -1; scriptPubKey.clear(); } bool IsNull() const { return (nValue == -1); } friend bool operator==(const CTxOut& a, const CTxOut& b) { return (a.nValue == b.nValue && a.scriptPubKey == b.scriptPubKey); } friend bool operator!=(const CTxOut& a, const CTxOut& b) { return !(a == b); } std::string ToString() const; };CTransaction/** The basic transaction that is broadcasted on the network and contained in * blocks. A transaction can contain multiple inputs and outputs. * * ** 基本的交易，就是那些在网络中广播并被最终打包到区块中的数据结构。 * 一个交易可以包含多个交易输入和输出 */ class CTransaction { public: // Default transaction version. static const int32_t CURRENT_VERSION=2; //默认交易版本 // Changing the default transaction version requires a two step process: first // adapting relay policy by bumping MAX_STANDARD_VERSION, and then later date // bumping the default CURRENT_VERSION at which point both CURRENT_VERSION and // MAX_STANDARD_VERSION will be equal. /** 更改默认交易版本需要两个步骤： * 1.首先通过碰撞MAX_STANDARD_VERSION来调整中继策略， * 2.然后在稍后的日期碰撞默认的CURRENT_VERSION * * 最终MAX_STANDARD_VERSION和CURRENT_VERSION会一致 */ static const int32_t MAX_STANDARD_VERSION=2; // The local variables are made const to prevent unintended modification // without updating the cached hash value. However, CTransaction is not // actually immutable; deserialization and assignment are implemented, // and bypass the constness. This is safe, as they update the entire // strcture, including the hash. /** 下面这些变量都被定义为常量类型，从而避免无意识的修改了交易而没有更新缓存的hash值； * 然而CTransaction不是可变的 * 反序列化和分配被执行的时候会绕过常量 * 这才是安全的，因为更新整个结构包括哈希值 */ const std::vector<CTxIn> vin; //交易输入 const std::vector<CTxOut> vout; //交易输出 const int32_t nVersion; //版本 const uint32_t nLockTime; //锁定时间 private: /** Memory only. */ const uint256 hash; uint256 ComputeHash() const; public: /** Construct a CTransaction that qualifies as IsNull() */ CTransaction(); /** Convert a CMutableTransaction into a CTransaction. */ /**可变交易转换为交易*/ CTransaction(const CMutableTransaction &tx); CTransaction(CMutableTransaction &&tx); template <typename Stream> inline void Serialize(Stream& s) const { SerializeTransaction(*this, s); } /** This deserializing constructor is provided instead of an Unserialize method. * Unserialize is not possible, since it would require overwriting const fields. * ** 提供此反序列化构造函数而不是Unserialize方法。 * 反序列化是不可能的，因为它需要覆盖const字段 */ template <typename Stream> CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {} bool IsNull() const { return vin.empty() && vout.empty(); } const uint256& GetHash() const { return hash; } // Compute a hash that includes both transaction and witness data uint256 GetWitnessHash() const; //计算包含交易和witness数据的散列 // Return sum of txouts. CAmount GetValueOut() const; //返回交易出书金额总和 // GetValueIn() is a method on CCoinsViewCache, because // inputs must be known to compute value in. /** * Get the total transaction size in bytes, including witness data. * "Total Size" defined in BIP141 and BIP144. * @return Total transaction size in bytes */ unsigned int GetTotalSize() const; // 返回交易大小 bool IsCoinBase() const //判断是否是创币交易 { return (vin.size() == 1 && vin[0].prevout.IsNull()); } friend bool operator==(const CTransaction& a, const CTransaction& b) { return a.hash == b.hash; } friend bool operator!=(const CTransaction& a, const CTransaction& b) { return a.hash != b.hash; } std::string ToString() const; bool HasWitness() const { for (size_t i = 0; i < vin.size(); i++) { if (!vin[i].scriptWitness.IsNull()) { return true; } } return false; } };
公钥：e、n，私钥：d、n，加密：C=M^e % n，解密：M=C^d % n。其中：n=p*q（p和q为大质数），1<e<ϕ(n)，gcd(e,ϕ(n))=1，ed % ϕ(n)=1，M为信息，C为密文数论基础质数：又称素数，一个大于1的自然数，除了1和它自身外，不能被其他自然数整除的数模运算：求余运算，整除运算中，求a除以b的余数，可用mod表示，即r = a mod b同余：两个整数a、b，若它们除以正整数m所得的余数相等，则称a、b相对于模m同余，记作: a≡b(mod m)最大公因数：指两个或多个整数共有因数中最大的一个，a和b的最大公因数记作：gcd(a,b)互质：若N个整数的最大公因数是1，我们就称这N个整数互质，即gcd(a,b)=1，a和b互质欧拉函数：对于正整数n，小于n的正整数中与n互质的数的个数，记为ϕ(n)，特别的ϕ(1)=1欧拉定理：若两个正整数a和m互质，那么a的φ(m)次方除以m的余数为1，即a^ϕ(m)≡1(mod m)模反元素：如果两个正整数a和n互质，则一定可以找到整数b，使得a×b-1被n整除，或者说ab≡1(mod n)，称b为a相对于n的模反元素比如，3和11互质，那么3相对于11的模反元素就是4，因为(3 × 4)-1可以被11整除a^(ϕ(n)-1)为a相当于n的模反元素，因a^ϕ(n)≡1(mod n) => a^(1+ϕ(n)-1)≡1(mod n) => a×a^(ϕ(n)-1)≡1(mod n)同余相关性质若a≡b(mod m)，b≡c(mod m)，则a±c≡b±d(mod m)若a≡b(mod m)，b≡c(mod m)，则a×c≡b×d(mod m)若a≡b(mod m)，那么a^n≡b^n(mod m)若a≡b(mod m)，n为m因数,则a≡b(mod n)互质相关性质任意两个质数是互质数较小数是质数，较大数不为它的倍数，这两个数是互质数较大数是质数的两个数是互质数1和任意一个自然数是是互质数2和任何奇数是互质数相邻的两个自然数是互质数相邻的两个奇数是互质数欧拉相关性质ϕ(1)=1，ϕ(2)=1当n是质数时，ϕ(n)=n-1当p为质数时，k为自然数，那么ϕ(p^k)=p^k - p^(k-1)当a和b互质时，ϕ(ab)=ϕ(a)ϕ(b)，故当n是奇数时，ϕ(2n)=ϕ(n)任意一个大于1的正整数，都可以写成一系列质数的积只有p的倍数与p^k互质，共有p^(k-1)个，即1p、2p、3p...p^(k-1)p，把它们去除，剩下的就是与p^k互质的数了，即ϕ(p^k)=p^k - p^(k-1)算法选择两个大质数p和q计算n=p×q，计算欧拉函数ϕ(n)=(p-1)×(q-1)选择一个数e，满足：1<e<ϕ(n)，且e与ϕ(n)互质计算e相对于ϕ(n)的模反元素d，即ed≡1(mod ϕ(n))公钥为{e，n}，私钥为{d，n}加密：C=M^e(mod n)，解密：M=C^d(mod n)，M为信息，C为密文，M需小于nRSA签名可用私钥加密信息摘要，验证者用公钥解密签名，和给出的签名进行一致性判断 *大质数生成随机构造一个满足最终大质数长度的奇数n判断n是不是质数，如果是则输出n，否则n=n+2并重复此步骤使用质数定义判断，将n除以2到n的算术平方根之间的所有数，如果余数都不为0，则此数一定为质数使用素性检测算法（Fermat、Miller–Rabin等等），多次判断此数都为质数的情况下，则此数极大概率为质数查找互质数利用互质特性直接得出结果（两个相邻的自然数是互质数，较小质数与不是倍数的较大数互质）使用辗转相除法计算两个数的最大公约数，如果是1，则两数互质计算模反元素随机选择一个正整数k根据定义：a×b % n = 1，则a相对于n的模反元素b = (k×n + 1) / a快速幕模算法计算a^b%n(a<n)，如果a和b很大，可以使用同余的性质来快速计算结果根据同余性质，有(a × a) % n = (a%n × a%n) % n若b为偶数，则a^b%n = (a^(b/2)%n × a^(b/2)%n) % n若b为奇数，则a^b%n = (a^(b/2)%n × a^(b/2)%n × a) % n令b' = b/2，有a^(b/2)%n = a^b'%n故这里可以使用递归的方式计算a^b%n，不断将b除2，直到1为止安全性随机数：使用完全随机的算法，避免潜在的安全，如果随机数被预测，私钥就有可能被破解密钥长度：为了保持算法的安全性，必须选择足够大的密钥长度，最低需要1024位，推荐使用2048位参数选择：尽量不重复使用大质数p和q，也不要选择太大或太小的e和d证明证明：M=C^d mod n (C=M^e mod n, 0<M<n)C^d mod n 代入C = M^e mod n = (M ^ e mod n)^d mod n 同余化简(a mod n) mod n = a mod n = M ^ (e × d) mod n 代入e × d = k × ϕ(n) + 1（k为任意正整数），因ed互为ϕ(n)的逆元 = M ^ (k × ϕ(n) + 1) mod n 等价转换 = M ^ (ϕ(n) × k) × M mod n 接下来需要证明此式等于M即可由n=p×q，M<n，可知M有三种情况：与n互质、p的倍数、q的倍数若M和n互质M ^ (ϕ(n) × k) × M mod n 代入M^ϕ(n) mod n = 1（欧拉定理） = 1^k × M mod n 代入1^k mod n = 1 = M mod n = M若M为p的倍数，则M必和q互质，M ^ (ϕ(n) × k) × M mod n 代入ϕ(n) = ϕ(p) × ϕ(q) = M ^ (ϕ(p) × ϕ(q) × k) × M mod n 因q为n的因数，使用a mod n = a mod q转换 = M ^ (ϕ(p) × ϕ(q) × k) × M mod q 代入M ^ ϕ(q) mod q = 1 （欧拉定理） = 1^(ϕ(p) × k) × M mod q 代入1^(ϕ(p) × k) mod q = 1 = M mod q = M同理可证M为q的倍数的情况
Restaking（再质押）是DeFi（去中心化金融）深化发展后的一种复杂产品形态，也是以太坊共识机制转PoS后才出现的新型金融衍生品。一、质押质押的概念出现于区块链的PoS共识机制（Poof of Staking，权益证明）。目前主要有两个主流的共识机制：PoW（Poof of Work，工作量证明）和PoS（Poof of Staking，权益证明）。区块链世界的鼻祖比特币就是采用的 PoW 共识机制。简单说，区块链相当于一个全球化的分布式账本，为了维护这个去中心化系统的运作，需要有人去算账和记账。以太坊区块链最开始也是采用的PoW共识机制，但是PoW也存在一些问题，比如消耗大量电力去计算数学题，没有产生任何对现实世界有价值的收益，而且出现了专门用来挖矿的设备以及具有规模化挖矿的矿场企业，趋向中心化了。因此后来出现了PoS共识机制（Poof of Staking，权益证明），就是想要获得记账权的人把代币质押到一个地方当作保证金，谁持有的代币更多和持有得更久，谁获得记账权的概率就越高，这样大家就不用消耗大量的算力来算没用的数学题了。质押就是让用户锁定一定资金作为保证金后成为节点，去维护项目的安全，从而赚取收益，若节点作恶则会罚没保证金。从技术视角看，质押是为了维持去中心化系统的自我运作PoW是通过算力占比来获得记账权；PoS是通过资产占比来获得记账权；从金融视角看，质押可以控制链上经济系统的货币发行PoW将代币直接奖励给矿工，矿工将链上资产换成现实世界资产买矿机，继续投入挖矿，实现了区块链世界和现实世界的融合；PoS将代币直接奖励给质押者，质押者通过质押资产获取了收益，质押资产变更了具有稳定收益率的 “国债”，衍生了各类金融玩法。质押方案独立质押：运行节点，成为质押者，需要32个ETH，这个是最基本的质押模式；质押即服务：运行节点很麻烦，需要一直在线，因此出现了质押即服务，同样需要32个ETH，但无需运行节点，将节点运作的工作委托给第三方运营商；联合质押32个ETH的门槛还是很高，因此出现了联合质押的平台，不需要32个ETH，每个人可以与其他人一起质押任意数量的 ETH，将节点运作委托给第三方；中心化交易所：使用联合质押的平台还是有一定门槛，用户需要懂得使用区块链应用，同时这类应用可能会存在合约风险，比如智能合约存在漏洞，被黑客攻击等等，因此出现中心化交易所帮助用户进行质押的需求，用户将资金完全交给交易所，交易所进行质押。这四种方案门槛是不断降低的，操作上也越来越简单，这样就可以触达更多的用户，当然，用户资产面临的风险也是越来越大的，越来越不受用户自己掌控。流动性质押（LSD）用户将资产质押了之后，资产就被锁在了链上，此时资金利用效率很低，因此出现了流动性质押平台（Liquid Staking Derivatives，LSD），比如Lido，当你质押了1个ETH，平台会1比1给你一个质押凭证，即1个stETH。这类流动性质押平台一般采用的是联合质押模式，用户可存入任意数量的ETH，帮助用户进行节点质押，用户可获得质押凭证，让用户可在DeFi中进行交易、借贷、提供流动性等操作，提升了资金使用效率。其实这可以类似银行存款，你将现金存到了银行，银行会给你一个存款凭证，然后你可以继续使用这个存款凭证做其他事情，比如交易、抵押借贷等。二、再质押除了区块链采用的PoS机制需要用户质押资产之外，很多项目也都需要Staking来保证项目安全，比如跨链桥、预言机、数据可用性层、零知识证明等。那么，每上线一个新项目，这个项目就需要用户锁定一定的资金，用户的流动资金就那么多，这就造成了不同项目之间的竞争。各个项目为了项目安全性不得不竞争市场上有限的流动资金，随着不同项目给出的质押收益率越来越高，项目自身承担的风险也越来越高，变成了一个恶性循环。另一方面，用户也只能把有限的资金选择有限的项目质押进去获得有限的回报，资金的利用率较低。随着公链、应用、各类项目越来越多，流动性也越来越割裂。因此，市场上出现了 “共享安全性” 的需求，需要有一个平台可以将用户质押的资产为多个项目提供安全性，这就是再质押（Restaking）出现的背景。类比现实世界，一些弱小的国家会引入强大国家的军事力量，自己则无需花费更多的资金构建自己专属的军事力量。目前安全性最强的PoS机制公链就是以太坊，以太坊上质押了大量的资金，具有极强的安全性，因此非常值得将以太坊的安全性共享给其他项目。另一方面，再质押可以为stETH这类质押凭证拓展了更多的应用场景，通过各类协议的可组合性，实现了以太坊生态的 “金融乐高”。再质押定义根据再质押出现的背景以及解决的问题，我们可以给一个再质押的定义：再质押的本质是建立一个共享质押池，从而实现共享安全性。这个共享资金池可以将一份资金同时为多个项目质押保证安全性，从而实现一鱼多吃，让资金与项目的关系从 1:1 变为 1:N。一方面，用户可以获得超额回报，另一方面减轻了项目争抢质押资金的压力。还有一种理解的视角是：Restaking是POS领域的合并挖矿。在 PoW 机制中，矿工可以通过挖掘使用同样Hash算法的主链和辅链来一鱼两吃，但是合并挖矿只提高了一定收益但没有继承安全性；但在PoS机制中，由于PoS有罚没机制，即作恶者节点的质押资金会被罚没，所以在Restaking中在辅链里作恶的行为会传回主链进行质押金的罚没，在这一点上可以继承主链的安全性。收益叠加对于用户来说，质押ETH得到LST（Liquid Staking Token），比如通过Lido等流动性质押协议获取的stETH；第二次质押LST得到LRT（Liquid Restaking Token），用户将stETH这类LST资产委托给流动性再质押协议，协议替用户将LST存入EigenLayer再质押，获得抵押凭证代币，即LRT资产，LRT可以进行再一次交易、借贷等等的金融操作。每多质押一次，就多了一次利用流动性博取收益的机会。风险加倍1、套娃风险牛市上升周期，风险会被对冲；但是到了熊市，在下行周期，风险就会被放大。多次质押，收益叠加，风险也会随之叠加。这就是以太坊创始人 Vitalik 所说的 “共识过载”：共享安全性后，劣势项目存在风险，最终给以太坊带来不可预知的风险。以太坊未来的终局是成为一条底层链，因此不能太复杂，需要保持简洁性，这类Restaking技术可能会产生连环爆雷从而影响以太坊安全。2、罚没风险以太坊质押机制中有 50% 的罚没风险，再质押协议对节点也有 50% 的罚没风险。因此，用户资金依旧会遇到资金罚没的风险，但是风险被均摊。3、可持续性风险没有能力做验证器的项目，项目风险可能比较大。这就像传统金融世界中的贷款，如果一个项目没有能力从银行贷款，那么说明这类项目的资质一般较差，风险较高，只能从其他渠道借高利贷。虽然项目给的利率高，但是风险也非常高。再质押赛道的新产品前期靠空投吸引质押资金，后期需要管控项目风险。最关键的是，再质押赛道的产品可以产生正向现金流，这样才能证明其模式具有可持续性。EigenLayer项目EigenLayer 是一个基于以太坊构建的协议，为以太坊生态引入了再质押的概念，用户可以将质押的 ETH 或 LST 重新质押，以此将以太坊的安全性扩展到以太坊生态中的其他应用。“共享安全性” 这个概念并非 EigenLayer 首创，Polkadot 的插槽方案、Cosmos 的链间安全共享、Avalanche 的子网都是安全共享的老玩家了，但 EigenLayer 首次在以太坊生态引入共享安全性。简单来说，EigenLayer 就是一个大型押金接单平台。EigenLayer 提供一个开放市场机制，让购买服务者可以根据自己的风险偏好自由选择自己需要的服务。而 EigenLayer 作为服务中介，将从 LSD 再次分配到中间件和基础设施中获得收益。除了 Restaking 业务之外，EigenLayer 还有一个产品叫 EigenDA，构建在 EigenLayer 之上。EigenDA 是 EigenLayer 上的第一个 AVS，可以理解为打样的自营 AVS，通过 EigenLayer 再质押提供的共享加密经济安全性，为 Rollup 提供经济高效、超大规模吞吐量的数据可用性。目前 EigenLayer 是再质押赛道的龙头项目，2024 年 2 月加密行业的头部投资机构 a16z 再次投资了 1 亿美元，估值可能达到百亿美元。再质押模式EigenLayer支持的再质押模式一共有4种：Native restaking：原生再质押，验证者可以将已经质押在以太坊中的 ETH 再次质押到 EigenLayer 中，此时一个 ETH 同时作为以太坊和 EigenLayer 的抵押品；这个过程是 L1→ EigenLayer。LST restaking：LST 再质押，用户将自己存入 LSD（流动性质押）协议后得到的 LST（质押凭证，如 stETH）存入 EigenLayer 再质押；这个过程是 DeFi →EigenLayer 。ETH LP restaking：ETH 金融衍生品再质押，这一种是第一种衍生出来的，即然在以太坊中质押的 ETH 可以再质押，那么只要包含 ETH 的金融资产也可以再质押，比如用户在去中心化交易所中提供流动性得到的包含 ETH 的存款凭证（LP 代币）；这个过程是 DeFi →EigenLayer 。LST LP restaking：LST LP 再质押，这一种是第二种衍生出来的，即然 LST（质押凭证，如 stETH）可以再质押，那么只要包含 LST 的金融资产也可以再质押，比如用户在去中心化交易所中提供流动性得到的包含 LST 资产的存款凭证（LP 代币）；这个过程是 L1 → DeFi→EigenLayer。从这四种质押模式可以看到，EigenLayer 支持和兼容了 ETH 资产以及 ETH 衍生出来的一系列资产，这些都被视为有价值的资产，可以用于再质押。系统架构EigenLayer整体可以分为4层，从下向上分别是：以太坊主网：EigenLayer构建在以太坊主网之上，因此最底层的基础是以太坊主网。中间层：中间层是AVS操作员（Operators），即节点运营商，在整个协议中是中间人的角色，Staker和AVS之间的桥梁，它帮助Staker管理资金，同时又帮助AVS执行具体任务。角色层质押者：为AVS提供资金以此赚取收益，将原生 ETH 或 LST ETH 重新抵押到 EigenLayer 协议的人；消费者：各种需要使用质押服务来保证安全性的项目；AVS开发者：在EigenLayer上构建自己的安全服务；治理层：EigenLayer的治理层；总的来说，Staker投入了资金成本，Operator投入了资源成本（运行节点所需的资源），AVS使用前面两者的服务，付出资金成本。
以太坊作为一个不断发展的区块链平台，随着时间的推移引入了多个改进提案来提升其性能和用户体验，其交易的数据结构也在一直“进化”交易类型过去，以太坊的交易都采用同一种格式：RLP([nonce, gas_price, gas_limit, to, value, data, v, r, s])在EIP-2718（2021年4月15日柏林（Berlin)升级）改进协议中，定义了一种带交易类型的通用交易格式：TransactionType || TransactionPayload将上述字段连接（合并）起来，即可得到一个类型化交易。字段的定义是：TransactionType：0至0x7f范围内的某个值，最多可代表128种事务类型。TransactionPayload：由事务类型定义的任意一个字节数组。EIP-2718没有为交易的有效负载定义格式。因此，交易的有效负载可以是任意一段经过编码的字节序列，只要采用符合新的交易类型（如RLP、SSZ等）定义的编码器即可。之所以选择简单的字节相连方式，是因为读取字节数组的第一个字节非常简单，无需使用任何库或工具。新的交易类型最多可达0x7f种。选择这一上限是为了保证向后兼容传统交易。经过RLP编码的交易的第一个字节始终大于或等于0xc0，因此类型化交易永远不会与传统交易产生冲突，而且类型化交易和传统交易之间可以通过第一个字节来区分。以太坊目前的源代码中定义了四种交易类型：// Transaction types. const ( LegacyTxType = 0x00 AccessListTxType = 0x01 DynamicFeeTxType = 0x02 BlobTxType = 0x03 )Legacy交易Legacy交易是以太坊早期的交易类型，从链开始持续很长时间都是此类型的交易。特点：Gas价格（Gas Price）：用户设定的固定值，表示愿意为每个Gas单位支付的费用。Gas限额（Gas Limit）：用户愿意为交易支付的最大Gas数量。交易费用：由 Gas Price * Gas Used 计算得出。示例：{ "from": "0xSenderAddress", "to": "0xRecipientAddress", "value": "1000000000000000000", // 1 ETH in Wei "gas": 21000, "gasPrice": "20000000000" // 20 Gwei }AccessList交易EIP-2930（2021年4月15日柏林（Berlin)升级）改进协议，引入了访问列表（Access List）功能，以优化Gas费和提高交易效率。增加了以下格式的交易：0x01 || RLP([chain_id, nonce, gas_price, gas_limit, to, value, data, access_list, y_parity, r, s])特点：访问列表（Access List）：提前声明交易将访问的存储和合约地址，减少Gas费。Gas价格和Gas限额：与Legacy交易类似，但增加了访问列表字段。示例：{ "from": "0xSenderAddress", "to": "0xRecipientAddress", "value": "1000000000000000000", // 1 ETH in Wei "gas": 21000, "gasPrice": "20000000000", // 20 Gwei "accessList": [ { "address": "0xContractAddress", "storageKeys": ["0xStorageKey1", "0xStorageKey2"] } ] }DynamicFee交易EIP-1559（2021年8月5日伦敦（London)升级）改进协议，引入动态费用功能，旨在改善Gas费的预测和用户体验。增加了以下格式的交易：0x02 || RLP([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, access_list, y_parity, r, s])特点：基础费用（Base Fee）：由网络动态调整，不会支付给矿工，而是被销毁。优先费（Priority Fee）：支付给矿工的费用，类似于小费，以激励矿工优先处理交易。最大费用（Max Fee）：用户愿意支付的最高费用，包括基础费用和优先费。示例：{ "from": "0xSenderAddress", "to": "0xRecipientAddress", "value": "1000000000000000000", // 1 ETH in Wei "maxFeePerGas": "30000000000", // 30 Gwei "maxPriorityFeePerGas": "2000000000", // 2 Gwei "gasLimit": 21000 }Blob交易EIP-4844（2024年3月13日坎昆（Cancun）升级）改进协议，可以将L2分片数据以廉价的方式提交到链上，旨在大幅提升以太坊的扩展性。增加了以下格式的交易：0x03 || RLP([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, access_list, max_fee_per_blob_gas, blob_versioned_hashes, y_parity, r, s]) 特点：数据分片（Data Sharding）：引入数据分片来分担以太坊主链的负载，大幅提高交易吞吐量。Blob数据：EIP-4844引入了新的交易类型，包含“blob”数据，这些数据不会永久存储在以太坊节点中，而是短期存储，提高数据处理效率。示例：{ "from": "0xSenderAddress", "to": "0xRecipientAddress", "value": "1000000000000000000", // 1 ETH in Wei "gas": 21000, "maxFeePerGas": "30000000000", // 30 Gwei "maxPriorityFeePerGas": "2000000000", // 2 Gwei "maxFeePerBlobGas": "3000000000", // 3 Gwei "blobVersionedHashes": "0xBlobData" }主要区别总结Gas费用机制：Legacy：用户设定固定的Gas价格。EIP-2930：类似Legacy，但增加了访问列表以优化Gas费。EIP-1559：引入动态调整的基础费用和优先费机制。EIP-4844：引入数据分片和blob数据。新功能：Legacy：无特别优化，使用最早的交易机制。EIP-2930：通过访问列表优化Gas费和交易效率。EIP-1559：改善Gas费预测和用户体验。EIP-4844：大幅提升扩展性，引入数据分片和blob数据。
说明以太坊区块链主要里程碑、分叉和更新的时间表分叉是区块链协议升级或修改，此时区块链会分成“两条链”，一条链继续使用旧的协议，另一条链则应用新的协议。如果协议向后兼容则为软分叉，否则为硬分叉（新协议可正常处理旧协议生成的区块）关键时间表2015年7月30日以太坊主网启动，开始公测，这个初始版本有诸多限制，在上面能做的事情很少，主要面向开发者。2016年3月14日家园分叉，包括若干协议修改和联网变更，相比初始版本来说稳定很多。2017年10月16日拜占庭升级，将区块挖矿奖励从5个以太币减少到3个以太币，修改完善虚拟机。2019年12月8日伊斯坦布尔分叉，优化了虚拟机中特定操作的燃料成本，添加CHAINID虚拟机指令2020年12月1日信标链启动，使用权益证明机制，未来将会替代以太坊的工作量证明机制2022年9月15日巴黎升级（合并），是以太坊历史上最重要的升级！结束了工作量证明挖矿算法及相关共识逻辑，使用信标链作为共识引擎，一个完整的节点包括执行客户端（原以太坊）和共识客户端。所有时间表2013年11月27日：发布白皮书2014年04月01日：发布黄皮书2014年07月22日：预售以太币2015年07月30日：发布第一个版本，前沿（Frontier）2015年09月07日：200,000区块高度，前沿解冻分叉2016年03月14日：1,150,000区块高度，家园（Homestead）分叉2016年07月20日：1,920,000区块高度，去中心化自治组织（DAO）分叉2016年10月18日：2,463,000区块高度，橘子口哨(Tangerine Whistle)分叉2016年11月22日：2,675,000区块高度，伪龙(Spurious Dragon)分叉2017年10月16日：4,370,000区块高度，拜占庭（Byzantium）升级2019年02月28日：7,280,000区块高度，君士坦丁堡（Constantinople）分叉2019年12月08日：9,069,000区块高度，伊斯坦布尔（Istanbul）分叉2020年01月02日：9,200,000区块高度，缪尔冰川（Muir Glacier）升级2020年10月14日：11,052,984区块高度，部署质押存款合约2020年12月01日：0纪元，信标链创世2021年04月15日：12,244,00区块高度，柏林（Berlin）升级2021年08月05日：12,965,00区块高度，伦敦（London）升级2021年10月27日：74,240纪元，天鹰座（Altair）升级2021年12月09日：13,773,000区块高度，箭形冰川（Arrow Glacier）升级2022年06月30日：15,050,000区块高度，灰色冰川（Gray Glacier）升级2022年09月06日：144,896纪元，Bellatrix升级2022年09月15日：15,537,394区块高度，巴黎（Paris）合并2023年04月12日：17,034,870区块高度（194,048纪元），上海嘉佩乐 (Shapella)升级，包括上海（Shanghai）升级和卡佩拉（Capella）升级2024年03月13日：19,426,587区块高度（269,568纪元），坎昆-天津四(Dencun)升级，包括坎昆（Cancun）升级和天津四（Deneb）升级参考链接：https://ethereum.org/zh/historyhttps://eips.ethereum.org/meta
改进CometBFT共识协议亮点在牺牲少部分中心化的情况下大大提高共识的速度无痛替换当前cosmos链的cometBFT共识模块开放更多的验证者参与共识过程双引擎异步工作，提高共识效率可以和当前的cosmos链进行跨链（如gaia）实现思路使用双共识引擎交叉协同工作，子引擎负责交易打包和执行，主引擎负责IBC跨链块的组装和最终块的生成实现方案约定指定质押最多的前N个节点作为子引擎的验证者（这里假设取500个）指定质押最多的前M个节点作为主引擎的验证者（这里假设取20个）两个引擎在一定程度上共享世界状态，但是区块有所不同主引擎共识的结果区块称为“主块”，子引擎共识的结果区块称为“子块”“子块”是一种中间块，不会直接存储，而是间接存储到“主块”中，从“主块”中可以恢复出所有“子块”子引擎工作流程选取一部分有效的交易Txn获取主引擎当前区块高度BH（同一个高度可以重复使用，避免等待主引擎出新块）优先选择主引擎块指定的11个验证者（如果有），否则从500个验证者中使用随机算法抽取11个验证者选择子引擎当前的世界状态T，执行交易，分发奖励和惩罚，得到新的世界状态T'11个验证者使用cometBFT共识出一个新的区块这里产生的是中间块，供主引擎打包使用子引擎区块内容包括正常cometBFT区块和主引擎区块高度主引擎工作流程：选择子引擎最新共识出来的区块列表（同一个高度可以重复使用，避免等待子引擎区块出新块），可以为空列表选择自上个主引擎区块打包的子引擎区块后新的的区块头列表和交易列表（为了避免产生的区块太大、可以只选择0-3个）20个验证者使用cometBFT共识出一个新的区块这里的世界状态等同于最新打包子引擎区块的世界状态主引擎区块内容包括正常cometBFT区块和子引擎区块头列表，交易列表为打包的子引擎区块列表的交易列表之和特性：可以各自出自己的块，不必等待另一个共识引擎工作的结果，主引擎可以以恒定速度出块（空块）子引擎相当于提前执行交易收集打包等工作流程，可以加快主引擎共识速度，同时也在一定程度上增加去中心化程度子引擎共识出的块头完全打包进了主引擎共识出来的块，可以从主引擎共识的块中还原出来的整个共识速度基本上取决于20个验证者，由于节点数量少，甚至可以达到2秒内子引擎共识卡块的解决方案随机的11个验证者可能出现故障导致不能出块，由主引擎重新随机新的11个验证者在一定时间内子引擎如果没有出块，那么主引擎会选择新的验证者，并将其写到区块头中子引擎将由新的11个验证者接管继续出块比如说主引擎连续打包了5个块时，都没有新的子块产生，那么将在第6个区块将指定新的11个验证者子引擎会识别主引擎的区块，并将最新主引擎的区块高度和哈希打包，此时可以识别新的验证者主引擎会打包子引擎的区块，并将最新的子引擎区块头列表打包，同时验证其有效性重要：不管子引擎怎么卡块和分叉，都由主引擎来修正和抉择、主引擎永不分叉流程图共识流程
一、简介Hardhat是以太坊合约开发环境，可以编辑、编译、调试和部署智能合约Hardhat是围绕任务和插件而设计的。每次从命令行运行Hardhat时，都相当于在运行一个任务。例如，npx hardhat compile运行内置编译合约任务。任务可以调用其他任务，从而完成复杂的工作流程二、入门操作系统：Linuxnode：20.5.0npm：9.8.1hardhat：2.17.11、初始化空白项目集成到已有项目可跳过此步骤创建示例目录后使用npm初始化mkdir example && cd example npm init -y2、集成hardhat安装hardhat工具npm install -D hardhat创建hardhat项目npx hardhat选择创建JavaScript项目，按照向导提示操作创建相关文件和安装基本hardhat插件初始化后的项目将包括以下文件：contracts：智能合约文件夹。test：合约测试文件夹。scripts：自动化脚本文件夹。hardhat.config.js：配置文件初始化时自动配置了一个示例合约，可以运行以下命令查看效果npx hardhat compile：编译智能合约npx hardhat test：执行合约测试npx hardhat node：启动一个虚拟的本地测试节点npx hardhat run scripts/deploy.js：运行部署合约脚本3、配置hardhat.config.js是hardhat的配置文件，此文件需要导出一个对象，对象可以包括defaultNetwork、networks、solidity、paths等多个配置选项，如果需要使用插件，则需要在此文件中导入申明，基本的配置文件内容如下/** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: "0.8.19", };网络配置networks字段配置可用的hardhat网络，是一个可选对象。defaultNetwork字段配置hardhat运行时默认使用的网络，如果省略此配置，则其默认值为"hardhat"自定义网络可配置以下字段：url: 节点的连接地址。自定义网络需要此参数。chainId：可选的链id，用于验证Hardhat连接到的网络。如果不存在，则省略此验证。from：用作默认发送交易的地址。如果不存在，则使用节点的第一个帐户。accounts：此字段控制Hardhat使用哪些帐户。它可以使用节点的帐户（设置为"remote"）、本地帐户列表（设置为16进制的私钥数组）和HD钱包，默认为"remote"Hardhat内置了一个名为hardhat的特殊网络。当使用这个网络时将会自动创建，比如运行任务、脚本或测试智能合约时编译器配置solidity字段配置合约编译器，可选以下值之一：要使用的solc版本，例如"0.8.19"描述编译器配置的对象。它包含version字段和settings字段（编译器设置对象）目录配置paths字段配置hardhat的文件目录root：Harhat的根目录，默认值为hardhat.config.js所在的目录。sources：存储合约的目录，默认值为./contractstests：测试所在的目录,默认值为./testcache：用于缓存其内部内容的目录,默认值为./cacheartifacts：存储编译结果的目录，默认值为./artifacts示例配置文件require("@nomicfoundation/hardhat-toolbox"); module.exports = { defaultNetwork: "goerli", networks: { goerli: { url: "https://goerli.infura.io/v3/<key>", accounts: { mnemonic: "test test test test test test test test test test test test", }, } }, solidity: { version: "0.8.19", settings: { optimizer: { enabled: true, runs: 200 } } }, paths: { sources: "./contracts", tests: "./test" }, }更多内容参考hardhat官方文档三、进阶以一个暂存资产的合约为例，从头开始搭建项目1、初始化一个hardhat项目mkdir demo && cd demo npm init -y npm install -D hardhat2、创建hardhat配置文件执行命令npx hardhat后选择Create an empty hardhat.config.js，也可以手动创建这个文件，内容如下/** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: "0.8.19", };3、安装hardhat核心插件先使用npm安装@nomicfoundation/hardhat-toolboxnpm install -D @nomicfoundation/hardhat-toolbox再编辑hardhat配置文件hardhat.config.js导入插件，更新后内容如下require("@nomicfoundation/hardhat-toolbox"); /** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: "0.8.19", };4、创建合约文件创建合约目录contracts并编写合约文件Demo.sol，内容如下// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; contract Demo { event Deposit(address user, uint amount); event Withdrawal(address user, uint amount); receive() external payable { emit Deposit(msg.sender, msg.value); } function withdraw(uint amount) public payable { require(amount <= address(this).balance, "there is not enough deposit"); emit Withdrawal(msg.sender, msg.value); payable(msg.sender).transfer(amount); } }这是一个名为Demo的合约，任意用户可以往这个合约存款和取款，更多合约开发参考solidity文档执行以下命令编译合约，如果编译失败，可以按照提示修改合约npx hardhat compile5、创建测试文件创建测试目录test并编写测试文件Demo.js，内容如下const { ethers } = require("hardhat"); const { expect } = require("chai"); describe("Demo", function() { async function deploy() { const Demo = await ethers.getContractFactory("Demo"); const demo = await Demo.deploy({ value: ethers.parseEther("1") }); const signers = await ethers.getSigners(); return { demo, signers }; } describe("Deployment", function() { it("Demo contract should deposit 1 ETH", async function() { const { demo } = await deploy(); const deposit = await ethers.provider.getBalance(demo.target); expect(deposit).to.equal(ethers.parseEther("1")); }); }); describe("Withdraw", function() { it("should withdraw 1 ETH", async function() { const { demo } = await deploy(); await expect(demo.withdraw(ethers.parseEther("1"))) .to.changeEtherBalance(demo.target, -ethers.parseEther("1")); }); }); describe("Events", function() { it("Should emit an event on withdrawals", async function() { const { demo, signers: [owner] } = await deploy(); await expect(demo.withdraw(ethers.parseEther("1"))) .to.emit(demo, "Withdrawal") .withArgs(owner.address, ethers.parseEther("1")); }); }); });执行以下命令测试合约，如果测试未通过，可以按照提示修改测试用例npx hardhat test6、创建部署文件创建脚本目录scripts并编写部署文件deploy.js，内容如下const { ethers } = require("hardhat"); async function main() { const demo= await ethers.deployContract("Demo", { value: ethers.parseEther("1")}); await demo.waitForDeployment(); console.log(`Demo deployed to ${demo.target}`); } main().catch((error) => { console.error(error); process.exitCode = 1; });执行以下命令部署合约，如果部署失败，可以按照提示修改部署文件npx hardhat run scripts/deploy.js7、部署合约到本地网络使用下面命令启动一个虚拟本地节点npx hardhat node然后使用下面命令部署合约到网络localhost，无需修改配置（hardhat配置中预置了hardhat和localhost两个网络）npx hardhat run --network localhost scripts/deploy.js如果需要部署到其他网络，可使用--network选项指定要部署的网络名称8、编辑npm脚本修改package.json文件，编辑scripts字段，内容如下 "scripts": { "compile": "hardhat compile", "test": "hardhat test", "node": "hardhat node", "deploy": "hardhat run --network localhost scripts/deploy.js" },保存更改之后，就可以使用npm命令来运行hardhat任务npm run compile #编译合约，等效:npx hardhat compile四、合约部署插件除了使用部署脚本外，在复杂环境下可以使用插件部署合约，提供更灵活的部署方法，使用以下命令安装插件包npm install -D hardhat-deploy编辑hardhat配置文件hardhat.config.js导入插件，同时命名deployer账户（第一个账户）用于部署合约，更新后内容如下require("@nomicfoundation/hardhat-toolbox"); require("hardhat-deploy"); /** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: "0.8.19", namedAccounts: { deployer: 0 } };创建目录deploy并编写部署文件00_demo.js，内容如下module.exports = async ({ getNamedAccounts, deployments }) => { const { deploy } = deployments; const { deployer } = await getNamedAccounts(); await deploy("Demo", {from: deployer, args: [],log: true}); }; module.exports.tags = ["Demo"];执行以下命令部署合约，如果部署失败，可以按照提示修改部署文件npx hardhat deploy更多插件内容参考文档
运行基于cosmos sdk开发的区块链程序一、环境操作系统：linuxgo版本：1.20.4以上ignite版本：0.27.1以上二、约定开发区块链应用程序可以参考文档ignite为了方便运行go语言程序，需要将目录$HOME/go/bin/加入到环境变量PATH里面可以在项目根目录运行ignite chain build命令来生成二进制程序（通常放到目录$HOME/go/bin/）为了方便解说，可以为区块链程序统一起个别名，例如：alias chaind=gaiad程序可以使用-h选项来查看更多配置参数，为了简单尽量使用了默认参数一般来说基于cosmos sdk开发的区块链，如果项目名称为appname，那么默认的程序和工作目录分别是appnamed和$HOME/.appname，默认的链id为appname三、节点配置1、初始化chaind init [moniker]命令创建节点工作目录，moniker是自定义的节点名称，生成默认配置文件、基础创世文件和随机节点密钥，目录主要包括以下文件├── config │ ├── app.toml # 应用程序相关的配置文件 │ ├── config.toml # CometBFT相关配置文件 │ ├── genesis.json # 创世文件 │ ├── node_key.json # p2p协议中用于节点身份验证的私钥 │ └── priv_validator_key.json # 在共识协议中用作验证节点的私钥 └── data # 节点使用的数据存储目录--home string：自定义工作目录--chain-id string：自定义创世文件中的链id--staking-bond-denom string：自定义质押币名称2、账户chaind keys add [name]命令创建新的密钥，name是密钥名称，可以重复执行创建多个不同的账户--keyring-backend string：自定义密钥后端，参考文档keyring--keyring-dir string：自定义密钥文件存放目录3、创世账户chaind add-genesis-account [address_or_key_name] [coin][,[coin]] 命令添加账户到创世文件中，address_or_key_name是之前创建的密钥名称或任意账户地址，coin是资产（例如1000个质押币1000stake），可以重复执行配置多个创世账户4、创世交易chaind gentx [key_name] [amount]命令构造并签名创世交易，key_name是之前创建的密钥名称，amount只能是质押币（至少是1000000000stake），交易内容是质押账户一定数量质押币来成为创世验证者--pubkey string：自定义节点公钥（默认由工作目录中priv_validator_key文件确定）--node-id string：自定义节点id（默认由工作目录中node_key.json文件确定）5、创世文件chaind collect-gentxs命令将创世交易写入到创世文件中，所有验证者签署交易后，由其中一个收集齐全后执行生成最终的创世文件--gentx-dir string：自定义创世交易目录6、启动节点chaind start命令将启动区块链节点，如果在一台电脑上运行多个节点需要分配端口避免端口冲突--home string：自定义节点工作目录--p2p.laddr string：默认tcp://0.0.0.0:26656--rpc.laddr string：默认tcp://127.0.0.1:26657--grpc.address string：默认0.0.0.0:9090--grpc-web.address string：默认0.0.0.0:9091--rpc.pprof_laddr string：默认0.0.0.0:6060--p2p.persistent_peers：持久的对等节点（逗号分割，ID@host:port）--p2p.seeds：种子节点（逗号分割，ID@host:port）除了通过命令行设置参数，也能通过修改节点配置文件（工作目录中的config/config.toml文件），例如：# persistent_peers = "[validator_address]@[ip_address]:[port],..." persistent_peers = "58811401b7b84caebea3cf674577a879dc53fdb1@127.0.0.1:26656"7、查询chaind tendermint show-validator：节点公钥chaind tendermint show-node-id：节点idchaind keys list：账户列表chaind keys show [name_or_address [name_or_address...]]：显示指定账户信息四、节点实例如果运行过区块链程序，可能需要删除之前的数据（包括但不限于工作目录）1、单节点推荐使用默认的工作目录、密钥后端、链id、质押币名称和端口号使用一个验证者创世# 初始化工作目录 chaind init testnode # 创建账户 chaind keys add key0 # 添加账户到创世文件 chaind add-genesis-account key0 10000000000000000000000000000stake --keyring-backend os # 签名创世交易 chaind gentx key0 100000000stake # 打包创世交易到创世文件中 chaind collect-gentxs # 启动节点 chaind start加入已存在的区块链网络需要准备指定区块链的程序、创世文件和对等节点地址列表等等，参考gaia的官方文档chaind init testnode # 复制指定区块链网络的创世文件genesis.json到工作目录中 # 参考章节：https://hub.cosmos.network/main/hub-tutorials/join-mainnet.html#genesis-file # 修改配置文件（config/config.toml）添加对等节点（种子节点）或在命令行中指定 # 参考章节：https://hub.cosmos.network/main/hub-tutorials/join-mainnet.html#seeds-peers chaind start2、多节点多节点需要配置区块链节点的工作目录和端口以避免程序冲突，其中包括--home string：指定工作目录--p2p.laddr string：默认tcp://0.0.0.0:26656--rpc.laddr string：默认tcp://127.0.0.1:26657--grpc.address string：默认0.0.0.0:9090--grpc-web.address string：默认0.0.0.0:9091--rpc.pprof_laddr string：默认0.0.0.0:6060--address string：默认tcp://0.0.0.0:26658--api.address string：默认tcp://0.0.0.0:1317一个验证者节点和一个同步节点创世并启动验证者节点node0# 初始化工作目录node0 chaind init testnode --home node0 # 创建账户key0 chaind keys add key0 --home node0 # 添加账户key0到创世文件 chaind add-genesis-account key0 10000000000000000000000000000stake --keyring-backend os --home node0 # 签名创世交易 chaind gentx key0 100000000stake --home node0 # 打包创世交易到创世文件中 chaind collect-gentxs --home node0 # 启动节点node0 chaind start --home node0启动同步节点node1# 初始化工作目录node1 chaind init testnode --home node1 # 创建账户key1 chaind keys add key1 --home node1 # 复制node0的创世文件到node1的工作目录中 cp node0/config/genesis.json node1/config/genesis.json # 启动节点node1 chaind start --home node1 --p2p.seeds $(chaind tendermint show-node-id --home node0)@127.0.0.1:26656 --rpc.laddr tcp://127.0.0.1:26667 --p2p.laddr tcp://0.0.0.0:26666 --grpc.address 0.0.0.0:9000 --grpc-web.address 0.0.0.0:9001 --rpc.pprof_laddr 0.0.0.0:6070将同步节点变成验证者节点# 给key1账户转账 chaind tx bank send key0 $(chaind keys show key1 -a --home node1) 100000000000stake --home node0 # 质押key1账户的币将node1节点变为验证者 chaind tx staking create-validator --amount 1000000000stake --from key1 --pubkey $(chaind tendermint show-validator --home node1) --node-id $(chaind tendermint show-node-id --home node1) --commission-rate 0.1 --commission-max-rate 0.2 --commission-max-change-rate 0.01 --min-self-delegation 1 --home node1两个验证者节点创世chaind init testnode --home node0 chaind init testnode --home node1 chaind keys add key0 --home node0 chaind keys add key1 --home node1 chaind add-genesis-account key0 10000000000000000000000000000stake --keyring-backend os --home node0 chaind add-genesis-account key1 10000000000000000000000000000stake --keyring-backend os --home node0 chaind gentx key0 100000000stake --home node0 chaind gentx key1 100000000stake --home node0 --pubkey $(chaind tendermint show-validator --home node1) --node-id $(chaind tendermint show-node-id --home node1) chaind collect-gentxs --home node0 cp node0/config/genesis.json node1/config/genesis.json chaind start --home node0 chaind start --home node1 --p2p.seeds $(chaind tendermint show-node-id --home node0)@127.0.0.1:26656 --rpc.laddr tcp://127.0.0.1:26667 --p2p.laddr tcp://0.0.0.0:26666 --grpc.address 0.0.0.0:9000 --grpc-web.address 0.0.0.0:9001 --rpc.pprof_laddr 0.0.0.0:6070五、节点交互运行了一个节点之后，可以查询其中的数据或者发送签名交易，节点程序内置客户端功能，也可以使用其他方式与节点交互，可以参考文档cosmos sdk，一般通过--node参数指定节点地址（默认值：tcp://localhost:26656）# 节点状态查询 chaind status # 查询账户key0资产 chaind query bank balances $(chaind keys show key0 -a) # 从账户key0到账户key1转账 chaind tx bank send key0 $(chaind keys show key1 -a) 1000000000000stake # 账户key1委托给验证者账户key0 chaind tx staking delegate $(chaind keys show key0 --bech val -a) 100000000stake --from key1 # 查询账户key1的所有委托详情 chaind query staking delegations $(chaind keys show key1 -a) # 查询账户key1的所有委托奖励 chaind query distribution rewards $(chaind keys show key1 -a) # 领取账户key1的所有委托奖励（验证者是自委托） chaind tx distribution withdraw-all-rewards --from key1 # 查询所有验证者详情（包括入狱的） chaind query staking validators # 查询所有验证者详情（实际参与共识的） chaind query tendermint-validator-set # 账户key1自委托成为验证者（绑定节点node1） chaind tx staking create-validator --amount 1000000000stake --from key1 --pubkey $(chaind tendermint show-validator --home node1) --commission-rate 0.1 --commission-max-rate 0.2 --commission-max-change-rate 0.01 --min-self-delegation 1 # 把账户key1给验证者账户key0的委托取消 chaind tx staking unbond $(chaind keys show key0 --bech val -a) 100000000stake --from key1 # 把账户key1给验证者账户key1的自委托取消（可能会导致此验证者入狱） chaind tx staking unbond $(chaind keys show key1 --bech val -a) 100000000stake --from key1验证者入狱：保留验证者身份，但不参与共识流程，验证者身份无法撤销，但可以撤销验证者自质押的所有币，验证者有不良行为或质押币不够多时可能会入狱
Cosmos分布式账本网络介绍开源的生态系统、去中心化的文件共享、以及公共的加密货币，这一系列技术的成功使人们启发和理解，去中心化的互联网协议是可以从根本上改善社会经济基础架构的。我们已经见识过个有专长的区块链应用，诸如比特币[1]（加密货币），ZCASH [2] (隐私加密货币)，也看到了例如以太坊 [3] 的大众智能合约平台，还有无数基于 EVM (以太坊虚拟机)开发的分布式应用，例如 Augur（预测市场）和 TheDAO [4] （投资俱乐部）然而，迄今为止，这些区块链已经暴露了各种缺陷，包括总体能效低下，性能不佳或受到限制和缺乏成熟的治理机制。为了扩大比特币交易吞吐量，已经研发了许多诸如隔离见证 [5]（Segregated-Witness）和 BitcoinNG [6]（一种新的可扩展协议）这样的解决方案，但这些垂直扩展解决方案仍然受到单一物理机容量的限制，以确保完整的可审计性。闪电网络 [7] 可以通过部分交易完全记录在主链账本外来扩展比特币的交易容量，这种方法十分适用于微支付和隐私保护支付通道，但是无法适用于更通用的扩展需求。理想的解决方案是允许多个并行的区块链交互操作的同时保持其安全特性。事实证明，采用工作量证明很难做到这一点，但也并非不可能。例如合并挖矿，允许在工作完成的同时，确保母链在子链上被重复使用，但交易必须通过每个节点依次进行验证，而且如果母链上的大多数哈希算力没有积极地对子链进行合并挖矿，那么就容易遭受到攻击。关于可替代区块链网络架构的学术回顾 将在附件中展示，我们也会在相关工作中对其他（技术）方案和缺陷进行概括。这里我们要介绍的 Cosmos，一个全新的区块链网络架构，能够解决所有这些问题。Cosmos 是由许多被称之为“分区”的独立区块链组成的网络。分区在 Tendermint BFT [8]的支持下运行，Tendermint BFT 是一个类似拜占庭容错安全共识引擎，具有高性能、一致性的特性，并且在严格的分叉追责 机制下能够制止恶意破坏者的行为。Tendermint BFT 的拜占庭容错共识算法十分适合用于扩展权益证明(PoS)机制下的公共区块链。使用其他共识模型的区块链, 包括类似基于权益证明(PoS)的以太坊，以及比特币也能够通过使用适配分区被 Cosmos 网络连接。Cosmos 的第一个分区称之为 Cosmos 枢纽。Cosmos 枢纽是一种多资产权益证明加密货币网络，它通过简单的治理机制能够对网络进行适配和升级。此外，Cosmos 枢纽可以通过链接其他分区来实现扩展。Cosmos 网络的枢纽及各个分区可以通过区块链间通信（IBC）协议进行通信，这种协议就是针对区块链的虚拟用户数据报协议（UDP）或者传输控制协议（TCP）。代币可以安全、快速地从一个分区转到其他分区，而无需在两个分区之间拥具有汇兑流动性。相反，所有跨分区的代币转移都会通过 Cosmos 枢纽，以此来追踪记录每个分区持有代币的总量。这个枢纽会将每个分区与其他故障分区隔离开。因为每个人都可以将新的分区连接到 Cosmos 枢纽，所以分区将可以向后兼容新的区块链技术。利用 Cosmos 可以实现区块链间的互操作。这是一个具有潜力的有价值的互联网络，其中的资产由不同的验证人发布和控制，并可以在不依靠需要信任的第三方的情况下实现跨链资产无缝的转移和交易。Tendermint在这一部分我们将阐述 Tendermint 共识协议和用于建立其应用程序的接口。 更多信息，请参见附录验证人在经典的拜占庭容错算法中，每个节点有相同的权重。在 Tendermint，节点有着不同数量（非负）的 投票权，而那些拥有相当数量投票权的节点称之为 验证人。验证人通过广播加密签名、投票或者对下一个区块表决同意来参与共识协议。验证者的投票权是一开始就确定好了，或者根据应用程序由区块链来决定修改投票权。例如，在像 Cosmos 枢纽的权益证明应用里，投票权可由绑定为押金的代币数量来决定。注意：像 ⅔ 和 ⅓ 这样的分数指的是占总投票权的分数，而不是总验证人，除非所有验证人拥有相同权重。而>⅔ 的意思是"超过 ⅔ "，≥⅓ 则是"⅓ 或者更多"的意思。共识Tendermint 是部分同步运作的拜占庭容错共识协议，这种协议源自 DLS 共识算法 [20]。Tendermint 以简易性、高性能以及分叉问责制而著称。协议要求这组验证人固定且被熟知，并且每个验证人都有其公钥验证身份。这些验证人试图同时在一个区块上达成共识，这些区块是一系列的交易记录。每个区块的共识轮流进行，每一轮都会有个领头人，或者提议人，由他们来发起区块。之后验证人分阶段对是否接受该区块，或者是否进入下一轮做出投票。每轮的提议人会从验证人顺序列表中按照其投票权比例来选择确定。更多协议的全部细节，请点击这里。Tendermint 采用了使用大多数投票（超过三分之二）和锁定机制的最优拜占庭容错，来确保其安全性。这些能够保证：蓄意破坏者想要造成安全性问题，必须有三分之一以上的投票权，并且要提交超过两份以上的值。如果有一组验证人成功破坏了安全性，或者曾试图这么做，他们会被协议识别。协议包括对有冲突的区块进行投票和广播那些有问题的投票。除了其超强的安全性外，Tendermint 还具备杰出的性能。以商用型云平台为例，Tendermint 共识以分布在五大洲七个数据中心的 64 位节点为基准，其每秒可以处理成千上万笔交易，订单提交延迟时间为 1-2 秒。而值得关注的是，即使是在极其恶劣的敌对环境中，比如验证人崩溃了或者是广播恶意破坏的投票，也能维持这种每秒超过千笔交易的较高性能。详见下图。轻客户端Tendermint 共识算法的主要好处是具有安全简易的客户端，使其成为手机和物联网用例的理想选择。比特币轻客户端必须同步运行区块头组成的链，并且找到工作量证明最多的那一条链，而 Tendermint 轻客戸端只需和验证组的变化保持一致，然后简单地验证最新区块中预先提交的>⅔，来确定最新情况。这种简单的轻客戸端证明机制也可以实现区块链之间的通信。防止攻击Tendermint 有各种各样的防御措施来防止一些明显的攻击，比如远程无利害关系双花攻击 及审查制度。 这些在附录中有更详细的讨论。ABCITendermint 共识算法是在叫做 Tendermint BFT 的程序中实现的。这个程序是独立于应用的“共识引擎”，可以将任何已经确定的黑盒应用转变为分布式、可复制的区块链。Tendermint BFT 可以通过应用区块链接口(ABCI) [17]与其他区块链应用连接。而且，应用区块链接口(ABCI) 接口允许区块链应用以任何语言编程实现，而不仅仅是写这个共识引擎所使用的语言。此外，应用区块链接口(ABCI) 也让交换任何现有区块链栈的共识层成为可能。我们将其与知名加密货币比特币进行了类比。在比特币这种加密币区块链中，每个节点都维持着完整的审核过的 UTXO（未使用交易输出）数据库。如果您想要在应用区块链接口(ABCI)基础上，创建出类似比特币的系统，那么 Tendermint BFT 可以做到：在节点间共享区块及交易创建规范或不可改变的交易顺序（区块链）同时，ABCI 应用也可以做到：维护 UTXO 数据库验证交易的加密签名防止出现不存在的余额被交易允许客户访问 UTXO 数据库Cosmos概述Cosmos是一个独立平行的区块链网络，其中每条区块链通过 Tendermint1这样的经典拜占庭容错共识算法来运行。网络中第一条区块链将会是 Cosmos 枢纽。Cosmos 枢纽通过全新的区块链间通信协议来连接其他众多区块链（或将其称之为 分区）。Cosmos 枢纽可以追踪无数代币的种类，并且在各个连接的分区里记录各种代币总数。代币可以安全快速地从一个分区转移到另一个分区，两者之间无需体现汇兑流动性，因为所有分区之间的代币传输都会经过 Cosmos 枢纽。这一架构解决了当今区块链领域面临的许多问题，包括应用程序互操作性、可扩展性、以及可无缝升级的能力。比如，从 Bitcoind、Go-Ethereum、CryptoNote、ZCash 或其他区块链系统中衍生出来的分区，都能被锚定接入 Cosmos 枢纽。这些分区允许 Cosmos 实现无限扩展，从而满足全球交易的需求。此外，分区也完全适用于分布式交易所，反之交易所也支持分区运行。Cosmos 不仅仅是单一的分布式账本，而 Cosmos 枢纽也不是封闭式庭院或宇宙的中心。我们正在为分布式账本的开放网络设计一套协议，这套协议将基于密码学、稳健经济学、共识理论、透明性及可追责制的原则，成为未来金融系统的全新基础。TENDERMINT-拜占庭容错Cosmos枢纽是Cosmos网络中第一条公共区块链，通过Tendermint的拜占庭共识算法运行。Tendermint开源项目创立于2014年，旨在解决比特币工作量证明共识算法的速度、可扩展性以及造成的环境问题。通过采用并提高已经过验证的拜占庭算法（1988 年在麻省理工学院开发）[20]，Tendermint 成为了首个在概念论证了权益证明加密货币的团队，这种机制可以解决 NXT 和 BitShares 这些第一代权益证明加密币面临的"无利害关系"的问题。如今，实际上所有比特币移动钱包都要使用可靠的服务器来进行交易验证。这是因为工作量证明机制需要在交易被认定为无法逆转前进行多次确认。而在 Coinbase 之类的服务中也已经出现双重支付攻击。和其他区块链共识系统不同，Tendermint 提供的是即时、可证明安全的移动客户端支付验证方式。因为 Tendermint 被设计为完全不分叉，所以移动钱包就可以实时接收交易确认，从而在智能手机上真正实现去信任的支付方式。这一点也大大影响了物联网应用程序。Cosmos 中的验证人角色类似比特币矿工，但是他们采用加密签名来进行投票。验证人是专门用来提交区块的安全机器。非验证人可以将权益代币（也叫做"atom"币）委托给任何验证人来赚取一定的区块费用以及 atom 奖励，但是如果验证人被黑客攻击或者违反协议规定，那么代币就会面临被惩罚（削减）的风险。Tendermint 拜占庭共识的可证明安全机制，以及利益相关方（验证人和委托人）的抵押品保证，为节点甚至是轻客户端提供了可证明、可量化的安全性。治理分布式公共账本应该要有一套章程与治理体系。比特币依靠比特币基金会以及挖矿来协作更新，但是这是一个反应缓慢的治理制度。以太坊在采用硬分叉成 ETH 和 ETC 来解决 The DAO 黑客，这主要是因为之前没有设定社会契约或机制来进行这类决定。Cosmos 枢纽的验证人与委托人可以对提案进行投票，从而改变预先默认设置好的系统参数（比如区块转账费用限制），协作更新，并对可读性的章程进行修订投票，从而治理 Cosmos 枢纽制度。这个章程允许权益相关者聚集到一起，来解决盗窃及漏洞等相关问题（比如 The DAO 事件），并得出更快更明确的解决方案。每个分区也可以制定自己的一套章程及治理机制。比如，Cosmos 枢纽的章程可以设置为强制实现枢纽的不可改变性（不能回滚，除了 Cosmos 枢纽节点产生的漏洞），而每个分区则可设置自己的回滚政策。Cosmos 网络能够在制度不同的分区间实现互操作性，这一点给客户极高的自由度和潜力而无需许可即可实验（新技术）。枢纽与分区这里我们将描述一个全新的去中心化与可扩展性模型。Cosmos 网络通过 Tendermint 机制来运行众多的区块链。虽然现存提案的目标是创建一个包含全球所有交易订单的"单一区块链"，但是 Cosmos 允许众多区块链在并行运行的同时，保持可互操作性。在这个基础上，Cosmos 枢纽负责管理称之为“分区”的众多独立区块链（有时也叫做"分片"，参考自众所周知的数据库扩展技术"分片"）。枢纽上的分片会源源不断地提交最新区块，这一点可以让枢纽同步每一个分区的状态。同样地，每个分区也会和枢纽的状态保持一致（不过分区之间不会同彼此的同步，除非间接通过枢纽来实现）。通过发布默克尔证明来证明消息被接受和发送，来让消息从一个分区传递到另一个分区。这种机制叫做"区块链间通信"，或者简称为"IBC"机制。任何分区都可以自行成为枢纽来建立非循环图表，但为了清楚起见，我们只描述这种只有一个枢纽和许多非枢纽的分区这样简单的配置枢纽Cosmos 枢纽是承载多种分布式账本资产的区块链，其中代币可以由个人或分区自己持有。这些代币能够通过特殊的 IBC 数据包，即"代币数据包"（coin packet）从一个分区转移到另一个分区。枢纽负责保持各个分区中各类代币总量不变。IBC 代币数据包交易必须由发送人、枢纽及区块接受者执行。因为 Cosmos 枢纽在整个系统中扮演着中央代币账本的角色，其安全性极其重要。虽然每个分区可能都是一个 Tendermint 区块链——只需通过 4 个，(或者在无需拜占庭容错共识的情况下更少的验证人来保证安全），但是 Cosmos 枢纽必须通过全球去中心化验证组来保证安全，而且这个验证组要能够承受最严重的攻击，比如区域网络分裂或者由国家发起的攻击。分区Cosmos 分区是独立的区块链，能够和 Cosmos 枢纽进行 IBC 消息交换。从枢纽的角度上看，分区是一种多重资产、动态会员制的多重签名账户，可以通过 IBC 数据包用来发送和接受代币。就像加密币账户一样，分区不能转移超出其持有量的代币，不过可以从其他拥有代币的人那里接收代币。分区可能会被指定为一种或多种代币的"来源"，从而赋予其增加代币供应量的权力。Cosmos 枢纽的 Atom 或可作为分区验证人连接到枢纽的筹码。虽然在 Tendermint 分叉责任制下，分区出现双重支付攻击会导致 atom 数量减少，但是如果分区中有超过 ⅔ 的选票都出现拜占庭问题的话，那这个分区就可以提交无效状态。Cosmos 枢纽不会验证或执行提交到其他分区的交易，因此将代币发送到可靠的分区间就是用户的责任了。未来 Cosmos 枢纽的管理系统可能会通过改善提案，来解决分区故障问题。比如，在检测到袭击时，可以将有些分区（或全部分区）发起的代币转账将被暂停，实现紧急断路（即暂时中止代币转账）。跨链通信-IBC现在我们来介绍下枢纽与分区之间通信的方法。假如现在有三个区块链，分别是"分区 1"、“分区 2"以及"枢纽”，我们想要"分区 1"生成一个数据包，通过"枢纽"发送给"分区 2"。为了让数据包从一个区块链转移到另一个区块链，需要在接收方区块链上发布一个证明，来明确发送方已经发起了一个数据包到指定目的地。接收方要验证的这个证明，必须和发送方区块头保持一致。这种机制就类似与侧链采用的机制，它需要两个相互作用的链，通过双向传送存在证明数据元（交易），来"知晓"另一方的情况。IBC 协议可以自然定义为两种交易的使用：一种是 IBCBlockCommitTx 交易，这种交易可以让区块链向任何观察员证明其最新区块哈希值；另一种是 IBCPacketTx 交易，这种交易则可以证明某个数据包确实由发送者的应用程序，通过默克尔证明机制（Merkle-proof）传送到了最新区块的哈希值上。通过将 IBC 机制分离成两个单独的交易，即 IBCBlockCommitTx 交易与 IBCPacketTx 交易，我们可以让接收方链的本地费用市场机制，来决定承认哪个数据包，与此同时还能确保发送方的完全自由，让其自行决定能够传出的数据包数量。在上述案例中，为了更新"枢纽"上"分区 1"的区块哈希（或者说"分区 2"上"枢纽"的区块哈希），必须将 IBCBlockCommitTx 交易的"分区 1"区块哈希值发布到"枢纽"上（或者将该交易的"枢纽"区块哈希值发布到"分区 2"中）。_关于两种 IBC 交易类型，详细请参见IBCBlockCommitTx和IBCPacketTx用例分布式交易所比特币借助大量复制来增加分布式账本的安全性。用类似的方式，我们可以在区块链上运行交易所，来降低其受内部及外部攻击的可能性。我们称之为去中心化交易所。现今，加密货币社区认为的去中心化交易所基于"跨链原子事务"交易（ AXC 交易）。通过 AXC 交易，两条不同链上的两个用户可以发起两笔转账交易，交易在两个账本上要么一起提交执行，或者两个账本都不执行（即交易的原子性）。比如，两位用户可以通过 AXC 交易来实现比特币和以太币之间的交易（或是在不同账本上的任意两种代币），即使比特币和以太坊的区块链之间并没有彼此连接。AXC 交易模式下的交易所用户双方不需要彼此信任，也不用依赖交易匹配服务。其弊端是，交易双方必须同时在线才能进行交易。另一种去中心化交易所是进行大量复制的具有独立区块链的分布式交易所。该种交易所的用户可以提交限价订单并关闭他们的计算机，交易可以在用户离线状态下执行。区块链将会代表交易者去完成匹配和交易。一个中心化的交易所可以构建一个有大交易量的限价交易的买卖盘账目，以此来吸引更多的交易者。在交易所领域，流动性会引发更多流动性，因此在交易所业务中，其具有的网络效应也愈发明显（或者说至少产生了"赢家通吃"效应）。目前加密货币交易所 Poloniex 以每 24 小时 2,000 万美元的交易量排名第一， Bitfinex 则每 24 小时 500 万美元的交易额位列第二。在这种强大的网络效应之下，基于 AXC 的去中心化交易所的成交量是不太可能超过中心化交易所。去中心化交易所要想和中心化交易所一争高下，就需要支持以限价订单构成的具有深度的交易买卖盘账目的运行。而只有基于区块链的去中心化交易所可以实现这一点。Tendermint 提供的快速交易执行是另一大优势。Cosmos 的内部网络可以在不牺牲一致性的前提下优先快速的确定最终性，来实现交易的快速完成 —— 同时针对交易订单交易，以及 IBC（跨区块链通信）代币与其他网络的交易。综上，根据现有加密货币交易所的情况，Cosmos 的一项重大应用就是去中心化交易所（称为 Cosmos DEX）。其交易吞吐能量和委托延时可以与那些中心化交易所媲美。交易者可以在各方离线的状态下提交限价订单。并且，基于 Tendermint，Cosmos 枢纽以及 IBC 的情况下，交易者可以快速地完成在交易所及其他网络的资金进出。作为其他加密货币的纽带特权分区可以作为和其他加密货币挂钩的代币来源。这种挂钩类似 Cosmos 枢纽与分区之间的关系，两者都必须及时更新彼此最新的区块链，从而验证代币已经从一方转移到另一方。Cosmos 网络上挂钩的”桥接分区“要和中心以及其他加密币保持同步。这种间接通过”桥接分区“可以保持枢纽逻辑的简洁。并且不必要了解其他的链上共识战略，如比特币工作量证明挖矿机制。向Cosmos枢纽发送代币每个挂钩桥接分区的验证人都会在基于 Tendermint 公式的区块链之上，运行带有特殊的 ABCI 桥接应用程序，但同时也会运行一个原有区块链的“全节点”。在原有区块链挖出新区块时，桥接分区验证人员将通过签署和分享起始点区块链的提示，各自局部视角可以达成一致。当一个桥接分区收到原有区块链的支付时（如在以太坊或比特币等 PoW 机制的链上有足够数目的确认），则在该桥接分区上创建具有该对应账户的余额。就以太坊而言，桥接分区可以和 Cosmos 枢纽共享相同的验证人。以太坊方面（原本区块链），一个桥接合约将允许以太拥有者通过将以太币发送到以太坊的桥接分区的桥接合约上。一旦挂桥接合约接收到以太币，以太币就不能被撤回，除非从桥接分区接收到对应的 IBC 数据包。桥接合约跟随桥接分区的验证组，它可能与 Cosmos 枢纽的验证人组相同。就比特币而言，概念是相似，除了代替一个桥接合约，每个 UTXO 将由一个门限多重签名 P2SH 数据库限制。由于 P2SH 系统的限制，签名者不能与 Cosmos 枢纽的验证人组相同。从Cosmos枢纽提出代币桥接分区上的以太币（“桥接以太币”）可以在枢纽间转进，转出，完成传送到特定以太坊提取地址后，转出的“桥接以太币”被彻底删除。一个 IBC 消息可以证明桥接分区上的交易，这个消息将被公布到以太坊桥接合约中，以便以太币被取出。就比特币而言，严谨的交易脚本系统让 IBC 币的镜像转换机制很难实现。每个 UTXO 都有自己的特定的脚本，所以当比特币履约签名者发生变化时，每个 UTXO 都必须迁移到新的 UTXO。一个解决方案是根据需要，压缩和解压缩 UTXO-set，以保持 UTXO 的总数量下降。挂钩区完全责任制这类挂钩合约存在风险的风险是，可能会出现恶意的验证人组。如果拜占庭投票权超过 ⅓，就会造成分叉，即从以太坊桥接合约中提取以太币的同时，还能保持桥接分区中的挂钩以太币不变。甚至，如果拜占庭投票权超过 ⅔，可能会有人直接通过脱离原始桥接分区的桥接逻辑，对发送以太币发到桥接合约中的帐户下手，盗取以太币。如果将这个桥接方法完全设计成责任制，就有可能解决这一问题。比如，枢纽及起始点的全部 IBC 包裹可能需要先通过桥接分区的认可，即让枢纽或起始点中的桥接合约对桥接分区的所有状态转换进行有效验证。枢纽及起始点要允许桥接分区的验证人提供抵押物，而侨界合约的代币转出需要延时（且抵押品解绑时间也要足够长），从而让单独的审计人有时间发起任何的质询。我们会把这一系统的设计说明以及执行方式开放，作为未来 Cosmos 改善的提议，以待 Cosmos 枢纽的管理系统审批通过。以太坊的扩展众所周知，扩展问题是一直困扰着以太坊的问题。目前以太坊节点会处理节点上每笔交易，并且存储所有的状态参考.。Tendermint 提交区块的速度比以太坊工作量证明要快，所以由 Tendermint 共识推动且使用桥接以太币运行的以太坊虚拟机分区能够强化太坊区块链的性能。此外，虽然 Cosmos 枢纽及 IBC 包裹机制不能实现每秒合约逻辑的执行，但是它可以用来协调不同分区中以太坊合约之间的代币流通，通过分片方式为以代币为中心的以太坊扩展奠定基础。多用一体化Cosmos 分区可以运行任意的应用逻辑，应用在分区创建时设定好，可通过管理者可以不断更新。这种灵活度使得 Cosmos 分区可以作为其他加密币的挂钩载体，比如以太坊或比特币，并且它还能和这些区块链的衍生品挂钩，利用同样的代码库，而在验证程序及初始分配有所区分。这样就允许多种现有加密币框架得以运行，如以太坊、Zerocash、比特币、CryptoNote 等等，将其同 Tendermint BFT 结合，成为通用网络中性能更优的共识引擎，为平台之间提供更多的交互机会。此外，作为多资产区块链，每笔交易都有可能包含多个输入输出项，其中每个输入项都可以是任意代币，使 Cosmos 直接成为去中心化交易所，当然这里假设交易订单通过其他平台进行匹配。替代方案是，让分区作为分布式容错交易所（包含买卖盘账目），这算是对中心化加密币交易所之上的严格改进——现行交易所在过去时常发生被攻击的事件。分区也可以作为区块链版的企业及政府系统，其原本由一个或多个组织运行的特定服务，现在作为 ABCI 应用在某个分区上运行，从而在不放弃对底层服务控制的前提下，维持公共 Cosmos 网络的安全性及交互性。所以，Cosmos 或可为那些既想使用区块链技术，又不愿彻底放弃控制权给分布式第三方的人，提供绝佳的运行环境。缓解网络分区问题有人认为像 Tendermint 这种支持一致性的共识算法有一个重大问题，就是网络分区会导致没有任何一个分区会拥有超过 ⅔ 的投票权（比如超过 ⅓ 投票权在线下），这会中断共识。而 Cosmos 架构可以缓解这个问题，它可以使用全球中心，同时，各分区实行地区自治，然后让每个分区的投票权按照正常的地域位置进行分配。如，一般范例就有可能是针对个别城市或地区的，让他们各自运行自己分区的同时，还能共享共同的枢纽（比如 Cosmos 枢纽），并且在临时的网络分区导致的中断期间，也可以继续维持地区自治活动。注意，这样一来在设计稳健的联邦式容错系统过程中，就可以去考虑真实的地理、政治及网络拓扑的特征了。联邦式名称解析系统NameCoin 是首批试图通过比特币技术解决名称解析问题的区块链之一。不过，这个方案存在一些不足。例如，我们可以通过 Namecoin 来验证@satoshi（聪）这个号是在过去某个时间点用特定公钥进行注册的。但是，该公钥是否更新过我们就不得而知了，除非将该名称最后一次更新之前的所有全部下载。这一点是比特币 UTXO 交易模式中默克尔化模型的局限性导致的，这类模型中只有交易（而非可变的应用状态）会以默克尔化加入到区块哈希中。它让我们得在之后用更新证明名称的存在，而非不存在。因此，我们必须依靠全节点才能明确这个名称的最近的值，或者花费大量资源下载整个区块链。即使在 NameCoin 上运用默克尔化的搜索树，其工作量证明的独立性还是会导致轻客戸端的验证出现问题。轻客戸端必须下载区块链中所有区块头的完整备份（或者至少是自其最后的名称更新的所有区块头）。这意味着带宽需要随着时间做线性的扩展。 21此外，在工作量证明制度使区块链上的名称更改需要等额外的工作量证明验证确认才能进行，它在比特币上可能要花费一个小时。有了 Tendermint，我们只需用到由法定数量验证人签署（通过投票权）的区块哈希，以及与名称相关的当前值的默克尔证明。这点让简易、快速、安全的轻客戸端名称值验证成为可能。在 Cosmos 中，我们可以利用这个概念并延伸。每一个在 Cosmos 上的名称注册都能有一个相关的最高级别域名（TLD），比如".com"或者".org"等，而且每个名称注册分区都有自己的管理和登记规则。发行与激励ATOM 代币Cosmos 枢纽是多资产分布式账本，它有自己的代币，是 Atom 。Atom 是 Cosmos 枢纽唯一的权益代币。Atom 是持有人投票、验证或委托给其他验证人的许可证明，就像以太坊上的以太币一样，Atom 也可以用来支付交易费以减少电子垃圾。额外的通胀 Atom 和区块交易费用就作为激励分给验证人及委托验证人。BurnAtomTx交易可以用来恢复储蓄池中任意比例的代币。众筹创世块上的 Atom 代币及验证人的初次分发是 Cosmos 众售参与者持有 75%，预售参与者持有 5%，Cosmos 网络基金会持有 10%，ALL IN BITS, 集团持有 10%。从创世块开始，Atom 总量的 1/3 将作为奖励发放给每年担保持有的验证人以及委托人。更多细节见Cosmos Plan验证人的数量限制与比特币或其他工作量证明区块链不同的是, 由于通信的复杂性增加, Tendermint 区块链会随着验证人的增加而变慢。幸运的是, 我们可以支持足够多的验证人来实现可靠的全球化分布式区块链， 并具有非常快的交易确认时间。 而且随着带宽、存储和并行计算容量的增加, 我们将来能够支持更多的验证人。在创世日, 验证人的最大数量将设置为 100, 这个数字将以 13% 的速度增长 10 年, 最终达到 300 位。Year 0: 100 Year 1: 113 Year 2: 127 Year 3: 144 Year 4: 163 Year 5: 184 Year 6: 208 Year 7: 235 Year 8: 265 Year 9: 300 Year 10: 300 ...成为创世日后的验证人Atom 持有者可以通过签署和提交 BondTx 交易成为验证人。抵押的 atom 数量不能为零。任何人任何时候都成为验证人, 除非当前验证人组的数量超过了最大值。在这种情况下, 只有当持有 atom 的数量大于现有验证人中持有有效 atom 数量的最少者, 该交易才有效, 其中有效 atom 包括受委托的 atom。当一个新的验证人以这种方式替换现有的验证人时, 现有的验证人将离线， 其所有的 atom 和受委托的 atom 进入解绑状态。对验证人的惩罚对于任何有意或无意的偏离认可协议的验证人, 必须对其施加一定的惩罚。有些证据立即可予受理, 比如在同样高度和回合的双重签名, 或违反 “预投票锁定” (Tendermint 协商一致议定书的规则)。这样的证据将导致验证人失去其良好的声誉, 其绑定的 atom 以及在储备池中的比例份额 – 统称为 “权益” – 将被大幅削减。有时, 由于区域网络中断、电源故障或其他原因, 验证人将不可用。如果在过去任意时间点的 ValidatorTimeoutWindow 块中, 验证人的提交投票不包括在区块链中超过 ValidatorTimeoutMaxAbsent 次, 该验证人将离线, 并减少 ValidatorTimeoutPenalty (默认 1%) 的权益。一些 “恶意” 行为在区块链上并没有产生明显的证据。在这些情况下, 如果存在多数的协商一致, 则验证人可以在带外协调,强制将这些恶意验证人超时。如果 Cosmos 枢纽 因为超过 ⅓ 的投票权离线而出现了中止情况，或者说超过 ⅓ 的投票权审查到进入区块链的恶意行为，这时候枢纽就必须借助硬分叉重组协议来恢复。（详见“分叉与审查攻击”）交易费用Cosmos 枢纽验证人可以接受任何种类的代币或组合作为处理交易的费用。每个验证人可自行设置兑换率， 并选择其想要的交易, 只要不超过 BlockGasLimit, 每隔 ValidatorPayoutPeriod (默认为 1 小时) 时间会根据权益相关人绑定的 Atom 比例进行分配。在所收取的交易费用中, ReserveTax (默认 2%) 将存入储备池来增加储备量, 增加 Cosmos 枢纽的安全性和价值。这些资金也可以按照治理系统的决策进行分配。将投票权委托给其他验证人的 Atom 持有人会支付一定佣金给委托方，而这笔费用可以由每个验证人进行设置。激励黑客Cosmos 枢纽的安全取决于底层验证人的安全性和委托人的委托选择。为了鼓励发现和早期报告发现的漏洞, Cosmos 枢纽鼓励黑客通过 ReportHackTx 交易发布成功的漏洞, 说, “这个验证人被入侵了，请把赏金发送到这个地址”。这种情况下, 验证人和委托人将挂起闲置, 每个人 HackPunishmentRatio (默认 5%) 的 atom 将被削减, HackRewardRatio (默认 5%) 的 atom 将发送到黑客的赏金地址作为奖励。验证人必须使用其备份密钥来恢复剩余的 atom。为了防止这一特性被滥用于转移未授权的 atom, 在 ReportHackTx 前后，Atom 的比例（授权的与未授权的） 将保持不变, 而黑客的赏金将包括一些未授权的 atom (如果有的话)。治理规范Cosmos 枢纽是由一个分布式组织管理的, 需要一个明确的治理机制, 以协调对区块链的各种变化, 如系统的参数变量, 以及软件升级和宪法修订.所有验证人负责对所有提案进行表决。如果未能及时对提案进行表决, 将导致验证人被自动停用一段时间。 这段时间被称为 AbsenteeismPenaltyPeriod (默认 1 周)。委托人自动继承其委托的验证人的投票权。这一投票可以被手动覆盖掉。而未绑定的 Atom 是没有投票权的。每个提案都需要 MinimumProposalDeposit 代币的保证金, 这可能是一个或多个代币 (包括 atom) 的组合。对于每项提案, 投票者可以投票表决取走保证金。如果超过半数的投票者选择取走保证金 (例如, 因为提案是垃圾信息), 那么保证金就会存入储备池, 除了被燃烧的 atoms。对于每项提案, 投票人可以选择下列方案:同意强烈同意反对强烈反对弃权决定采纳（或不采纳）提案需要严格的多数投“同意”或“强烈同意”（或者“反对”及“强烈反对”），但是超过 1/3 的人投“强烈反对”或“强烈支持”的话就可以否决大多数人的决定。如果大多数人票被否决，那么他们每个人都会失去 VetoPenaltyFeeBlocks (默认是一天的区块值 ，税费除外) 作为惩罚，而否决大多数决定的那一方还将额外失去 VetoPenaltyAtoms 默认为 0.1%）的 Atom 作为惩罚。参数变更提案这里定义的任何参数都可在 ParameterChangeProposal 通过后改变。赏金提案通过 BountyProposal 后， Atom 可以增发和预留储备池资金作为赏金。文本提案所有其他提案，比如用来更新协议的提案，都会通过通用的 TextProposal 来协调。路线图详见计划.相关工作过去几年涌现了很多区块链共识及扩展性方面的创新。在这一部分中将挑选一些重要的创新进行简单分析。共识系统经典拜占庭容错二十世纪八十年代早期就开始研究存在恶意参与者的共识机制，当时 Leslie Lamport 创造了”拜占庭容错”这个词，用来指那些图谋不轨参与者做出的恶意的行为，与”死机故障”不同，后者只是处理过程崩溃而已。早期针对同步网络也探索出了一些解决方案，网络信息滞后有一个上限，但实际使用是在高度受控的环境下进行，比如精密飞行仪器以及使用原子钟同步的数据中心。直到九十年代后期，实用拜占庭容错（ Practical Byzantine Fault Tolerance ,PBFT）[11]才作为有效的、部分同步的共识算法被逐步推广。它可以容忍 ⅓ 参与者有恶意行为。PBFT 成为标准算法，催生了各种版本，包括最近由 IBM 提出并使用于 Hyperledger 超级账本中的算法。和 PBFT 相比，Tendermint 共识的主要好处在于其改善且简化了的底层结构，其中有些是遵循了区块链典范的结果。Tendermint 中，区块必须按顺序提交，这就消除复杂性，节省 PBFT 中状态变化相关的通信开支。在 Cosmos 和众多加密币中，如果区块 N 本身没有提交，那么就不能让它之后的区块 N+i（i>=1）提交。如果是通信带宽限制导致了区块 N 未提交到 Cosmos Zone 上，那么将通信带宽用于分享选票给区块 N+i 是一种浪费。如果由于网络分区或者节点掉线导致的区块 N 未提交，那么 N+i 就无论如何也不能提交。此外，将交易打包成块可以用默克尔哈希纪录应用程序的状态，而不是用 PBFT 检查机制进行定时摘要。这可以让轻客戸端更快的提交交易证明，以及更快的跨链通信。Tendermint BFT 中也优化了很多 PBFT 特性以外的功能。比如，验证人提交的区块被分割多个部分，对其默克尔化后，然后在节点间广播。这种方式可以提高其广播性能（具体请查看 LibSwift 19）。而且，Tendermint BFT 不会对点对点连接做任何假设，只要点对点间的网络不断开，那么它就能正常运行。BitShare委托权益BitShares [12]不是第一个采用权益证明机制（proof-of-stake,PoS）的区块链，但是其对 PoS 在区块链上的研究与推进做出了巨大的贡献，尤其是在 DPoS，即受委托权益证明方面。在 BitShares 中，相关方选择”见证者”负责提交交易顺序并提交；相关方选择”委托人”负责协调软件更新与参数变化。尽管 BitShare 在理想环境下能达到很高的性能：100k tx/s，1 秒的滞后。每一块只有一个单独的签名，得到交易的最终性的时间比区块时间略长。一个标准的协议仍在开发中。利益相关者可以每天去除或者替换有恶意行为的验证人，但是不同于 Tendermint PoS 的保证金机制，BitShares 没有要求验证人或者代理人的提交押金，如果发生双花攻击的话，押金不会被削减。StellarStellar [13]是以 Ripple 推行的解决方案为基础，它优化了联邦拜占庭协议模型，其中参与共识过程的并不构成一个固定的全局过程。 相反，每个进程节点组织一个或多个“仲裁片”，每个“仲裁片”构成一组可信进程。 Stellar 中的“法定人数”被定义为一组包含至少个个节点的一个仲裁片。从而可达成一致。恒星机制的安全性依赖于任何两个仲裁的交集都是非空的假设，同时，节点的可用性要求至少一个“仲裁片”完全由诚实节点组成。这就需要在“法定人数”的大小上作出妥协：人数过少难以获得共识，人数过多则难以信任所有人。可能难以平衡而不对信任做出重大假设。 除此之外，节点必须维护一定数量的仲裁片以获得足够的容错能力（或者任何“完整节点”，大部分结果的依赖），并且提供一种层级化的配置策略，类似于边界网关协议（Border Gateway Protocol,BGP）。BGP 被互联网服务供应商（Internet Service Provider，ISP）用来建立全球路由表，也被浏览器用来管理传输层安全协议（Transport Layer Security，TLS）证书。他们都因为不安全而臭名昭着。对于 Stellar 论文中基于 Tendermint 的 PoS 批评可以通过本文描述的代币策略来缓解。本文提出了名为 atom 的新的代币，它代表未来交易过程中产生的费用和奖励。 基于 Tendermint PoS 的优势在于其原理相对简单，同时仍可充分保证和证明安全性。BitcoinNGBitcoinNG 是对比特币的改进，允许垂直扩展，比如增加块的大小而避免带来负面的经济后果，例如对矿工造成的影响严重不成比例。 这种改进是通过将 leader 选举与交易广播分开来实现的：leader 首先通过“微块 micro-blocks”的 PoW 选举，然后 leader 能够广播交易直至下一个新的“微块”。 这减少了赢得 PoW 比赛所需的带宽要求，使矿主竞争更公平，并通过允许最后一名矿工提交微块以加快交易提交频率。CasperCasper [16]是以太坊提出的 PoS 共识算法。 它的主要操作模式是“预测押注”的一致。 通过让验证者基于他们目前看到的其他投注来迭代地下注他们认为哪个块将提交入区块链。最终性可以立即实现。链接。 这是 Casper 团队研究的一个热点领域。 挑战在于构建一个可以证明是一个演化稳定策略的投注机制。 与 Tendermint 相比，Casper 的主要优势可能在于提供“可用性超越一致性” — 达成共识不需要超过 50％的投票权 — 可能是以提交速度或实现复杂性为代价的。水平扩展Interledger协议Interledger 协议（The Interledger Protocol，ILP）[14]不是一种严格的扩展方案。 它通过一个松散耦合的双边关系网络，提供一种指定的跨不同账本系统交互操作。像闪电网络一样，ILP 的目的是实现支付，但是它特别关注跨账本类型的支付，并扩展原子事务的处理机制，使得事务的处理不仅支持哈希锁，而且还包括法定人数的公证人（称为原子运输协议）。 后者在账本间交易中实施原子性的机制与 Tendermint 的轻客户 SPV 机制类似，因此比较 ILP 和 Cosmos / IBC 之间的区别是有必要的，具体见下文。ILP 不支持连接器公证员的变更，也不允许公证员之间有灵活的权重。 另一方面，IBC 是专门为区块链设计的，验证人可以拥有不同的权重，并且随着区块链的发展，成员可以随时更改。与闪电网络一样，ILP 中的接收人必须在线才能向发起人发送确认。 在 IBC 代币传输中，接收者所在区块链的验证人集合负责提供确认，而不是接收用户本人。最大的不同在于 ILP 连接器不需要负责对支付状态保持权威性，然而在 Cosmos 中，hub 的验证人负责 IBC 代币传输状态和每个 zone 内持有代币数量的权威性。允许从 zone 之间的安全地不对称地交换代币是本质的创新。在 cosmos 中的 ILP 连接器可以看作是一个持久和最安全的区块链分类账：cosmos hub。ILP内的跨账本支付需要一个交易所的指令集的支持。因为不存在从一个分类账到另一个分类账不对称的代币转移，只能做到市场等价物的转移。侧链Sidechains [15]是一种通过使用与比特币区块链“双向挂钩”替代区块链来扩展比特币网络性能的机制。（双向挂钩相当于桥接，在 cosmos 中被称为“桥接”与市场挂钩区分）。侧链使得比特币可以方便的在比特币区块链和侧链间移动，并允许在侧链上实验新功能。在 Cosmos Hub 中，侧链和比特币是彼此的轻客户端，在比特币区块链和侧链间移动时使用 SPV 证明。当然，由于比特币使用 PoW，以比特币为中心的侧链遭受许多由于 PoW 作为共识机制的引起的问题和风险。而且，这是一个比特币利益最大化的解决方案，并不像 Cosmos 那样本地支持各种代币和 zone 间网络拓扑结构。但是，双向挂钩的核心机制原则上与 Cosmos 所采用的机制相同。以太坊扩展性的努力以太坊目前正在研究许多不同的战略，将以太坊区块链的状态分区化，以解决可扩展性的需求。 这些努力的目标是在共享状态空间之上，维持当前以太坊虚拟机提供抽象层。 目前，多项研究工作正在进行。18Cosmos vs Ethereum 2.0 MauveCosmos 和 Ethereum 2.0 Mauve [22] 有不同的设计理念。Cosmos 是针对代币儿 Mauve 是关于扩大计算能力。Cosmos 不仅限于 EVM, 所以即使不同的 VM 也可以交互。Cosmos 让 zone 的创建者决定验证人。任何人都可以在 Cosmos 中建立新的 zone（除非管理者另做决定）。hub 与 zone 的失效隔离，所以全局的代币不变量可以保持。普遍扩展闪电网络闪电网络被设计成一种代币传输网络，在比特币区块链（及其他公有区块链）上一层运行，通过把大部分交易从共识分类账之外转移到所谓的“ 付款渠道“。 这通过链上加密货币脚本来实现，这些脚本使双方能够进入双方持有的状态化合同，通过共享数字签名来更新状态，并且在合同结束后最终通过在区块链上发布证据，这种机制首先受到跨链原子互换交易的欢迎。 通过与多方开通支付渠道，闪电网络的参与者可以成为集中点，为其他人的支付提供路由，从而导致支付渠道网络的完全联通，其代价是绑定在支付渠道上的资金。虽然闪电网络也可以轻松地跨越多个独立的区块链，并借助交易市场实现价值转移，但它不能实现从一个区块链到另一个区块链的非对称代币交易。 这里描述的 Cosmos 网络的主要优点是实现直接的代币交换。 也就是说，我们希望支付渠道和闪电网络将会与我们的代币传输机制一起被广泛采用，从而节省成本和保护隐私。隔离验证人隔离见证是一个比特币改进建议 BIP，链接 旨在将每块交易吞吐量提高 2 倍或 3 倍，同时使新节点能更快同步区块。 这个解决方案的亮点在于它如何在比特币当前协议的局限下，允许软分叉升级（例如，具有旧版本软件的客户端将在升级后仍可继续运行）。 Tendermint 作为一个新的协议没有设计的限制，所以它具有不同的扩展优先级。 TendermintBFT 的循环算法，主要基于加密签名而不是采矿，这种算法允许通过多个并行区块链进行水平扩展，而更常规、更频繁的区块提交也允许垂直扩展。附录分叉问责制经过精心设计的共识协议应该能够在超出容错能力或者共识出错的情况下为系统提供一定的保障。这在能够通过拜占庭行为获取实质经济回报的金融系统中显得尤为必要。分叉问责制 就属于这种非常重要的保障机制，这种制度会使一个导致共识出错的进程（例如使协议客户端开始接受不同值——即分叉）被识别出来，并且根据协议规则对其进行惩罚，甚至将其移送至司法系统处置。但当司法系统不可靠或者诉讼费极其昂贵时，为了让验证人们都参与到这个机制当中，该制度会强制要求他们建立安全保证金，一旦检测到恶意行为，那么这些保证金将会被罚没或者削减[10].注意这与比特币有所不同，由于网络非同步与局部哈希碰撞的概率特性，比特币的分叉是定期出现的。因为在很多情况下，恶意分叉与非同步引起的分叉是无法分辨的，除非让矿工为挖到的孤立区块支付隐性的机会成本，否则比特币就很难准确地执行分叉问责制。TENDERMINT共识我们把投票阶段分为 预投票 和 预提交 两个阶段。一个投票可以是用于特定区块，也可以用于 Nil。我们把同一轮超过 ⅔ 的单个区块的预投票总和称为 Polka ，把同一轮超过 ⅔ 的单个区块的预提交总和称为 Commit。如果在同一轮中对 Nil 的预提交超过 ⅔，他们就进入到下一轮中。注意到协议中的严格的确定性会引发一个弱同步假设，因为错误的发起者必须被检测到并将其略过。验证人们在为 Nil 预投票之前会等待一段时间，称之为超时提议，这个超时提议的 hi 等待时间也会随着每一轮的进行而递增。每一轮的进行都是完全不同步的，在这个过程中，只有当验证人收听到超过 ⅔ 的网络投票才能进入到下一轮中。实际上，它需要极其强大的阻碍才能阻挠这个弱同步假设（导致无达成共识，无法提交区块），而且通过每个验证人超时提议（TimeoutPropose）的随机值还可更加提高这么做的难度。另一个附加的约束条件，或者叫锁定条例，它能确保网络最终在每个高度只提交一个区块。任何试图在给定高度提交超过一个区块的恶意行为都会被识别出来。首先，一个区块的预提交必须被认为是正当的，并且以 Polka 的形式提交。如果验证人已经准备在 R_1 轮中预提交一个区块，我们称他们锁定了这个区块，并且然后用于验证 R_2 轮新预提交动作的 Polka 必须进入 R_polka 轮，其中 R_1 < R_polka <= R_2。其次，验证人们必须为他们锁定的区块提议并且（或者）预投票。这两个条件共同作用，确保了验证人在对其正当性没有充分论证的情况下不能进行预提交操作，并且保证已经完成预提交的验证人不能再为其他东西的预提交贡献证明投票。这样不但可以保证共识算法的安全性，还能保证它的活跃度。关于这一协议的全部细节参考这里TENDERMINT轻客户端因为生成侧链（一个分叉）意味着至少 ⅓ 的担保权益被罚没，Tendermint 权益证明（Tendermint-PoS）取消了同步所有区块头的要求。当然，罚没保证金也是需要有人共享分叉证据的，所以轻客戸端就要存储任何它见证的区块哈希提交。另外，轻客戸端可以定期地与验证人组的改变保持同步，以避免出现远程攻击（但是其他解决方案也具有可能性）。与以太坊类似，Tendermint 能够让应用程序在每个区块中嵌入一个全局默克尔根的哈希值，可以简单方便的验证的状态查询，比如查询账户余额、在智能合约中的值，或者未使用交易输出（UTXO）的存在，具体由应用程序的特性决定。远程攻击的防御假设有一个足够有弹性的广播网络采集与一组静态验证人组存在，那么任何区块链分叉都可以被检测到，而且发起攻击的验证人提交的保证金会被罚没。这个由 Vitalik Buterin 在 2014 年首次提出的新方法，解决了其他权益证明加密货币的"没有任何相关权益"问题（详见 相关工作部分）。但由于验证人组必须是能够变化的，在较长的时间段内最初的一些验证人会解除 j 押金绑定，这就使他们可以自由地从创世区块中创建新链，并且因为他们不再有被锁定的保证金，他们将不需要为这个行为支付任何费用。这类攻击被称为远程攻击（LRA），与短程攻击相比，后者对处在押金绑定中的验证人发起的分叉是可以对其进行惩罚的（假设有类似 Tendermint 共识这样的分叉问责制拜占庭容错算法）。所以远程攻击经常被认为是对权益证明机制的一种危险打击。幸运的是，远程攻击（LRA）可以用以下的途径来缓解。第一，对于解除绑定的验证人而言（取回抵押保证金并且不再从参与共识中获取费用），保证金在一定时间内不能转移，也可以称其为"解绑周期"，这个周期可能长达数周或数月。第二，对于轻客户端的安全性而言，其首次连接到网络时必须根据可信源验证最新的一个区块哈希或者多个最好的区块哈希。这种情况有时被称为"弱主观性"。最后，为了保证安全，必须与最新的验证人组进行频繁的同步，时长与解绑周期一致。这样就确保了轻客戸端在因验证人解绑资金而失去任何权益之前，知道验证人组的变化情况，否则解绑的验证人就会在其绑定的高度后面开始创建新区块来实施远程攻击，以此来欺骗客户端（假设它可以控制足够多的早期私钥）。注意到用这样的方式来对抗远程攻击（LRA）需要对工作量证明（proof-of-work）的原始安全模块进行彻底检查。在工作量证明中（PoW），一个轻客户端可以通过在每一个区块头中运行工作量证明，以此简便地在任何时候与可信任的创始区块的当前高度进行同步。但是，为了对抗远程攻击（LRA），我们需要轻客戸端定期上线追踪验证人组的变动，其中在首次上线时必须格外仔细地根据可靠源来验证从网络采集的信息。诚然，后面这个要求和比特币类似，其协议和软件也必须从可靠源获得。以上这些为了防止远程攻击的方法，比较好地适用于由 Tendermint 驱动下的区块链验证人节点以及全节点，因为这些节点需要保持与网络的连接。这些方法同样适用于希望频繁地与网络同步的轻客户端。但是，对于那些不希望频繁接入互联网或者区块链网络的轻客户端来说，还有另一种方法可以解决远程攻击的问题。非验证人节点可以在很长的解绑期内（比如比验证人的解绑期更久）使用代币作为保证金，并且为轻客戸端提供二级证明当前有效性以及过去区块哈希的解决方案。虽然这些代币对于区块链共识的安全性并没有价值，不过他们还是可以为轻客戸端提供强大的保障。如果在以太坊中支持历史区块哈希查询，那么任何人都可以用特定的智能合约来绑定他们的代币，并且提供付费证明服务，从而有效地针对轻客戸端 LRA 安全问题开发出一个市场。克服分叉与审查攻击由于提交区块流程的定义，任何联合后不少于 ⅓ 的投票权的节点都可以通过下线或者不广播选票来中止区块链运行。这样的联合也可以通过拒绝包含这些交易的区块来审查特定的交易，尽管这将导致大多数区块提案被拒绝，致使区块提交速率减缓，降低了它的实用性与价值。恶意的联合或许仍然会陆陆续续地广播选票，用阻挠区块链的区块提交来将其逼停，或者使用任何这些攻击的组合攻击。最终，它会通过双重签名或者违反锁定规则来造成区块链分叉。如果一个全球活跃的作恶者也参与进来，就会用可能出现错误的验证组人子集导致速度降低的方法来分割网络。这不只是 Tendermint 面临的局限性，更确切地说是所有被活跃敌对者控制了网络的共识协议所面临的局限性 1。对于这些类型的攻击，验证人的子集应该通过外部的方式进行协调，以签署选择一个分叉（及关系到的所有证据）与带有签名的验证人的初始子集的重组提案。签署了这样一份重组提案的验证者，将放弃在所有其他分叉上属于他们的保证金。客户端应在重组提案中验证签名以及任何相关的证据，并作出判断或提示终端用户作出决定。例如，一个手机钱包 app 应该在可能接受任何由一半以上的初始验证人们通过投票权利签署的重组提案时，给予用户安全警告提示。当多于 ⅓ 的投票权益是不诚实的时候，一个非同步的拜占庭容错算法步能够达成共识，然而，分叉假设不少于 ⅓ 的投票权益已经因不正当的双重签名或者锁定改变而成为不诚实的。因此，签署重组提案是一个协调问题，任何非同步协议都无法解决这个问题（也就是自动的，并且不考虑底层网络的可靠性）。目前，我们通过互联网媒体的社会共识，把重组提案的协调问题留给了用户去协调。验证人必须在签署重组提案之前就确保没有出现网络分割的问题，以此来避免签署两个相冲突的重组提议的情况发生。假设外部协调媒介和协议是可靠的，对于分叉的担心会比审查攻击要少许多。除了需要大于 ⅓ 的拜占庭投票权益才能启动的分叉和审查制度以外，超过 ⅔ 的联合投票权益可能会提交任意、无效的状态。这是任何拜占庭容错算法的共识系统所特有的问题。与利用简单可验证证明来创建分叉的双重签名不同，检测无效状态的提交需要非验证节点来验证整个区块，这意味着非验证节点会保留一份本地的状态副本并执行每一笔交易，然后为他们自己独立计算出状态的根源。一旦检测出来，处理这类故障的唯一方法就是社会共识。打一个比方，在比特币出现问题的情况下，无论是由于软件漏洞造成的分叉（正如 2013 年 3 月），还是由于矿工拜占庭行为提交的无效状态（正如 2015 年 7 月），由商户、开发者、矿工和其他组织组成的联系紧密的社区所建立起来的社会共识会让他们按照分工来参与到修复网络的工作当中去。此外，由于 Tendermint 区块链的验证人身份是可识别的，那么如果需要的话，无效状态的提交实际上是可以被法律或其他外部法律体系惩治的。ABCI说明ABCI 由 3 种主要的信息类型组成，这三类信息从共识引擎传递到应用程序上，然后应用程序用相应回复信息做出应答。AppendTx信息是应用程序的主要传递媒介。区块链中的每一笔交易都通过这个信息来传递。应用程序需要验证每笔交易，这将通过接收针对当前状态、应用协议和交易密码证书的 AppendTx 信息来实现。验证过的交易将需要通过添加数值到键值存储或者更新 UTXO 数据库的方式来更新应用状态。CheckTx信息与 AppendTx 信息类似，但它只是为了交易验证。Tendermint BFT 的内存池会先用 CheckTx 验证交易有效性，并且只会将有效的交易传递给其他的节点。应用程序会检查交易序列号，如果序列号过期就会根据 CheckTx 返回一个错误。Commit信息是用来计算之后会存入到下一区块头中的当前应用状态的加密提交项。这具有便利的特性。状态的前后矛盾性将会像引起程序错误，从而导致区块链分叉。这也简化了安全轻客戸端的开发，因为默克尔哈希证明可以通过检查区块哈希来加以验证，而区块哈希是由规定人数的验证人们签署的（通过投票权益）。此外，ABCI 信息允许应用程序保持追踪验证人组的改变，并让应用程序接收诸如高度和提交选票之类的区块信息。ABCI 请求/响应是简单的 Protobuf 信息。请参考这里的模式文件。AppendTx__参数__:Data ([]byte): 交易请求信息__返回值__:Code (uint32): 回复代码Data ([]byte): 结果字节，如果有的话Log (string): 错误信息__使用__:提交并执行一笔交易，如果交易有效，那返回CodeType.OKCheckTx__参数__:Data ([]byte): 交易请求信息__返回值__:Code (uint32): 回复代码Data ([]byte): 结果字节，如果有的话Log (string): 错误信息__使用__:验证一笔交易。这个信息不应该改变应用状态。交易在广播给其他节点前，首先通过CheckTx运行。你可以发起半状态化 CheckTx，并在Commit或BeginBlock上清算状态，以允许序列执行同一区块中相关的交易。Commit__返回值__:Data ([]byte): 默克尔根值Log (string): 调试或出错信息__使用__:返回当前应用状态。Query__参数__:Data ([]byte): 请求数据__返回值__:Code (uint32): 回复代码Data ([]byte): 查询回复字节Log (string): 调试或出错信息Flush__使用__:刷新回复队列。应用types.Application的应用程序无需实施这条信息——这个由项目进行处理。Info__返回值__:Data ([]byte): 信息字节串__使用__:返回关于应用程序状态的信息. 应用指定。SetOption__参数__:Key (string): 设置参数Value (string): 参数值__返回值__:Log (string): 调试或出错信息__使用__:比如，针对内存池的连接可以将键设置为"mode"（模式），值为"mempool"（内存池）。或者针对共识连接，将键设置为"mode"，值设置为"consensus"（共识）。其他选项根据可具体应用进行专门设置。InitChain__参数__:Validators ([]Validator): 初始化创世验证人__使用__:在创世区块创建时调用BeginBlock__参数__:Height (uint64): 区块刚开始的高度__使用__:为新区块的开始提供信号。在附加交易（AppendTxs）前进行调用。EndBlock__参数__:Height (uint64): 结束时的区块高度__返回值__:Validators ([]Validator): 具有新选票的变动后的验证人（归零就去除）__Usage__:为区块结束提供信号。在每次提交前所有交易后调用。更多细节请参考ABCI知识库。IBC数据包交付确认发送者有很多需要接收链提供数据包交付确认的原因。比如，如果预计目的链会出错，那发送者就可能无法了解目的链的状态。或者，当目的链可能遇到因接收数据包猛烈增多而形成的拒绝服务攻击时，发送者会想要设定数据包超时时限（借助MaxHeight 即最大值包域）。在这些案例中，发送人可以通过在AckPending上设置初始数据包状态来要求提供交付确认。然后就由接收链通过包含一个简化的IBCPacket的应用默克尔哈希来确认交付。![Figure of Zone1, Zone2, and Hub IBC withacknowledgement][4]首先，一个IBCBlockCommit和IBCPacketTx是被上传到“枢纽”上用来证明"分区 1"上的IBCPacket的存在的。假设IBCPacketTx的值如下：FromChainID: "Zone1"-FromBlockHeight：100（假设）Packet：一个 IBCPacket：Header：一个 IBCPacketHeader：-SrcChainID："Zone1"-DstChainID："Zone2"-Number：200（假设）-Status：AckPending-Type："coin"-MaxHeight：350（假设“Hub”当前高度为300）Payload：<一个"代币"的有效负荷字节>其次，一个IBCBlockCommit和IBCPacketTx被传输都“分区2”上用来证明IBCPacket在“枢纽”上的存在。假设IBCPacketTx的值如下：FromChainID："Hub"-FromBlockHeight：300Packet：一个 IBCPacket：Header：一个 IBCPacketHeader：-SrcChainID："Zone1"-DstChainID："Zone2"-Number：200-Status：AckPending-Type："coin"-MaxHeight：350Payload：<一个"代币"相同的有效负荷字节>接下来，"Zone2"必须将缩写的来显示AckSent的最新状态包添加到应用程序状态哈希中。IBCBlockCommitand和IBCPacketTx会传输到“枢纽"上来证明简化的IBCPacket 存在于"分区 2"上。假设IBCPacketTx的值如下：-FromChainID："Zone2"-FromBlockHeight：400（假设）Packet：一个 IBCPacket：Header：一个 IBCPacketHeader：-SrcChainID："Zone1"-DstChainID："Zone2"-Number：200-Status：AckSent-Type："coin"-MaxHeight：350PayloadHash：<一个"代币"相同的有效负荷字节的哈希值>最后，“枢纽”必须更新从AckPending到AckReceived的数据包状态。这个新完成状态的证明应该返回到“分区2”上。假设IBCPacketTx的值如下：FromChainID："Hub"-FromBlockHeight：301Packet：一个 IBCPacket：Header：一个 IBCPacketHeader：-SrcChainID："Zone1"-DstChainID："Zone2"-数量：200-状态：AckReceived-类型："coin"-最大高度：350PayloadHash：<相同"代币"有效负荷的哈希字节>与此同时，“分区1”会假设“代币”包的交付已经成功，除非"枢纽"上有证据给出相反的证明。在上述例子中，如果"枢纽"没有从"分区2"接收到第350个区块的AckSent状态，那么它就会自动将其设置为Timeout（超时）。这个超时的证据可以贴回到"Zone1"上，然后所有代币都会被返还。默克尔树及默克尔证明的说明Tendermint/Cosmos 生态支持的两种默克尔树：简单树和 IAVL+树。简易版默克尔树简易版默克尔树针对基础的静态列表。如果项目的数量不是2的次方，那么有些树叶就会在不同的层上。简易树试图让树的两侧在同一高度，但是左边可能会稍大一点。这种默克尔树就是用于一个区块交易的默克尔化的，而顶层元素就是应用状态的根。 * / \ / \ / \ / \ * * / \ / \ / \ / \ / \ / \ * * * h6 / \ / \ / \ h0 h1 h2 h3 h4 h5 具有7个元素的简易版默克尔树IAVL+树IAVL+数据结构的目的是永久储存应用状态中的密钥对，这样就可以对确定的默克尔根哈希进行高效的运算。这个树的平衡通过AVL 算法的变体来实现，所有运行都是 O(log(n))。在 AVL 树中，任意节点的两个子树的高度至多有一处不同。无论在什么时候这种情况都是与更新相违背的，这个树都会通过创造 O(log(n))新节点（指向旧树上未修改的节点）来再次达到平衡。在初始的 AVL 算法中，内部节点也可以保留密钥值对。AVL+算法（注意这里有个"+"号）对 AVL 算法进行了修改，来维持所有数值都在树叶节点上，同时还只需采用分支-节点来存储密钥。这样在维持较短的默克尔哈希轨迹对的同时，还简化了算法。AVL+树类似于以太坊的帕氏树。其中也有一定的折中。密钥不需要在嵌入到 IAVL+树之前生成哈希，所以这就为密钥空间提供了较快的命令迭代，这会为很多应用程序带来好处。逻辑实现更简单，只需要内部节点和树叶节点这两种节点类型。作为一个平衡的二叉树，其默克尔证明平均更短。而另一方面，IAVL+树的默克尔根有取决于命令的更新。 我们将支持额外有效的默克尔树，比如当二元变量可用时的以太坊帕氏树。交易类型在标准的执行中，交易通过ABCI界面涌入Cosmos Hub的应用程序中。Cosmos Hub将接收几类主要的交易类型，包括SendTx,BondTx,UnbondTx,ReportHackTx,SlashTx,BurnAtomTx,ProposalCreateTx，以及ProposalVoteTx（发送交易、绑定交易、解绑交易、攻击报告交易、削减交易、Atom 燃烧交易，创建提案交易、以及提案投票交易），这些都不需要加以说明，会在未来版本的文档中加以备案。这里我们主要列举两个主要的IBC交易类型： IBCBlockCommitTx以及IBCPacketTx（即IBC区块提交交易以及IBC数据包交易）IBCBlockCommitTxIBCBlockCommitTx交易主要由这些组成：ChainID (string): 区块链的IDBlockHash ([]byte): 区块哈希字节，就是包括应用程序哈希默克尔根BlockPartsHeader (PartSetHeader): 区块部分设置的头字节，只用于验证投票签BlockHeight (int): 提交高度BlockRound (int): 提交回合Commit ([]Vote)：超过 ⅔ 的包括区块提交的 Tendermint 预提交投票ValidatorsHash ([]byte)：新验证组的默克尔树根哈希ValidatorsHashProof (SimpleProof)： 在区块哈希中证明验证人哈希的简易树默克尔证明AppHash ([]byte)：IAVL 树，应用程序状态的默克尔树根哈希AppHashProof (SimpleProof): 在区块哈希中验证应用程序哈希的简易版默克尔树证明AppHash against the BlockHashIBCPacketTxIBCPacket由下列项组成：Header (IBCPacketHeader): 数据包头Payload ([]byte): 数据包有效负荷字节。可选择。PayloadHash ([]byte)：数据包字节哈希。可选择。有效负荷Payload或有效负荷哈希PayloadHash必须存在一个。IBCPacket的哈希就是两个项的简易版默克尔根，即头和有效负荷。没有完整有效负荷的IBCPacket被称作_缩写版包_。IBCPacketHeader由下列项组成：SrcChainID (string): 源区块链IDDstChainID (string)：目标区块链IDNumber (int): 所有数据包的唯一编号Status (enum): 可以是AckPending,AckSent,AckReceived,NoAck或TimeoutType（string）：类型取决于应用程序。Cosmos保留“coin”包类型MaxHeight (int): 如果状态不是这个高度给出的NoAckWanted或者AckReceived，那么状态就算超时。_可选择_IBCPacketTx交易有下列项组成：FromChainID (string): 提供给这个数据包的区块链 ID，不是源所必须的FromBlockHeight (int): 区块链高度，其中接下来的包会包含在（默克尔化的）源链的区块哈希中Packet (IBCPacket): 数据包，其状态可能是以下之一:AckPending、AckSent、AckReceived、NoAck或TimeoutPacketProof (IAVLProof): IAVL树默克尔证明，用于验证在给定高度下的源链应用哈希中的数据包哈希通过"Hub"，将数据包从"Zone1"发送到"Zone2"的序列，描述在{Figure X}函数中。首先，一个IBCPacketTx会向"Hub"证明数据包是包含在"Zone1"的应用程序状态中。然后，另一个IBCPacketTx 会向"Zone2"证明数据包包含在"Hub"的应用程序状态中。在这个过程中，IBCPacketTx 的字段是相同的：SrcChainID永远是"Zone1"，而DstChainID 永远是"Zone2"。PacketProof必须有正确的默克尔证明路径，如下：IBC/<SrcChainID>/<DstChainID>/<Number>当“Zone1”要通过“Hub”将数据包传送到“Zone2”中，无论数据包是否在“Zone1”、“Hub”、或者“Zone2”中默克尔化了，IBCPacket数据都是相同的。唯一易变的字段是为追踪交付的Status。鸣谢我们为所有朋友欲同行们在概念成型与检查方面给予的帮助，以及对我们在Tendermint与Cosmos工作中的大力支持，表示衷心地感谢。[SkuChain]( https://www.Zaki Manian)(https://github.com/zmanian )措辞，特别是在ABCI部分Jehan Tremback的Althea和Dustin Byington帮助进行初始迭代Andrew MillerHoney Badger对共识的反馈Greg Slepak对共识和措辞的反馈也感谢Bill Gleim 和Seunghwan Han的各种贡献。你的名字和组织在这里为你的贡献引用[1] Bitcoin: https://bitcoin.org/bitcoin.pdf[2] ZeroCash: http://zerocash-project.org/paper[3] Ethereum: https://github.com/ethereum/wiki/wiki/White-Paper[4] TheDAO: https://download.slock.it/public/DAO/WhitePaper.pdf[5] Segregated Witness: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki[6] BitcoinNG: https://arxiv.org/pdf/1510.02037v2.pdf[7] Lightning Network: https://lightning.network/lightning-network-paper-DRAFT-0.5.pdf[8] Tendermint: https://github.com/tendermint/tendermint/wiki[9] FLP Impossibility: https://groups.csail.mit.edu/tds/papers/Lynch/jacm85.pdf[10] Slasher: https://blog.ethereum.org/2014/01/15/slasher-a-punitive-proof-of-stake-algorithm/[11] PBFT: http://pmg.csail.mit.edu/papers/osdi99.pdf[12] BitShares: https://bitshares.org/technology/delegated-proof-of-stake-consensus/[13] Stellar: https://www.stellar.org/papers/stellar-consensus-protocol.pdf[14] Interledger: https://interledger.org/rfcs/0001-interledger-architecture/[15] Sidechains: https://blockstream.com/sidechains.pdf[16] Casper: https://blog.ethereum.org/2015/08/01/introducing-casper-friendly-ghost/[17] ABCI: https://github.com/tendermint/abci[18] Ethereum Sharding: https://github.com/ethereum/EIPs/issues/53[19] LibSwift: http://www.ds.ewi.tudelft.nl/fileadmin/pds/papers/PerformanceAnalysisOfLibswift.pdf[20] DLS: http://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf[21] Thin Client Security: https://en.bitcoin.it/wiki/Thin_Client_Security[22] Ethereum 2.0 Mauve Paper: http://vitalik.ca/files/mauve_paper.htmlUnsorted linkshttps://www.docdroid.net/ec7xGzs/314477721-ethereum-platform-review-opportunities-and-challenges-for-private-and-consortium-blockchains.pdf.html英文原版