text: webpackJsonp([0xee22153e3ddc],{518:function(e,t){e.exports={data:{markdownRemark:{html:'<h2>Cardano contributing guide:</h2>\n<p>Can be found here <a href="https://github.com/input-output-hk/cardano-sl/blob/develop/CONTRIBUTING.md">https://github.com/input-output-hk/cardano-sl/blob/develop/CONTRIBUTING.md</a></p>',frontmatter:{path:"/en/for-contributors/",doc_title:"For Contributors",author:null,date:"2017-01-04",label:"docs",language:"en",keywords:null}},allMarkdownRemark:{edges:[{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/AAA.en.md absPath of file >>> MarkdownRemark",excerpt:"\n##This is Post 1\n\npost1 one Cillum enim sint excepteur laborum mollit nulla dolore dolore id pariatur. Ea ullamco ex aute aliquip deserunt. Quis deserunt fugiat adipisicing ea cupidatat. Duis anim nisi officia sit irure. Esse Lorem exercitation ex ut.\n",html:"<h2>This is Post 1</h2>\n<p>post1 one Cillum enim sint excepteur laborum mollit nulla dolore dolore id pariatur. Ea ullamco ex aute aliquip deserunt. Quis deserunt fugiat adipisicing ea cupidatat. Duis anim nisi officia sit irure. Esse Lorem exercitation ex ut.</p>\n<!-- end -->\n<p>Tempor duis nisi ipsum deserunt Lorem duis voluptate aliqua deserunt ipsum occaecat consectetur velit ipsum. Minim eu eu culpa deserunt sit quis reprehenderit velit sunt esse non irure quis velit. Incididunt magna ipsum anim cillum excepteur proident excepteur aliquip tempor.</p>",frontmatter:{path:"/en/post-1",doc_title:"Post 1",author:"Charles Hoskinson",date:"06-09-2018",language:"en",label:"docs",keywords:"post1 one",group:null}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/2017-01-04-installation.cn.md absPath of file >>> MarkdownRemark",excerpt:"安装 支持的平台 支持的平台包括 Windows, macOS 和 Linux。这是 代达罗斯钱包 的  Windows 和 macOS 平台安装器 。 Linux 平台的安装器将在不久发布。目前来说，有两种方式在 Linux…",html:'<!-- Reviewed at d0868afac50ba6ffcbd95054e65cbf77fa513082 -->\n<h1>安装</h1>\n<!-- CARDANO_SL_README_BEGIN_3 -->\n<h2>支持的平台</h2>\n<p>支持的平台包括 Windows, macOS 和 Linux。这是<a href="https://github.com/input-output-hk/daedalus">代达罗斯钱包</a>的 <a href="https://daedaluswallet.io/#download">Windows 和 macOS 平台安装器</a>。</p>\n<p>Linux 平台的安装器将在不久发布。目前来说，有两种方式在 Linux 上运行卡尔达诺结算层：</p>\n<ol>\n<li>从源码构建（推荐方式）。请参考<a href="https://github.com/input-output-hk/cardano-sl/blob/develop/docs/how-to/build-cardano-sl-and-daedalus-from-source-code.md">如何通过源代码构建卡尔达诺结算层以及代达罗斯钱包</a>文档。</li>\n<li>\n<p>使用<strong>非官方</strong> Arch Linux 安装包：</p>\n<ul>\n<li><a href="https://aur.archlinux.org/packages/cardano-sl/">cardano-sl</a></li>\n<li><a href="https://aur.archlinux.org/packages/daedalus-bridge/">daedalus-bridge</a></li>\n<li><a href="https://aur.archlinux.org/packages/daedalus/">daedalus</a></li>\n</ul>\n</li>\n</ol>\n<!-- CARDANO_SL_README_END_3 -->',frontmatter:{path:"/cn/installation",doc_title:"安装",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/2017-01-13-for-contributors.cn.md absPath of file >>> MarkdownRemark",excerpt:"Redirecting...",html:'<h1>Redirecting...</h1>\n<script>\n    //window.location.replace("https://github.com/input-output-hk/cardano-sl/blob/develop/CONTRIBUTING.md");\n</script>',frontmatter:{path:"/cn/for-contributors/",doc_title:"对于贡献者",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/2017-01-01-index.cn.md absPath of file >>> MarkdownRemark",excerpt:"亲爱的读者，本文档的目的是让您对于 Cardano 平台技术栈第一层即结算层有所了解。如果您理解了结算层是什么，我们建议您先阅读 论文和实现的差异 ，然后再阅读 协议和实现的文档 。 本文档目标读者是 IOHK…",html:'<!-- Reviewed at d0868afac50ba6ffcbd95054e65cbf77fa513082 -->\n<p>亲爱的读者，本文档的目的是让您对于 Cardano 平台技术栈第一层即结算层有所了解。如果您理解了结算层是什么，我们建议您先阅读<a href="/cardano/differences/">论文和实现的差异</a>，然后再阅读<a href="/technical/protocols/csl-application-level/">协议和实现的文档</a>。</p>\n<p>本文档目标读者是 IOHK 的开发人员，第三方软件开发人员，审计和致力于实现卡尔达诺结算层或使用卡尔达诺结算层参考实现的咨询人员。</p>\n<!-- CARDANO_SL_README_BEGIN_1 -->\n<h2>什么是卡尔达诺结算层?</h2>\n<p>Cardano SL（或卡尔达诺运算层）是由 <a href="https://iohk.io/team">IOHK</a> 联合爱丁堡大学，雅典大学和康涅狄格大学共同设计开发的一种加密货币。卡尔达诺运算层是基于 Aggelos Kiayias，Alexander Russell，Bernardo David 和 Roman Oliynykov 的白皮书 <a href="https://iohk.io/research/papers/#9BKRHCSI">『乌洛波罗斯：可证明安全的权益证明协议』</a>的 Haskell 实现。</p>\n<p>您可以将卡尔达诺结算层视为基于比特币重新设计的针对比特币缺陷的自由修复。 有关卡尔达诺结算层和比特币之间的相似之处和差异的更多信息，请阅读<a href="http://cardanodocs.com/introduction/cn/#%E5%8D%A1%E5%B0%94%E8%BE%BE%E8%AF%BA%E8%BF%90%E7%AE%97%E5%B1%82%E4%B8%BA%E4%BB%80%E4%B9%88%E7%89%B9%E5%88%AB">『卡尔达诺结算层为什么特别?』</a>。</p>\n<!-- CARDANO_SL_README_END_1 -->\n<h2>加密货币基础</h2>\n<p>在给出加密货币的定义之前，我们先来谈谈为什么我们在意数字货币，特别是加密货币。</p>\n<h3>我们为什么在意?</h3>\n<h4>速度</h4>\n<p>与传统（也称为法定）中心银行货币，与日元或美元相反，电子货币不需要一个银行系统来转移价值。这一限制的解除，使用数字货币的速度要快于银行业务，尤其是在全球范围内。使用数字货币从大阪转移10美元到丹佛不再需要数天的时间。无论距离如何，所有交易都能迅速完成。</p>\n<h4>你掌控你自己的钱</h4>\n<p>所有的商业银行账户所有者在收到支付请求后在合理的时间内只能支付一定的金额。银行体系对任何价值量都有限制，使个人无法迅速撤出或转移大量资金。有加密货币的情况下，持有一种称为<strong>密钥</strong>这一特殊信息的人就可以随意花钱。没有其他实体有权操纵用户拥有的价值。</p>\n<h4>匿名</h4>\n<p>人们可以根据需要，拥有任意多的加密货币地址，从不同的地址接收，消费资产。经营电子商务商店的商家可以拥有一组收款和退款的地址，以及一个用于他们自身需要的单独的个人『钱包』。通过统一的接口控制所有这些钱包，并且不需要登录到多个支付平台，这使得该过程非常节省时间。</p>\n<h4>安全</h4>\n<p>你的钱就像可用于消费的<strong>密钥</strong>一样安全。这意味着将密钥存储在保险箱中的 USB 闪存上相当于让纸币处于安全状态。即使进行了成功的网络攻击，也绝对没有人能够窃取这笔钱。</p>\n<h4>扩展性</h4>\n<p>使用一种称为<a href="https://www.blockstream.com/sidechains.pdf">侧链</a>的方法，以及通用加密货币，如卡尔达诺结算层和比特币，就可以启用特定领域的加密货币，例如以太经典。这样一来，通过特定领域的加密货币开发的任何创新产品都可以让参与者在通用的加密货币中保持价值。这样的应用程序的例子有身份管理，游戏和赌博，以及可验证计算。</p>\n<h3>什么是加密货币?</h3>\n<p>加密货币是一种数字货币形式，使用密码来控制价值。密码学提供了一种生成任何类型信息的真实真实性证据的方法。这就是所谓的<em>数字签名</em>。在加密货币中，我们通过签署和发送交易到网络并接收已确认的交易块，生成一个总账（一个提供每个地址有多少钱的信息的数据库）。加密货币通常是分散的，这意味着来自全球各地的许多人通过运行加密货币节点参与总账的生成。因此，必须达成关于总账状况的共识。下一节讨论实现这种共识的两个最重要的方法。</p>\n<h2>卡尔达诺结算层为什么特别</h2>\n<!-- v0.1.0.0 -->\n<p>虽然比特币和卡尔达诺结算层之间有相似之处，但这两个加密货币之间也有很多不同之处。最显着的区别是，比特币是工作量证明类型的加密货币，而卡尔达诺结算层使用权益证明的方法达成共识。这鼓励诚信和长期的参与。</p>\n<h3>共识算法的目的</h3>\n<p>共识算法被用来产生新的交易区块，使账本更新状态。每当有人发布一个交易区块时，他们（或者说他们的运行加密货币协议的节点）就必须附上他们已经证明的证据。下面讨论两种类型的证明。</p>\n<h3>工作量证明和挖矿</h3>\n<p>工作量证明是加密货币最普遍的共识算法类型。它起源于比特币，加密货币就是这么工作的。为了生成工作证明，计算机必须解决一个挑战。这是难以解决的计算繁重的问题，但解决方案很容易验证。当一台基于网络的工作量证明的计算机找到一个解决方案时，它会将交易发布于同它一起计算的其他计算机。这台计算机会因为产生区块得到交易费和奖励。整个过程被称为<em>挖矿</em>。挖矿是非常耗能的，所需的能源数量在不断增加，这可能导致不健康的竞争。</p>\n<h3>权益证明和铸币</h3>\n<p>权益证明是一种生成区块的新方法。由 <a href="https://iohk.io/team/aggelos-kiayias/">Aggelos Kiayias 教授</a>领导的 IOHK 科学家们设计了第一个可证明的，称为乌洛波罗斯的权益证明算法。乌洛波罗斯是卡尔达诺结算层的核心。研究小组已经发表了一篇<a href="https://iohk.io/research/papers/a-provably-secure-proof-of-stake-blockchain-protocol/">白皮书</a> ，这封白皮书对于那些拥有加密货币理论背景的人来说是值得一读的。权益证明的核心思想是，不要浪费电力来解决计算繁重的问题，而是选择一个节点来铸造一个新的区块，其概率与这个节点的硬币数量成正相关。如果一个节点有整数个(> 0)的 <a href="/cardano/proof-of-stake/#stake">slot</a>，它被称为 slot 所有人。如果一个节点最终被选中来铸造一个区块，那么这个节点被称为 slot 领导者。您可以在<a href="/cardano/proof-of-stake/">卡尔达诺结算层的股权证明</a>中了解更多关于该流程的信息。</p>\n<!-- CARDANO_SL_README_BEGIN_2 -->\n<h2>卡尔达诺结算层之上</h2>\n<p>卡尔达诺结算层被称为『层』是有原因的。这是卡尔达诺平台的第一个组件。最终，它将被扩展到一个控制层，作为一个可信的计算框架来评估一种特殊的证明，以确保一定的计算正确执行。在游戏和赌博中，这样的系统被用于验证随机数生成和游戏结果的真实性。伴随着侧链，它将有可能完成诸如在游戏中公平分配奖金的任务。但是控制层的应用远远超出了游戏和赌博。身份管理，信用系统等将成为卡尔达诺平台的一部分。我们将迭代卡尔达诺<a href="https://github.com/input-output-hk/daedalus">钱包应用程序 Daedalus</a>，使其变成一个具有自动加密货币交易功能和合法加密货币交易功能的通用加密货币钱包。</p>\n<!-- CARDANO_SL_README_END_2 -->',frontmatter:{path:"/cn/introduction/",doc_title:"介绍",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/2017-01-19-glossary.cn.md absPath of file >>> MarkdownRemark",excerpt:"术语表 Ada 我们的货币的名字，为纪念  Ada\nLovelace…",html:'<!-- Reviewed at d0d6c2fedefb642744a24b4b0a6d8d7ad11532f6 -->\n<h1>术语表</h1>\n<h2>Ada</h2>\n<p>我们的货币的名字，为纪念 <a href="https://en.wikipedia.org/wiki/Ada_Lovelace">Ada\nLovelace</a> 而命名。</p>\n<h2>地址</h2>\n<p><a href="#%E8%8A%82%E7%82%B9">节点</a>的唯一标示符。请阅读<a href="/cardano/addresses/">卡尔达诺结算层的地址</a>获得更多信息。</p>\n<h2>余额</h2>\n<p>请阅读<a href="/cardano/balance-and-stake/">卡尔达诺结算层的余额和权益</a> 获得解释。</p>\n<h2>区块</h2>\n<p><a href="#%E8%B4%A6%E6%9C%AC">账本</a>的基础元素。请阅读<a href="/technical/blocks/">卡尔达诺区块</a>获取技术细节。</p>\n<h2>区块链</h2>\n<p>请阅读<a href="#%E8%B4%A6%E6%9C%AC">账本</a>。</p>\n<h2>卡尔达诺结算层</h2>\n<p>卡尔达诺 SL (或者说卡尔达诺结算层) 是由 <a href="https://iohk.io/team">IOHK</a> 设计和开发的去中心化加密货币。为纪念 <a href="https://en.wikipedia.org/wiki/Gerolamo_Cardano">Gerolamo Cardano</a> 而命名。</p>\n<h2>掷币</h2>\n<p>掷币协议是允许两方或多方获得均匀随机值的协议。我们使用掷币协议作为 <a href="#ssc">SSC</a> 的基础。请阅读<a href="#%E8%AE%BA%E6%96%87">论文</a>（第36页）以了解掷币协议的更多详情。</p>\n<h2>一致性算法</h2>\n<p>分布式系统对于共享数据集合达成一致观点的一种方式。卡尔达诺结算层使用<a href="/cardano/proof-of-stake/">乌洛波罗斯一致性算法</a>，这是一个基于<a href="#%E6%9D%83%E7%9B%8A%E8%AF%81%E6%98%8E">权益证明</a>的算法。</p>\n<h2>加密货币</h2>\n<p>使用加密协议来生成账本的计算机系统，请阅读<a href="/introduction/#cryptocurrency-basics">加密货币基础</a>了解更多信息。</p>\n<h2>代达罗斯</h2>\n<p>卡尔达诺结算层钱包应用。 它为用户提供一个用户界面, 用户可以管理，发送，收取资金等等。请阅读<a href="/technical/wallet-frontend/">卡尔达诺结算层钱包应用前端</a>获取更多信息。</p>\n<h2>去中心化</h2>\n<p>通过独立节点进行交互操作的计算机系统的概念。在维护共享数据集合，如账本的情况下，需要对数据的一致性和可靠性达成共识。</p>\n<h2>Epoch</h2>\n<p>我们将知道谁有权利在每个 slot 中生成一个区块的更长的时间段。请阅读<a href="#%E8%AE%BA%E6%96%87">论文</a>（第3页）了解技术细节。</p>\n<h2>追随中本聪</h2>\n<p>一种随机选择权益所有者在区块链中建立一个新区块的机制，根据协议中的股份数量，按比例获得选举机会。</p>\n<h2>保证输出交付</h2>\n<p>保证输出交付是一种机制，能证明诚实方能保证成功完成多方计算（MPC）。我们在 <a href="#ssc">SSC</a> 中使用 G.O.D.</p>\n<h2>诚实的大多数</h2>\n<p>诚实的大多数是指诚实的参与者数量严格大于攻击者数量的情况，即至少 50% + 1 是诚实的大多数。</p>\n<h2>Kademlia</h2>\n<p>请阅读<a href="#%E5%AF%B9%E7%AD%89%E7%82%B9%E5%8F%91%E7%8E%B0">对等点发现</a>。</p>\n<h2>领导者选举</h2>\n<p>挑选谁将在下一个 epoch 生成区块的过程。将依据领导者的股权比例选出（参见<a href="#%E6%9D%83%E7%9B%8A%E8%AF%81%E6%98%8E">权益证明</a>, <a href="#%E8%BF%BD%E9%9A%8F%E4%B8%AD%E6%9C%AC%E8%81%AA%E7%AE%97%E6%B3%95">追随中本聪算法</a>)。</p>\n<h2>账本</h2>\n<p>个人所拥有的价值的数据集合。请阅读<a href="#%E8%AE%BA%E6%96%87">论文</a>了解技术细节。</p>\n<h2>Lovelace</h2>\n<p>我们的货币的最小单位的名称。为纪念 <a href="https://en.wikipedia.org/wiki/Ada_Lovelace">Ada\nLovelace</a> 而命名。</p>\n<h2>铸币</h2>\n<p>在<a href="/introduction/#%E6%9D%83%E7%9B%8A%E8%AF%81%E6%98%8E%E5%92%8C%E9%93%B8%E5%B8%81">权益证明和铸币</a>系统中生成新区块的过程。</p>\n<h2>节点</h2>\n<p>参与分布式协议系统的计算机程序。请阅读<a href="/technical/#%E9%AB%98%E5%B1%82%E6%AC%A1%E6%A6%82%E8%BF%B0">高层次概述</a>获取更多细节。</p>\n<h2>论文</h2>\n<p>官方协议论文：<a href="https://eprint.iacr.org/2016/889">乌洛波罗斯：一个可证安全的权益证明区块链协议</a>。请注意，卡尔达诺结算层的实现与论文的实现不同，<a href="/cardano/differences/">请阅读差异</a>以了解详情。</p>\n<h2>节点发现</h2>\n<p>节点运行后找到其他节点的方法。我们使用的节点发现基于 Kademlia DHT。请阅读 <a href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf"> Kademlia\n论文</a>获得技术细节。</p>\n<h2>Plutus</h2>\n<p>在卡尔达诺中定义智能协议的强类型纯函数式语言。请阅读 <a href="/technical/plutus/introduction/">Plutus</a> 获取更多细节。</p>\n<h2>权益证明</h2>\n<p>乌洛波罗斯权益证明算法是<a href="#%E8%AE%BA%E6%96%87">协议</a>中最重要的部分。它定义了<a href="#%E8%8A%82%E7%82%B9">节点</a>对<a href="#%E8%B4%A6%E6%9C%AC">账本</a>状态达成共识的方式。请阅读<a href="/cardano/proof-of-stake/">乌洛波罗斯权益证明算法</a>获取更多细节。</p>\n<h2>PVSS</h2>\n<p>公开验证密钥共享模式 (Publicly Verifiable Secret Sharing)是我们在 <a href="#ssc">SSC</a> 中使用的密码方案。请阅读<a href="/technical/pvss/">卡尔达诺结算层 PVSS</a> 获取更多细节。</p>\n<h2>富人</h2>\n<p>有足够股权参与一些行动的权益所有人。具体来说，有三种类型的动作：随机性生成（<a href="/technical/leader-selection/">slot 领导者选举过程</a>），<a href="/technical/delegation/#%E9%87%8D%E9%87%8F%E7%BA%A7%E6%9D%83%E7%9B%8A%E5%A7%94%E6%B4%BE">重量级权益委派</a>，<a href="/cardano/update-mechanism/#%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%9B%B4%E6%96%B0%EF%BC%9A%E7%AD%BE%E7%BD%B2%E5%92%8C%E5%AE%A3%E5%B8%83">更新提案的投票</a>。</p>\n<h2>签名</h2>\n<p>一种用来生成我们在<a href="#%E5%8A%A0%E5%AF%86%E8%B4%A7%E5%B8%81">加密货币</a>中使用的保证任何类型信息真实性证据的方法。</p>\n<h2>Slot</h2>\n<p>在不同节点上显著大于预期的不同时钟数的一小段物理时间。请阅读<a href="#%E8%AE%BA%E6%96%87">论文</a>(第4页)获取更多技术细节。</p>\n<h2>Slot 领导者</h2>\n<p>slot 领导者是一个被选举为有权在当前 slot 创建区块的节点。请阅读<a href="#%E8%AE%BA%E6%96%87">论文</a>(第7页)获取更多技术细节。</p>\n<h2>SSC</h2>\n<p>SSC (Shared Seed Computation) 是 <a href="#%E9%A2%86%E5%AF%BC%E8%80%85%E9%80%89%E4%B8%BE">Slot 领导者选举</a>的一部分。这部分被实现为<a href="#%E4%BF%9D%E8%AF%81%E8%BE%93%E5%87%BA%E4%BA%A4%E4%BB%98">保证输出交付</a>的<a href="#%E6%8E%B7%E5%B8%81">掷币</a>协议。作为 SSC 的结果，我们得到一个将用于<a href="#%E8%BF%BD%E9%9A%8F%E4%B8%AD%E6%9C%AC%E8%81%AA">追随中本聪</a>机制的随机算法。</p>\n<h2>权益</h2>\n<p>请阅读 <a href="/cardano/balance-and-stake/">卡尔达诺结算层的余额和权益</a> 章节获取解释。</p>\n<h2>权益所有人</h2>\n<p>一个拥有正数股权的节点。</p>\n<h2>转账</h2>\n<p>表示价值转移的数据。请阅读<a href="/cardano/transactions/">卡尔达诺结算层的转账</a>获取更多细节。</p>\n<h2>转账费用</h2>\n<p>请阅读<a href="/cardano/transaction-fees/">卡尔达诺结算层转账费用</a>章节获取解释。</p>',frontmatter:{path:"/cn/glossary",doc_title:"术语表",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/contributors/2017-01-01-building-from-source.cn.md absPath of file >>> MarkdownRemark",excerpt:"重定向中...",html:'<h1>重定向中...</h1>\n<script>\n    // window.location.replace("https://github.com/input-output-hk/cardano-sl/blob/develop/docs/how-to/build-cardano-sl-and-daedalus-from-source-code.md");\n</script>',frontmatter:{path:"/cn/for-contributors/building-from-source/",doc_title:"从源码构建卡尔达诺结算层",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"for-contributors"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/contributors/2017-01-03-haddock.cn.md absPath of file >>> MarkdownRemark",excerpt:"Haddock 文档 这里是卡尔达诺结算层的 Haddock 文档。 最新版本 这是  最新文档 。 发布版本 稳定版本的文档将在之后发布。",html:'<!-- Reviewed at c507f6675c16810ba9ca72b71dac57288fd1735c -->\n<h1>Haddock 文档</h1>\n<p>这里是卡尔达诺结算层的 Haddock 文档。</p>\n<h2>最新版本</h2>\n<p>这是 <a href="/haddock/latest/index.html">最新文档</a>。</p>\n<h2>发布版本</h2>\n<p>稳定版本的文档将在之后发布。</p>',frontmatter:{path:"/cn/for-contributors/haddock/",doc_title:"Haddock 文档",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"for-contributors"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/2017-01-01-index.en.md absPath of file >>> MarkdownRemark",excerpt:"What is Cardano SL? Cardano SL (or Cardano Settlement Layer) is a cryptographic currency designed\nand developed by  IOHK  in conjunction…",html:'<h2>What is Cardano SL?</h2>\n<p>Cardano SL (or Cardano Settlement Layer) is a cryptographic currency designed\nand developed by <a href="https://iohk.io/team">IOHK</a> in conjunction with the University\nof Edinburgh, the University of Athens and the University of Connecticut. Cardano\nSL is based on the Haskell implementation of the white paper\n<a href="https://iohk.io/research/papers/#9BKRHCSI">"Ouroboros: A Provably Secure Proof of Stake Blockchain Protocol"</a>\nby Aggelos Kiayias, Alexander Russell, Bernardo David and Roman Oliynykov.</p>\n<p>You can think of Cardano SL as Bitcoin reimagined with a freedom to fix Bitcoin’s\ndesign flaws. Please read <a href="https://en/cardanodocs.com/introduction/#what-makes-cardano-sl-special">"What Makes Cardano SL Special?"</a>\nfor more information about similarities and differences between Cardano SL and Bitcoin.</p>\n<!-- CARDANO_SL_README_END_1 -->\n<h2>Cryptocurrency Basics</h2>\n<p>Before giving a definition of a cryptocurrency, let\'s talk about why we care\nabout digital currencies in general and cryptographic currencies in particular.</p>\n<h3>Why Do We Care?</h3>\n<h4>Speed</h4>\n<p>As opposed to conventional (also known as fiat), centrally banked currencies,\nsuch as the Yen or the American Dollar, digital currencies do not require a\nbanking system to move value. With this restriction lifted, working with digital\ncurrencies is much faster than working with banking, especially on a global\nscale. Transferring 10 USD from Osaka to Denver no longer takes days when a\ndigital currency is used. All transactions are made rapidly regardless of the\ndistance.</p>\n<h4>You Own Your Money</h4>\n<p>All that a commercial bank account owner is given is a promise of being paid a\ncertain amount of money within a reasonable amount of time after receiving a\npayout request. Banking systems also have limits to any volume of value being\nmoved, rendering an individual unable to withdraw or transfer large amounts\nquickly. In case of cryptocurrencies, the person who holds a special kind of\ninformation called <em>a secret key</em> can spend the money at will. No other entity\nhas a power to manipulate the value that a user owns.</p>\n<h4>Pseudonymity</h4>\n<p>One can have as many cryptocurrency addresses as they wish, receiving and\nspending money from different addresses as per their purpose. A merchant running\nan E-Commerce shop can have a set of addresses for receiving money and issuing\nrefunds, and a separate personal "wallet" for their own needs. A single interface is used\nto control all of these wallets, and there is no need to log in to several\npayment platforms, which makes the process very time-efficient.</p>\n<h4>Security</h4>\n<p>Your money is as secure as the <em>secret key</em> that allows spending it. This means\nthat storing your secret key on a USB flash drive in a safe is equivalent to\nhaving banknotes in a safe. Absolutely nobody can steal this money even by\ncarrying out a successful cyberattack.</p>\n<h4>Extensibility</h4>\n<p>Using an approach known as <a href="https://www.blockstream.com/sidechains.pdf"><em>side\nchains</em></a>, general purpose\ncryptocurrencies such as Cardano SL or Bitcoin can enable domain specific\ncryptocurrencies, such as Ethereum Classic. This way, any innovation developed\nvia domain specific cryptocurrency can have participants who hold value in a\ngeneral purpose cryptocurrency. Examples of such applications are identity\nmanagement, gaming and gambling, and verifiable computations.</p>\n<h3>What is a Cryptocurrency?</h3>\n<p>Cryptocurrency is a form of digital currency that uses cryptography to\nmanipulate value. Cryptography provides a way to generate proof of genuine\nauthenticity of any kind of information. This is called <em>digital signing</em>. In\ncryptocurrencies we generate a ledger (a database which provides information on\nhow much money each address has) by signing and sending transactions to the\nnetwork and receiving blocks of confirmed transactions. Cryptocurrencies are\nnormally decentralized, meaning that many people from all over the globe\nparticipate in ledger generation by running cryptocurrency nodes. Thus, a\nconsensus about the state of the ledger has to be achieved. Two most significant\napproaches for achieving such consensus are discussed in the next section.</p>\n<h2>What Makes Cardano SL Special?</h2>\n<!-- v0.1.0.0 -->\n<p>While there are similarities between Bitcoin and Cardano SL, there are also many\ndifferences between these two cryptocurrencies. The most significant difference\nis that Bitcoin is a proof of work type cryptocurrency, while Cardano SL makes\nuse of a proof of stake approach to reach consensus. This encourages honesty and\nlong term participation.</p>\n<h3>Purpose of a Consensus Algorithm</h3>\n<p>Consensus algorithms are used to produce new transaction blocks, resulting in an\nupdated state of the ledger. Whenever someone publishes a block of transactions,\nthey — or rather, their node that runs the cryptocurrency protocol — have to\nattach a proof that they have merited it. Below two types of such proofs are\ndiscussed.</p>\n<h3>Proof of Work and Mining</h3>\n<p>Proof of work is the most common consensus algorithm type for cryptocurrencies.\nIt originated in Bitcoin, and this is how this cryptocurrency works. To generate\nproof of work, a computer has to solve a challenge. The challenge is a\ncomputationally heavy problem which is hard to solve, but the solution is easy\nto verify. When a computer on a proof of work based network finds a solution, it\npublishes it along with the transactions that the computer has been observing while\ncracking the problem. The owner of this computer collects the transaction fees\nand a reward for generating a block. The entire process is called <em>mining</em>.\nMining is very energy consuming, and the amount of energy needed is constantly increasing,\nwhich can lead to unsound competition.</p>\n<h3>Proof of Stake and Minting</h3>\n<p>Proof of stake is a novel approach to block generation. IOHK scientists led by\n<a href="https://iohk.io/team/aggelos-kiayias/">Prof. Aggelos Kiayias</a> have designed the\nfirst provably secure proof of stake algorithm called Ouroboros. Ouroboros lies\nat the heart of Cardano SL. Research team has published a\n<a href="https://iohk.io/research/papers/a-provably-secure-proof-of-stake-blockchain-protocol/">white paper</a>\nthat is a worthy read for anyone with a background in cryptocurrency theory. The\ncore idea of proof of stake is that instead of wasting electricity on cracking\ncomputationally heavy problems, a node is selected to mint a new block, with a\nprobability proportional to the amount of coins this node has. If a node\nhas positive (> 0) <a href="/en/cardano/proof-of-stake/#stake">stake</a>, it is called <em>a\nstakeholder</em>. If a node eventually becomes chosen to mint a block, it is called <em>a\nslot leader</em>. You can read more about this process in <a href="/en/cardano/proof-of-stake/">Proof of Stake in Cardano\nSL</a>.</p>\n<!-- CARDANO_SL_README_BEGIN_2 -->\n<h2>Beyond Settlement Layer</h2>\n<p>Cardano SL is called "Layer" for a reason. It is the first component of\nthe Cardano Platform. Eventually, it will be expanded with a Control Layer,\nserving as a trusted computation framework to evaluate a special\nkind of proofs to ensure that a certain computation was carried out\ncorrectly. In gaming and gambling, such systems are used for\nverifying honesty of random number generation and game\noutcomes. Accompanied with side chains, it will make possible to accomplish\nsuch tasks as provably fair distribution of winnings in games. But the\napplication of Control Layer lies well beyond gaming and gambling. Identity\nmanagement, credit system and more will be a part of Cardano Platform.\nWe are also aiming to evolve Daedalus, the Cardano SL <a href="https://github.com/input-output-hk/daedalus">wallet application</a>,\ninto a universal cryptocurrency wallet featuring automated\ncryptocurrency trading and cryptocurrency-to-fiat transactions.</p>\n<!-- CARDANO_SL_README_END_2 -->',frontmatter:{path:"/en/introduction/",doc_title:"Introduction",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-01-06-explorer.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层浏览器 正如之前提到的，浏览器是一个在卡尔达诺网络中搜索卡尔达诺结算层 转账 ， 地址 ，时间区间（ epochs  和  slots ）信息的服务。 浏览器后端工作流 浏览器利用 命令行参数 选项启动。所有支持的选项都可以通过  cardano-explorer…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<h1>卡尔达诺结算层浏览器</h1>\n<p>正如之前提到的，浏览器是一个在卡尔达诺网络中搜索卡尔达诺结算层<a href="/glossary/#%E8%BD%AC%E8%B4%A6">转账</a>，<a href="/glossary/#address">地址</a>，时间区间（<a href="/glossary/#epoch">epochs</a> 和 <a href="/glossary/#slot">slots</a>）信息的服务。</p>\n<h2>浏览器后端工作流</h2>\n<p>浏览器利用<a href="https://github.com/input-output-hk/cardano-sl-explorer/blob/f64fb137415c03e8569129067a7798bb8a51456c/src/explorer/ExplorerOptions.hs#L25">命令行参数</a>选项启动。所有支持的选项都可以通过 <code>cardano-explorer --help</code> 命令查看。</p>\n<p>然后，浏览器通过 <code>cardano-sl</code> 库运行『<a href="https://github.com/input-output-hk/cardano-sl-explorer/blob/f64fb137415c03e8569129067a7798bb8a51456c/src/explorer/Main.hs#L74">内部节点</a>』。因此我们可以把浏览器当做有着两个<a href="https://github.com/input-output-hk/cardano-sl-explorer/blob/f64fb137415c03e8569129067a7798bb8a51456c/src/explorer/Main.hs#L70">特殊插件</a> <code>explorerPlugin</code>, <code>notifierPlugin</code> 的普通节点。</p>\n<p>第一个插件用于<a href="https://github.com/input-output-hk/cardano-sl-explorer/blob/e343db1def575cc2a47d9168414c22c2599c50e6/src/Pos/Explorer/Web/Api.hs#L25">浏览器 web API</a>，第二个启动<a href="https://github.com/input-output-hk/cardano-sl-explorer/blob/e343db1def575cc2a47d9168414c22c2599c50e6/src/Pos/Explorer/Socket/App.hs#L164">通知服务器</a>，这个基于 websocket 的服务器通知前端关于区块/转账的修改。</p>\n<h2>浏览器后端 API</h2>\n<p>目前，浏览器后端 Web API 提供了一系列从卡尔达诺网络获取信息的方法。<code>servant</code> 库提供了很多构建 API 的方法模块。该库使用组合器来构建 HTTP 原子操作，并将这些原子方法组合在一起形成更大，更完整的 API。</p>\n<h3>HTTP API</h3>\n<p>浏览器 web api 在<a href="https://github.com/input-output-hk/cardano-sl-explorer/blob/f64fb137415c03e8569129067a7798bb8a51456c/src/Pos/Explorer/Web/Api.hs#L25">这里</a>定义。如果事件请求失败，则有一个 <a href="https://github.com/input-output-hk/cardano-sl-explorer/blob/f64fb137415c03e8569129067a7798bb8a51456c/src/Pos/Explorer/Web/Error.hs#L11"><code>ExplorerError</code></a> 类型，它简单地封装在 <code>Text</code> 里面，以显示发生了什么。</p>\n<p>浏览器 Web API 的文档可以在<a href="https://cardanodocs.com/technical/explorer/api/">这里</a>找到。</p>\n<h3>socket.io API</h3>\n<p>目前我们有这些事件客户可以订阅到：</p>\n<pre><code class="language-haskell">data ClientEvent\n    = Subscribe Subscription\n    | Unsubscribe Subscription\n    | CallMe\n</code></pre>\n<p>订阅可以是以下事件：</p>\n<pre><code class="language-haskell">data Subscription\n    = SubAddr\n    | SubBlockLastPage\n    | SubTx\n</code></pre>\n<p>相应的服务器事件是：</p>\n<pre><code class="language-haskell">data ServerEvent\n    = AddrUpdated\n    | BlocksLastPageUpdated\n    | TxsUpdated\n    | CallYou\n</code></pre>\n<p>用户可以调用所需的事件并订阅它们：</p>\n<pre><code class="language-js">var client = require(\'socket.io-client\');\nvar socket = client(\'http://localhost:8110\');\n\nsocket.on(\'CallYou\', function(msg){ console.log(msg); })\nsocket.emit(\'CallMe\', \'test\');\n</code></pre>\n<p>你也可以尝试运行 purescript repl（<code>pulp psci</code> ），尝试一下事件：</p>\n<pre><code class="language-purescript">import Prelude\nimport Control.SocketIO.Client\nimport Control.Monad.Eff.Console\n\nlet socket = connect "http://localhost:8110"\n\nsocket >>= \\soc -> emit soc "CallYou" "test"\n</code></pre>',frontmatter:{path:"/cn/technical/explorer/",doc_title:"卡尔达诺结算层浏览器",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-01-02-launcher.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层启动器 概述 可执行文件  cardano-launcher  是启动卡尔达诺结算层的工具。它实际运行整个卡尔达诺结算层系统（即一个节点，一个钱包）并处理更新。要做到这一点， cardano-launcher  使用两个独立的工具： cardano-node…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<h1>卡尔达诺结算层启动器</h1>\n<h2>概述</h2>\n<p>可执行文件 <a href="/technical/cli-options/#cardano-launcher"><code>cardano-launcher</code></a> 是启动卡尔达诺结算层的工具。它实际运行整个卡尔达诺结算层系统（即一个节点，一个钱包）并处理更新。要做到这一点，<a href="/technical/cli-options/#cardano-launcher"><code>cardano-launcher</code></a> 使用两个独立的工具：<a href="/technical/cli-options/#cardano-node"><code>cardano-node</code></a> 和 <a href="https://github.com/input-output-hk/cardano-updater"><code>cardano-updater</code></a>。</p>\n<p>有关可选项的详细信息，请查阅 <a href="/technical/cli-options/#cardano-launcher"><code>cardano-launcher</code> 的说明</a>。</p>\n<h2>场景</h2>\n<p><code>cardano-launcher</code> 有两种工作场景：客户端场景和服务端场景。如果你在启动过程中用 <code>--wallet</code> 参数提供一个钱包（例如代达罗斯）路径，<code>cardano-node</code> 将在<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L178">客户端</a>场景下运行，\n否则将在<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L171">服务端</a>场景下运行。</p>\n<h3>服务端场景</h3>\n<p>开始时，有两个步骤：</p>\n<ol>\n<li>运行更新程序。</li>\n<li>运行一个节点。</li>\n</ol>\n<p>更新程序的工作<a href="#%E6%9B%B4%E6%96%B0%E5%99%A8">如下所述</a>。</p>\n<p>一个节点<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L280">以一个单独的进程运行</a>。之后，我们<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L201">等待，直到节点停止</a>。节点退出后，将检查其退出代码，如果等于 <code>20</code>，我们<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L204">重新启动 launcher</a>，否则我们退出。</p>\n<p>在退出前日志会<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L207">写入到日志文件</a>。要做到这一点，我们在启动时必须提供两个额外的参数：<code>--report-server</code> 和\n<code>--node-log</code>。第一个参数定义了收集日志的 URl，第二个参数定义了日志文件的路径。我们将日志<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L343">异步发送到收集日志服务器</a>。请注意 <code>--node-log</code> 参数中的文件必须存在。</p>\n<h3>客户端场景</h3>\n<p>当进程开始时，有三个步骤：</p>\n<ol>\n<li>运行更新程序。</li>\n<li>运行一个节点。</li>\n<li>运行一个钱包。</li>\n</ol>\n<p>对于步骤1和2，请参与上面的<a href="#%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%9C%BA%E6%99%AF">服务器场景</a>。</p>\n<p>钱包<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L227">作为一个独立进程运行</a>。</p>\n<p>之后，我们<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L228">等待节点或钱包停止</a>。当它停止时，我们会检查它：</p>\n<ol>\n<li>如果节点退出了，我们写一条日志（见上面<a href="#%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%9C%BA%E6%99%AF">服务端场景</a>的解释），然后<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L235">等待钱包退出</a>。  </li>\n<li>如果钱包退出，我们会检查其退出代码，如果它等于 <code>20</code>，我们<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L242">杀死这个节点</a>，<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L244">重新启动客户端场景的启动程序</a>。请注意，不会立即杀死这个节点；节点在一定的超时过后才会被终止，其值从上述的 <code>--node-timeout</code> 参数获得。</li>\n<li>如果钱包退出<em>并且</em>退出码不等于 <code>20</code>，我们立即杀死节点。</li>\n</ol>\n<h2>更新器</h2>\n<p><code>cardano-launcher</code> 另一个非常重要的作用是更新节点。两种场景的公共步骤是<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L255">运行更新程序</a>。</p>\n<p>核心思想非常简单。节点更新是一个特殊的 <code>.tar</code> 存档：它表明节点的旧（当前）版本和新版本之间的区别。这个归档的路径通过 <code>--update-archive</code> 参数获得。\n因此，<code>cardano-launcher</code> 将该归档应用到该节点，并且在重新启动后可以使用该节点的新版本。</p>\n<p>请注意，当我们的 <code>cardano-launcher</code> 在客户端场景下运行时，钱包的用户能够看到更新已经准备就绪，并且有两种可能的情况。</p>\n<p>如果用户<em>同意</em>采用这次更新，钱包立即以退出码 <code>20</code> 退出。在这种情况下，如上所述，启动器重新启动节点并更新应用。</p>\n<p>如果用户<em>不同意</em>采用这次更新，钱包将继续工作，当时，当它<em>被</em>重新启动（早晚的事情），这个更新<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L223"><em>将</em>被应用</a></p>\n<p><strong>重要</strong>：更新器同步运行，我们启动它，然后<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L269">等待它完成</a>，如果更新程序<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L271">成功</a>运行，<code>.tar</code> 文件将被删除。</p>\n<h3>实现概述</h3>\n<p>有关卡尔达诺结算层更新系统的更多实现细节，请参阅<a href="/technical/updater/">这一章</a>。</p>',frontmatter:{path:"/cn/technical/launcher/",doc_title:"卡尔达诺结算层启动器",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-02-14-leader-selection.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层中的领导者选举 这一章描述 领导者 选举过程。 追随中本聪算法 如 前 所述，卡尔达诺结算层使用追随中本聪算法（FTS）来选择领导者。每个当前 epoch 的领导者在当前 epoch 开始的时候，由 FTS…",html:'<!-- Reviewed at e1d0f9fb37a3f1378341716916f0321fb55698df -->\n<h1>卡尔达诺结算层中的领导者选举</h1>\n<p>这一章描述<a href="/glossary/#slot-leader">领导者</a>选举过程。</p>\n<h2>追随中本聪算法</h2>\n<p>如<a href="/cardano/proof-of-stake/#follow-the-satoshi">前</a>所述，卡尔达诺结算层使用追随中本聪算法（FTS）来选择领导者。每个当前 epoch 的领导者在当前 epoch 开始的时候，由 FTS 算法计算得出。所以创始区块包含一组领导者列表。领导者的数量和 epoch 的 slot 数量是一致的，这个数量<a href="https://github.com/input-output-hk/cardano-sl/blob/5f7b619c6ec9056c6fe778d862c426233af165df/core/Pos/Core/Constants/Raw.hs#L136">取决</a>于在<a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/core/constants.yaml#L10">配置文件</a>中定义的基本安全参数 <code>K</code>。</p>\n<p>FTS 使用<a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/core/Pos/Core/Types.hs#L256">共享种子</a>，该<a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/core/Pos/Core/Types.hs#L256">共享种子</a>为上个 epoch 计算的结果：在 MPC 的结果中的一些节点会揭露它们的种子，这些种子的 XOR 就被称为共享种子，实际上共享种子就是一个<a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/core/Pos/Core/Types.hs#L257">字符串</a>。</p>\n<p>股东被选举为领导者的概率与股东持有的币的数量相关。同一个股东可以在同一个 epoch 里面被选举为多个 slot 的领导者。</p>\n<h2>算法</h2>\n<p>在<a href="/glossary/#%E8%AE%BA%E6%96%87">论文</a>的第11页从以学术角度描述了领导者的选举过程。</p>\n<p>节点将所有未花费的输出(<code>utxo</code>)按照一种特定的方法（按字典）进行排序，因此结果是一对 <code>(StakeholderId, Coin)</code> 的有序<a href="https://github.com/input-output-hk/cardano-sl/blob/1f866450a8a530c119e3fc9edb84c97c56417aa2/src/Pos/Genesis.hs#L177">序列</a>，<code>StakeholderId</code> 是股东的 ID（股东的公钥哈希值），<code>Coin</code> 是股东持有币的数量。这里假设 <code>utxo</code> <a href="https://github.com/input-output-hk/cardano-sl/blob/1f866450a8a530c119e3fc9edb84c97c56417aa2/src/Pos/Lrc/FtsPure.hs#L52">不是空的</a>。</p>\n<p>然后节点选择几个在 <code>1</code> 和<a href="https://github.com/input-output-hk/cardano-sl/blob/1f866450a8a530c119e3fc9edb84c97c56417aa2/src/Pos/Lrc/FtsPure.hs#L49">系统中 Lovelaces 的数量</a>之间的随机数 <code>i</code>。为了找到第 <code>i</code> 个币的拥有者，节点找到最小的 <code>x</code>，使得这个列表从 <code>x</code> 到 <code>i</code> 的所有币的总数不小于 <code>i</code>(这样第 <code>x</code> 个地址就是第 <code>i</code> 个的拥有者)。</p>\n<p>结果是一个非空的 <code>StakeholderId</code> 序列，也就是被选中的股东们的 ID，<a href="https://github.com/input-output-hk/cardano-sl/blob/5f7b619c6ec9056c6fe778d862c426233af165df/core/Pos/Core/Types.hs#L264"><code>SlotLeaders</code></a> 序列保存在<a href="https://github.com/input-output-hk/cardano-sl/blob/da70b2597aab352d7574a3946a366395b09e97eb/node/src/Pos/Context/Context.hs#L94">节点运行环境中</a>。</p>\n<p>由于是 P2SH 地址，所以节点不知道是会谁将要给它们发送资金。因此，P2SH 地址可以包含目标地址，该目标地址指明哪些地址应该被视为『拥有』用于 FTS 的基金。</p>',
  frontmatter:{path:"/cn/technical/leader-selection/",doc_title:"卡尔达诺结算层中的领导者选举",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-05-15-wallet-backend.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层钱包后端 地址 章节讨论的地址是发送和接收资金的基础，而钱包是简化用户最终流程的一种方式。 什么是钱包？ 在卡尔达诺中，钱包的定义如下： 其中  CWalletMeta…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<h1>卡尔达诺结算层钱包后端</h1>\n<p><a href="/cardano/addresses/">地址</a>章节讨论的地址是发送和接收资金的基础，而钱包是简化用户最终流程的一种方式。</p>\n<h2>什么是钱包？</h2>\n<p>在卡尔达诺中，钱包的定义如下：</p>\n<pre><code class="language-haskell">data CWallet = CWallet\n    { cwId       :: !CWalletAddress\n    , cwMeta     :: !CWalletMeta\n    , cwAccounts :: ![CAccount]\n    , cwAmount   :: !CCoin\n    }\n</code></pre>\n<p>其中 <code>CWalletMeta</code> 指明当前钱包是共享的还是个人的，以及钱包使用的货币和钱包的名字。有了这个，钱包类型很容易扩展，因为任何附加的功能可以添加到 <code>CWalletMeta</code> 类型，而其他字段不变。每个钱包，无论名称，类型和货币，都必须具有上述字段。</p>\n<h2>交易和钱包</h2>\n<p>在<a href="/cardano/transactions/">转账</a>章节定义了交易数据的结构。然而，为了方便客户的操作，交易在客户中有不同的表现形式，他们被表示为：</p>\n<pre><code class="language-haskell">data CTx = CTx\n    { ctId            :: CTxId\n    , ctAmount        :: CCoin\n    , ctConfirmations :: Word\n    , ctMeta          :: CTxMeta\n    , ctInputAddrs    :: [CAddress Acc]\n    , ctOutputAddrs   :: [CAddress Acc]\n    }\n</code></pre>\n<p>本质上，一个客户端的转账由实际交易 <code>Id</code>，收到的币的数量，交易已得到的确认数（即当前位于包含所述交易区块顶部的区块数量），输入和输出地址。元数据，数据类型 <code>CTxMeta</code>，表明交易的货币，标题或名称，描述信息，以及 POSIX 格式的发送日期。</p>\n<h2>钱包后端 API</h2>\n<p>目前，钱包 API 提供了一系列使用钱包的方法。Haskell 库 <code>servant</code> 提供了一个模块化的 API 构建方法。该库使用组合器来构建院子 HTTP 操作，并将这些原子方法粘合在一起以形成更大和更完整的 API。</p>\n<p>请注意，只有当您使用 <code>--wallet</code> 选项运行节点时，钱包 Web API 才可用，这个 API 的默认端口 <code>8090</code> 可以通过 <code>--wallet-port</code> 选项进行更改。</p>\n<p>钱包 Web API 文档可以在<a href="https://cardanodocs.com/technical/wallet/api/">这里</a>找到</p>\n<h3>TLS 连接</h3>\n<p>钱包 Web API 使用 TLS 进行安全通信。调用 API 需要发送客户端 CA 证书，该证书在启动节点时使用，并将客户端标识为允许调用服务器 API。</p>\n<p>请注意，客户端证书文件是启动节点时 <code>--tlsca</code> 作为选项提供的文件。</p>\n<p>例如，如果该文件是可用的 <code>ca.crt</code>，那么对于运行节点 <code>localhost:8090</code> 调用 curl 命令可以像这样：</p>\n<pre><code class="language-bash">curl --cacert ca.crt -v https://localhost:8090/api/settings/sync/progress\n</code></pre>\n<p>如果该请求成功，那么您已经正确配置了 TLS。</p>\n<h3>处理错误</h3>\n<p>如果事件请求失败，则有一个 <code>WalletError</code> 类型，它只封装一个 <code>Text</code> 来显示发生了什么。</p>',frontmatter:{path:"/cn/technical/wallet-backend/",doc_title:"卡尔达诺结算层钱包后端",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-05-16-wallet-frontend.cn.md absPath of file >>> MarkdownRemark",excerpt:"…",html:'<!-- Reviewed at cd26fb28eb48f893a4ca2d045a10da19c211b807 -->\n<h1>卡尔达诺结算层钱包前端</h1>\n<p>卡尔达诺结算层发展时，用户需要一个可以查看资金，发送接收转账，处理其他个人电子货币钱包的任务这样的用户界面，这一需求在增长。代达罗斯钱包是对于这些需求的解决方案。</p>\n<p>目前，它允许用户使用上述功能，并计划在不久的将来提供对其他货币的支持，包括电子货币和非电子货币。</p>\n<h2>构建代达罗斯客户端 API</h2>\n<p>要在本地运行代达罗斯客户端 API，您必须按照下面的要求开启 <a href="https://github.com/input-output-hk/cardano-sl/"><code>cardano-sl</code></a> 的钱包 API。</p>\n<p>请确保您在 <code>cardano-sl</code> 的根目录。同时确保您已经安装 <a href="https://www.npmjs.com/">npm</a> 程序。</p>\n<h2>运行和测试代达罗斯客户端 API</h2>\n<p>为了在操作中看到代达罗斯客户端 API，首先运行一个本地的卡尔达诺结算层网络：</p>\n<pre><code class="language-bash"># run tmux in another window\n$ tmux\n# launch nodes\n$ ./scripts/launch/demo-with-wallet-api.sh\n</code></pre>\n<p>默认情况下，这将启动由3个互连节点组成的尔达诺结算层网络。一个节点运行钱包 API，它会同生产环境中运行的代达罗斯钱包行为一致。</p>\n<h2>WEBSOCKETS 通知</h2>\n<p>我们可以用一个小工具(<code>npm install -g wscat</code>)来测试 websocks：</p>\n<pre><code class="language-bash">> wscat -c ws://127.0.0.1:8090\n\nconnected (press CTRL+C to quit)\n\n&#x3C; {"tag":"ConnectionOpened"}\n\n&#x3C; {"tag":"NetworkDifficultyChanged","contents":{"getChainDifficulty":1}}\n&#x3C; {"tag":"LocalDifficultyChanged","contents":{"getChainDifficulty":1}}\n&#x3C; {"tag":"NetworkDifficultyChanged","contents":{"getChainDifficulty":2}}\n&#x3C; {"tag":"LocalDifficultyChanged","contents":{"getChainDifficulty":2}}\n&#x3C; {"tag":"NetworkDifficultyChanged","contents":{"getChainDifficulty":3}}\n&#x3C; {"tag":"LocalDifficultyChanged","contents":{"getChainDifficulty":3}}\n&#x3C; {"tag":"NetworkDifficultyChanged","contents":{"getChainDifficulty":4}}\n&#x3C; {"tag":"LocalDifficultyChanged","contents":{"getChainDifficulty":4}}\n</code></pre>\n<p>从这我们可以看到相同的改变：</p>\n<pre><code class="language-bash">curl http://localhost:8090/api/settings/sync/progress\n</code></pre>\n<p>Accound 应该重命名为地址。请查看这个 issues <a href="https://issues.serokell.io/issue/CSM-249">CSM-249</a> 获取更多细节。</p>\n<h2>钱包事件</h2>\n<p>除了这些 HTTP 接入点外，还有一个从服务器到客户端的单向 websocket 通道，<code>notify</code> 接入点。</p>\n<p>这个通道充当通知系统。以便可以告知代达罗斯 UI 相关事件。目前支持的事件有：</p>\n<ul>\n<li><code>LocalDifficultyChanged</code> - 当前区块链高度，</li>\n<li><code>NetworkDifficultyChanged</code> - 全球区块链高度，</li>\n<li><code>UpdateAvailable</code> - 新的系统可用更新，</li>\n<li><code>ConnectedPeersChanged</code> - 连接到对等节点数量的改变，</li>\n<li><code>ConnectionOpened</code> - 打开 websocket 连接，</li>\n<li><code>ConnectionClosed</code> - 关闭 websocket 连接。</li>\n</ul>\n<p>由于此通道是单向的，因此从客户端发送到通道的任何消息都会被忽略。</p>',frontmatter:{path:"/cn/technical/wallet-frontend/",doc_title:"卡尔达诺结算层钱包前端",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/timeline/2017-01-01-testnet.cn.md absPath of file >>> MarkdownRemark",excerpt:"…",html:'<!-- Reviewed at 357ac1f7b4a9f1d98ee7f7bee46e874d7356958f -->\n<h1>测试网阶段</h1>\n<p>让社区掌握加密货币，打磨实现，消除可能的缺陷和不稳定性，卡尔达诺测试网络（测试网）是必须的。</p>\n<p>在测试网阶段，包括奖励机制在内的所有功能都将被激活，任何人都可以从卡尔达诺测试网接口兑换密钥，拿到币。</p>\n<p>我们鼓励大家下载对应平台的卡尔达诺结算层客户端，从接口获取一些币（我们称它们为 <a href="/cn/glossary/#lovelace">Lovelace</a>），邀请其他人参与 beta 版本的测试。</p>\n<p>测试网的结束是卡尔达诺结算层的<a href="/timeline/bootstrap">发布</a>。</p>',frontmatter:{path:"/cn/timeline/testnet/",doc_title:"测试网阶段",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"timeline"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/timeline/2017-01-03-reward.cn.md absPath of file >>> MarkdownRemark",excerpt:"奖励阶段 在 引导阶段 之后，奖励阶段将开始。在这个阶段，网络将是完全去中心化，非可信模式。我们预计在这个阶段权益池将会出现，让股权比较少的股民也能获得奖励，因为大股东会让节点时刻保持在线来维护去中心化协议。 系统将会定期收到软件更新，并在不久的将来发布大量新功能。",html:'<!-- Reviewed at 357ac1f7b4a9f1d98ee7f7bee46e874d7356958f -->\n<h1>奖励阶段</h1>\n<p>在<a href="/timeline/bootstrap">引导阶段</a>之后，奖励阶段将开始。在这个阶段，网络将是完全去中心化，非可信模式。我们预计在这个阶段权益池将会出现，让股权比较少的股民也能获得奖励，因为大股东会让节点时刻保持在线来维护去中心化协议。</p>\n<p>系统将会定期收到软件更新，并在不久的将来发布大量新功能。</p>',frontmatter:{path:"/cn/timeline/reward/",doc_title:"奖励阶段",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"timeline"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/timeline/2017-01-02-bootstrap.cn.md absPath of file >>> MarkdownRemark",excerpt:"引导阶段 在卡尔达诺测试网阶段和卡尔达诺结算层发布之后，该网络会在『引导模式』下运行一段时期，称为引导阶段。当购买 Ada…",html:'<!-- Reviewed at c23493d7a33a82d559d5bd9d289486795cf6592f -->\n<h1>引导阶段</h1>\n<p>在卡尔达诺测试网阶段和卡尔达诺结算层发布之后，该网络会在『引导模式』下运行一段时期，称为引导阶段。当购买 Ada 的人兑换他们的币时，股权将自动被委派给维护网络的可信节点池。在此期间，不会发放任何区块奖励 - 我们将保持网络在线。这是必要的，因为为了协议功能正常，拥有大部分期权的一些权益所有人必须在线，而在网络运行的头几个月，情况并非如此。</p>\n<p>引导阶段将慢慢进入<a href="/timeline/reward">奖励阶段</a>，在这期间更新协议将被发布，将为大宗权益所有人提供在云服务器运行的方便选项。</p>\n<h2>股权锁定</h2>\n<p>引导阶段存在于卡尔达诺结算层存在的时期，它只允许固定的预定义用户对系统进行控制。这些用户集（引导阶段权益所有人）以及他们各自控制的总权益的比例，在创始区块中定义。</p>\n<p>引导阶段的目的是为了解决在主网开始的时候，大部分股权可能会脱机（开始时违反协议）的担忧。引导阶段将在网络稳定，并且大部分股权在线时结束。</p>\n<p>引导阶段之后的下一个阶段被称为<a href="https://cardanodocs.com/timeline/reward/cn/">奖励阶段</a>，奖励阶段实际上是卡尔达诺结算层作为 PoS 加密货币的『正常』运行模式。</p>\n<h3>要求</h3>\n<ol>\n<li>在引导阶段，卡尔达诺的股权应当被有效地委派给一组固定的密钥 <code>S</code>。</li>\n<li><code>S</code> = 7</li>\n<li>股权应该在 <code>s</code> ∈  <code>S</code></li>\n<li>\n<p>在引导阶段结束时应该解开股权</p>\n<ol>\n<li>Ada 买家能够自己参与协议（或将其权利委派给某个代表 <code>S</code>)。</li>\n<li>\n<p>每个 Ada 买方都应该明确声明自己想要控制的股份。</p>\n<ul>\n<li>否则，一旦奖励阶段开始，很容易导致在少于大多数股权在线的情况。</li>\n</ul>\n</li>\n<li>在撤销股权行动之前，股权应该仍然由 <code>S</code> 节点控制。</li>\n</ol>\n</li>\n</ol>\n<h3>提案</h3>\n<p>现在让我们来看看引导阶段的解决方案：</p>\n<ol>\n<li>初始 <code>utxo</code> 包含引导阶段股权所有人的所有股权。初始 <code>utxo</code> 由 <code>(txIn, txOut)</code> 组成，并且每个 <code>txOut</code> 都有一个存有股权分发的地址。所以我们只是以一种将所有币发送给所有股权所有的方式设置分配。</li>\n<li>引导阶段开始时，用户可以发送更改初始 <code>utxo</code> 的请求。我们为每个交易输出设定股权分配，以将权益分配给引导阶段权益相关者。这有效得使得利益分配是系统不变的。</li>\n<li>\n<p>重量级代表团有成因状态。它包含对 <code>(Issuer, ProxySK)</code>，其中 <code>Issuer</code> 是被委托的利益相关者的标识符，<code>ProxySK</code> 是委派的代理密钥。请注意：</p>\n<ul>\n<li>代表必须与发行人不同，即不允许撤销；</li>\n<li>委派人不能成为发行人，即不支持过渡性委派。</li>\n</ul>\n</li>\n<li>当引导阶段结束后，我们禁用股权分配的限制。股权所有人将投票让引导阶段结束：将形成特殊的更新提案，其中一个特定的常量将被适当设置，以触发引导阶段结束的更新提案获得通过。系统的运行方式与引导阶段相同，但用户需要明确说明自己的股份所有权，能承担处理节点的责任。为了获取他的股权，用户应该发送一个交易，指定股权分配的代理密钥（s）。它可能是用户自己拥有的密钥，也可能是某个关键代表（可能是引导阶段股权所有人中的一个或几个）。</li>\n</ol>',frontmatter:{path:"/cn/timeline/bootstrap/",doc_title:"引导阶段",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"timeline"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-05-14-hd-wallets.cn.md absPath of file >>> MarkdownRemark",excerpt:"HD 钱包 HD 钱包是一个允许用户以一种确定性方式从普通种子中获取密钥的功能。基本上，你可以从一个随机种子中产生一个初始密钥。然后你就可以从  SK₀  得到孩子  SK₀-₀ ,  SK₀-₁ 。从这些孩子中，你可以得到  SK₀-₀-₀ ,  SK₀-₀-₁ ,  SK…",html:"<!-- Reviewed at 866fd6a29a15c503e54426f17b91bd8b0903c5dc -->\n<h1>HD 钱包</h1>\n<p>HD 钱包是一个允许用户以一种确定性方式从普通种子中获取密钥的功能。基本上，你可以从一个随机种子中产生一个初始密钥。然后你就可以从 <code>SK₀</code> 得到孩子 <code>SK₀-₀</code>, <code>SK₀-₁</code>。从这些孩子中，你可以得到 <code>SK₀-₀-₀</code>, <code>SK₀-₀-₁</code>, <code>SK₀-₁-₀</code> 等（派生任意深度的树）。</p>\n<!-- For subscripts and other symbols: https://help.ubuntu.com/community/ComposeKey -->\n<p>我们会区分两种类型的键：</p>\n<ul>\n<li><strong>Hardened</strong></li>\n<li><strong>Non-hardened</strong></li>\n</ul>\n<p>这里唯一的区别是 <strong>hardened</strong> 密钥允许从父密钥派生出子密钥。因此，为了派生一个 <strong>hardened</strong> 键，你必须拥有私钥。<strong>Non-hardened</strong>密钥允许从父公钥派生子公钥（不具有可用密钥）。</p>\n<p>每个孩子被分配一个4字节的索引 <code>i</code>:</p>\n<ul>\n<li><code>i ≤ 2³¹ - 1</code> <strong>non-hardened</strong> 键。</li>\n<li><code>i > 2³¹ - 1</code> <strong>hardened</strong> 键。</li>\n</ul>\n<h2>属性:</h2>\n<ol>\n<li>树结构保存在根地址中。用户需要复制公钥将其传递给任何想要恢复树的人。</li>\n</ol>\n<h2>地址格式</h2>\n<p>我们使用 <code>PublicKey</code> 地址（已经存在于系统中），并添加属性字段。在由 <code>0</code> (<strong>HD 钱包属性</strong>) ，我们存储树数据。</p>\n<p>树存储为<strong>派生路径</strong>的列表。每个<strong>派生路径</strong>被指定为<strong>派生索引</strong>的列表。每个<strong>派生索引</strong>都是4字节的无符号整数。</p>\n<p>所得到的对象被序列化并使用对称方案（<em>ChaChaPoly1305</em>算法进行加密），密码被计算为根公钥的SHA-512散列。只要我们实际上没有再根密钥上存储任何资金（不通过共识规则，而是通过用户界面），那么将不允许攻击者将链上的所有地址映射到根。</p>\n<p><strong>设计的关键点：</strong>根密钥不用于实际存储金钱。</p>\n<h2>用例</h2>\n<h3>财务审计</h3>\n<p>应该提供一个根公钥的审计散列，让审计人员找到层次结构中的所有密钥。</p>\n<h3>付款服务器</h3>\n<p>它只适用于 <strong>non-hardened</strong> 键。</p>\n<p>为了使服务器能够获得后续地址来收取付款，需要上传：</p>\n<ul>\n<li>根公钥</li>\n<li>\n<p>有效载荷：</p>\n<ul>\n<li><code>i</code> 级别的 <code>PK</code></li>\n<li>跟公钥的哈希</li>\n<li><code>PK</code> 的树路径</li>\n</ul>\n</li>\n</ul>\n<h3>钱包</h3>\n<p>要使钱包在某个子树上运行，需要提供：</p>\n<ul>\n<li>根密钥</li>\n<li>\n<p>有效载荷：</p>\n<ul>\n<li><code>SK</code> 级别的密钥 <code>i</code></li>\n<li>根公钥的哈希</li>\n<li><code>SK</code> 的树路径</li>\n</ul>\n</li>\n</ul>\n<h2>要求</h2>\n<p><code>A(K)</code> 表示保存密钥对信息的地址 <code>K</code>。<code>child(K, i)</code> 表示第 <code>i</code>个子密钥对 <code>K</code>。<code>tree(K)</code> 表示从 <code>K</code>（有证书余额）派生，以 <strong>utxo</strong> 保存的密钥对地址树。</p>\n<p><code>a -> b</code> 表示 <code>b</code> 从 <code>a</code> 派生。<code>a -x b</code> 表示 <code>b</code> 不是从 <code>a</code> 派生的（在任何情况下）：</p>\n<pre><code>priv(K) -> pub(K)\npub(K) -> A(K)\npub(K) -x priv(K)\nA(K) -x pub(K)\nA(K) -x A(child(K, i))\n</code></pre>\n<p>对于 <strong>hardened</strong> 键：</p>\n<pre><code>(priv(K), utxo) -> tree(K)\npub(K) -x pub(child(K, i))\npriv(K) -> priv(child(K, i))\n</code></pre>\n<p>对于 <strong>non-hardened</strong> 键：</p>\n<pre><code>(pub(K), utxo) -> tree(K)\npub(K) -> pub(child(K, i))\npriv(K) -> priv(child(K, i))\n</code></pre>\n<h2>派生加密接口</h2>\n<h3>符号:</h3>\n<ul>\n<li><code>kp</code> 表示具有索引 <code>p</code> 的私钥。只是一个 <strong>Ed25519</strong> 私钥。</li>\n<li><code>kp</code> 表示带有索引 <code>p</code> 的公钥。只是一个 <strong>Ed25519</strong> 公钥。</li>\n<li><code>cp</code> 表示带有索引的链。</li>\n</ul>\n<h3>熵</h3>\n<p>在比特币中，它们使用512位的散列，但 <code>kp</code> 只有 256 位，因为这个原因，我们需要遵循512位的密钥，所以我们不减少哈希空间。</p>\n<ul>\n<li>扩展的私钥是表示为 <code>(ki, ci)</code> 的一对。</li>\n<li>扩展的私钥是表示为 <code>(Ki, ci)</code> 的一对。</li>\n</ul>\n<p>从应用角度来看，HD 钱包（BIP-32）引入了以下密码原语：</p>\n<ul>\n<li>\n<p><code>CKDpriv :: ((kpar, cpar), i) → (ki, ci)</code><br>\n从父扩展私钥计算自扩展私钥</p>\n</li>\n<li>\n<p><code>CKDpub :: ((Kpar, cpar), i) → (Ki, ci)</code><br>\n从父扩展私钥中调用一个子扩展私钥</p>\n</li>\n</ul>\n<h1>代达罗斯 HD 钱包</h1>\n<p>本节介绍 HD 钱包功能的使用方式。它分为两部分：</p>\n<ol>\n<li>扩展钱包后端 API 以在本地支持 HD 钱包结构（就像在比特币中完成的那样）</li>\n<li>利用新的地指数型来扩展区块链处理以保持多个客户端实例的 HD 结构同步。</li>\n</ol>\n<h2>本地存储</h2>\n<h3>旧的存储</h3>\n<p>旧的钱包存储存的是地址列表。每个地址都与一个名称相关联，并且是从单独的密钥（由助记符备份并用消费密码加密）派生而来。</p>\n<h3>新的存储</h3>\n<p>钱包的存储扩展到存储<strong>钱包</strong>列表。每个钱包对应一个根密钥（由助记符备份并用消费密码加密）。</p>\n<p>每个钱包都包含一个<strong>账户</strong>。</p>\n<p>每个账户都包含多个<strong>地址</strong>（即地址是 HD 树中第二层的关键字）。</p>\n<p>这映射到一个 HD 树：</p>\n<ul>\n<li>钱包组对应第 0 级（<em>根</em>）密钥。</li>\n<li>钱包对应1级密钥（根的孩子）。</li>\n<li>地址对应于第2级（根的孙子）的密钥。</li>\n</ul>\n<p>钱只保存在地址上。</p>\n<p>当从一个或多个地址花费金钱时，如果有的话，将产生新的余额。</p>\n<h3>可用性</h3>\n<p>用户能够：</p>\n<ul>\n<li>导入/导出任意数量的<strong>钱包</strong>，</li>\n<li>生成任意数量的<strong>账户</strong>，</li>\n<li>分配<strong>钱包</strong>和<strong>账户</strong>名称，</li>\n<li>生成任意数量的地址，</li>\n<li>改变钱包消费密码。</li>\n</ul>\n<h2>从区块链中读取 HD 钱包数据</h2>\n<p>有两种导入/导出钱包的方法：</p>\n<ul>\n<li>通过<strong>助记符</strong>，</li>\n<li>通过导出文件。</li>\n</ul>\n<p>助记符在前端生成，并允许确定性地生成密钥。名称不会被恢复。</p>\n<p>导出文件能够恢复整个钱包结构。</p>\n<h3>导入</h3>\n<p>在两种情况下我们都有一个根密钥。在导入的时候会执行下面的步骤：</p>\n<ul>\n<li>根密钥在本地存储中被检查为不存在。</li>\n<li>遍历 <strong>utxo</strong> 查找与此根密钥对应的所有有余额的地址，并将它们与服务（钱包）一起添加到存储中。</li>\n<li>在文件导入的情况下，从步骤2得到的结构标有名称。此外，导入的文件中列出的钱包/地址，目前没有被使用。</li>\n</ul>\n<h3>新的事务处理</h3>\n<p>当有新的交易可用时（出现在区块或内存池中），输入会被分析。如果输入对应于具有 <strong>HD 钱包属性</strong>的公共密钥地址，则检查该地址是否对应于我们的<strong>钱包</strong>之一。如果是这样，地址将被导入到结构中（为了在用于界面显示余额）。</p>",frontmatter:{path:"/cn/technical/hd-wallets/",doc_title:"HD 钱包",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-02-16-delegation.cn.md absPath of file >>> MarkdownRemark",excerpt:"…",html:'<!-- Reviewed at c23493d7a33a82d559d5bd9d289486795cf6592f -->\n<h1>卡尔达诺结算层股权委派</h1>\n<p>这一章描述权益委托过程的实现细节。</p>\n<p>如前所述。为了产生新区块，被选举为领导者的股东必须在线。这种情况可能没有什么吸引力，因为大多数的当选股东都必须为了刷新随机数而参加投币协议（领导者选举过程的关键属性）。如果有很多当选的领导者，会让股东和网络都有很大的压力，因为需要广播和存储大量的提交和共享。</p>\n<p>委派的功能允许被称为发行人（<em>issuers</em>） <code>I1...In</code> 的股权所有人将他们的『参与义务』转移给某些代表团（<em>delegates</em>） <code>D1...Dm</code>，这些代表团会在<a href="https://github.com/input-output-hk/cardano-sl/blob/4bd49d6b852e778c52c60a384a47681acec02d22/src/Pos/Ssc/GodTossing.hs">投币协议</a>中代表股权所有人 <code>S1...Sn</code>。在这种情况下，真正参与到投币协议中节点的数量就少很多，可以看看<a href="/glossary/#paper">论文</a>的第38页。</p>\n<p>不仅如此，代表团不仅可以生产新区块，参与到 <a href="/technical/leader-selection/#follow-the-satoshi">MPC/SSC</a> 中，还可以在<a href="/cardano/update-mechanism/">系统更新</a>时进行投票。</p>\n<h2>策略</h2>\n<p>领导者可以将自己生产新区块的权利转移给代表团。为了转移这个权利，领导者使用一个代理委托的策略：领导者产生一个<a href="https://github.com/input-output-hk/cardano-sl/blob/4378a616654ff47faf828ef51ab2f455fa53d3a3/core/Pos/Crypto/SignTag.hs#L33">代理签名钥匙</a>，或者说 PSK，然后代表团会使用它<a href="https://github.com/input-output-hk/cardano-sl/blob/ed6db6c8a44489e2919cd0e01582f638f4ad9b72/src/Pos/Delegation/Listeners.hs#L65">签名</a>信息来认证一个区块。有两种类型的 PSK：重量级和轻量级（见下文）</p>\n<p>具体来说，股权所有人通过自己的公钥构建一个特殊证书来指定代表团的身份。以便之后代表团可以在有限的信息空间内用已签名的证书在自己的公钥下为这些信息提供签名。</p>\n<p>这是<a href="https://github.com/input-output-hk/cardano-sl/blob/d01d392d49db8a25e17749173ec9bce057911191/core/Pos/Crypto/Signing.hs#L256">代理签名</a>的格式。它包括了：</p>\n<ul>\n<li>代理私钥，</li>\n<li>签名。</li>\n</ul>\n<p>代理私钥包括：</p>\n<ol>\n<li>omega 值，</li>\n<li>发行人的公钥，</li>\n<li>代表团的公钥，</li>\n<li>代理证书。</li>\n</ol>\n<p>Omega (or ω) 是<a href="/glossary/#paper">论文</a>中一个特殊的值。在我们的实现中，它是<a href="https://github.com/input-output-hk/cardano-sl/blob/f374a970dadef0fe62cf69e8b9a6b8cc606b5c7d/core/Pos/Core/Types.hs#L235">一对 epoch 的标识符</a>。这些标识符定义了委托有效期：如果 epoch 索引在这个范围内那么生产的区块就是有效的。</p>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/d01d392d49db8a25e17749173ec9bce057911191/core/Pos/Crypto/Signing.hs#L209">代理证书</a>就是 omega 和代表团公钥的<a href="https://github.com/input-output-hk/cardano-crypto/blob/84f8c358463bbf6bb09168aac5ad990faa9d310a/src/Cardano/Crypto/Wallet.hs#L74">签名</a>。</p>\n<h2>重量级委派</h2>\n<p>重量级委托使用权益阈值 <code>T</code>，这意味着股权所有人拥有的权益不少于 <code>T</code> 时才能参与重量级委托。这个阈值在<a href="https://github.com/input-output-hk/cardano-sl/blob/42f413b65eeacb59d0b439d04073edcc5adc2656/lib/configuration.yaml#L224">配置文件</a>中定义。就像主网的这个阈值是总权益的 0.03%，这个值可以通过系统更新来改变。</p>\n<p>来自重量级委托的代理签名证书存储在区块链中。请注意发行者在每个 epoch 只能发布一个证书。</p>\n<p>请注意重量级委托有一个传递关系，所以，如果 <code>A</code> 委派给 B，然后 B 又委派给 <code>C</code>，那么 <code>C</code> 代表的权益等于 <code>A + B</code>，而不仅仅是 <code>B</code>。</p>\n<h3>到期</h3>\n<p>在每一个 epoch 开始时，股权所有人不再传递阈值 <code>T</code>, 那么重量级委派证书就会过期。这样做是为了预防委派池膨胀攻击：用户提交了一个证书然后将自己所有的钱（高于阈值）都转到另一个账户，并且重复此操作。</p>\n<h2>轻量级委派</h2>\n<p><strong>注意：目前轻量级委派功能是关闭的，在 <a href="https://cardanoroadmap.com/">Shelley 版本</a>中会打开这个功能，所以下面的信息可能是过期的。</strong></p>\n<p>与重量级委托相反，轻量级委派不要求代表团拥有 <code>T</code> 或更多的股份。所以轻量级委派可以用于任何的节点。但是轻量级委派的代理签名证书不存在区块链中，所以轻量级委派证书必须要广播到代表团。</p>\n<p>之后轻量级 PSK 可以被指定发行者的公钥、签名和信息本身进行<a href="https://github.com/input-output-hk/cardano-sl/blob/42f413b65eeacb59d0b439d04073edcc5adc2656/lib/src/Pos/Delegation/Logic/Mempool.hs#L309">验证</a>。</p>\n<p>请注意『每个 epoch 只能发布一个证书』的规则在轻量级委托中不适用。因为轻量级证书不存储在区块链中，所以可以在每个 epoch 签发很多轻量级证书，不会导致区块链膨胀。</p>\n<h3>确认代理签名支付</h3>\n<p>代表团应该使用他拥有的代理签名密钥，使用 PSK 和代表团的钥匙制作一个 PSK 签名。如果签名是正确的，那么就是由代表团进行签名的（由 PSK 策略确保是这种结果）。</p>\n<h2>为什么有两个委派</h2>\n<p>你可以将重量级委托和轻量级委托想象成强委托和弱委托。</p>\n<p>重量级委派证书被存储在区块链中，所以被委派的权益可能会通过加入到委派权益中而参与 MPC。所以有很多重量级委派的代表团可能会累计足够的权益通过阈值的门槛。不仅如此，重量级委派可以参与卡尔达诺结算层更新的投票。</p>\n<p>与此相反，轻量级委派的权益不会被计算到代表团的 MPC 相关权益。所以轻量级委派只能用来生产新区块。</p>\n<h2>回撤证书</h2>\n<p>回撤证书是一种特殊的证书，发行者创建一个回撤证书来撤回委托。重量级委托和轻量级委托都可以被撤回，不过撤回的方法不同。</p>\n<p>作为相同的标准 PSK 的发行者和委派，撤销证书也是相同的。（换句话说，发行者委派给他自己）</p>\n<p>要撤销轻量级委派，发行者发送撤销证书给网络，要求撤销委派，但是不能强制撤销，因为轻量级的 PSK 不是区块链的一部分。所以理论上轻量级委派是可以忽略撤销证书的，这样的话，他就一直保持着委派直到它的委派过期。但这样的情况不会妨碍区块链。</p>\n<p>重量级委派撤销的处理是另一种方式。因为来自重量级委派的代理签名证书是存储在区块链中的，撤销证书也会被提交到区块链中。这种情况下，节点会删除撤销证书签发之前的重量级委派证。不过有三点很重要：</p>\n<ul>\n<li>如果提交的重量级委派证书是在节点的内存池里，而且撤销证书也被提交了，那么委派证书将会从内存池中被删除，显然，这种情况下委派证书将永远不会添加到区块链中。  </li>\n<li>如果一个用户提交委派证书后丢失了他的钱，他仍然可以撤销那个委派，即使那个时候他已经没有足够的钱了（也就是说他拥有的钱少于上面提到的阈值 <code>T</code>)  </li>\n<li>尽管发行者在当前的 epoch 只能发布一个证书，在同一个 epoch 他可以撤销他的重量级委派。</li>\n</ul>',frontmatter:{path:"/cn/technical/delegation/",doc_title:"卡尔达诺股权委派",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-01-01-proof-of-stake.cn.md absPath of file >>> MarkdownRemark",excerpt:"乌洛波罗斯权益证明算法 乌洛波罗斯权益证明算法是协议中最重要的部分。它定义了节点达到 账本 一致性的方式。 乌洛波罗斯算法是唯一一个基于科学证明的安全的区块链权益证明协议。 为什么要有权益证明？ 不选择被比特币采用的 PoW（工作量证明）而选择 PoS…",html:'<!-- Reviewed at c4c45ce9a7a8f4aa6d88a32829755196a017f6a1 -->\n<h1>乌洛波罗斯权益证明算法</h1>\n<p>乌洛波罗斯权益证明算法是协议中最重要的部分。它定义了节点达到<a href="/glossary/#ledger">账本</a>一致性的方式。</p>\n<p>乌洛波罗斯算法是唯一一个基于科学证明的安全的区块链权益证明协议。</p>\n<h2>为什么要有权益证明？</h2>\n<p>不选择被比特币采用的 PoW（工作量证明）而选择 PoS (权益证明) 最重要的原因是考虑了能源消耗。运行比特币协议非常消耗资源，据估计，一个比特币的转账所需要的能源是3.8个美国家庭一天消耗的能源。随着越来越多的比特币矿工将资金投入矿业，运行比特币协议的能源要求只会越来越高，他们挖矿的难度也会越来越大。这也是为什么研究人员尽力研究达成共识的替代算法，比如使用所谓的 BFT（Byzantine Fault Tolerant）一致性算法和 PoS 算法。</p>\n<h2>什么是权益证明算法</h2>\n<p>权益证明是生成区块的新方法。权益证明的核心思想是，不要浪费电力来解决计算量大的问题，而是选择一个节点来产生（或『铸造』）一个新的区块，其概率与这个节点所拥有的币数量成正比。如果一个节点具有正数（>0）的股权，则被称为权益所有人。如果一个节点最终被选中来铸造新的区块，它被称为『slot 领导者』。</p>\n<h3>证明</h3>\n<p>『权益证明』的『证明』部分是指证明交易块是合法的。</p>\n<h3>权益</h3>\n<p>『权益』指的是节点上的地址所拥有的相对价值。『相对价值』指的是『卡尔达诺结算层系统中某个节点钱包上的价值除以总价值』。请阅读<a href="/cardano/balance-and-stake/">卡尔达诺结算层的平衡和权益</a> 章节获取更多信息。</p>\n<h2>关于 Slot 领导者</h2>\n<p>有正资产的节点称作权益所有人，只有权益所有人能参与运行协议。权益所有人必须被选举为 slot 领导者才让区块链生成区块。Slot 领导者可能监听到其他节点的交易信息，然后通过密钥生成一个交易区块发给全网。</p>\n<p>你可以认为 slot 领导者是比特币中的矿工，但上述的一致性协议会确定谁，什么时候能挖矿，能挖到多少矿。</p>\n<h2>Epochs 和 Slots</h2>\n<p>乌洛波罗斯协议将物理的时间划分为 <strong>epochs</strong>, 每一个 epoch 又划分为 <strong>slots</strong>:</p>\n<pre><code>+----------+----------+-------+----------+--------------------> t\n|  slot 0  |  slot 1  |  ...  |  slot N  |\n\n \\                                      / \\\n  -------------- epoch M ---------------   -- epoch M+1 -- ...\n</code></pre>\n<p>请注意 slot 是相对较短的一段时间（比如20秒）。</p>\n<p>每个 slot 有且只有一个领导者（slot leader，SL）：</p>\n<pre><code>+----------+----------+-------+----------+----> t\n|  slot 0  |  slot 1  |  ...  |  slot N  |\n\n    SL 0       SL 1               SL N\n</code></pre>\n<p>slot 领导者有权在他的 slot 内生成一个区块。</p>\n<pre><code>  +------+   +------+           +------+\n  | Bl 0 |&#x3C;--| Bl 1 |&#x3C;-- ... &#x3C;--| Bl N |\n  +------+   +------+           +------+\n+----------+----------+-------+----------+----> t\n|  slot 0  |  slot 1  |  ...  |  slot N  |\n\n    SL 0       SL 1               SL N\n</code></pre>\n<p>这意味着 slot 领导者的数量一定等于一个 epoch 内 slots 的数量（不妨设为 <code>N</code>)，因此不可能在一个 epoch 里面生成超过 <code>N</code> 个区块。</p>\n<p>如果 slot 领导者错过了它的 slot（比如，在那个阶段它离线了），在下一次被选举为领导者之前，它没有权利再生成区块。</p>\n<p><strong>请注意：</strong> 可以有一个或多个 slots 是空的（即，不生成区块），但在一个 epoch 期间，它必须生成大部分块（至少50%+1）。</p>\n<h2>Slot 领导者选举是怎么工作的</h2>\n<p>Slot 领导者从所有的权益所有人中选举。请注意并不是所有的权益所有人能参与这次选举，只有有足够多的权益（比如，总量的2%)才有资格。我们称这些权益所有人为『候选人』</p>\n<p>在 epoch 的选举中会选举一个 slot 领导者参与下一次 epoch。因此，在 epoch <code>N</code> 结束的时候，我们就能知道 epoch <code>N+1</code> 的 slot 领导者是谁，并且这是不可更改的。</p>\n<p>你可以把这样的选举当做 『公平抽签』：权益所有人中的任何一个都能成为 slot 领导者。但 PoS 中一个很重要的的思想是，权益所有人拥有的股份越多，它被选举为 slot 领导者的可能性也就越大。</p>\n<p><strong>请注意：</strong>同一个 epoch，一个权益所有人可以被多次选做 slot 领导者。</p>\n<h3>多方计算</h3>\n<p>选举过程的根本问题之一是无偏性。我们需要一些随机性作为选举的基础，这样的话，选举的结果是随机的，公平的，问题是，这个随机性从哪来？</p>\n<p>多方计算（multiparty computation (MPC) ）方法用来实现这个随机性，每个参选人独立进行一次『投硬币』的行为，然后与其他参选人分享结果。这个想法就是：结果由每个参选人随机产生，但最终它们在相同的最终价值上达成一致。</p>\n<h4>提交阶段</h4>\n<p>首先，参选人会产生一个密钥（特殊的随机值）。接着，参选人会形成一个『提交』，这是一个包含加密份额（见下面的解释）以及密码的证明的消息。</p>\n<p>然后参选人会用密钥来签署这个提交，指定 epoch 编号，附上它的公钥。在这种情况下，每个人都可以知道谁创建了这个提交，以及这个提交属于哪个 epoch。</p>\n<p>随后，参选人会将其提交交给其他参选人，最终每个参选人都会拿到其他参选人的提交。</p>\n<p>注意：这些提交将被放入区块中，也就是说它们将成为区块链的一部分。</p>\n<h4>开启阶段</h4>\n<p>在这个阶段参选人发送一个『开启』状态，这是一个打开提交的特殊值。一个提交就像一个锁着的盒子（里面有一个密钥），我们需要一个开启的钥匙来打开这个盒子，获取里面的密钥。</p>\n<p><strong>注意：</strong>所有的开启都将放入区块中，它们会变成区块链的一部分。</p>\n<h4>恢复阶段</h4>\n<p>这是最后的阶段。</p>\n<p>最终，参选者既有提交，也有开启。从理论上来说，一些选民可以是对手。它可以公布它的提交，但<strong>不</strong>公开它的开启。</p>\n<p>在这种情况下，诚实的选民可以张贴（上面有提到）来重建密钥，这个想法很简单：即使某些选民是对手，选举也能成功结束。</p>\n<p>随后，参选者验证提交，开启匹配，如果成功，从提交中提取密钥，并从这些密钥中形成种子（随机生成的字符串）。所以所有的选民都会得到相同的种子，并且会被用于追随中本聪算法。</p>\n<h3>追随中本聪</h3>\n<p>在参选者获取种子之后（我们需要随机性），他们必须为下一个 epoch 选择特定的 slot 领导者。这时候就引入了追随中本聪算法。它类似于这样：</p>\n<pre><code>         +-----+\nSEED --->| FTS |---> ELECTED_SLOT_LEADERS\n         +-----+\n</code></pre>\n<p>我们解释一下 slot 领导者是怎么被选中的。我们将最小的，原子级的币叫做 『<a href="/glossary/#lovelace">Lovelace</a>』。基本上，因为 slot 领导者只能从权益所有者中选择，账本会生成币的分发。FTS 是一个挑选币的可证算法，当权益所有人 <code>S</code> 的币被选中时，<code>S</code> 就成为一个 slot 领导者。很明显，<code>S</code> 的币越多，他的币被选中的几率也就越大。</p>\n<p>为什么它被称为『追随中本聪算法』是因为在比特币中，货币的最小单位被称为『聪』，这是为了表彰比特币的发明人中本聪（Satoshi Nakamoto）</p>\n<h2>大多数都是诚实的</h2>\n<p>协议的基本假设前提是<strong>大多数都是诚实的</strong>。这意味着至少有 50%+1 的权益所有人是诚实的。在这种情况下，我们可以<strong>证明</strong>攻击者无法打破区块链的<em>持久化</em>和<em>活跃度</em>。欲了解更多信息，请参阅<a href="/glossary/#paper">论文</a> (2到3页)。</p>',frontmatter:{path:"/cn/cardano/proof-of-stake/",doc_title:"乌洛波罗斯权益证明算法",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-01-04-differences.cn.md absPath of file >>> MarkdownRemark",excerpt:"…",html:'<!-- Reviewed at c4c45ce9a7a8f4aa6d88a32829755196a017f6a1 -->\n<h1>乌洛波罗斯协议论文与实现的区别</h1>\n<p>本文档的目标是概述卡尔达诺结算层实现方式与<a href="/glossary/#%E8%AE%BA%E6%96%87">论文</a>中提供的乌洛波罗斯算法协议规范的不同，并阐明论文中的典型问题。</p>\n<p>本文档分为四个部分：</p>\n<ol>\n<li><em>说明</em> - 阐述在论文中没有提到但实际实现中非常重要的细节。  </li>\n<li><em>修改</em> - 列出哪些在论文中有说明，但在卡尔达诺结算层中以不同的方式实现。  </li>\n<li><em>新增功能</em> - 简要概述了在论文中没有介绍但在卡尔达诺结算层中实现的新功能。  </li>\n<li><em>遗漏</em> - 列出了论文中有描述，但尚未在卡尔达诺结算层中实现的特性。</li>\n</ol>\n<h1>说明</h1>\n<p>这一章节概述需要阐明的任何话题。</p>\n<h2>时间, Slots, 和同步</h2>\n<p>在协议的基本模型中，时间被分成称为 slot 的离散单位。但是，没有安全获得足够精度的当前时间的详细方法。</p>\n<p>在卡尔达诺结算层中，当前时间值从用户的计算机系统时间值获取。</p>\n<p>我们还有一个功能来通知用户他们的系统时间是否不正确（我们将它与 NTP 服务器的时间进行比较）。这个功能计划将来发布。</p>\n<h2>投币和可验证的密钥共享</h2>\n<p>论文中由 Schoenmakers 为卡尔达诺结算层提供 PVSS(Publicly Verifiable Secret Sharing) 方案。但是，卡尔达诺结算层目前使用 <a href="https://eprint.iacr.org/2017/216.pdf">"SCRAPE: Scalable Randomness Attested by\nPublic Entities"</a> PVSS 方案 </p>\n<p>使用 VSS（可验证的密钥分享，Verifiable Secret Sharing）方案时的一个挑战是将用于签名的公钥与用于 VSS 方案的公钥相关联（<code>VssPublicKey</code>）。这是通过引入 <code>VssCertificate</code> 来解决的。这个证书是一个由签名密钥给出的签名，它由一个对 <code>VssPublicKey</code> 以及这个证书的有效时间组成。最初，所有参与随机生成的权益所有者都拥有证书。当出现一个拥有足够股份的新权益所有人时，或现有证书到期时，应该生成一个新的证书并提交给网络。<code>VssCertificate</code> 被存储在区块中。</p>\n<p>PVSS 方案使用共享验证信息，这也包括了对密钥的提交。它也被用做协议中的提交。PVSS 提交已经在 elliptic curve (TODO)\nsecp256r1 实现，请参考 <a href="/technical/pvss/">PVSS 在卡尔达诺结算层的实现</a>获取更多细节。</p>\n<h2>区块生成时间</h2>\n<p>在论文中，他们没有明确说明何时 slot 领导者应该生成一个新的区块发送给网络：它可以在 slot 的开始，slot 的结尾，slot 的中间等等。在卡尔达诺结算层中有一个特殊的常量，叫做『网络直径』（network diameter），它接近于将区块广播到网络中所有节点所需的最大时间。例如，如果网络直径值为3，则在 slot 结束前，区块会被生成，并且广播3秒。</p>\n<h2>权益委派</h2>\n<p>权益委派，如论文中描述的，不明确规定代理签名证书是否应存储在区块链中（尽管建议存储区块链中的撤销列表）。在区块链没有存储代理签名证书的情况下，几乎没有可能考虑检查委派的股份的阈值合格性。另一方面，如果所有的证书都存储在区块链中，当大部分区块被代理证书占用时，可能会导致区块链膨胀。提交证书是免费的，所以攻击者可以根据需要生成尽可能多的证书。</p>\n<p>卡尔达诺结算层有两种委派：重量级和轻量级。加入重量级委派有一个门槛。来自重量级代理的代理签名证书存储在区块链中。相反，每个人都可以使用轻量级委派，但证书不会存储在区块链中，在检查资格限制时不会考虑证书，正如论文所建议的，使用委派代理方案。</p>\n<p>请阅读<a href="(/technical/delegation/)">卡尔达诺结算层权益委派</a> 获取实现细节。</p>\n<h1>修改</h1>\n<h2>领导者选举过程</h2>\n<p>在论文中，领导者选举过程被描述为翻转币的有偏估计量 <code>(1 - p₁) … (1 - pⱼ₋₁) pⱼ</code>，以判断第 j 个权益所有人是否为给定 slot 的领导者。这里 <code>pⱼ</code> 为选择第 j 个权益所有人的可能性。</p>\n<p>在卡尔达诺结算层中，它以稍微不同的方式实现。生成 R 个范围为 <code>[0 .. totalCoins]</code> 的随机数，这里 <code>R</code> 为一个 epoch 里面的 slot 数量。权益所有人在这个范围内占据不同的部分，这与他们的股权成正比。这样一来，每个随机数据对应权益所有人。另外，正如论文所建议的，使用一个短的（32位）的种子来初始化 PRG，而不是使用 <code>n ⌈log λ⌉</code> 随机位数。</p>\n<p>请阅读<a href="/technical/leader-selection/">卡尔达诺结算层领导者选举</a>获得实现细节。</p>\n<h2>提交，开放，股权发送</h2>\n<p>发送时间是在一个很小的时间间隔内随机分配的。这样做是为了避免所有投币者同时发送数据时的网络过载。这个时间间隔必须足够小，以保证协议安全。如果这个数据发送得太晚，则可能会发生数据不包含在区块中的情况。</p>\n<h2>多个权益所有人</h2>\n<p>在论文中，每个权益所有人都是基本 VSS 模型的参与者。然而，拥有更多股份的权益所有人比秘密共享股份的权益所有人更重要。例如，如果3个诚实的权益所有人控制了总共60%的股份（每个控制20%），并且有40个敌对权益所有人各持有1%的股份，那么对手就完全控制了秘密股份。</p>\n<p>为了解决这个问题，卡尔达诺结算层为每个利益相关者分配了一定比例的股份。</p>\n<h2>随机生成失败</h2>\n<p>论文没有涵盖提交无法恢复的情况。但是，一个现实的实现应该考虑这种情况。如果没有可以收回的提交，卡尔达诺结算层的实现使用由全零组成的种子。</p>\n<h1>增加的特性</h1>\n<h2>更新系统</h2>\n<p>请查阅这篇文章：<a href="/cardano/update-mechanism/">更新系统</a>.</p>\n<h2>P2P 的安全性</h2>\n<p>请查阅这篇文章：<a href="/technical/protocols/p2p/">P2P 的实现和强化</a>.</p>\n<h1>遗漏</h1>\n<p><em>输入背书人</em>和<em>激励结构</em>还没有实现。这些部分将与侧链悬而未决的研究一起实现，并随侧链的发布一起发布。</p>',frontmatter:{path:"/cn/cardano/differences/",doc_title:"论文与实现的区别",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-01-13-balance-and-stake.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层的余额和权益是怎么运行的 卡尔达诺结算层中有两个重要的概念：余额和权益。这一章将解释着两个概念的差异。 余额 余额是用户真实拥有的币数。当你在计算机上安装了代达罗斯钱包，执行  Ada 兑换 流程时，您会收到一定数量的 Ada 币。这个 Ada…",html:'<!-- Reviewed at e070e675764738b5190b2f93424de403f1937216 -->\n<h1>卡尔达诺结算层的余额和权益是怎么运行的</h1>\n<p>卡尔达诺结算层中有两个重要的概念：余额和权益。这一章将解释着两个概念的差异。</p>\n<h3>余额</h3>\n<p>余额是用户真实拥有的币数。当你在计算机上安装了代达罗斯钱包，执行 <a href="/timeline/bootstrap/">Ada 兑换</a>流程时，您会收到一定数量的 Ada 币。这个 Ada 币的数量称为你的余额，您可以向其他用户发送一定数量的 Ada 币（在此余额内），也可以从其他用户接收任意数量的 Ada 币。</p>\n<p>因此，当我们谈到余额时，我们讨论的是用户的实际资金。</p>\n<h3>权益</h3>\n<p>与余额（拥有的实际数额）不同，权益是卡尔达诺结算层整个金融系统的关键因素。权益让用户能够控制各种卡尔达诺结算层的算法，比如：成为 slot 领导者，在更新系统中投票，参加 MPC/ SSC，这就是为什么卡尔达诺结算层协议中的所有阈值都以权益，而不是余额来表示。</p>\n<p>因此，当我们谈到权益时，我们正在讨论用户实际控制卡尔达诺结算层的能力。有关权益的更多信息，请参阅<a href="/glossary/#%E8%AE%BA%E6%96%87">论文</a></p>\n<h3>余额和权益的关系</h3>\n<p>卡尔达诺结算层的每一枚币都与余额和权益相关。我们使用<a href="/cardano/transactions/#design">交易输出</a>将币 <code>C</code> 与用户余额相关联，并且我们使用股权分配将币 <code>C</code> 与用户权益相关联。</p>\n<p>注意：可以使用权益委派来更改币和股权之间的关联。</p>',frontmatter:{path:"/cn/cardano/balance-and-stake/",doc_title:"余额和权益",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-02-01-monetary-policy.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺货币政策 ADA 币在卡尔达诺协议发布时发行 启动期间的销售，卖出了 25,927,070,538 个 Ada 币。5,185,414,108 个 ADA 币，相当于所售 ADA 数量的 20%，生成并分发给组成卡尔达诺技术和业务生态系统的三个实体： IOHK…",html:'<!-- Reviewed at 1bd2a2f5979233f4f50a7e66ab4e1819ac486400 -->\n<h1>卡尔达诺货币政策</h1>\n<div  markdown="1">\n<h3>ADA 币在卡尔达诺协议发布时发行</h3>\n<p>启动期间的销售，卖出了 25,927,070,538 个 Ada 币。5,185,414,108 个 ADA 币，相当于所售 ADA 数量的 20%，生成并分发给组成卡尔达诺技术和业务生态系统的三个实体：<a href="https://iohk.io">IOHK</a>, <a href="http://emurgo.io/">Emurgo</a> 以及 <a href="https://cardanofoundation.org/">卡尔达诺基金会</a>。因此 ADA 发布时的总量是 31,112,484,646 个。</p>\n<h3>ADA 供给量</h3>\n<p>Ada 币以 45,000,000,000 或者说 450 亿封顶。</p>\n<h3>卡尔达诺协议运行期间发行的 ADA 币</h3>\n<p>剩余的 13,887,515,354 个 ADA 币，将在铸币的过程中发行。</p>\n<p>注意：ADA 的数量永远不会超过 45,000,000,000</p>\n</div>\n<h2>财政和费用</h2>\n<div  markdown="1">\n这一章将概述财政政策和相关费用。\n<h3>启动阶段 (发行)</h3>\n<p>卡尔达诺正处于启动阶段。在这个阶段，交易费没有被收集起来，没有 ADA 被铸造。这一时期的费用会在未来被收集然后他们就会被销毁。</p>\n<h3>国库</h3>\n<p>卡尔达诺将有一个国库。这个国库由部分（还没决定）新铸造的 ADA 币以及转账费用捐赠。国库为 ADA 持有者所有。</p>\n<h3>最小费用 (当前计算方式)</h3>\n<p>最小费用 = 0.155381 ADA + 0.000043946 (ADA/字节) x 转账数据大小</p>\n<p>费用计算和激励措施仍在研究中。</p>\n<h3>面额</h3>\n<ul>\n<li>1 ADA = 1,000,000 Lovelaces</li>\n<li>1 Lovelace = 1/1,000,000 Ada</li>\n<li>Ada 有6个小数点</li>\n<li>1.000000 = 1 ADA</li>\n<li>0.000001 = 1 Lovelace</li>\n</ul>\n<p>在货币单位方面有两点考虑。首先在日本，日元面额要大得多，10000 日元相当于 100美元，相当于250亿 ADA 对应 两亿五千万。第二点，与比特币的8位小数不同，ADA 有6位小数，一个 ADA 有100万个 Lovelaces（最小单位）。Adjusting for this takes you to 2.5 million. (TODO)</p>\n</div>',frontmatter:{path:"/cn/cardano/monetary-policy/",doc_title:"货币政策",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-01-19-topology.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层网络拓扑 这一篇是卡尔达诺结算层网络拓扑的概述 节点组 虽然卡尔达诺结算层被设计，实现为一个分布式网络，为了防 DDoS…",html:'<!-- Reviewed at ba744590c89d8ffa6d6f0919ec11f52202a6d8f2 -->\n<h1>卡尔达诺结算层网络拓扑</h1>\n<p>这一篇是卡尔达诺结算层网络拓扑的概述</p>\n<h2>节点组</h2>\n<p>虽然卡尔达诺结算层被设计，实现为一个分布式网络，为了防 DDoS，卡尔达诺结算层的实现和拓扑加入了一些额外的功能。当前所有的节点被分为三组：</p>\n<ul>\n<li>核心组</li>\n<li>中继组</li>\n<li>边缘组</li>\n</ul>\n<p>让我们分别讲解一下每组的节点。</p>\n<h3>核心节点</h3>\n<p>核心节点是最重要的。</p>\n<p>就像<a href="/timeline/bootstrap/#stake-locking">这里</a>描述的, 在 Byron 版本中，我们将会把权益高效地锁定在核心节点联盟上。只有很少的节点能够成为<a href="/glossary/#slot-leader">领导者</a>，所以只有这些节点能够在这个时期生成新区块。这是网络核心节点能够很好的运行和维护区块链的精髓所在。我们还为核心节点提供了更高的安全级别：我们把它们放在中介节点的中间，因此核心节点与公有网络隔离，并且只允许中继节点和核心节点进行同学。这就是我们减少核心节点被攻击的方法。</p>\n<p>请注意核心节点永远不会创建货币交易（只有边缘节点可以创建，请看下文）。</p>\n<h3>中继节点</h3>\n<p>你可以将中继节点想象为核心节点和公有网络的代理。</p>\n<p>因为中继节点是不隔离的，所以它们可以被攻击，原则上它们没有状态而且没有权益，所以它们可以被移除，也可以增加数量。如果中继节点崩溃了，会导致拒绝服务，但核心节点（和区块链）的完整性不会受影响。</p>\n<p>由于中继节点没有任何权益，所以它们不能成为领导者。不仅如此，它们也不能创建货币交易。</p>\n<p>中继节点是完全被初始股东联合会控制的。</p>\n<h3>边缘节点</h3>\n<p>边缘节点是最简单的节点，每个人都可以在自己的电脑上运行边缘节点，只有这些节点可以创建货币交易。</p>\n<p>由于边缘节点没有任何的权益，它们同中继节点一样不能成为领导者，此外，边缘节点不能直接与核心节点通信，只能与中继节点以及其他边缘节点进行通信。</p>',frontmatter:{path:"/cn/cardano/topology/",doc_title:"拓扑",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-02-02-transaction-fees.cn.md absPath of file >>> MarkdownRemark",excerpt:"…",html:'<h1>卡尔达诺结算层的转账费用</h1>\n<h2>驱动力</h2>\n<p>卡尔达诺结算层需要交易费主要因为两个原因：</p>\n<ol>\n<li>\n<p>人们运行卡尔达诺结算层完整节点，需要花费时间、金钱和经历来运行协议，为此他们应得到补偿和奖励。在卡尔达诺结算层中与比特币不同的是，当新货币在每个区块被挖出时，交易费用是协议参与者的唯一收入来源。</p>\n</li>\n<li>\n<p>第二个原因是为了防 DDoS（分布式拒绝服务攻击）。在 DDoS 攻击者，攻击者尝试用虚假交易来冲击网络，如果他必须为每个虚假交易支付足够高的费用，这种攻击形式对于他来说就过于昂贵了。</p>\n</li>\n</ol>\n<h2>交易费用如何运作</h2>\n<p>每当有人想要转移一定数量的 Ada，这笔转账就会有一个最低的转账费。如果想让这个交易有效，必须包含这笔很小的费用，尽管发送者可以选择支付更高的费用。</p>\n<p>请阅读<a href="#transaction-fees-distribution">下面</a>的交易分配方式。</p>\n<h2>最低转账费</h2>\n<p>一笔转账的最低费用通过下面的公式计算：</p>\n<pre><code>a + b × size\n</code></pre>\n<p>其中:</p>\n<ul>\n<li><code>a</code> 是一个特殊常量，目前是 0.155381 ADA;</li>\n<li><code>b</code> 是一个特殊常量，目前是 0.000043946 ADA/byte;</li>\n<li><code>size</code> 是以字节为单位的转账数据大小</li>\n</ul>\n<p>这意味着每笔交易至少需要 0.155381 ADA, 每字节的交易需要额外的 0.000043946 ADA。例如，大小为200字节（相当典型的大小）的转账费用是：</p>\n<pre><code>0.155381 ADA + 0.000043946 ADA/byte × 200 byte = 0.1641702 ADA.\n</code></pre>\n<p>有参数 <code>a</code> 的原因是为了防止上面提到的 DDoS 攻击：即使是非常小的虚假交易也要花费足够的代价，以此来防止试图产生成千上万交易的攻击者。</p>\n<p>引入参数 <code>b</code> 用来反映实际成本：存储更大的交易比存储更小的交易需要更多计算机内存，因此数据量更大的交易应该比数据量小的交易收费更贵。</p>\n<p>虽然是通过特定参数 <code>a</code> 和 <code>b</code> 计算的，这些值可能会在未来进行调整，以更好地反映实际成本。</p>\n<h2>交易分配方式</h2>\n<p>在一个特定 <a href="http://cardanodocs.com/glossary/cn/#epoch">epoch</a> 中产生的交易费用会被收集到一个虚拟池里，然后将这个池里的资金重新分配给由 PoS 算法选举的那些 <a href="https://cardanodocs.com/glossary/cn/#slot-leader">slot 领导者</a>。</p>\n<p>在卡尔达诺结算层这个阶段，所有的区块都是有 IOHK 以及我们的合作伙伴运行的节点创建的，收集了费用（为了防止 DDoS 攻击），但它们不会被重新分配，而是被销毁。</p>\n<p>不久，卡尔达诺结算层进入下一个阶段，<a href="https://cardanoroadmap.com/">完全分布式阶段</a>后，费用会按如上所述分配。</p>',
  frontmatter:{path:"/cn/cardano/transaction-fees/",doc_title:"转账费用",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-01-07-addresses.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层的地址 要发送和接收价值，基本所有加密货币都使用地址。卡尔达诺结算层支持3种类型的地址： 公钥地址 脚本地址 兑换地址 公钥地址在就像其他的加密货币一样，是个正常的，经过哈希的公钥。 脚本地址被用在一个称为『支付脚本 Hash』（P2SH…",html:'<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<h1>卡尔达诺结算层的地址</h1>\n<p>要发送和接收价值，基本所有加密货币都使用地址。卡尔达诺结算层支持3种类型的地址：</p>\n<ol>\n<li>公钥地址</li>\n<li>脚本地址</li>\n<li>兑换地址</li>\n</ol>\n<p>公钥地址在就像其他的加密货币一样，是个正常的，经过哈希的公钥。</p>\n<p>脚本地址被用在一个称为『支付脚本 Hash』（P2SH）的交易中。它会自动运作，就像银行里的存款一样：你可以向它汇款，但为了兑换这笔钱你必须满足一些特定的条件，条件由于地址相关的脚本决定。地址本身包含着序列化脚本的哈希值。请阅读下面的 <a href="#pay-to-script-hash">P2SH</a> 获取更多信息。</p>\n<p>赎回地址是 ADA 赎回的一种特殊地址类型。</p>\n<p>不仅如此，卡尔达诺结算层还支持 <code>Unknown</code> 地址类型。这种类型可以允许我们在未来使用自定义的地址类型。</p>\n<h2>地址看起来像什么？</h2>\n<p>地址是 <code>base58</code> 编码的字符串，例如：</p>\n<pre><code>Ae2tdPwUPEZKmwoy3AU3cXb5Chnasj6mvVNxV1H11997q3VW5ihbSfQwGpm\n</code></pre>\n<h3>编码</h3>\n<p><code>base58</code> 编码也是比特币中使用的编码。它使用58个符号的字母表来对数据进行编码，这也是它名字的由来。下面就是我们使用的字母表：</p>\n<pre><code>123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\n</code></pre>\n<p>它去除了非字母数字字符和显示时看起来模棱两可的字母（<code>0</code>, <code>O</code>, <code>I</code>, <code>l</code>）；因此它适用于手动输入数据，从可视化的源代码复制数据的普通用户，并且允许通过双击来简单的拷贝和粘贴，不过双击通常会选择整个字符串。</p>\n<h2>公钥地址</h2>\n<p>就像<a href="/introduction/#you-own-your-money">介绍</a>章节提到的，在用户界面你看到钱包就代表着在这个特定的钱包中你拥有可以花费这笔钱的私钥。但是这样的花销是如何被网络验证，你又如何接收到别人支付给你的钱呢？答案就是跟控制你钱包价值的私钥一起产生的一个公钥。这个公共的部分即指可以被任何人知道，因此叫做『公钥』。</p>\n<p>一个公钥的地址包含了公钥的哈希值。</p>\n<p>公钥同时用来在你创建一个交易或其他辅助用途的时候验证你的身份。</p>\n<h2>P2SH</h2>\n<p>P2SH 的思想是为花费制定复杂的规则提供很大的灵活性。与发送一笔交易到公钥地址不同，我们创建一个验证脚本，该脚本使用赎回脚本当做参数。为了赎回里面的资金，我们发送一个赎回请求给验证器，然后开始计算。如果计算结果是 <code>success</code>, 钱就会被汇到指定的赎回者那里，否则的话什么都不会发生。</p>\n<p>引用一下比特币 WiKi：</p>\n<blockquote>\n<p>使用 P2SH，你可以将比特币打给一个用多种不常见的方法保护着的地址，不用知道关于该地址安全设置的任何详细信息。接收者可能需要多个人的签名，或一个密码，或一个非常独特的要求才能使用这些比特币。</p>\n</blockquote>\n<h2>赎回地址</h2>\n<p>赎回地址就是 P2PKH。这样的地址包含了赎回公钥的哈希值，并且这个钥匙是 <a href="http://ed25519.cr.yp.to/">Ed25519</a> 公钥。</p>\n<h2>其他地址类型</h2>\n<p>在未来，我们可能会用升级的系统来引入其他地址类型。请阅读<a href="/cardano/update-mechanism/#soft-fork-updates">查看更多</a> 来了解以无缝升级的方式来扩展系统的相关信息。</p>\n<h2>地址结构</h2>\n<p>地址由三部分组成</p>\n<ul>\n<li>地址根</li>\n<li>地址属性</li>\n<li>地址类型</li>\n</ul>\n<p>我们可以把地址想象成类似 JSON 的结构，例如：</p>\n<pre><code>Address {\n    addrRoot = AbstractHash e63175c654dfd93a9290342a067158dc0f57a1108ddbd8cace3839bd,\n    addrAttributes = Attributes {\n        data: AddrAttributes {\n            aaPkDerivationPath = Nothing,\n            aaStakeDistribution = BootstrapEraDistr\n        } \n    },\n    addrType = ATPubKey\n}\n</code></pre>\n<p><code>addrRoot</code> 是由 <code>addrType</code>、<code>addrSpendingData</code>、<code>addrAttributes</code> 组成数组的 BLAKE2b-224 哈希值。</p>\n<p>addrSpendingData 是一个与地址绑定的特殊值，消费在这个地址的币必须是被公开的。例如，对于公钥来说，这个值就包含着公钥。这样一来，在不知道公钥的时候不可能改变地址属性，因为如果属性改变了，整个地址就变成无效的了。</p>\n<p><code>addrAttributes</code> 包含了每个地址重要的属性：衍生的路径和权益的分配。</p>\n<p>想要了解更多关于衍生路径的内容请阅读<a href="https://cardanodocs.com/technical/hd-wallets/">卡尔达诺结算层的 HD 钱包</a>章节。</p>\n<p>想要了解更多关于权益分配的内容请阅读<a href="https://cardanodocs.com/cardano/transactions/#stake-distribution">卡尔达诺结算层的转账</a>章节。</p>\n<p><code>addrType</code> 的值与上面提到的地址类型相对应，在上面的例子中它是一个公钥地址。</p>\n<h3>长度</h3>\n<p>地址的长度可能是不同的，地址长度与地址类型和附加数据有关。</p>\n<p>例如这个地址：</p>\n<pre><code>Ae2tdPwUPEZKmwoy3AU3cXb5Chnasj6mvVNxV1H11997q3VW5ihbSfQwGpm\n</code></pre>\n<p>以及这个地址：</p>\n<pre><code>4swhHtxKapQbj3TZEipgtp7NQzcRWDYqCxXYoPQWjGyHmhxS1w1TjUEszCQT1sQucGwmPQMYdv1FYs3d51KgoubviPBf\n</code></pre>\n<p>都是公钥地址。</p>',frontmatter:{path:"/cn/cardano/addresses/",doc_title:"地址",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-02-05-explorer.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺运算层浏览器 这是卡尔达诺浏览器服务的概述 (下文称作『浏览器』). 浏览器是一个搜索卡尔达诺网络中的地址，转账，epochs，slots 信息的 在线服务 地址 找到一个用户的地址信息是有可能的。在得到一个 hash…",html:'<!-- Reviewed at dec0d911d6c4beb8e708ed4076f832ff871f6125 -->\n<h1>卡尔达诺运算层浏览器</h1>\n<p>这是卡尔达诺浏览器服务的概述 (下文称作『浏览器』).</p>\n<p>浏览器是一个搜索卡尔达诺网络中的地址，转账，epochs，slots 信息的<a href="https://cardanoexplorer.com/">在线服务</a></p>\n<h2>地址</h2>\n<p>找到一个用户的地址信息是有可能的。在得到一个 hash 地址后，我们将看到：</p>\n<ol>\n<li>与这个地址有关的交易数量</li>\n<li>这个地址的最终余额</li>\n<li>这个地址的 QR 码</li>\n</ol>\n<p>Hash 地址的例子: <code>1fhXcTriF8i8FFSdCTaU9d3yp3oCLFQhon5KBkevT8rQDPP</code>.</p>\n<h2>转账</h2>\n<p>我们可以找到转账的相关信息。在得到一个交易 ID 后，我们将看到：</p>\n<ol>\n<li>交易日期和时间</li>\n<li>交易的来源地址</li>\n<li>交易的目标地址</li>\n<li>这次交易转移的 ADA 金额</li>\n<li>手续费</li>\n</ol>\n<p>交易 ID 的例子:</p>\n<p><code>fe0681c7fe20c27071befc329caac059bb183afaf68b9595744c52125c61cf68</code>.</p>\n<h2>时间</h2>\n<p>我们能找到某个时间点的交易信息。目前只能指定 <a href="/glossary/#epoch">epoch</a> 和 <a href="/glossary/#slot">slot</a>，在得到 epoch 和 slot 的索引后，我们将看到：</p>\n<ol>\n<li>这个 slot 的交易数</li>\n<li>在这次 slot 中的转移的 ADA 金额</li>\n<li>在这个 slot 中产生的区块的大小</li>\n</ol>\n<h3>Slot</h3>\n<p>我们可以找到特定 slot 的相关信息。在得到 slot 的 hash 值之后，我们可以看到：</p>\n<ol>\n<li>这个 slot 的交易次数</li>\n<li>总产值</li>\n<li>这个 slot 的预计 ADA 数量</li>\n<li>费用</li>\n<li>slot 的 ID</li>\n</ol>\n<p>此外，我们还能得到散列的信息：</p>\n<ol>\n<li>slot 的散列</li>\n<li>前一个 slot 的散列（如果存在的话）</li>\n<li>下一个 slot 的散列（如果存在的话）</li>\n<li>The Merkle root. (TODO)</li>\n</ol>',frontmatter:{path:"/cn/cardano/explorer/",doc_title:"浏览器",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/for-contributors/2017-01-03-haddock.md absPath of file >>> MarkdownRemark",excerpt:"Haddock Documentation Here you can find the Haddock-based documentation for Cardano SL. Latest This is the  latest documentation . Release…",html:'<!-- Reviewed at c507f6675c16810ba9ca72b71dac57288fd1735c -->\n<h1>Haddock Documentation</h1>\n<p>Here you can find the Haddock-based documentation for Cardano SL.</p>\n<h2>Latest</h2>\n<p>This is the <a href="https://cardanodocs.com/haddock/latest/index.html">latest documentation</a>.</p>\n<h2>Release</h2>\n<p>Documentation for stable releases will be published later.</p>',frontmatter:{path:"/en/for-contributors/haddock-documentation/",doc_title:"Haddock Documentation",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"for-contributors"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/for-contributors/2017-01-01-building-from-source.md absPath of file >>> MarkdownRemark",excerpt:"Redirecting...",html:'<h1>Redirecting...</h1>\n<script>\n    // window.location.replace("https://github.com/input-output-hk/cardano-sl/blob/master/docs/how-to/build-cardano-sl-and-daedalus-from-source-code.md");\n</script>',frontmatter:{path:"/en/for-contributors/building-cardano-sl-from-source-code/",doc_title:"Building Cardano SL From Source Code",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"for-contributors"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/timeline/2017-01-01-testnet.md absPath of file >>> MarkdownRemark",excerpt:"Testnet Era The Cardano SL test network (the testnet) is required to get the community\nacquainted with the cryptocurrency and to polish the…",html:'<!-- Reviewed at 357ac1f7b4a9f1d98ee7f7bee46e874d7356958f -->\n<h1>Testnet Era</h1>\n<p>The Cardano SL test network (the testnet) is required to get the community\nacquainted with the cryptocurrency and to polish the implementation, eliminating\npossible flaws or instabilities.</p>\n<p>During the Testnet era all functionality, including the reward mechanism, are\nactivated. Anyone is able to redeem a private key from Cardano SL Testnet Faucet\nto get their coin supply.</p>\n<p>We encourage everyone to download Cardano SL client for their platform, get some\ncoins (we call them <a href="/glossary/#lovelace">Lovelace</a>) from the faucet, and invite\nother people to participate in beta testing.</p>\n<p>The result of the Testnet era is the <a href="/timeline/bootstrap">release</a> of Cardano SL.</p>',frontmatter:{path:"/en/timeline/testnet-era/",doc_title:"Testnet Era",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"timeline"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/timeline/2017-01-03-reward.md absPath of file >>> MarkdownRemark",excerpt:"Reward Era After the  Bootstrap era , the Reward era will start.\nDuring this time, the network will operate in a completely decentralized…",html:'<!-- Reviewed at 357ac1f7b4a9f1d98ee7f7bee46e874d7356958f -->\n<h1>Reward Era</h1>\n<p>After the <a href="/timeline/bootstrap">Bootstrap era</a>, the Reward era will start.\nDuring this time, the network will operate in a completely decentralized,\ntrustless mode. We expect staking pools to emerge during this era, allowing\nstakeholders with little stake to get rewards as stakeholders with large stake\nkeep their nodes online to maintain the protocol in a decentralized fashion.</p>\n<p>The system will receive regular software updates moving forward, and a massive\namount of new features will be released in the near future.</p>',frontmatter:{path:"/en/timeline/reward-era/",doc_title:"Reward Era",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"timeline"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-01-07-blocks.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺清算层的区块 这份指南介绍区块设计和区块处理的逻辑。 区块相关类型在  Pos.Block.Core.Main.Types  模块和  Pos.Block.Core.Genesis.Types  模块中定义。在\n Pos.Block.Logic…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<h1>卡尔达诺清算层的区块</h1>\n<p>这份指南介绍区块设计和区块处理的逻辑。</p>\n<p>区块相关类型在 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Types.hs">Pos.Block.Core.Main.Types</a> 模块和 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Genesis/Types.hs">Pos.Block.Core.Genesis.Types</a> 模块中定义。在\n<a href="https://github.com/input-output-hk/cardano-sl/tree/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic">Pos.Block.Logic.*</a> 模块中定义了使用区块的逻辑。</p>\n<h2>设计</h2>\n<p>区块是账本的基础部分。有两种类型的区块：<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Types.hs#L110"><strong>主块</strong></a>和<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Genesis/Types.hs#L66"><strong>生成块</strong></a>。</p>\n<h3>主区块</h3>\n<p>一个主区块由<em>头</em>和<em>主体</em>组成。<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/core/Pos/Core/Block.hs#L99">区块头</a>包含块的元信息：</p>\n<ol>\n<li>指向前一个区块签名的头。</li>\n<li>区块主体信息的验证。</li>\n<li>验证共识算法的共识数据。</li>\n<li>一些额外的数据。</li>\n</ol>\n<p>区块主体包含的有效载荷和一些额外的数据也是如此。有效载荷包括：</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L66">转账有效载荷</a>。这个有效载荷是最主要的。事务存储在 Merkle 树中。这个有效载荷也包括<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Txp/Core/Types.hs#L283">见证名单</a>，请阅读<a href="/cardano/transactions/">卡尔达诺结算层</a>的交易，了解交易和见证的更多信息。</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L68">SSC 有效载荷</a>。按照跟随<a href="/cardano/proof-of-stake/#follow-the-satoshi">中本聪算法</a>使用 SSC（共享种子计算）。在每一个 epoch 中，必须选出下一个 epoch 的领导者。这些 slot 的领导者将能够生成主区块并加入到账本中。所以 SSC 被用作领导者选举过程的随机来源。</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L70">委派的有效载荷</a>。该有效载荷由<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Delegation/Types.hs#L49">重量级代理签名密钥列表</a>组成。请阅读关于<a href="/technical/delegation/">卡尔达诺结算层的股权委派</a>获取更多信息。</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L72">更新有效载荷</a>。它包含软件更新的<a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/update/Pos/Update/Core/Types.hs#L300">建议</a>和特定更新的选项列表。请阅读<a href="/cardano/update-mechanism/">更新系统模型</a>获得更多信息。</li>\n</ol>\n<h3>创世块</h3>\n<p>一个创始块不包含交易，每个 epoch 我们都只有一个创始块。创始块就像主区块一样，只有一个区块头和一个区块主体。该块的主题包括：</p>\n<ol>\n<li>与该区块相关的 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Genesis/Chain.hs#L33">epoch 索引</a>。</li>\n<li>这个 epoch 的 slot 领导者列表。该列表<a href="https://github.com/input-output-hk/cardano-sl/blob/b4b2c282b0e2a2e4415163e70dcb559396a2237c/core/Pos/Core/Types.hs#L272">不能为空</a>。</li>\n<li>链复杂度。他表示生成一个链的复杂度，它是链中主块的数量。</li>\n</ol>\n<h2>区块处理逻辑</h2>\n<p>我们根据区块和区块头进行处理。基本上，我们可以：</p>\n<ul>\n<li>创建一个区块</li>\n<li>验证一个区块</li>\n<li>申请块</li>\n<li>回滚一个块</li>\n</ul>\n<p>以及：</p>\n<ul>\n<li>按不同的标准获取块头</li>\n<li>给区块头分类</li>\n</ul>\n<h2>创建区块</h2>\n<p>如上所述，有两种区块：<strong>主</strong>区块和<strong>生成</strong>块。主区块由 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L156"><code>createMainBlock</code></a> 函数创建，生成块由 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L92"><code>createGenesisBlock</code></a> 创建。</p>\n<h3>主区块创建</h3>\n<p>如果可能的话，我们尝试在最佳链的顶部创建一个新的主区块。如果满足以下条件，可以创建一个新区块：</p>\n<ul>\n<li>我们知道 epoch 给定 slot ID 的主区块，</li>\n<li>最后一个已知的区块不超过给定的 slot 的 <a href="https://github.com/input-output-hk/cardano-sl/blob/f571087e5b5af339767198141981c850227ca99c/core/Pos/Core/Constants.hs#L86"><code>slotSecurityParam</code></a> 个区块。</li>\n</ul>\n<p><code>slotSecurityParam</code>（实际上是 slot 的数量）的值取决于可被回滚区块的最大数量。这个<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/core/Pos/Core/Constants.hs#L81">最大数量</a>来自<a href="/glossary/#paper">论文</a>中的安全参数。</p>\n<p>首先，我们必须检查我们的软件是否可以<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Update/Logic/Global.hs#L139">根据当前的全局状态</a>创建一个区块，如果不能，我们会<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L172">报告</a>。如果可以的话，我们<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L206">创建并应用区块</a>。</p>\n<h3>创世纪块的创建</h3>\n<p>当当前已知最佳链的头 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Types.hs#L112"><code>MainBlock</code></a>  对应于 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/core/Pos/Core/Constants.hs#L81"><code>slotSecurityParam</code></a> （i-1）个时期的最后一个 slot 之一时，为当前时期创建一个生成块。</p>\n<p>首先，我们试图获得 slot 领导者，如果<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L99">没有领导者</a>或 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L102">LRC 没有足够的区块</a>，则会报告错误。否则，我们试图创建一个<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L115">新的创始块</a>。然而有时候我们<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L106">不应该创建</a>。例如，我们不应该在第 0 个 epoch 做这件事情，因为<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L108">第 0 个 epoch</a> 的生成块是硬编码的。</p>\n<h2>区块应用</h2>\n<p>我们使用 <a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/VAR.hs#L182"><code>applyBlocks</code></a> 函数应用区块。区块的顺序应该是绝对有效的：我们必须验证关于块的所有谓词和数据检查。</p>\n<p><strong>重要</strong>： 在这个序列中的所有区块都必须是相同的 epoch！</p>\n<p>如果所有的条件都满足了，我们<a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/Internal.hs#L107">真正应用区块</a>：</p>\n<ul>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/Internal.hs#L141">应用 US (更新系统)</a>，</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/Internal.hs#L142">应用委派</a>，</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/Internal.hs#L143">应用转账</a>。</li>\n</ul>\n<p>而且，我们可以在应用程序之前验证区块（即只有在区块有效时才应用区块）。我们使用 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/VAR.hs#L99"><code>verifyAndApplyBlocks</code></a> 函数的功能，如果在应用程序发生错误，有两个选项：</p>\n<ol>\n<li>在这个函数中应用的所有区块都将<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/VAR.hs#L137">回滚</a>。</li>\n<li>这个函数将尝试<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/VAR.hs#L126">尽可能地多应用区块</a></li>\n</ol>\n<h2>区块回滚</h2>\n<p>您可以把回滚视为应用程序的对立面：当执行回滚时，应用程序所做的所有修改都将被取消，为此，我们使用 <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/VAR.hs#L208"><code>rollbackBlocks</code></a> 函数的功能。</p>\n<p>get the tip？第一个区块将回滚。如果他们不匹配，则报告错误。如果他们匹配，我们实际上回滚区块的顺序为：</p>\n<ul>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Internal.hs#L173">回滚委派</a>，抹掉内存池中的认证。</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Internal.hs#L174">回滚 US</a></li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Internal.hs#L172">回滚交易</a></li>\n</ul>\n<h2>区块头分类</h2>\n<p>区块头部可以分为：</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L51">继续</a>。</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L54">可选</a>。</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L59">无效</a>。</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L57">无用</a>。</li>\n</ol>\n<p>如果<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L120">验证成功</a>，则头部为<strong>继续</strong>：头部是主链的直接延续（即，其服务是我们的 tip）。</p>\n<p>如果头部的父亲不是我们的 tip，<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L124">它不太可能是我们的主链</a>，头部为<strong>可选</strong>。</p>\n<p>如果<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L170">头部链中有任何错误</a>，或者<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L172">没有对应链中最老元素（应该是检查点之一）</a>的父亲的块，那么头部被视为<strong>无效</strong>。</p>\n<p>如果在不同的条件下（例如，头部的 slot <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L94">小于或等于我们 tip 的 slot</a>，或者<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L129">头部与主链不连续，复杂度更大</a>），头部为<strong>无用</strong>。</p>',frontmatter:{path:"/cn/technical/blocks/",doc_title:"卡尔达诺结算层区块",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-01-04-updater.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层更新器概览 更新系统的实现可以从  Pos.Update  系列模块中找到。实现的方法与 CSL 的其他子系统相同，比如 Txp, Ssc…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<!-- Updated at 6b5eda44e5942599a9781e5ad3f51eb820665b83 -->\n<h1>卡尔达诺结算层更新器概览</h1>\n<p>更新系统的实现可以从 <a href="https://github.com/input-output-hk/cardano-sl/tree/6b5eda44e5942599a9781e5ad3f51eb820665b83/src/Pos/Update">Pos.Update</a> 系列模块中找到。实现的方法与 CSL 的其他子系统相同，比如 Txp, Ssc 和委派。更新系统有一个全局状态，存储在数据库中。全局状态可以从区块链中明确导出。本地状态，有时候也被称为『内存池』，被存储在内存中。内存池用于数据传输，将传输的数据保存到区块中。在<a href="/technical/protocols/binary-protocols/">二进制文档</a>中描述的二进制协议在<a href="/technical/protocols/csl-application-level/">应用级文档</a>中描述了网络协议（使用标准的 <a href="https://github.com/input-output-hk/cardano-sl/tree/43a2d079a026b90ba860e79b5be52d1337e26c6f/infra/Pos/Communication/Relay">Inv/Req/Data\npattern</a> 模式构建)。</p>\n<p>目前，通过软件更新，执行研究部分所述的硬分叉来增加硬分叉的功能已经准备好了；软分叉（或者说软件更新）已经完全实现。</p>\n<h2>软分叉可更新字段</h2>\n<p>一个 <a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/update/Pos/Update/Core/Types.hs#L110">UpdateProposal</a> 包含用于修改由卡尔达诺结算层使用的一些参数（例如 slot 持续时间）的字段。具体来说，<code>upBlockVersion</code> 用于提议协议有了一些修改；如果 <code>upBlockVersion</code> 比上一次使用的区块还新，<code>upBlockVersionData</code> 的修改就会被采用。</p>\n<p><code>upBlockVersionData</code> 具有 <a href="https://github.com/input-output-hk/cardano-sl/blob/fe5e6a377ab63c506173545fd4d8633cd1afbdc6/core/Pos/Core/Types.hs#L206">BlockVersionData</a> 的类型。</p>\n<p>这些字段如下所述：</p>\n<ul>\n<li><code>bvdScriptVersion</code> - 用于验证脚本转账的脚本语言版本，如果协议中 <code>upBlockVersion</code> 增加了，它必须也给增加 <code>upBlockVersion</code> 1（不能保持不变）。</li>\n<li><code>bvdSlotDuration</code> - slot 持续时间（以毫秒为单位）。</li>\n<li><code>bvdMaxBlockSize</code> - 区块大小限制（以字节为单位）。与上一个限制相比而言，协议不能将区块的大小限制增加两倍以上。</li>\n<li><code>bvdMaxHeaderSize</code> - 区块大小限制（以字节为单位）。</li>\n<li><code>bvdMaxTxSize</code> - 转账大小限制（以字节为单位，<a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/core/constants.yaml#L17">当前为4096字节</a>)，限制 <a href="/technical/protocols/binary-protocols/#transaction-auxilary">TxAux</a> 的大小。</li>\n</ul>\n<p>这些检查在 <a href="https://github.com/input-output-hk/cardano-sl/blob/893e3c838bf847613313e8dbf04330176a788af4/update/Pos/Update/Poll/Logic/Base.hs#L232">verifyNextBVData</a> 中进行。</p>\n<p>此外，有一些现在未被使用，但将来会被使用的字段。以下是它们的简要说明：</p>\n<ul>\n<li><code>bvdMpcThd</code> MPC 的资格临界值。</li>\n<li><code>bvdHeavyDelThd</code> 重量级委派的临界值。</li>\n<li><code>bvdUpdateVoteThd</code> 投赞成票和反对更新所需的股份份额。</li>\n<li><code>bvdUpdateProposalThd</code> 所有股份的一个份额，要让区块拥有 <code>UpdateProposal</code>，权益所有人的投票份额必须大于这一份额。</li>\n<li><code>bvdUpdateImplicit</code> 静默更新之后的 slot 数（除非它有更多的否定票数）。</li>\n<li><code>bvdUpdateSoftforkThd</code> 所有股份的一个份额，如果某些区块权益所有人的总持股比例比该数值大，则采用该区块版本。</li>\n</ul>\n<h2>内存池结构</h2>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/update/Pos/Update/MemState/Types.hs#L29"><code>内存池</code></a> 由投票和提案组成。除此以外，<a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/update/Pos/Update/MemState/Types.hs#L39"><code>内存池</code></a> 还包含 tip，slot 以及 <code>MemPool</code> 对应的 <code>PollModifier</code>（当前 <code>GState</code>，即应用的 <code>MemPool</code> 对应 <code>GState</code>）。无论是来自网络/内存池提案状态改变，还是来自区块链加载的提案状态改变，<code>PollModifier</code> 都表示全局状态的改变，会被应用到内存池。</p>\n<h3>更新内存池</h3>\n<p>随着节点反序列化<a href="/technical/protocols/binary-protocols/#update-system">更新系统消息的数据</a>，内存池会被更新，实现在<a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/update/Pos/Update/MemState/Functions.hs#L35">这里</a>。</p>\n<p><code>MemPool</code> 在三种情况下会被更新：</p>\n<ol>\n<li>\n<p><strong>当收到新的提案/表决时</strong>。在这种情况下，调用一个<a href="https://github.com/input-output-hk/cardano-sl/blob/763822c4fd906f36fa97b6b1f973d31d52342f3f/update/Pos/Update/Logic/Local.hs#L186">处理函数</a>，然后调用 <a href="https://github.com/input-output-hk/cardano-sl/blob/dff5e00612c84af24964a98e5254602fa4f7fc17/update/Pos/Update/Poll/Logic/Apply.hs#L66"><code>verifyAndApplyUSPayload</code></a> 并更新当前 <code>PollModifier</code> 和 <code>MemPool</code>。  </p>\n</li>\n<li>\n<p><strong>当一个新 slot 开始时</strong>。在这种情况下，一些内存池的数据可能会失效。事实上，只有 epoch 发生变化时才会发生这种情况。这种情况可能会发生是因为稳定的股份分配发生了变化，有些投票可能没有足够的股份。这是 <a href="https://github.com/input-output-hk/cardano-sl/blob/763822c4fd906f36fa97b6b1f973d31d52342f3f/update/Pos/Update/Logic/Local.hs#L283"><code>processNewSlot</code></a> 方法实现的。</p>\n</li>\n<li>\n<p><strong>当 <code>GState</code> 更新时</strong>。它被称为 <a href="https://github.com/input-output-hk/cardano-sl/blob/763822c4fd906f36fa97b6b1f973d31d52342f3f/update/Pos/Update/Logic/Local.hs#L248"><code>usNormalize</code></a>。有些数据可能由于区块应用程序或回滚而变得无效。例如，我们在内存中有个提案，将这个提案应用于区块，然后它变无效了（因为它已经在区块中）。我们应该放弃这个提案。或者我们从某个区块对提案进行投票，然后回滚这个区块，然后投票变得无效。它通过将所有本地数据应用于空状态来实现的，忽略所有不再有效的数据。</p>\n</li>\n</ol>\n<h3>提案和投票累计</h3>\n<p>要为提案投票，节点应该发送它们的<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/update/Pos/Update/Core/Types.hs#L255">投票</a>。提案和投票存储在内存池（即使没有足够的选票加入区块，这种方式也可以自动收集投票），或者从区块链收集，以确定哪个方案通过。</p>\n<h2>与数据库的交互</h2>\n<p>为了验证更新系统数据，我们必须从全局状态（数据库）获取这些数据。有一个文档详实的类型类 <a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/update/Pos/Update/Poll/Class.hs#L29"><code>MonadPollRead</code></a> 提供这样的接口。这种类型不但用于数据库交互，还用于在处理从网络接收到的数据时将内存池写入账户。非常重要的一点是，它的实现依赖于 <a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/update/Pos/Update/DB.hs"><code>Pos.Update.DB</code></a> 模块中的函数。</p>\n<h2>核心类型</h2>\n<p>核心类型在<a href="/technical/protocols/binary-protocols/">二进制协议</a>文档中提到。这些类型直接反映了研究章节的概念，有关更多信息，请参阅<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/update/Pos/Update/Core/Types.hs">核心类型模块</a>。</p>\n<h2>更新提案批准</h2>\n<p>更新机制实现的一个很重要的部分是创始块的部分。这个逻辑在 <a href="https://github.com/input-output-hk/cardano-sl/blob/6b5eda44e5942599a9781e5ad3f51eb820665b83/src/Pos/Update/Poll/Logic/Softfork.hs#L68"><code>processGenesisBlock</code></a> 中。下面将解释与该过程有关的术语。</p>\n<h3>阈值</h3>\n<p>假设有一个区块版本 <code>X</code>。以及在 slots <code>S</code> 中创建的版本为 <code>X</code> 的区块（其中 <code>S</code> 是一组 slots）。如果所有 slot 的领导者的总相对资产 <code>S</code> ≥ <code>softforkResolutionThreshold</code> (在代码中被称为阈值)，则 <code>X</code> 被采纳。请参阅<a href="/cardano/update-mechanism/#soft-fork-updates">研究概述</a>获取更详细说明。</p>\n<h3>提案状态</h3>\n<p>更新的提案状态可处于下面的状态之一。</p>\n<h4>未定</h4>\n<p>这意味着更新提案被包含在其中一个区块中，但是它没有 <code>50%</code> 的赞成/反对票（这里的 <code>50%</code> 的意义是赞成/反对提案选民总数相对于系统所有权益相关者的总股权），默认赞同规则还没有触发。</p>\n<!-- TODO: **Important remark:** when we are talking about stake, we need to be clear about\nwhich stake distribution we are talking about. For each epoch we know stable distribution\nfor this epoch. It used in leaders selection (follow-the-satoshi) and also in many other\ncases. Stable distribution is distribution as it was \ufeff⁠⁠⁠⁠2k\ufeff⁠⁠⁠⁠ slots before the end of epoch.\nTo calculate stake of votes for proposal \ufeff⁠⁠⁠⁠p\ufeff⁠⁠⁠⁠ we use stake distribution as per epoch in\nwhich \ufeff⁠⁠⁠⁠p\ufeff⁠⁠⁠⁠ was added to blocks. I. e. distribution which was \ufeff⁠⁠⁠⁠2k\ufeff⁠⁠⁠⁠ slots before the\nend of that epoch. This ensures that nobody can transfer his funds to another address\nand vote from that address to increase total stake of voters.\n\n**Another important remark:** when we are talking about stake, it\'s also important to be\nclear whether we consider delegated stake. I. e. if Alice delegated to Bob, do we consider\nthat Alice\'s funds belong to Bob or Alice? When we use stake for votes, we consider delegated\nstake, i. e. we consider that Alice\'s funds belong to Bob. Note that here we consider\nonly heavyweight delegation. I hope it\'s covered in documentation, but I am not sure. -->\n<h4>批准</h4>\n<p>这意味着这个提案有超过 <code>50%</code> 的投票或很久之前加入了区块（根据默认批准规则），赞同的票数比反对的票数更多（与股权比较）。</p>\n<h4>拒绝</h4>\n<p>如果反对该提案的投票超过 <code>50%</code>，或很久之前加入了区块（根据默认批准规则），反对的票数比赞同的票数更多（再次与股权比较）。</p>\n<h4>确认</h4>\n<p>如果至少 <code>k</code> 个区块提案通过，那么这个<strong>批准</strong>的提案被称为<strong>确认</strong>。这时候我们可以确定该提案不会被拒绝。因为深度超过 <code>k</code> 的回滚是不可能的。</p>\n<h4>废弃</h4>\n<p>如果至少 <code>k</code> 个区块提案未通过，那么这个<strong>拒绝</strong>的提案被<strong>废弃</strong>。这时候我们可以确定该提案不会被通过。因为深度超过 <code>k</code> 的回滚是不可能的。</p>\n<h2>下载新版本</h2>\n<p>在 <a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/src/Pos/Update/Download.hs"><code>Pos.Update.Download</code></a> 模块中，实现了以下算法。已下载的更新通过一个叫做 <a href="https://github.com/input-output-hk/cardano-sl/blob/82ba83c3ffb670201b309ff47e3d0ab5f4a17455/src/launcher/Main.hs"><code>cardano-launcher</code></a> 的工具操作。</p>\n<h3>下载更新的版本</h3>\n<p>要下载更新的版本，我们从 <a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/update/Pos/Update/Poll/Types.hs#L114"><code>ConfirmedProposalState</code></a> 提取更新的哈希值。如果更新哈希值成功提取了，则调用『下载更新哈希值』算法以下载保存更新的版本，这取决于我们是否在给定的平台使用安装程序。</p>\n<h3>通过哈希值下载更新</h3>\n<p>为了<a href="https://github.com/input-output-hk/cardano-sl/blob/daa8b81785f38038187c45385c9a94510a5c3780/src/Pos/Update/Download.hs#L108">通过哈希值下载更新</a>，我们会使用 HTTP 中的 <code>httpLBS</code>，遍历已知的更新服务器，用给定的哈希值下载更新。很简单：最后，我们要么完成了更新的下载，要么遍历完服务器清单，上报错误信息。已知更新服务器的 URI 使用 <code>cardano-node</code> 可执行文件的 <code>--update-server</code> 参数定义。</p>',frontmatter:{path:"/cn/technical/updater/",doc_title:"卡尔达诺结算层更新器",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-02-15-pvss.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层中 PVSS 的实现 卡尔达诺结算层使用公开验证密钥共享模式，它基于『SCRAPE：可扩展的随机性公共实体证明』这篇由 Ignacio Cascudo 和 Bernardo David 写的 论文 。接下来我们将引用论文中的页，比如  [6]  表示第…",html:'<!-- Reviewed at 18852484704ff4a7ce3fcac2791499c340eb8e02 -->\n<h1>卡尔达诺结算层中 PVSS 的实现</h1>\n<p>卡尔达诺结算层使用公开验证密钥共享模式，它基于『SCRAPE：可扩展的随机性公共实体证明』这篇由 Ignacio Cascudo 和 Bernardo David 写的<a href="https://eprint.iacr.org/2017/216.pdf">论文</a>。接下来我们将引用论文中的页，比如 <code>[6]</code> 表示第6页。</p>\n<p>本指南介绍了<a href="https://github.com/input-output-hk/cardano-sl/blob/65e295599817ec1f52f225810264d856f882fbb7/core/Pos/Crypto/SecretSharing.hs#L1">卡尔达诺结算层</a>中 <code>pvss-haskell</code> <a href="https://github.com/input-output-hk/pvss-haskell">库</a>的实现细节。</p>\n<h2>什么是 PVSS</h2>\n<p>VSS 模式的核心思想是参与者验证自己的份额，成功构建密钥（之前由参与者中的经销商分发（TODO））的能力。而 PVSS 模式的核心思想是，参与者不仅可以验证其股权，而且任何人都可以验证参与者是否收到了正确的股权。因此（参考我们的重建协议），参与者不仅要发行他们的股权，还要为每个发行的股票提供一个正确地证明(<code>[9]</code>)。（TODO）</p>\n<p>我们使用 <code>t-out-of-n</code> 重建方案(<code>[8]</code>)，其中 <code>n</code> 是参与者的数量，<code>t</code> 是一个阈值。所以任何 <code>t+1</code> 份额的子集可以用来成功恢复密钥。</p>\n<p>所以，协议有四个基本阶段(<code>[8]</code>)组成：</p>\n<ol>\n<li>建立，</li>\n<li>分配，</li>\n<li>验证，</li>\n<li>重建。</li>\n</ol>\n<h2>建立</h2>\n<p>每个参与者 <code>Pi</code> 必须生成器私钥 <code>SKi</code> 并注册其公钥 <code>PKi</code>。</p>\n<h2>分配</h2>\n<p>首先，我们准备一个新的托管环境。要做到这一点，我们需要上面提到的<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L76">阈值</a>和参与者的<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L175">公钥清单</a>。该操作的结果是 <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L120"><code>Escrow</code></a>，它包括：</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L85">额外的生成器</a>，</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/Polynomial.hs#L24">多项式</a>，</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L89">密钥</a>，</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/DLEQ.hs#L39">证明</a>。</li>\n</ol>\n<p>额外的生成器基于一个<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L92">点</a>（<a href="http://hackage.haskell.org/package/cryptonite-openssl-0.6/docs/Crypto-OpenSSL-ECC.html#t:EcPoint">椭圆曲线点</a>）。我们使用 <code>prime256v1</code> 椭圆曲线，参见 <a href="https://www.ietf.org/rfc/rfc5480.txt">RFC</a>。</p>\n<p>多项式是一组从 smallest degree 开始的一组系数（这些系统是<a href="http://hackage.haskell.org/package/cryptonite-0.23/docs/Crypto-PubKey-ECC-P256.html#t:Scalar">标</a>值）。</p>\n<p>密钥也基于一个<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L92">点</a>，实际上它是上面提到的多项式的第一个<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L140">元素</a>。</p>\n<p>证明从<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L142">挑战</a>，<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L140">原始密钥</a>，<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L143">DEEQ-参数生成</a>中<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/DLEQ.hs#L62">生成</a>。</p>\n<p>挑战是基于<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L125">加密哈希</a>。</p>\n<p>之后，我们必须<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L168">完成托管创建</a>。参与者的公共密钥列表被用于<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L202">创建加密股份</a>和<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L202">承诺</a>。加密的股份包括：</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L82">分享 ID</a>，</li>\n<li>通过参与者公钥加密的 <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L99">Value</a>，</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L99">证明</a>这个股份是有效的 (<code>[8]</code>)。</li>\n</ol>\n<h2>验证</h2>\n<p>现在可以在参与者之间发布承诺和加密的股份。由于 PVSS 模式的公共性质，任何知道公共密钥的人都可以通过散列匹配来<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L249">验证加密的股份</a>。</p>\n<h2>重建</h2>\n<p>首先，参与者必须使用<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L84">公钥</a>，<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L80">私钥</a>密钥对<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L230">解密加密的股份</a>。为了获得 DLEQ 的值，我们使用 <code>prime256v1</code> <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L156">曲线生成器</a>。结果，我们得到 <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L109"><code>DecryptedShare</code></a>，其结构与加密股份相同。</p>\n<p>由于解密的股份包含一个证明，所以我们可以确定解密的股份和加密的股份是一样的，并且有<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L260">验证功能</a>。要<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/DLEQ.hs#L74">做到这一点</a>，我们使用 DLEQ 值和来自<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L263">解密股份的证明</a>。实际的验证是 DLEQ 点的<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L146">散列</a>的<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/DLEQ.hs#L77">比较</a>。</p>\n<p>现在，如果我们有 <code>t+1</code> 解密股份，我们可以<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L285">恢复一个密钥</a>。</p>\n<p>恢复的密钥也可以被<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L267">验证</a>。所以我们可以确定恢复的密钥是相同的托管。要做到这一点，我们不仅需要一个证明和一个密钥，还需要<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L268">承诺</a>（实际上是<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L278">第一个</a>）。</p>\n<h2>VSS 证书</h2>\n<p>正如<a href="/cardano/differences/#coin-tossing-and-verifiable-secret-sharing">前面所说的</a>，同时使用 PVSS 方案的挑战之一是相关联的用于与签名的公钥用于 VSS 方案。这是通过引入 <a href="https://github.com/input-output-hk/cardano-sl/blob/f0de5f1dd31cc4afb0c67a24deca713cf6304814/core/Pos/Core/Vss/Types.hs#L46">VSS 证书</a>来解决的。</p>\n<p>VSS 证书包括：</p>\n<ol>\n<li>用于 VSS 方案的公钥（例如 <a href="https://github.com/input-output-hk/cardano-sl/blob/fefc39f058f5a053fc1e59bc3594bdadf7699ca0/core/Pos/Crypto/SecretSharing.hs#L57">VSS 密钥</a>)。</li>\n<li>用于签名的公钥（<a href="https://github.com/input-output-hk/cardano-sl/blob/f0de5f1dd31cc4afb0c67a24deca713cf6304814/core/Pos/Core/Vss/Types.hs#L51">例如签名密钥</a>）。</li>\n<li>过期 epoch 的索引（例如，在 epoch 的最后，证书是有效的）。</li>\n<li>签名对 <code>(A,B)</code>，其中 <code>A</code> 是一个 VSS 键，<code>B</code> 是一个 epoch 索引。</li>\n</ol>\n<p>最初，拥有足够股份参与随机生成的所有权益相关者（我们成为<a href="/glossary/#richman">富人</a>）<a href="https://github.com/input-output-hk/cardano-sl/blob/35c6bff7409472352140f5207a7c79c59d8eaa8f/ssc/Pos/Ssc/GodTossing/Workers.hs#L163">拥有自己的证书</a>。当出现一个拥有足够多股权的新利益相关者时，或者现有证书过期时，应该生成一个新的证书并<a href="https://github.com/input-output-hk/cardano-sl/blob/35c6bff7409472352140f5207a7c79c59d8eaa8f/ssc/Pos/Ssc/GodTossing/Workers.hs#L166">提交给网络</a>。其他节点接受此证书，如果该证书有效并且该节点具有足够的股权。证书存储在区块中。</p>\n<p>请注意 VSS 证书在使用前必须是稳定的。如果我们检索证书的 epoch 是第一个（即有索引 <code>0</code>)，稳定的证书是<a href="https://github.com/input-output-hk/cardano-sl/blob/35c6bff7409472352140f5207a7c79c59d8eaa8f/ssc/Pos/Ssc/GodTossing/Functions.hs#L139">起始证书</a>，否则，稳定的证书是<a href="https://github.com/input-output-hk/cardano-sl/blob/35c6bff7409472352140f5207a7c79c59d8eaa8f/ssc/Pos/Ssc/GodTossing/Functions.hs#L141">最后一个已知 slot 的未到期证书</a>。</p>',
  frontmatter:{path:"/cn/technical/pvss/",doc_title:"卡尔达诺结算层 PVSS",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-01-10-transactions.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层的转账 概要 一个交易（ tx ) 是一组特殊的数据，代表着节点间价值转移的 行为 （从用户的角度来看就是钱包之间价值的转移）。因此，当用户 Alice 汇款给用户 Bob 时，新的交易就产生了。\n让我们称该交易为  Tx1 ，Alice 钱包下的节点称为  N…",html:'<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<h1>卡尔达诺结算层的转账</h1>\n<h2>概要</h2>\n<p>一个交易（<strong>tx</strong>) 是一组特殊的数据，代表着节点间价值转移的<em>行为</em>（从用户的角度来看就是钱包之间价值的转移）。因此，当用户 Alice 汇款给用户 Bob 时，新的交易就产生了。\n让我们称该交易为 <code>Tx1</code>，Alice 钱包下的节点称为 <code>N1</code>，Bob 钱包下的节点称为 <code>N2</code>。</p>\n<p>节点 <code>N1</code> 会执行下面的步骤：</p>\n<ul>\n<li>创建一个 <code>Tx1</code> 交易然后用自己的私钥给交易签名。</li>\n<li>将交易发送给所有节点（也就是相邻节点）。</li>\n<li>将该交易保存到本地的数据中。</li>\n</ul>\n<p><code>N1</code> 的每个相邻节点也会将 <code>Tx1</code> 发送给自己相邻的节点，依次类推。然后某个领导者会将该笔交易放入到账本中的某个区块里面。请注意，如果网络处于高负荷状态，可能需要很长的时间才能让交易真正地加入到某个区块中。</p>\n<h2>设计</h2>\n<p>每个交易都包含了一系列的<em>输入</em>和一系列的<em>输出</em>；交易 <code>Tx0</code> 的输出可以被当用来当做其他如 <code>Tx1</code> 交易的输入，以此类推：</p>\n<pre><code>            Tx0                           Tx1\n  +----------------------+      +----------------------+\n  |                      |      |                      |\n  |  Inputs     Outputs  |      |  Inputs     Outputs  |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  | | In0  |   | Out0  + |      | | In0  |   | Out0  | |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  | | In1  |   | Out1  | |      | | In1  |   | Out1  | |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  | | ...  |   | ...   | |      | | ..   |   | ...   | |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  | | InN  |   | OutM  | |      | | InN  |   | OutM  | |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  |                      |      |                      |\n  +----------------------+      +----------------------+     ...\n</code></pre>\n<p>输入和输出携带着金钱走向的信息：输入告知金钱是从哪里来的，输出告知金钱往哪里去。请注意上面有 N 和 M，是因为实际的情况输入和输出的个数可能并不相同。</p>\n<p>每个输入包括：</p>\n<ul>\n<li>交易 <code>TxN</code> 的 ID，<code>TxN</code> 的输出就是该输入（每笔交易的输出就是另一笔交易的输入）。交易 ID 是一个 BLAKE2b-256 哈希值，就像这样：<code>f9bcbe752aee4512457f1fd350200cf870906b7e6e836688c9a3779645c86c01</code>。  </li>\n<li>在 <code>TxN</code> 的输出中使用的输出的索引。  </li>\n</ul>\n<p>每个输出包括：</p>\n<ul>\n<li>节点 <code>N</code> 的地址，该节点就是我们想要发送价值给它的节点。一个地址就是节点 <code>N</code> 的公钥的 BLAKE2b-224 哈希值，大概像这样：<code>1fsAhhf4E1LQDB8agSds8teuD4E7U8JsRESngEX52kinBhi</code>。请阅读<a href="/cardano/addresses/">卡尔达诺结算层的地址</a>来获取更多信息。</li>\n<li>我们想要汇款的金额。这是一个64位，无符号的整形数字，最大值为 <code>45000000000000000</code>。</li>\n</ul>\n<p>例如：</p>\n<pre><code>  Tx 891971a4cc31e32..                           Tx f9bcbe752aee4512..\n------------------------+           +----------------------------------------------+\n\\                       |           |                                              |\n/        Outputs        |           |       Inputs                  Outputs        |\n\\  +------------------+ |           | +-----------------+     +------------------+ |\n/  | Out0             | |           | | In0             |     | Out0             | |\n\\  | +--------------+ | |           | | +-------------+ |     | +--------------+ | |\n/  | | Value        | | |           | | | Tx id       | |     | | Value        | | |\n\\  | | 100 ADA      | | |           | | | 891971a4c.. | |     | | 100 ADA      | | |\n/  | +--------------+------->>  ------>>+-------------+ |     | +--------------+------->>\n\\  | | Node address | | |           | | | Out index   | |     | | Node address | | |\n/  | | a00e4bb2..   | | |           | | | 0           | |     | | 88ca7f79..   | | |\n\\  | +--------------+ | |           | | +-------------+ |     | +--------------+ | |\n/  | ...              | |           | | ...             |     | ...              | |\n\\  +------------------+ |           | +-----------------+     +------------------+ |\n/                       |           |                                              |\n------------------------+           +----------------------------------------------+\n</code></pre>\n<p>节点 <code>a00e4bb2..</code> 生成交易 <code>f9bcbe752aee4512..</code>，这笔交易告诉我们：</p>\n<ol>\n<li>我们想要从地址为 <code>a00e4bb2..</code> 的当前节点发送100 ADA 到地址 <code>88ca7f79..</code> 节点。  </li>\n<li>这笔钱对应上笔 ID 为 <code>891971a4c..</code> 的交易的第0个输出。</li>\n</ol>\n<h2>验证</h2>\n<p>如上所述，一笔交易的输出会变成另一笔交易的输入。在这种情况下，我们把交易输出称为<em>成交的交易输出</em>。因为它已经是交易 <code>f9bcbe752aee4512..</code> 的输入。</p>\n<p>但这种成交不会立刻发生，一个<em>还未</em>成为其他交易输入的输出称为<em>未成交的交易输出</em>。为了防止<a href="https://en.bitcoin.it/wiki/Double-spending">双重支付</a>，只有未成交的输出才能被用来当做其他交易的输入。</p>\n<p>因此在网络中的每个节点不仅仅接收交易，还会验证它们。为了验证交易，每个节点都必须保持对未成交输出的跟踪，这样就可以验证发布的交易中的输入是未成交的输出。所有未成交的输出叫做 <em>utxo</em>，它也是一个被称为<em>全球状态</em>的特殊键值数据库的一部分。</p>\n<h2>交易合法性的证明</h2>\n<p>在卡尔达诺结算层中的每笔交易都有一个证明（也叫做见证）来表明这笔交易是合法的。即使一个输出是一个未成交的输出，我们也应该有权来让它成交。由于一个 <code>TxN</code> 交易可以有多个输入，那么它的见证就包含了 <code>TxN</code> 中所有输入的见证，如果所有的输入都是合法的，<code>TxN</code> 就是合法的。如果某个交易不是合法的，那么网络就会拒绝这笔交易。</p>\n<p>因为有<a href="/cardano/addresses/#what-does-an-address-look-like">两种可用的节点地址类型</a>，所以我们使用两种对应版本进行验证：基于公钥的和基于脚本的。</p>\n<p>例如，基于公钥的验证使用公钥 <code>PK</code> 和交易签名：合法的输入必须使用与 <code>PK</code> 相对应的私钥进行签名。以此来检查这个签名是被接收了还是被拒绝了。</p>\n<p>验证被存储在区块链中，每个人都可以看见，可以查看，单独验证。但经过一段时间后，节点为了节省空间可能会删除老的证明。分开存储交易和证明被称为『隔离见证』（你可能听到过它，最近在<a href="https://bitcoincore.org/en/2016/01/26/segwit-benefits/">比特币中实现</a>了）。在这种策略下，交易和证明被存储在两个不同的地方，并且可以独立地进行处理。</p>\n<h2>权益分配</h2>\n<p>权益分配是卡尔达诺结算层另一个组成部分，虽然和委派没有直接关系，但都可以通过它来获取相应的利润分红。</p>\n<p>有些地址有多个拥有者，这也产生了一个权益计算的问题。因为追随中本聪算法的每个币对于每个股东的总权益而言只能计数一次。与余额（余额中的真实币数）不同，权益赋予用户控制算法不同部分的权利：成为领导者、投票更新系统、参加 MPC/SSC。</p>\n<p>权益分配关联了每个地址的值。技术上来说该值是地址属性的一部分，该值对应于下面三种情况的某一种：</p>\n<ol>\n<li>Bootstrap 时代分配。这是一个特殊的值，它是 Bootstrap 时代里的受托者，但是它在 Bootstrap 时代之后还可以使用。 </li>\n<li>单密钥分配，这是指所有的权益会被分配给一个指定的股东。在这种分配情况下会包含股东的身份。\n3。 多个密钥分配，这是指权益会被分配给多个股东（至少两个）。在这种分配情况下包含了一对『股东身份-输出部分』的信息。交易的输出有一个值，该值的一部分就是权益。</li>\n</ol>\n<p><a href="http://cardanodocs.com/technical/leader-selection/cn">领导者选举过程</a>和富人计算两者都考虑了权益分配。</p>\n<p>这个特性可以以类似的方式用在<a href="http://cardanodocs.com/technical/delegation/cn">委派</a>中，但是有点区别：</p>\n<ol>\n<li>没有凭证。要撤销委派 <code>A</code> 必须移动资金，提供不同的权益分配。  </li>\n<li><code>A</code> 的部分权益可以通过分配来委托。相反的是，委托需要你同时委托全部地址的资金。</li>\n</ol>',frontmatter:{path:"/cn/cardano/transactions/",doc_title:"转账",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-01-16-updating.cn.md absPath of file >>> MarkdownRemark",excerpt:"更新研究概览 在更新机制研究中，我们设法提出了一个更新系统，它能够进行不影响生产环境的，几乎无缝的软件更新，并为权益所有人提供投票选择硬分叉（向后不兼容的协议更新）的选项，无需引入任何非协议级别的工具。 我们建议使用权益来对软硬分叉进行投票。 更新系统模型 对于 CSL…",html:'<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<!-- Updated at 6b5eda44e5942599a9781e5ad3f51eb820665b83 -->\n<h1>更新研究概览</h1>\n<p>在更新机制研究中，我们设法提出了一个更新系统，它能够进行不影响生产环境的，几乎无缝的软件更新，并为权益所有人提供投票选择硬分叉（向后不兼容的协议更新）的选项，无需引入任何非协议级别的工具。</p>\n<p>我们建议使用权益来对软硬分叉进行投票。</p>\n<h2>更新系统模型</h2>\n<p>对于 CSL，我们决定在协议层本身增加对协议更新的支持。它给区块链处理带来了一些开销，但有几个重要的好处：</p>\n<ol>\n<li>对于每个实现该协议的用户，其最新版本的区块链是已知的。</li>\n<li>没有中央实体负责维护或分发更新，任何此类更新都是在大多数权益的默认或明确同意下提出的，然后以分布式的方式分发。</li>\n<li>我们不依赖客户及时更新 PC 上的软件；这是自动完成的，更新通过区块链直接发布。</li>\n<li>如果在某些版本的 CSL 协议或某些特定实现中检查到任何安全漏洞，将会有一种机制来快速分发更新（仍然在大多数权益的同意下）</li>\n</ol>\n<h2>应用程序更新：签署和宣布</h2>\n<p>这里，我们考虑如何安全地更新应用。协议更新是本文档相关部分涵盖的一个独立问题。</p>\n<p>要进行更新，首先需要批准其提案。至少有一个协议达成，更新提案才能通过。</p>\n<ol>\n<li><strong>明确通过</strong>：它拥有权益的大部分肯定投票（即严格大于 50%）。</li>\n<li><strong>隐式通过</strong>：权益的肯定投票大于否定投票，并且至少在 <code>U</code> 个 slot 的区块链中。</li>\n</ol>\n<p>这个方法似乎自然地适用于 CSL 模型，就像 PoS 加密货币一样。每个权益相关者都负责按照他们股权的相对比例维护系统，区块链则通过权益所有人之间的共识来维持。</p>\n<p>软件更新也是这个维护过程的一部分，所以权益相关者应该考虑这个可信更新。</p>\n<h3>隐式通过</h3>\n<p>权益所有人负责系统更新的事实并不会限制我们每个更新都需要大部分股权签名的系统。我们可以介绍一个<strong>隐式通过</strong>的概念。</p>\n<p>更新必须至少有在区块链发布的权益签名的最小限度（<a href="https://github.com/input-output-hk/cardano-sl/blob/e26ad11397c87ce8b00f2a26d5e237f54d6ea90a/lib/configuration.yaml">configuration.yaml</a> 中的 <code>updateProposalThd</code>）。权益所有人签署更新是不够的，他们应该赞成或反对。</p>\n<h3>接入第三方客户</h3>\n<p>IOHK 将维护一个唯一的官方客户端。但社区维护的第三方客户端也有生存空间。人们需要从权益所有人收集足够多签名来发布他们的系统更新，当然也有可能不是一个『更新』，而是一个从头开始的不同的客户端，或者是官方客户端的一个分支。只要这个更新有足够多的权益所有人的签名，网络就认为它是可信的，可以通过与官方客户端相同的机制进行更新。</p>\n<h2>应用更新：分发和应用</h2>\n<p>IOHK 维护的一系列 HTTP 的镜像足够作为开始。</p>\n<p>在这个过程中，我们计划维护一个基于 Bittorrent 的，或类似 Bittorrent 的解决方案来分发更新。总的来说，基于法律上的考虑，P2P 分发更新是一个至关重要的业务需求。这决定我们将使用哪种类似于 Bittorrent 的解决方案。</p>\n<p>此外，有趣的是，更新本身并不需要安全且可信的通道来分发，因为它已经预先知道了一些已知的可信密钥（或一组密钥）。</p>\n<p>应用更新通过 <a href="https://github.com/mendsley/bsdiff">bsdiff</a> 准备，可以直接或通过安装程序更新。我们正在考虑将来转移到 <a href="http://dev.chromium.org/developers/design-documents/software-updates-courgette">courgette</a>。</p>\n<h2>协议更新</h2>\n<p>首先，我们需要区分软硬协议更新。</p>\n<p>软分叉会修改区块链共识规则，以便新版本仍然与旧版本客户端兼容，硬分叉则不会与旧版本保持向前兼容。</p>\n<p><a href="https://github.com/bitcoin/bips/blob/ed283b05b332b85b6fd683be3a5d73fab6c15554/bip-0099.mediawiki">BIP-99</a> 提供了很好的标准来区分这两种分叉。</p>\n<ul>\n<li>一个<strong>软分叉</strong>引入新的规则，对区块进行限制。这样一来，之前无效的仍然无效，而之前有效的一些区块也会变成无效。 </li>\n<li>硬分叉是一个让之前无效区块变成有效的分叉。</li>\n</ul>\n<p>软分叉具有向后兼容等部署优势，不需要大家的共识，因为大多数用户可以添加新的规则。相比之下，硬分叉需要所有用户升级。</p>\n<p>理论上，硬分叉可能会导致网络分裂为两个部分的情况，每部分都维护一个单独的链：一个来自采用最新系统更新的节点，另一个则来自拒绝这样做的节点。这意味着第一部分的一些区块被另一部分认为是无效的，反之亦然。</p>\n<p>我们将<strong>协议版本定义为一个元组 <code>(Maj, Min, Alt)</code></strong>：</p>\n<ul>\n<li>主版本号（2字节）：很少修改，改变不是向后兼容的，会产生一个硬分叉。</li>\n<li>\n<p>次版本号（2字节）：每个更新需要调整的整数</p>\n<ul>\n<li>更新应该是向后兼容的，因为新版本生成的区块应该被旧版本以某种方式接受。</li>\n<li>一个特定的区块可能包含未知类型的地址。对于这种情况，应该找到一个简洁的解决方法，以免影响系统的稳定性和正确性。</li>\n</ul>\n</li>\n<li>替代版本（1字节）：管理多个同时存在的协议更新版本。</li>\n</ul>\n<p>协议版本将在应用程序更新中公布，稍后将放入到由更新的软件创建的每个区块中。</p>\n<p>主版本号的改变会在将来触发硬分叉的问题。</p>\n<p>次版本的版本更新通知网络后续应用程序更新修改了软分叉的协议。</p>\n<p>替代版本是新功能的标志。它允许独立开发人员向协议引入多个更改。例如，如果一个供应商决定经由软分叉引入特性 X，另一个引入特性 Y（经过软分叉），他们的软件将以版本 <code>a.b.X</code> 和版本 <code>a.b.Y</code> 生成区块，其可以在区块链上共存，但是，最终只有一个会被采纳。</p>\n<h2>软分叉更新</h2>\n<p>在软分叉中，我们可以做什么，不可以做什么，有一条细线：</p>\n<ol>\n<li>老版本的客户端应该总是能找到最近的有效区块。（这是 <a href="https://github.com/bitcoin/bips/blob/ed283b05b332b85b6fd683be3a5d73fab6c15554/bip-0099.mediawiki">BIP-99</a> 所说的『一些无效仍然无效』）</li>\n<li>较旧版本的客户端发出的某些模块可能会被认为是无效的。</li>\n</ol>\n<p>显然，强行推行规则2可能会导致网络分为两部分：一个权益所有人的股份足够大，可以更新，维护自己的链，拒绝其他链，但其他权益所有人还是能够维持链，拒绝这个权益所有人的区块（因为他没有占多数的股份，因此不能追上其他人，所以他的链更短）。一个简单的解决方案规则可能是这样的：如果最新的2016个区块有95%具有较新的区块版本，则旧版本会被拒绝。</p>\n<p><strong>注意</strong>：此处和之后的<strong>区块版本</strong>和协议版本具有相同的含义。</p>\n<p>为什么我们想在某个时刻想让某个块版本无效这一点可能不是很清楚。这里关键的一点是，一个新的功能实际上是对我们之前所做的一个限制。例如，目前我们可能有基于公钥或基于脚本的普通旧提交。然后在某个时候，我们决定包含第三种地址类型（不管目的是什么）。我们使用哪种策略来验证具有未知类型地址的提交的区块？显然唯一的选择是不验证这个地址。</p>\n<p>想象有人提出一个交易到这个地址，可能这么做是带着满足一些条件之前保障资金的意图，一旦条件满足，它们在版本1上的区块花费了其他交易，这是关键的一点。如果网络没有假定旧版本被启用了（因为我们只能在启用旧版本时开始拒绝区块），我们就不能使用限制。（TODO)</p>\n<p>我们也不能接受所有高于目前所采用的区块的区块，因为在我们的实现中，每个区块都有一个专门用于存储辅助信息的字段。攻击者可以生成她使用了更高版本的协议，并生成一个 <code>attributes</code> 被无意义密钥污染的区块。如果我们接受它，它会使我们的区块链变得臃肿。</p>\n<p>这是下面要描述的逻辑的动机。</p>\n<p>在我们实现中，区块版本可以以下面的状态存在：</p>\n<ul>\n<li><strong>已采用</strong>，确认区块版本的软分叉规则被触发了（见下文）</li>\n<li><strong>已确认</strong>，当有包含软件的确认版本和此区块版本的更新提案时。注意，『软件的确认版本』是<a href="/cardano/update-mechanism/#soft-fork-updates">其他地方</a>的技术术语。如果有多个区块版本，相应的软件被确认，但这些版本不被采用，我们称之为竞争。举例来说，有可能有版本 <code>2.0.0</code>, <code>2.0.1</code>, <code>1.2.0</code>, <code>1.2.1</code>, <code>1.1.1</code> 和 <code>1.1.2</code>，最后通过的版本是 <code>1.1.3</code>。在这种情况，那些竞争的版本是 <code>2.0.0</code>, <code>2.0.1</code>, <code>1.2.0</code> 和 <code>1.2.1</code>。旧版本 <code>1.1.1</code> 和 <code>1.1.2</code> 没有竞争，因为 <code>1.1.3</code> 已经被采纳。</li>\n<li>其他情况。举例来说，提出一个新的区块版本，但软件版本没有确认。这种状态没有特殊的名字。</li>\n</ul>\n<p>软分叉的工作原理如下：</p>\n<ul>\n<li>非正式的，当一个确定比例的权益以版本 <code>X</code> 创建区块，区块版本变成<em>已采用</em>。</li>\n<li>正式的，我们做以下事情。首先回顾一下，我们的系统在设计上，不允许回滚超过某个固定的全局阈值 <code>k</code>，这样可以为每个权益所有者确定稳定的股权。当我们处理创始块 <code>e</code> 时，我们从网络的一开始就计算所有 slot 的所有领导者的稳定股权。对于版本 <code>X</code> 的区块当前竞争的版本，我们取所有版本 <code>X</code> 的稳定版本，收集这些领导者的区块，统计他们的股权。如果其中一个版本大于 75%，则被采纳。如果多于一个版本大于 75%，我们采用其中一个（TODO）。</li>\n</ul>\n<p>请注意，采用的区块版本在 epoch 期间（只在 epoch 之间）是不可变的，因此在一个 epoch 中的所有区块都根据相同的规则进行验证（因为规则是由采用的区块版本定义的）。但假设一个 epoch 中的所有区块都具有相同的区块版本是错误的。在采用区块版本之后，另一个区块版本可以竞争，并且一些节点可以使用这个新版本创建区块。</p>\n<p>所以，总结一下：</p>\n<ol>\n<li>一旦确认了更新，协议的版本（比如说 <code>0.5.0</code>）就可以使用了。</li>\n<li>\n<p>该节点的行为<em>已</em>被更新（即可以发出，验证新版本的区块）：</p>\n<ol>\n<li>在软分叉解决之前（即在解析规则被出发之前），使用新版本 <code>0.5.0</code> 发布区块，但不包括任何新的 <code>attributes</code>（如果有的话）。同区块版本 <code>0.4.0</code> 一样验证 <code>0.5.0</code>。</li>\n<li>一旦软分叉解决，发布和验证每个版本为 <code>0.5.0</code> 的区块，包括新的 <code>attributes</code></li>\n</ol>\n</li>\n<li>\n<p>该节点的行为<em>还没有</em>被更新（即不能发出并使用新版本验证模块）：</p>\n<ol>\n<li>软分叉解决之前，发行并验证每个版本为 <code>0.4.0</code> 的区块。除此之外，任何包含未知 <code>attributes</code> 的区块都不会被接受</li>\n<li>一旦软分叉解决，开始接收所有版本为 <code>0.5.0</code> 的区块，包括有未知 <code>attributes</code> 的区块。同时也验证 <code>0.4.0</code> 的版本。</li>\n</ol>\n</li>\n</ol>\n<h2>硬分叉更新</h2>\n<p>硬分叉通过修改后的 PoB（proof of burn）来解决。由于尚未实现，我们从本文中省略本节，并将其作为单独的文档发布。</p>',frontmatter:{path:"/cn/cardano/update-mechanism/",doc_title:"更新机制",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/timeline/2017-01-02-bootstrap.md absPath of file >>> MarkdownRemark",excerpt:"Bootstrap Era After the Cardano SL Testnet era and release of Cardano SL, the network will\noperate in “bootstrap mode” for a period of time…",html:'<!-- Reviewed at c23493d7a33a82d559d5bd9d289486795cf6592f -->\n<h1>Bootstrap Era</h1>\n<p>After the Cardano SL Testnet era and release of Cardano SL, the network will\noperate in “bootstrap mode” for a period of time called Bootstrap era. As people\nwho purchased Ada redeem their coins, the stake will automatically get delegated\nto a pool of trusted nodes that will maintain the network. During this time no\nblock rewards will be issued — we will maintain the network pro bono. This is\nrequired because in order for the protocol to function properly, some of the\nstakeholders who jointly posses majority of stake have to be online, which in\nreality won\'t be the case during the first months of network operation.</p>\n<p>The Bootstrap era will lead to the <a href="/timeline/reward">Reward era</a>, during which\nupdates to the protocol will be issued, and the major stakeholders will be\nprovided with convenient options to run their nodes on personal servers in the\ncloud.</p>\n<h2>Stake Locking</h2>\n<p>The Bootstrap era is the period of Cardano SL existence that allows only fixed predefined\nusers to have control over the system. The set of such users (the bootstrap stakeholders)\nand propotion of total stake each of them controls is defined in genesis block.</p>\n<p>Purpose of Bootstrap era is to address concern that at the beginning of mainnet majority of\nstake will probably be offline (which breaks the protocol at the start). Bootstrap era is to be ended\nwhen network stabilizes and majority of stake is present online.</p>\n<p>The next era after Bootstrap is called <a href="https://cardanodocs.com/timeline/reward/">the Reward era</a>.\nReward era is actually a "normal" operation mode of Cardano SL as a PoS-cryptocurrency.</p>\n<h3>Requirements</h3>\n<ol>\n<li>During Bootstrap era stake in Cardano SL should be effectively delegated to a fixed set of keys <code>S</code>.</li>\n<li><code>S</code> = 7</li>\n<li>Stake should be distributed among <code>s</code> ∈  <code>S</code>.</li>\n<li>\n<p>At the end of Bootstrap era stake should be unlocked:</p>\n<ol>\n<li>Ada buyers should be able to participate in protocol themselves (or delegate their rights to some\ndelegate not from <code>S</code>).</li>\n<li>\n<p>Each Ada buyer should explicitly state she wants to take control over her stake.</p>\n<ul>\n<li>Otherwise it may easily lead to situation when less than majority of stake is online once Reward\nera starts.</li>\n</ul>\n</li>\n<li>Before this withdrawing stake action occurs, stake should be still being controlled by <code>S</code> nodes.</li>\n</ol>\n</li>\n</ol>\n<h3>Proposal</h3>\n<p>Let us now present the Bootstrap era solution:</p>\n<ol>\n<li>Initial <code>utxo</code> contains all the stake distributed among Bootstrap stakeholders. Initial <code>utxo</code>\nconsists of <code>(txIn, txOut)</code> pairs, and every <code>txOut</code> contains an address with stake distribution in it.\nSo we just set distribution in a way it sends all coins to all Bootstrap stakeholders.</li>\n<li>While the Bootstrap era takes place, users can send transactions changing initial <code>utxo</code>. We enforce\nsetting stake distribution for each transaction output to spread stake to Bootstrap stakeholders in. This\neffectively makes stake distribution is system constant.</li>\n<li>\n<p>There is genesis state of heavyweight delegation. It contains pairs <code>(Issuer, ProxySK)</code>, where\n<code>Issuer</code> is an identifier of stakeholder who delegated and <code>ProxySK</code> is a proxy secret key for delegate.\nPlease note that:</p>\n<ul>\n<li>delegate must differ from an issuer in each pair, i. e. no revocations are allowed;</li>\n<li>delegate can\'t be an issuer, i.e. transitive delegation is not supported.</li>\n</ul>\n</li>\n<li>When the Bootstrap era is over, we disable restriction on stake distribution. Bootstrap stakeholders will\nvote for Bootstrap era ending: special update proposal will be formed, where a particular constant\nwill be set appropriately to trigger Bootstrap era end at the point update proposal gets adopted.\nSystem operates the same way as in Bootstrap era, but users need to explicitly state they understand\nowning their stake leads to responsibility to handle the node. To get his stake back user should\nsend a transaction, specifying delegate key(s) in stake distribution. It may be the key owned by user\nhimself or the key of some delegate (which may also be one or few of Bootstrap stakeholders).</li>\n</ol>\n<p>Please read about <a href="/technical/delegation/">Stake Delegation in Cardano SL</a> for more details about\ndelegation mechanism.</p>',frontmatter:{path:"/en/timeline/bootstrap-era/",doc_title:"Bootstrap Era",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"timeline"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-01-06-explorer.md absPath of file >>> MarkdownRemark",excerpt:"Cardano SL Explorer As  mentioned earlier , Explorer is a service for searching\ninformation about  transactions ,\n addresses  and time…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<h1>Cardano SL Explorer</h1>\n<p>As <a href="/cardano/explorer">mentioned earlier</a>, Explorer is a service for searching\ninformation about <a href="/glossary/#transaction">transactions</a>,\n<a href="/glossary/#address">addresses</a> and time periods (<a href="/glossary/#epoch">epochs</a> and\n<a href="/glossary/#slot">slots</a>) in the Cardano network.</p>\n<h2>Explorer Backend Workflow</h2>\n<p>Explorer starts with\n<a href="https://github.com/input-output-hk/cardano-sl/blob/master/explorer/src/explorer/ExplorerNodeOptions.hs">CLI-options</a>.\nAll supported options can be viewed by <code>cardano-explorer --help</code> command.</p>\n<p>Then explorer <a href="https://github.com/input-output-hk/cardano-sl/blob/master/explorer/src/explorer/Main.hs">runs "internal"\nnode</a>\nvia <code>cardano-sl</code> library. So we can think of explorer\'s backend as of a common\nnode with <a href="https://github.com/input-output-hk/cardano-sl/blob/master/explorer/src/explorer/Main.hs#L64">two special\nplugins</a>:\n<code>explorerPlugin</code> and <code>notifierPlugin</code>.</p>\n<p>The first plugin is for serving <a href="https://github.com/input-output-hk/cardano-sl/blob/master/explorer/src/Pos/Explorer/Web/Api.hs">explorer web\nAPI</a>.\nThe second one <a href="https://github.com/input-output-hk/cardano-sl/blob/master/explorer/src/Pos/Explorer/Socket/App.hs#L215">starts notification\nserver</a>.\nThis websocket-based server notifies frontend about changes with\nblocks/transactions.</p>\n<h2>Explorer Backend API</h2>\n<p>Currently, the explorer web API provides a series of methods to obtain\ninformation from the Cardano network. The <code>servant</code> Haskell library that\nprovides a modular approach to API-building is used. This library uses\ncombinators both to build atomic HTTP actions and to glue these atomic methods\ntogether to form larger and more complete APIs.</p>\n<h3>HTTP API</h3>\n<p>Explorer web API is defined\n<a href="https://github.com/input-output-hk/cardano-sl/blob/master/explorer/src/Pos/Explorer/Web/Api.hs">here</a>.\nIf the event requests fail, there is a\n<a href="https://github.com/input-output-hk/cardano-sl/blob/master/explorer/src/Pos/Explorer/Web/Error.hs"><code>ExplorerError</code></a>\ntype, which is simply a wrapper over <code>Text</code> to show what happened.</p>\n<p>Documentation for explorer web API is available\n<a href="https://cardanodocs.com/technical/explorer/api/">here</a>.</p>\n<h3>socket.io API</h3>\n<p>We currently have these events a client can register to:</p>\n<pre><code class="language-haskell">data ClientEvent\n    = Subscribe Subscription\n    | Unsubscribe Subscription\n    | CallMe\n</code></pre>\n<p>A subscription can be to the following events:</p>\n<pre><code class="language-haskell">data Subscription\n    = SubAddr\n    | SubBlockLastPage\n    | SubTx\n</code></pre>\n<p>And the corresponding server events are here:</p>\n<pre><code class="language-haskell">data ServerEvent\n    = AddrUpdated\n    | BlocksLastPageUpdated\n    | TxsUpdated\n    | CallYou\n</code></pre>\n<p>A user can call the desired events and subscribe to them:</p>\n<pre><code class="language-js">var client = require(\'socket.io-client\');\nvar socket = client(\'http://localhost:8110\');\n\nsocket.on(\'CallYou\', function(msg){ console.log(msg); })\nsocket.emit(\'CallMe\', \'test\');\n</code></pre>\n<p>You can also try running purescript repl (<code>pulp psci</code>) and then playing around\nwith the events:</p>\n<pre><code class="language-purescript">import Prelude\nimport Control.SocketIO.Client\nimport Control.Monad.Eff.Console\n\nlet socket = connect "http://localhost:8110"\n\nsocket >>= \\soc -> emit soc "CallYou" "test"\n</code></pre>',frontmatter:{path:"/en/technical/cardano-sl-explorer/",doc_title:"Cardano SL Explorer",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-02-14-leader-selection.md absPath of file >>> MarkdownRemark",excerpt:"Leader Selection in Cardano SL This chapter describes  slot-leader  selection process. Follow the Satoshi As mentioned  earlier , Cardano SL…",html:'<!-- Reviewed at e1d0f9fb37a3f1378341716916f0321fb55698df -->\n<h1>Leader Selection in Cardano SL</h1>\n<p>This chapter describes <a href="/glossary/#slot-leader">slot-leader</a> selection process.</p>\n<h2>Follow the Satoshi</h2>\n<p>As mentioned <a href="/cardano/proof-of-stake/#follow-the-satoshi">earlier</a>, Cardano SL\nuses Follow the Satoshi (FTS) algorithm to choose slot leaders. Leaders for\neach slot of the current epoch are computed by FTS in the beginning of the current\nepoch. So genesis block contains a list of selected slot leaders. The number of\nselected slot-leaders corresponds to a number of slots in epoch, and this number\n<a href="https://github.com/input-output-hk/cardano-sl/blob/5f7b619c6ec9056c6fe778d862c426233af165df/core/Pos/Core/Constants/Raw.hs#L136">depends</a>\non fundamental security parameter <code>k</code> defined in <a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/core/constants.yaml#L10">configuration\nfile</a>.</p>\n<p>FTS uses a <a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/core/Pos/Core/Types.hs#L256">shared\nseed</a>\nwhich is result of <a href="/cardano/proof-of-stake/#multi-party-computation">Multi Party Computation\n(MPC)</a> algorithm for previous\nepoch: in the result of MPC some nodes reveal their seeds, XOR of these seeds is\ncalled <em>shared seed</em>. Actually shared seed <a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/core/Pos/Core/Types.hs#L257">is a bytestring</a>.</p>\n<p>The probability that a stakeholder will be chosen as a slot leader is\nproportional to the number of coins this stakeholder holds. The same stakeholder\ncan be chosen as a leader for multiple slots within an epoch.</p>\n<h2>Algorithm</h2>\n<p>Theoretical aspects of the slot leader selection process is described in\n<a href="/glossary/#paper">paper</a>, page 11.</p>\n<p>The node sorts all unspent outputs (<code>utxo</code>) in a deterministic way\n(lexicographically), so result is an ordered\n<a href="https://github.com/input-output-hk/cardano-sl/blob/1f866450a8a530c119e3fc9edb84c97c56417aa2/src/Pos/Genesis.hs#L177">sequence</a>\nof pairs <code>(StakeholderId, Coin)</code>, where <code>StakeholderId</code> is an id of stakeholder\n(its public key hash) and <code>Coin</code> is an amount of coins this stakeholder has.\nIt\'s assumed that <code>utxo</code> <a href="https://github.com/input-output-hk/cardano-sl/blob/1f866450a8a530c119e3fc9edb84c97c56417aa2/src/Pos/Lrc/FtsPure.hs#L52">isn\'t\nempty</a>.</p>\n<p>Then the node chooses several random <code>i</code>s between <code>1</code> and <a href="https://github.com/input-output-hk/cardano-sl/blob/1f866450a8a530c119e3fc9edb84c97c56417aa2/src/Pos/Lrc/FtsPure.hs#L49">amount of Lovelaces\nin the system</a>.\nTo find owner of <code>i</code>-th coin node finds the lowest <code>x</code> such that sum of all coins\nin this list up to \'i\'-th is not less than \'i\' (and then \'x\'-th address is the\nowner of <code>i</code>-th coin).</p>\n<p>The result is a non-empty sequence of <code>StakeholderId</code>, ids of selected stakeholders.\nThis sequence of <a href="https://github.com/input-output-hk/cardano-sl/blob/5f7b619c6ec9056c6fe778d862c426233af165df/core/Pos/Core/Types.hs#L264"><code>SlotLeaders</code></a>\nis storing in the <a href="https://github.com/input-output-hk/cardano-sl/blob/da70b2597aab352d7574a3946a366395b09e97eb/node/src/Pos/Context/Context.hs#L94">node\'s runtime\ncontext</a>.</p>\n<p>With P2SH addresses, node doesn\'t know who is going to end up with funds sent to\nthem. Therefore, P2SH addresses can contain destination address which specifies\nwhich addresses should count as “owning” funds for the purposes of FTS.</p>',frontmatter:{path:"/en/technical/leader-selection-in-cardano-sl/",doc_title:"Leader Selection in Cardano SL",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-01-02-launcher.md absPath of file >>> MarkdownRemark",excerpt:"Cardano SL Launcher Overview An executable\n cardano-launcher \nis a tool for launching Cardano SL. It actually runs the whole Cardano SL…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<h1>Cardano SL Launcher</h1>\n<h2>Overview</h2>\n<p>An executable\n<a href="/technical/cli-options/#cardano-launcher"><code>cardano-launcher</code></a>\nis a tool for launching Cardano SL. It actually runs the whole Cardano SL system\n(i.e. a node, a wallet) and handles updates. To do this, <code>cardano-launcher</code> uses two\nseparate tools: <a href="/technical/cli-options/#cardano-node"><code>cardano-node</code></a> and\n<a href="https://github.com/input-output-hk/cardano-updater"><code>cardano-updater</code></a>.</p>\n<p>Please see <a href="/technical/cli-options/#cardano-launcher"><code>cardano-launcher</code>\'s description</a>\nfor detailed information about available options.</p>\n<h2>Scenarios</h2>\n<p>There are two work scenarios for <code>cardano-launcher</code>: client scenario and server scenario.\nIf you provide a path to the wallet (e.g. Daedalus) using <code>--wallet</code> argument during\nstart, <code>cardano-node</code> will run in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L178">client</a>\nscenario, otherwise it will run in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L171">server</a>\none.</p>\n<h3>Server Scenario</h3>\n<p>After the start, there are 2 steps:</p>\n<ol>\n<li>Running an updater.</li>\n<li>Running a node.</li>\n</ol>\n<p>Updater\'s work is explained <a href="#updater">below</a>.</p>\n<p>A node is <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L280">spawning as a separate\nprocess</a>.\nAfter that we just <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L201">wait until the node\nstops</a>.\nAfter a node exits, its exit code is checked. If it equals <code>20</code>, we <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L204">restart the\nlauncher</a>,\notherwise we quit.</p>\n<p>Log info can be <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L207">written to the log file</a> before quitting. To do it, we must\nprovide two additional arguments during launcher\'s start: <code>--report-server</code> and\n<code>--node-log</code>. The first argument defines an URL of the report server, the second\none defines a path to the log file. We asynchronously <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L343">send log info to the\nreport server</a>.\nPlease note that the file from the <code>--node-log</code> argument must exist.</p>\n<h3>Client Scenario</h3>\n<p>As the process starts, there are 3 steps:</p>\n<ol>\n<li>Running an updater.</li>\n<li>Running a node.</li>\n<li>Running a wallet.</li>\n</ol>\n<p>For steps 1 and 2, see <a href="#server-scenario">Server Scenario</a> above.</p>\n<p>The wallet is <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L227">spawning as a separate\nprocess</a>.</p>\n<p>After that, we <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L228">wait until node or wallet\nstops</a>.\nWhen it stops, we check it:</p>\n<ol>\n<li>If the node exits, we write a log (see <a href="#server-scenario">Server Scenario</a>\nabove for explanations) and <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L235">wait for the wallet\'s\ndeath</a>.</li>\n<li>If the wallet exits, we check the exit code, and if it equals <code>20</code>, we\n<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L242">kill the node</a>\nand <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L244">restart the launcher in the client\nscenario</a>.\nPlease note that killing the node isn\'t executed immediately; the node is\nkilled after some timeout, and its value is obtained from the\n<code>--node-timeout</code> argument mentioned above.</li>\n<li>If the wallet exits <em>and</em> exit code isn\'t equal to <code>20</code>, we\n<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L250">kill the node</a>\nimmediately.</li>\n</ol>\n<h2>Updater</h2>\n<p>Another important thing <code>cardano-launcher</code> does is updating a node. The first\nstep in both scenarios is <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L255">running an\nupdater</a>.</p>\n<p>The core idea is very simple. The node update is a special <code>.tar</code>-archive: it\nrepresents the <em>difference</em> between the old (current) version of the node and a\nnew version of it. A path to this archive is obtained via <code>--update-archive</code>\nargument. So, <code>cardano-updater</code> applies this archive to the node, and after\nrestart a new version of the node can be used.</p>\n<p>Please note that when we run <code>cardano-launcher</code> in the client scenario, a wallet\'s\nuser is able to see that an update is ready, and there are two situations\npossible.</p>\n<p>If a user <em>agrees</em> to apply this update, the wallet exits immediately with an\nexit code <code>20</code>. In this case, as described above, launcher restarts the node and\nthe update is applied.</p>\n<p>If a user <em>doesn\'t agree</em> to apply this update, the wallet continues working.\nBut when it <em>is</em> restarted (sooner or later), that update <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L223"><em>will</em> be applied</a>.</p>\n<p><strong>Important</strong>: the updater runs synchronously, we start it and then <a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L269">wait for it to\nfinish</a>.\nIf the updater finishes its work\n<a href="https://github.com/input-output-hk/cardano-sl/blob/194f4876d7b72766f7fe72ed4a1fba828903cae0/src/launcher/Main.hs#L271">successfully</a>,\nthe<code>.tar</code>-archive is deleted.</p>\n<h3>Implementation Overview</h3>\n<p>For more implementation details about Cardano SL Update system please see <a href="/technical/updater/">this chapter</a>.</p>',
  frontmatter:{path:"/en/technical/cardano-sl-launcher/",doc_title:"Cardano SL Launcher",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-05-15-wallet-backend.md absPath of file >>> MarkdownRemark",excerpt:"Cardano SL Wallet Backend While addresses discussed in  Addresses  section are\nfundamental to send and receive funds, wallets are a way to…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<h1>Cardano SL Wallet Backend</h1>\n<p>While addresses discussed in <a href="/cardano/addresses/">Addresses</a> section are\nfundamental to send and receive funds, wallets are a way to simplify these\nprocesses for end-users.</p>\n<h2>What is a Wallet?</h2>\n<p>In Cardano, wallets are defined in the following manner:</p>\n<pre><code class="language-haskell">data CWallet = CWallet\n    { cwId       :: !CWalletAddress\n    , cwMeta     :: !CWalletMeta\n    , cwAccounts :: ![CAccount]\n    , cwAmount   :: !CCoin\n    }\n</code></pre>\n<p>where <code>CWalletMeta</code> is a type that presently indicates whether the wallet is\nshared or personal, the currency that this wallet uses, and the wallet\'s name.\nWith this, the wallet type is easily extensible, as any additional features can\nbe added to the <code>CWalletMeta</code> type, leaving other fields untouched. Every\nwallet, regardless of name, type and currency, must have the said fields.</p>\n<h2>Transactions and Wallets</h2>\n<p>In the <a href="/cardano/transactions/">Transactions</a> section, the structure of\ntransactions is defined. However, to facilitate client operations, transactions\nare represented differently in clients. They are represented as</p>\n<pre><code class="language-haskell">data CTx = CTx\n    { ctId            :: CTxId\n    , ctAmount        :: CCoin\n    , ctConfirmations :: Word\n    , ctMeta          :: CTxMeta\n    , ctInputAddrs    :: [CAddress Acc]\n    , ctOutputAddrs   :: [CAddress Acc]\n    }\n</code></pre>\n<p>Essentially, a client transaction is composed by the actual transaction <code>Id</code>, by\nthe amount the wallet in question received, the number of confirmations this\ntransaction has received (i.e., the number of blocks that are currently on top\nof the block containing the transaction in question), input and output\naddresses. Meta-information - the datatype <code>CTxMeta</code> - indicates the\ntransaction\'s currency, its title or name, its description and the\nPOSIX-formatted date of sending it.</p>\n<h2>Wallet Backend API</h2>\n<p>Currently, the wallet\'s API provides a series of methods to work with wallets.\nThe <code>servant</code> Haskell library that provides a modular approach to API-building\nis used. This library uses combinators both to build atomic HTTP actions and to\nglue these atomic methods together to form larger and more complete APIs.</p>\n<p>The wallet web API is enabled by default. It uses the <code>IP:PORT</code> specified with a\n<code>--wallet-address</code> option (defaults to: <code>127.0.0.1:8090</code>).</p>\n<p>Documentation for wallet web API is available\n<a href="/technical/wallet/api/v0">here</a>.</p>\n<h3>TLS Connections</h3>\n<p>The Wallet Web API uses TLS for secure communication. Calls to the API need\nto send a client CA certificate that was used when launching the node and\nidentifies the client as being permitted to invoke the server API.</p>\n<p>Note that the client certificate file is the one which was supplied as the\n<code>--tlsca</code> option, when launching the node.</p>\n<p>For example, If that file is available as <code>ca.crt</code>, then a curl call to a node\nrunning on <code>localhost:8090</code> can be made like so -</p>\n<pre><code class="language-bash">curl --cacert ca.crt -v https://localhost:8090/api/settings/sync/progress\n</code></pre>\n<p>If that request succeeds, then you have configured TLS properly.</p>\n<h3>Handling errors</h3>\n<p>If the event requests fail, there is a <code>WalletError</code> type, which is simply a\nwrapper over <code>Text</code> to show what happened.</p>',frontmatter:{path:"/en/technical/cardano-sl-wallet-backend/",doc_title:"Cardano SL Wallet Backend",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-05-16-specification-wallet-backend.md absPath of file >>> MarkdownRemark",excerpt:"Formal specification for a Cardano wallet This document is a formal specification of a wallet for Cardano (or any UTxO-based cryptocurrency…",html:'<h1>Formal specification for a Cardano wallet</h1>\n<p>This document is a formal specification of a wallet for Cardano (or any UTxO-based cryptocurrency). The purpose is to help understand some of the subtleties and give a reasonable starting point for tests and implementations.</p>\n<p>To the best of our knowledge, no other existing cryptocurrency wallet comes with such a formal specification. We have therefore attempted to formalise the core functionality of the existing wallet and let our knowledge of the difficulties with the current implementation be a guide in deciding which aspects of the wallet needed more careful thought. We also state and (partially) prove various properties of the wallet models we develop, not only to prove its correctness but also to try and capture our intuitions about what a cryptocurrency wallet is, exactly.</p>\n<p><a href="/files/formal-specification-of-the-cardano-wallet.pdf" target="_blank"><img src="/img/formal-specification-of-the-cardano-wallet4.jpg" alt="" /></a></p>',frontmatter:{path:"/en/technical/formal-specification-for-a-cardano-wallet/",doc_title:"Formal specification for a Cardano wallet",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-05-16-wallet-frontend.md absPath of file >>> MarkdownRemark",excerpt:"Cardano SL Wallet Frontend When developing Cardano SL, the need arose for a UI from which users could\naccess their funds, send and receive…",html:'<!-- Reviewed at cd26fb28eb48f893a4ca2d045a10da19c211b807 -->\n<h1>Cardano SL Wallet Frontend</h1>\n<p>When developing Cardano SL, the need arose for a UI from which users could\naccess their funds, send and receive transactions, and perform other tasks\nrelated to managing a personal cryptocurrency wallet. The Daedalus wallet is the\nCardano\'s solution to these necessities.</p>\n<p>Currently, it allows a user to use their ADA in the aforementioned actions, and\nproviding support for other currencies is planned for the near future — as is\nthe exchange between different currencies, both digital and not.</p>\n<h2>Building Daedalus client API</h2>\n<p>To run Daedalus client API locally, you have to start <a href="https://github.com/input-output-hk/cardano-sl/"><code>cardano-sl</code></a>\nwith wallet API as follows.</p>\n<p>Please make sure that you are in the root directory of <code>cardano-sl</code> repository.\nAlso make sure you have <a href="https://www.npmjs.com/">npm</a> program.</p>\n<h2>Running and testing Daedalus client API</h2>\n<p>In order to see Daedalus client API in action, first run a local Cardano SL network:</p>\n<pre><code class="language-bash"># run tmux in another window\n$ tmux\n# launch nodes\n$ ./scripts/launch/demo-with-wallet-api.sh\n</code></pre>\n<p>By default, this should launch Cardano SL network consisting of 3 nodes talking to\neach other. One node is running wallet API, and it will behave the same as Daedalus\nwallet that is run in production.</p>\n<h2>Notify websockets</h2>\n<p>We can test the websockets with a small utility\napplication(<code>npm install -g wscat</code>):</p>\n<pre><code class="language-bash">> wscat -c ws://127.0.0.1:8090\n\nconnected (press CTRL+C to quit)\n\n&#x3C; {"tag":"ConnectionOpened"}\n\n&#x3C; {"tag":"NetworkDifficultyChanged","contents":{"getChainDifficulty":1}}\n&#x3C; {"tag":"LocalDifficultyChanged","contents":{"getChainDifficulty":1}}\n&#x3C; {"tag":"NetworkDifficultyChanged","contents":{"getChainDifficulty":2}}\n&#x3C; {"tag":"LocalDifficultyChanged","contents":{"getChainDifficulty":2}}\n&#x3C; {"tag":"NetworkDifficultyChanged","contents":{"getChainDifficulty":3}}\n&#x3C; {"tag":"LocalDifficultyChanged","contents":{"getChainDifficulty":3}}\n&#x3C; {"tag":"NetworkDifficultyChanged","contents":{"getChainDifficulty":4}}\n&#x3C; {"tag":"LocalDifficultyChanged","contents":{"getChainDifficulty":4}}\n</code></pre>\n<p>We should be seeing the same changes manually from here:</p>\n<pre><code class="language-bash">curl http://localhost:8090/api/settings/sync/progress\n</code></pre>\n<p>Account should be renamed into address. Please see an issue\n<a href="https://issues.serokell.io/issue/CSM-249">CSM-249</a> for details.</p>\n<h2>Wallet events</h2>\n<p>Aside from these HTTP endpoints, there is one unidirectional websocket channel\nopened from server to client, the <code>notify</code> endpoint.</p>\n<p>This channel serves as a notification system so that Daedalus UI can be informed\nabout events. Currently supported events are:</p>\n<ul>\n<li><code>LocalDifficultyChanged</code> - local blockchain height,</li>\n<li><code>NetworkDifficultyChanged</code> - global blockchain height,</li>\n<li><code>UpdateAvailable</code> - new system update available,</li>\n<li><code>ConnectedPeersChanged</code> - number of peers connected to the node changed,</li>\n<li><code>ConnectionOpened</code> - websocket connection opened,</li>\n<li><code>ConnectionClosed</code> - websocket connection closed.</li>\n</ul>\n<p>As this channel is unidirectional, any message sent to the channel from the\nclient will be ignored.</p>',frontmatter:{path:"/en/technical/cardano-sl-wallet-frontend/",doc_title:"Cardano SL Wallet Frontend",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-05-14-hd-wallets.md absPath of file >>> MarkdownRemark",excerpt:"HD wallets Hierarchical Deterministic (HD) wallets allow users to derive keys from a\ncommon seed making backup easier and allowing for new…",html:'<!-- Reviewed at 866fd6a29a15c503e54426f17b91bd8b0903c5dc -->\n<h1>HD wallets</h1>\n<p>Hierarchical Deterministic (HD) wallets allow users to derive keys from a\ncommon seed making backup easier and allowing for new wallet features and privacy\nimprovements.</p>\n<h2>How it works</h2>\n<p>Basically, you generate an initial secret key <code>SK₀</code> from a\nrandom seed. Then you can derive child keys <code>SK₀-₀</code>, <code>SK₀-₁</code> from <code>SK₀</code>. From\nthese children, you can derive <code>SK₀-₀-₀</code>, <code>SK₀-₀-₁</code>, <code>SK₀-₁-₀</code> and so on\n(derivations for a tree of arbitrary depth).</p>\n<!-- For subscripts and other symbols: https://help.ubuntu.com/community/ComposeKey -->\n<p>We distinguish two types of keys:</p>\n<ul>\n<li><strong>Hardened</strong></li>\n<li><strong>Non-hardened</strong></li>\n</ul>\n<p>The only distinction here is that <strong>hardened</strong> keys allow only generation of\nchild secret keys from parent secret keys. Thus, to derive a child key for\na hardened key, you have to own the private key. <strong>Non-hardened</strong> keys allow one to\nderive a child public key from a parent public key (without requiring access to the secret key).</p>\n<p>Each child is assigned a 4-byte index <code>i</code>:</p>\n<ul>\n<li><code>i ≤ 2³¹ - 1</code> for <strong>non-hardened</strong> keys,</li>\n<li><code>i > 2³¹ - 1</code> for <strong>hardened</strong> keys.</li>\n</ul>\n<h2>Properties:</h2>\n<ol>\n<li>Metadata to reconstruct the tree is stored as part of the root address.</li>\n</ol>\n<h2>Root Address format</h2>\n<p>We start with a <code>PublicKey</code> type <a href="/cardano/addresses/">address</a> and add a new field for additional attributes.\nThe attribute indexed by <code>0</code> (<strong>HD wallets attribute</strong>) is used to store tree\ndata in the form of <strong>derivation paths</strong>. Each <strong>derivation path</strong> is\nspecified as a list of <strong>derivation indices</strong>. Each <strong>derivation index</strong> is 4-byte\nunsigned int.</p>\n<p>The resulting object is serialized and encrypted with the symmetric scheme\n(<a href="https://en.wikipedia.org/wiki/Salsa20#ChaCha_variant">ChaChaPoly1305</a> algorithm) using the passphrase computed from the SHA-512 hash of the\nroot public key. This will not allow an adversary to map all child addresses on the chain to\ntheir root as long as we do not actually store any funds on the root key (which\nis not forced by consensus rules, rather by UI).</p>\n<p><strong>Crucial point in wallet design:</strong> root public keys are not used to actually store\nmoney.</p>\n<h2>Use cases</h2>\n<h3>Financial audit</h3>\n<p>An auditor requires only the hash of a root public key in order to view all\nkeys / addresses in the hierarchy.</p>\n<h3>Payment server</h3>\n<p><em>This is applicable for <strong>non-hardened</strong> keys only.</em></p>\n<p>For a payment server to be able to derive subsequent addresses for receiving\npayments, one of the following is required on the server:</p>\n<ul>\n<li>Root public key</li>\n</ul>\n<p>Or</p>\n<ul>\n<li>\n<p>Payload of:</p>\n<ul>\n<li>\n<p>Public key <code>PK</code> of level <code>i</code></p>\n</li>\n<li>\n<p>Hash of root public key</p>\n</li>\n<li>\n<p>Tree path for <code>PK</code></p>\n</li>\n</ul>\n</li>\n</ul>\n<h3>Wallet</h3>\n<p>For a wallet to operate over some subtree, one needs to provide either:</p>\n<ul>\n<li>Root secret key</li>\n</ul>\n<p>Or</p>\n<ul>\n<li>\n<p>Payload of:</p>\n<ul>\n<li>\n<p>Secret key <code>SK</code> of level <code>i</code></p>\n</li>\n<li>\n<p>Hash of root public key</p>\n</li>\n<li>\n<p>Tree path for <code>SK</code></p>\n</li>\n</ul>\n</li>\n</ul>\n<h2>Requirements</h2>\n<p>Let <code>A(K)</code> denote the address that holds information about keypair <code>K</code>. Let\n<code>child(K, i)</code> denote the <code>i</code>-th child keypair of <code>K</code>. Let <code>tree(K)</code> denote the\ntree of addresses for keypairs, derived from <code>K</code> (and having positive balance)\nand held in <strong>utxo</strong>.</p>\n<p><code>a -> b</code> denotes <code>b</code> is derivable from <code>a</code>. <code>a -x b</code> denotes that <code>b</code> can not be derived from <code>a</code>:</p>\n<pre><code>priv(K) -> pub(K)\npub(K) -> A(K)\npub(K) -x priv(K)\nA(K) -x pub(K)\nA(K) -x A(child(K, i))\n</code></pre>\n<p>For <strong>hardened</strong> keys:</p>\n<pre><code>(priv(K), utxo) -> tree(K)\npub(K) -x pub(child(K, i))\npriv(K) -> priv(child(K, i))\n</code></pre>\n<p>For <strong>non-hardened</strong> keys</p>\n<pre><code>(pub(K), utxo) -> tree(K)\npub(K) -> pub(child(K, i))\npriv(K) -> priv(child(K, i))\n</code></pre>\n<h2>Derivation Crypto Interface</h2>\n<h3>Notation:</h3>\n<ul>\n<li>\n<p><code>kp</code> denotes a private key with index <code>p</code>. Just an <strong>Ed25519</strong> private key.</p>\n</li>\n<li>\n<p><code>Kp</code> denotes public key with index <code>p</code>. Just an <strong>Ed25519</strong> public key.</p>\n</li>\n<li>\n<p><code>cp</code> denotes chain code with index <code>p</code>.</p>\n</li>\n</ul>\n<h3>Entropy</h3>\n<p>Bitcoin uses a 512-bit hash, but <code>kp</code> is only 256 bit. For this reason we need\nto supply 512 bits of entropy, so we do not reduce hashing space.</p>\n<ul>\n<li>\n<p>Extended private key is a pair denoted as <code>(ki, ci)</code>.</p>\n</li>\n<li>\n<p>Extended public key is a pair denoted as <code>(Ki, ci)</code>.</p>\n</li>\n</ul>\n<p>From application perspective, HD wallets (as defined in <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">BIP-32</a>) introduce following crypto primitives:</p>\n<ul>\n<li>\n<p><code>CKDpriv :: ((kpar, cpar), i) → (ki, ci)</code></p>\n<p>Computes a child extended private key from the parent extended private key.</p>\n</li>\n<li>\n<p><code>CKDpub :: ((Kpar, cpar), i) → (Ki, ci)</code></p>\n<p>Computes a child extended public key from the parent extended public key.</p>\n</li>\n</ul>\n<h1>Daedalus HD wallets</h1>\n<p>This section describes how HD wallets are used. It is\nsplit into two parts:</p>\n<ol>\n<li>\n<p>Extension of wallet backend API to support HD wallet structure locally (as\nimplemented in Bitcoin).</p>\n</li>\n<li>\n<p>Extension to blockchain handling to utilize new address attribute to keep HD\nstructure of multiple wallet clients in sync.</p>\n</li>\n</ol>\n<h2>Local storage</h2>\n<h3>Old storage</h3>\n<p>The old wallet stored a simple list of addresses. Each address was associated with a name\nand was derived from separate secret key (backed up by mnemonics and encrypted\nwith the spending password).</p>\n<h3>New storage</h3>\n<p>Wallet storage is extended to store a list of <strong>wallets</strong>. Each wallet corresponds\nto a single root secret key (backed up by mnemonics and encrypted with spending\npassword).</p>\n<p>Each wallet contains a number of <strong>accounts</strong>.</p>\n<p>Each account contains a number of <strong>addresses</strong> (i.e. an address is a key of the\n2nd level in a HD tree).</p>\n<p>This maps to a HD tree:</p>\n<ul>\n<li>\n<p>wallet set corresponds to key of 0-th level (<em>root</em>),</p>\n</li>\n<li>\n<p>wallet corresponds to key of 1-th level (children of root),</p>\n</li>\n<li>\n<p>address corresponds to key of 2-th level (grandchildren of root).</p>\n</li>\n</ul>\n<p>Funds are kept only on addresses.</p>\n<p>When funds are spent from one or more addresses, a new one is generated\nto receive the change (unspent coins) from the payment.</p>\n<h3>Usability</h3>\n<p>A user is able to:</p>\n<ul>\n<li>\n<p>import/export an arbitrary number of <strong>wallets</strong>,</p>\n</li>\n<li>\n<p>generate an arbitrary number of <strong>accounts</strong>,</p>\n</li>\n<li>\n<p>assign names to <strong>wallets</strong> and <strong>accounts</strong>,</p>\n</li>\n<li>\n<p>generate an arbitrary number of <strong>addresses</strong>,</p>\n</li>\n<li>\n<p>change <strong>wallet</strong> spending password.</p>\n</li>\n</ul>\n<h2>Backup and restore</h2>\n<p>There are two ways of backing up a wallet:</p>\n<ul>\n<li><strong>mnemonics</strong>: 24 words which allow the wallet to later regenerate all required keypairs. Names will not be restored however.</li>\n<li>Wallet backup file: will restore the whole wallet structure with names.</li>\n</ul>\n<h3>Import</h3>\n<p>In both cases we have a secret root key which can be used to regenerate the wallet using the following procedure:</p>\n<ul>\n<li>\n<p>Root key is checked to be absent from local storage.</p>\n</li>\n<li>\n<p>The <strong>utxo set</strong> is traversed to find all addresses with a non-zero balance\ncorresponding to each derived keypair and add them to storage along with their\nparent wallets.</p>\n</li>\n<li>\n<p>In case of file import, the structure that resulted from step 2 is additionally labeled with\nnames (if they exist in the backup file).</p>\n</li>\n</ul>\n<h3>New transaction handling</h3>\n<p>When a new transaction becomes available (appears either in block or in the mempool),\nit will be analyzed to see if it modifies outputs associated with addresses belonging to a wallet we own. If it does, the address and balance is shown in the\nuser interface.</p>',frontmatter:{path:"/en/technical/hd-wallets/",doc_title:"HD wallets",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/plutus/2017-01-01-introduction.cn.md absPath of file >>> MarkdownRemark",excerpt:"Plutus 介绍 Plutus 是用于在 Cardano 中定义智能合约的严格类型的纯函数式编程语言。语法相当像 Haskell，但与 Haskell 不同的是， (TODO) 声明数据类型 在 Plutus…",html:"<!-- Reviewed at f766612fb6c75b941cbe3c2d9c2db17dd2dc9bd3 -->\n<h1>Plutus 介绍</h1>\n<p>Plutus 是用于在 Cardano 中定义智能合约的严格类型的纯函数式编程语言。语法相当像 Haskell，但与 Haskell 不同的是， (TODO)</p>\n<h2>声明数据类型</h2>\n<p>在 Plutus 中，为定义一个数据类型，我们给出类型的名称，然后是任何类型参数，然后是一系列的构造参数 - 就像 Haskell 中的那样，每个构造函数都有其参数的类型。</p>\n<p>所以，例如， Peano 的数字的类型被定义为</p>\n<pre><code>data Nat = { Zero | Suc Nat }\n</code></pre>\n<p>而二叉树被定义为</p>\n<pre><code>data Tree a = { Leaf | Branch (Tree a) a (Tree a) }\n</code></pre>\n<p><code>Tree</code> 类型的结构接受一个参数 <code>a</code>。它有两个构造函数构造的值，<code>Leaf</code> 没有参数，并且 <code>Branch</code> 有三个子树，一个左子树 <code>Tree a</code>，类型是 <code>a</code>，一个右子树，<code>Tree a</code>。</p>\n<p>我们可以用 <code>case</code> 结构来查看数据，如下所示：</p>\n<pre><code>case t of {\n  Leaf -> ... ;\n  Branch l x r -> ...\n}\n</code></pre>\n<h2>声明值</h2>\n<p>要声明一个新的值（不管它是否是函数），我们提供它的类型，然后指定它的值。例如，要定义自然数的加法，我们可以使用下面的递归定义 <code>case</code>：</p>\n<pre><code>add : Nat -> Nat -> Nat {\n  add = \\m n ->\n    case m of {\n      Zero -> n ;\n      Suc m' -> Suc (add m' n)\n    }\n}\n</code></pre>\n<p>我们也可以像 Haskell 中那样使用模式匹配，这使得这样的函数定义更加优雅：</p>\n<pre><code>add : Nat -> Nat -> Nat {\n  add Zero n = n ;\n  add (Suc m) n = Suc (add m n)\n}\n</code></pre>\n<h2>智能合约计算</h2>\n<p>Plutus 在智能合约计算专用语言中有一个重要类型：类型构造函数 <code>Comp</code>，它带有一个类型参数。创建值最简单的方法是使用两个计算构造函数 <code>success</code>，<code>M</code> 值使用类型 <code>A</code>（任何 <code>A</code> 的选择），并生成一个 <code>Comp A</code> 代表成功的返回 <code>M</code> 的智能合约类型计算结果。你也可以构造一个返回错误的 <code>Comp A</code> 类型，表明一个失败的计算结果。</p>\n<p>同样可以使用 <code>do</code> 符号将智能合约计算连接在一起。给定一个 <code>Comp A</code> 类型的 <code>A</code>，以及有着变量 <code>x</code> 的类型 <code>A</code>，我们可以形成 <code>do { x &#x3C;- M ; N }</code> 运行计算 <code>M</code>，绑定它的返回值 <code>X</code>，然后运行计算 <code>N</code>。如果这个 <code>M</code> 计算结果是 <code>failure</code>，那么这个失败就会被这个 <code>do</code> 结构传播，整个事务就被计算为 <code>failure</code>。</p>\n<p>这对于构建只能合约的验证器脚本非常有用。这么做的标准方式是要求一个 <code>Comp A</code> 类型的赎回程序和一个 <code>A -> Comp B</code> 类型的验证程序，然后组成一个 <code>do { x &#x3C;- redeemer ; validator x }</code> 类型的验证程序。该 <code>redeemer</code> 运行时的时候，不管 <code>validator</code> 需要什么数据都返回给它，<code>validator</code> 都会运行。</p>\n<h2>更详细的概述</h2>\n<p>Plutus 部分的其他章节提供了对 Plutus 的语法，类型和程序的更详细的概述，包括内置的类型和功能，在深入编写程序前应该阅读。还有一个演示文件，展示了一些常用函数的实现，一遍可以更好地理解该语言的使用。</p>",frontmatter:{path:"/cn/technical/plutus/introduction/",doc_title:"介绍",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical-plutus"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/plutus/2017-01-03-examples.cn.md absPath of file >>> MarkdownRemark",excerpt:"Plutus 例子（TODO） 这里，我们看看一些常见的程序示例，让您更好地了解 Plutus 语言的工作原理。我们将实现 Peano 数字类型，cons 列表，二叉树，以及一些相关的常见功能。 首先，让我们定义 Peano 数字类型 （Peano…",html:"<!-- Reviewed at 25dc86c0fd9741b2f1c59d3a594c48844bbc73f5 -->\n<h1>Plutus 例子（TODO）</h1>\n<p>这里，我们看看一些常见的程序示例，让您更好地了解 Plutus 语言的工作原理。我们将实现 Peano 数字类型，cons 列表，二叉树，以及一些相关的常见功能。</p>\n<p>首先，让我们定义 Peano 数字类型</p>\n<pre><code>data Nat = { Zero | Suc Nat }\n</code></pre>\n<p>（Peano）数字类型支持各种功能，当然有加法，乘法，阶乘和斐波那契这些，这些是程序的典型例子。</p>\n<pre><code>add : Nat -> Nat -> Nat {\n  add Zero n = n ;\n  add (Suc m) n = Suc (add m n)\n}\n\nmul : Nat -> Nat -> Nat {\n  mul Zero _ = Zero ;\n  mul (Suc m) n = add (mul m n) n\n}\n\nfac : Nat -> Nat {\n  fac Zero = Suc Zero ;\n  fac (Suc n) = mul (Suc n) (fac n)\n}\n\nfib : Nat -> Nat {\n  fib Zero = Suc Zero ;\n  fib (Suc Zero) = Suc Zero ;\n  fib (Suc (Suc n)) = add (fib n) (fib (Suc n))\n}\n</code></pre>\n<p>Cons 列表也是一种熟悉的类型：</p>\n<pre><code>data List a = { Nil | Cons a (List a) }\n</code></pre>\n<p>这演示了参数类型的使用，其中 <code>List a</code> 有具有 <code>a</code> 元素类型的类型参数。举个例子，<code>List Nat</code> 是 Peano 数字类型的列表。</p>\n<p>列表支持各种功能，例如 <code>length</code>, <code>append</code> 和 <code>map</code>:</p>\n<pre><code>length : forall a. List a -> Nat {\n  length Nil = Zero ;\n  length (Cons _ xs) = Suc (length xs)\n}\n\nappend : forall a. List a -> List a -> List a {\n  append Nil ys = ys ;\n  append (Cons x xs) ys = Cons x (append xs ys)\n}\n\nmap : forall a b. (a -> b) -> List a -> List b {\n  map _ Nil = Nil ;\n  map f (Cons x xs) = Cons (f x) (map f xs)\n}\n</code></pre>\n<p>这里我们可以看到 Plutus 使用多态原则，这些函数适用于任何列表，不管元素类型如何，所以我们可以通过使用元素类型来抽象 <code>forall</code>。例如，<code>length</code> 对于任何 <code>a</code>，我们都有类型函数 <code>List a -> Nat</code>。</p>\n<p>需要重点注意的是，在 Plutus 中，这个多态只存在于值的声明中，你在任何时候使用一个多态声明的值，类型变量的选择必须在 use site 固定。一般来说，你不能像在 System-F 中那样将这些声明视为给出多态值。相反，声明中的多态类型是相同定义的 infinite 家族的缩写，只在该类型变量的选择上有所不同。例如，我们可以像这样定义多个 <code>length</code> 函数。</p>\n<pre><code>lengthNat : List Nat -> Nat {\n  lengthNat Nil = Zero ;\n  lengthNat (Cons _ xs) = Suc (lengthNat xs)\n}\n\nlengthBool : List Bool -> Nat {\n  lengtBool Nil = Zero ;\n  lengthBool (Cons _ xs) = Suc (lengthBool xs)\n}\n\nlengthListNat : List (List Nat) -> Nat {\n  lengthListNat Nil = Zero ;\n  lengthListNat (Cons _ xs) = Suc (lengthListNat xs)\n}\n</code></pre>\n<p>除了名字和 <code>a</code> 的不同外，它们都是相同的 <code>a</code>。这当然是多余的，所以我们可以使用上面给出的多态声明。但这个声明没有给我们具有 <code>forall a. List a -> Nat</code> 类型的值 <code>length</code>。相反，他给了我们整个 infinite 家族的定义，但有一个方便的缩写语法。这就是为什么使用这个多态声明需要在 use site 固定类型变量。</p>\n<p>另一种常见的类型是在分支中有数据的二叉树类型：</p>\n<pre><code>data Tree a = { Leaf | Branch a (Tree a) (Tree a) }\n</code></pre>\n<p>这样的树支持 <code>count</code>, <code>traversal</code> 和 <code>reverse</code> 的功能：</p>\n<pre><code>count : forall a. Tree a -> Nat {\n  count Leaf = Zero ;\n  count (Branch _ l r) = Suc (add (count l) (count r))\n}\n\ntraversal : forall a. Tree a -> List a {\n  traversal Leaf = Nil ;\n  traversal (Branch x l r) = Cons x (append (traversal l) (traversal r))\n}\n\nreverse : forall a. Tree a -> Tree a {\n  reverse Leaf = Leaf ;\n  reverse (Branch x l r) = Branch x (reverse r) (reverse l)\n}\n</code></pre>",frontmatter:{path:"/cn/technical/plutus/examples/",doc_title:"例子",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical-plutus"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/plutus/2017-01-02-types.cn.md absPath of file >>> MarkdownRemark",excerpt:"Plutus 类型 本章包括了关于 Plutus 语言类型的参考。它使用了一些非正式的类型理论，希望对于阅读这个文件的每个人都易于理解。 Plutus 有一些内置类型（int, float, bytestrings) 和一个内置的类型操作符（functions…",html:'<!-- Reviewed at 25dc86c0fd9741b2f1c59d3a594c48844bbc73f5 -->\n<h1>Plutus 类型</h1>\n<p>本章包括了关于 Plutus 语言类型的参考。它使用了一些非正式的类型理论，希望对于阅读这个文件的每个人都易于理解。</p>\n<p>Plutus 有一些内置类型（int, float, bytestrings) 和一个内置的类型操作符（functions)。其他类型由程序的作者定义，我们将一次讨论每一种类型。</p>\n<h2>Ints, Floats 和 Byte Strings</h2>\n<p><code>Int</code>, <code>Float</code> 和 <code>ByteString</code> 是原始类型，具有由一下语法指定的常量给出的构造函数形式。</p>\n<pre><code>&#x3C;int> ::= "-"? &#x3C;digit>+\n&#x3C;float> ::= "-"? &#x3C;digit>+ &#x3C;fractExponent>\n&#x3C;digit> = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"\n&#x3C;fractExponent> ::= &#x3C;fraction> &#x3C;exponent>? | &#x3C;exponent>\n&#x3C;fraction> ::= "." &#x3C;digit>+\n&#x3C;exponent> ::= ("e" | "E") ("-" | "+") &#x3C;digit>+\n\n&#x3C;bytestring> ::= "#" &#x3C;byte>*\n&#x3C;byte> ::= &#x3C;nybble> &#x3C;nybble>\n&#x3C;nybble> ::= &#x3C;digit>\n           | "a" | "b" | "c" | "d" | "e" | "f"\n           | "A" | "B" | "C" | "D" | "E" | "F"\n</code></pre>\n<p>这些类型没有真正的 eliminator 形式，但是有一些内置操作可以应用于这些类型。我们编写的内置签名如下：<code>f : (A,B) ⇀ C</code>，表示 一个内置的名字 <code>f</code> 可以被应用于一个 <code>A</code> 和一个 <code>B</code> 产生一个 <code>C</code>。这些原始类型的内置函数如下，用 Haskell 函数实现：</p>\n<pre><code>addInt : (Int,Int) ⇀ Int\n  implemented as `(+) :: Int -> Int -> Int`\n\nsubtractInt : (Int,Int) ⇀ Int\n  implemented as `(-) :: Int -> Int -> Int`\n\nmultiplyInt : (Int,Int) ⇀ Int\n  implemented as `(*) :: Int -> Int -> Int`\n\ndivideInt : (Int,Int) ⇀ Int\n  implemented as `div :: Int -> Int -> Int`\n\nremainderInt : (Int,Int) ⇀ Int\n  implemented as `(%) :: Int -> Int -> Int`\n\nlessThanInt : (Int,Int) ⇀ Bool\n  implemented as `(&#x3C;) :: Int -> Int -> Bool`\n\nequalsInt : (Int,Int) ⇀ Bool\n  implemented as `(==) :: Int -> Int -> Bool`\n\nintToFloat : (Int) ⇀ Float\n  implemented as `fromInteger . toInteger :: Int -> Float`\n\nintToByteString : (Int) ⇀ ByteString\n  implemented as `encode :: Int -> ByteString`\n\naddFloat : (Float,Float) ⇀ Float\n  implemented as `(+) :: Float -> Float -> Float`\n\nsubtractFloat : (Float,Float) ⇀ Float\n  implemented as `(-) :: Float -> Float -> Float`\n\nmultiplyFloat : (Float,Float) ⇀ Float\n  implemented as `(*) :: Float -> Float -> Float`\n\ndivideFloat : (Float,Float) ⇀ Float\n  implemented as `(/) :: Float -> Float -> Float`\n\nlessThanFloat : (Float,Float) ⇀ Bool\n  implemented as `(&#x3C;) :: Float -> Float -> Bool`\n\nequalsFloat : (Float,Float) ⇀ Bool\n  implemented as `(==) :: Float -> Float -> Bool`\n\nceiling : (Float) ⇀ Float\n  implemented as `ceiling:: Float -> Float`\n\nfloor : (Float) ⇀ Float\n  implemented as `floor :: Float -> Float`\n\nround : (Float) ⇀ Float\n  implemented as `round :: Float -> Float`\n\nconcatenate : (ByteString,ByteString) ⇀ ByteString\n  implemented via `concat :: [ByteString] -> ByteString`\n\ndrop : (Int,ByteString) ⇀ ByteString\n  implemented via `drop :: Integer -> ByteString -> ByteString`\n\ntake : (Int,ByteString) ⇀ ByteString\n  implemented via `take :: Integer -> ByteString -> ByteString`\n\nsha2_256 : (ByteString) ⇀ ByteString\n  implemented via `hash : [Char8] -> Digest SHA256`\n\nsha3_256 : (ByteString) ⇀ ByteString\n  implemented via `hash : [Char8] -> Digest SHA3_256`\n\nequalsByteString : (ByteString,ByteString) ⇀ Bool\n  implemented as `(==) :: ByteString -> ByteString -> Bool`\n</code></pre>\n<p>通过在名称前加上前缀 <code>!</code>，将其完全加上参数，使用这些内置函数。例如，加2和3就是 <code>!addInt 2 3</code>。</p>\n<h2>函数类型</h2>\n<p>给定任意 <code>A</code> 和 <code>B</code> 类型，有一种函数类型 <code>A -> B</code>。要获得这种类型，我们可以使用 lambada 的形式，如下所述：如果 <code>M</code> 有类型 <code>B</code>，有一个变量类型为 <code>A</code> 的变量 <code>x</code>，那么 <code>\\x -> M</code> 有类型 <code>A -> B</code>。我们可以使用一个具有函数类型的术语：如果 <code>M</code> 有类型 <code>A -> B</code>，<code>N</code> 有类型 <code>A</code>，<code>M N</code> 有类型 <code>B</code>。函数的计算是标准的 beta 递减：<code>(\\x -> M) N</code> 到 <code>[N/x]M</code>，即 <code>M</code> 用 <code>N</code> 取代 <code>x</code>。在 Plutus 中，计算是立即执行的，因此 <code>N</code> 在替换之前获得结果。（TODO)</p>\n<h2>用户声明的类型</h2>\n<p>例如，当用户声明新的数据类型时</p>\n<pre><code>data Foo a = { Bar | Baz a }\n</code></pre>\n<p>这定义了一个新的类型构造函数，在这种情况下 <code>Foo</code> 具有以下推理规则：给定任意类型 <code>A</code>, <code>Foo A</code> 也是一种类型。</p>\n<p>它也带有构造函数的推理规则，如下：<code>Bar</code> 有 <code>Foo A</code> 类型，对于 <code>A</code> 的任意选项，如果 <code>M</code> 有类型 <code>A</code>, 那么 <code>Baz M</code> 也有类型 <code>Foo A</code>。</p>\n<p>用户声明类型的 eliminator 表单是 case 结构，用于所有类型。案例分析和 Haskell 一样，例如我们可以写做</p>\n<pre><code>case foo of { Bar -> 0 | Baz x -> x }\n</code></pre>\n<p>分析 <code>Foo Int</code> 元素的类型，需计算 <code>Int</code>。与 Haskell 有一点不同：我们可以同时分析多个 term，将他们（及其相应的模式）以 <code>|</code> 分割：</p>\n<pre><code>case foo0 | foo1 of { Bar | Bar -> 0 ; Baz x | Baz y -> !addInt x y }\n</code></pre>\n<p>案例分析不是必须的。也就是说，可能会有缺失的模式。任何失败的匹配都会导致整个程序运行失败，并导致事务被视为无效。</p>\n<p><code>Int</code>, <code>Float</code> 和 <code>ByteString</code> 也可以为模式；例如，我们可以这种方式来定义阶乘函数：</p>\n<pre><code>facInt : Int -> Int {\n  facInt n = case n of {\n    0 -> 1 ;\n    _ -> !multiplyInt n (!subtractInt n 1)\n  }\n}\n</code></pre>',frontmatter:{path:"/cn/technical/plutus/types/",doc_title:"类型",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical-plutus"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/plutus/2017-01-01-introduction.md absPath of file >>> MarkdownRemark",excerpt:"Plutus Introduction Plutus is a strictly typed pure functional programming language used for\ndefining smart contracts in Cardano. The syntax…",html:"<!-- Reviewed at f766612fb6c75b941cbe3c2d9c2db17dd2dc9bd3 -->\n<h1>Plutus Introduction</h1>\n<p>Plutus is a strictly typed pure functional programming language used for\ndefining smart contracts in Cardano. The syntax is fairly Haskell-like, but\nunlike Haskell, the language is eagerly evaluated.</p>\n<h2>Declaring Data Types</h2>\n<p>In Plutus, to define a data type, we give the name of the type, then any type\nparameters, together with a list of constructor alternatives — like in Haskell.\nEach constructor alternative has the types of its arguments.</p>\n<p>So, for instance, the type of Peano numerals would be defined as</p>\n<pre><code>data Nat = { Zero | Suc Nat }\n</code></pre>\n<p>whereas binary trees would be defined as</p>\n<pre><code>data Tree a = { Leaf | Branch (Tree a) a (Tree a) }\n</code></pre>\n<p>The type constructor <code>Tree</code> takes one parameter, <code>a</code>. It's inhabited by values\nconstructed by two constructors, <code>Leaf</code>, which has no arguments, and <code>Branch</code>,\nwhich has three arguments, a left subtree of type <code>Tree a</code>, a value of type <code>a</code>,\nand a right subtree of type <code>Tree a</code>.</p>\n<p>We can inspect data using the <code>case</code> construct, like so:</p>\n<pre><code>case t of {\n  Leaf -> ... ;\n  Branch l x r -> ...\n}\n</code></pre>\n<h2>Declaring Values</h2>\n<p>To declare a new value (whether it's a function or not), we provide its type,\nand then specify its value. For instance, to define addition for natural\nnumbers, we can give a recursive definition using <code>case</code>:</p>\n<pre><code>add : Nat -> Nat -> Nat {\n  add = \\m n ->\n    case m of {\n      Zero -> n ;\n      Suc m' -> Suc (add m' n)\n    }\n}\n</code></pre>\n<p>We can also use pattern matching equations in the same way as in Haskell, which\nmakes the definition of functions like this much more elegant:</p>\n<pre><code>add : Nat -> Nat -> Nat {\n  add Zero n = n ;\n  add (Suc m) n = Suc (add m n)\n}\n</code></pre>\n<h2>Smart Contract Computations</h2>\n<p>Plutus has one important type built into the language specific for smart\ncontract computations: the type constructor <code>Comp</code>, which takes one type\nparameter. The simplest way to make values is with the two computation\nconstructors <code>success</code>, which takes a value <code>M</code> with type <code>A</code> (for any choice of\n<code>A</code>) and produces a computation of type <code>Comp A</code> which represents a successful\nsmart contract computation that returns <code>M</code>. You can also build a value of type\n<code>Comp A</code> with just <code>failure</code>, which represents a failed computation.</p>\n<p>It's also possible to chain smart contract computations together using <code>do</code>\nnotation. Given a term <code>M</code> of the type <code>Comp A</code>, and a term <code>N</code> of type <code>Comp B</code>\nwith a free variable <code>x</code> of type <code>A</code>, we can form <code>do { x &#x3C;- M ; N }</code> which runs\nthe computation <code>M</code>, binds its returned value to <code>x</code>, then runs the computation\n<code>N</code>. If the term <code>M</code> computes to <code>failure</code>, then the failure is propagated by\nthe <code>do</code> construct and the whole thing computes to <code>failure</code>.</p>\n<p>This is most useful for building validator scripts for smart contracts. The\nstandard way of doing this is by asking for a redeemer program of type <code>Comp A</code>\nand a validator program of type <code>A -> Comp B</code>, which then are composed to form\n<code>do { x &#x3C;- redeemer ; validator x }</code>. The <code>redeemer</code> program is run, returning\nwhatever data <code>validator</code> needs, and then that data is given to <code>validator</code>\nwhich is then run.</p>\n<h2>More Detailed Overview</h2>\n<p>The other chapters in Plutus section provide a more detailed overview of the\ngrammar, types, and programs of Plutus, including the built-in types and\nfunctionality, and should be read before diving into writing programs. There's\nalso a demo file, showing the implementation of a number of common functions, to\ngive a good sense of the use of the language.</p>",
  frontmatter:{path:"/en/technical/plutus/introduction/",doc_title:"Introduction",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical-plutus"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/wallet/2018-03-14-api-docs.md absPath of file >>> MarkdownRemark",excerpt:"API Documentation V0 (deprecated) The API documentation for v0, now  deprecated , has been moved  here . V1 The API documentation for v1 is…",html:'<h2>API Documentation</h2>\n<h1>V0 (deprecated)</h1>\n<p>The API documentation for v0, now <strong>deprecated</strong>, has been moved <a href="/technical/wallet/api/v0">here</a>.</p>\n<h1>V1</h1>\n<p>The API documentation for v1 is available <a href="/technical/wallet/api/v1">here</a>.</p>',frontmatter:{path:"/en/technical/wallet/api/",doc_title:"API Documentation",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/cardano/2017-02-03-transaction-assurance.cn.md absPath of file >>> MarkdownRemark",excerpt:"交易确认层级 下面的表格基于颜色表示确认层级，以确保交易不会被某些分叉取消。 举个例子，在正常的安全级别，如果攻击者的份额是10％（或600万美元，卡尔达诺市值6000万美元），则用户交易的确认级别是： 最低确认（用红色编码） - 当用户的转账确认数小于…",html:'<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<style>\n.full-width {\n    width: 100%;\n}\n\n.r {\n    color: white;\n    background-color: #ef4e4e;\n    text-align: right;\n    font-weight: 400;\n}\n\n.y {\n    color: white;\n    background-color: #c09e0f;\n    text-align: right;\n    font-weight: 400;\n}\n\n.g {\n    color: white;\n    background-color: green;\n    text-align: right;\n    font-weight: 400;\n}\n\n.gr {\n    color: white;\n    background-color: #aaa;\n    font-weight: 700;\n}\n\n.rd {\n    background-color: #fca8a8;\n    text-align: right;\n    font-weight: 700;\n}\n\n.yd {\n    background-color: #eccd4a;\n    text-align: right;\n    font-weight: 700;\n}\n\n.gd {\n    background-color: #53d153;\n    text-align: right;\n    font-weight: 700;\n}\n\n.center {\n    text-align: center;\n}\n\n.pct25 {\n    width: 25%;\n}\n</style>\n<h1>交易确认层级</h1>\n<p>下面的表格基于颜色表示确认层级，以确保交易不会被某些分叉取消。</p>\n<p>举个例子，在正常的安全级别，如果攻击者的份额是10％（或600万美元，卡尔达诺市值6000万美元），则用户交易的确认级别是：</p>\n<ol>\n<li>最低确认（用红色编码） - 当用户的转账确认数小于<strong>3</strong>个区块时。</li>\n<li>中等确认（用黄色编码） - 用用户的转账确认数为<strong>3</strong>到<strong>7</strong>块。</li>\n<li>高度确认（用绿色编码） - 当用户的转账具有<strong>9</strong>个或更多区块的确认时。</li>\n</ol>\n<h2>正常安全层级</h2>\n<p>正常级别可以防攻击（这个模型将包含在最新版本的乌洛波罗斯算法中），表中的数值对应6亿美元的卡尔达诺市值。</p>\n<table class="full-width">\n<tr>\n    <th class="center">             攻击者的份额，%</th>\n    <th class="center pct25">       攻击者的份额，$ mln </th> \n    <th colspan="6" class="center"> 确认水平         </th>\n</tr>\n<tr class="center">\n    <td></td>\n    <td></td>\n    <td> Low    </td>\n    <td> 0.950  </td>\n    <td> 0.990  </td>\n    <td> 0.995  </td>\n    <td> 0.999  </td>\n    <td> High   </td>\n</tr>\n<tr>\n    <td class="gr"> 10          </td>\n    <td class="gr"> 6           </td>\n    <td class="rd"> &lt; 3      </td>\n    <td class="yd"> 3           </td>\n    <td class="yd"> 5           </td>\n    <td class="yd"> 7           </td>\n    <td class="gd"> 9           </td>\n    <td class="gd"> 9 &lt;      </td>\n</tr>\n<tr>\n    <td>            15          </td>\n    <td>            9           </td>\n    <td class="r">  &lt; 5      </td>\n    <td class="y">  5           </td>\n    <td class="y">  9           </td>\n    <td class="y">  11          </td>\n    <td class="g">  15          </td>\n    <td class="g">  15 &lt;     </td>\n</tr>\n<tr>\n    <td>            20          </td>\n    <td>            12          </td>\n    <td class="r">  &lt; 7      </td>\n    <td class="y">  7           </td>\n    <td class="y">  13          </td>\n    <td class="y">  15          </td>\n    <td class="g">  21          </td>\n    <td class="g">  21 &lt;     </td>\n</tr>\n<tr>\n    <td>            25          </td>\n    <td>            15          </td>\n    <td class="r">  &lt; 9      </td>\n    <td class="y">  9           </td>\n    <td class="y">  19          </td>\n    <td class="y">  23          </td>\n    <td class="g">  33          </td>\n    <td class="g">  33 &lt;     </td>\n</tr>\n<tr>\n    <td>            30          </td>\n    <td>            18          </td>\n    <td class="r">  &lt; 17     </td>\n    <td class="y">  17          </td>\n    <td class="y">  31          </td>\n    <td class="y">  39          </td>\n    <td class="g">  55          </td>\n    <td class="g">  55 &lt;     </td>\n</tr>\n<tr>\n    <td>            35          </td>\n    <td>            21          </td>\n    <td class="r">  &lt; 29     </td>\n    <td class="y">  29          </td>\n    <td class="y">  57          </td>\n    <td class="y">  71          </td>\n    <td class="g">  101         </td>\n    <td class="g">  101 &lt;    </td>\n</tr>\n<tr>\n    <td>            40          </td>\n    <td>            24          </td>\n    <td class="r">  &lt; 67     </td>\n    <td class="y">  67          </td>\n    <td class="y">  133         </td>\n    <td class="y">  163         </td>\n    <td class="g">  235         </td>\n    <td class="g">  235 &lt;    </td>\n</tr>\n<tr>\n    <td>            45          </td>\n    <td>            27          </td>\n    <td class="r">  &lt; 269    </td>\n    <td class="y">  269         </td>\n    <td class="y">  539         </td>\n    <td class="y">  661         </td>\n    <td class="g">  951         </td>\n    <td class="g">  951 &lt;    </td>\n</tr>\n<tr>\n    <td>            46          </td>\n    <td>            27.6        </td>\n    <td class="r">  &lt; 421    </td>\n    <td class="y">  421         </td>\n    <td class="y">  843         </td>\n    <td class="y">  1033        </td>\n    <td class="g">  1487        </td>\n    <td class="g">  1487 &lt;   </td>\n</tr>\n<tr>\n    <td>            47          </td>\n    <td>            28.2        </td>\n    <td class="r">  &lt; 751    </td>\n    <td class="y">  751         </td>\n    <td class="y">  1501        </td>\n    <td class="y">  1841        </td>\n    <td class="g">  2649        </td>\n    <td class="g">  2649 &lt;   </td>\n</tr>\n<tr>\n    <td>            48          </td>\n    <td>            28.8        </td>\n    <td class="r">  &lt; 1691   </td>\n    <td class="y">  1691        </td>\n    <td class="y">  3381        </td>\n    <td class="y">  4143        </td>\n    <td class="g">  5965        </td>\n    <td class="g">  5965 &lt;   </td>\n</tr>\n<tr>\n    <td>            49          </td>\n    <td>            29.4        </td>\n    <td class="r">  &lt; 6763   </td>\n    <td class="y">  6763        </td>\n    <td class="y">  13527       </td>\n    <td class="y">  16585       </td>\n    <td class="g">  23869       </td>\n    <td class="g">  23869 &lt;  </td>\n</tr>\n</table>\n## 严格安全层级\n<p>严格的安全层级可以防止所有的攻击（它需要更多的块确认）。表中的数值对应6亿美元的卡尔达诺市值。</p>\n<table class="full-width">\n<tr>\n    <th class="center">             攻击者的份额，%</th>\n    <th class="center pct25">       攻击者的份额，$ mln </th> \n    <th colspan="6" class="center"> 确认水平         </th>\n</tr>\n<tr class="center">\n    <td></td>\n    <td></td>\n    <td> Low    </td>\n    <td> 0.950  </td>\n    <td> 0.990  </td>\n    <td> 0.995  </td>\n    <td> 0.999  </td>\n    <td> High   </td>\n</tr>\n<tr>\n    <td class="gr"> 10          </td>\n    <td class="gr"> 6           </td>\n    <td class="rd"> &lt; 5      </td>\n    <td class="yd"> 5           </td>\n    <td class="yd"> 9           </td>\n    <td class="yd"> 11          </td>\n    <td class="gd"> 15          </td>\n    <td class="gd"> 15 &lt;     </td>\n</tr>\n<tr>\n    <td>            15          </td>\n    <td>            9           </td>\n    <td class="r">  &lt; 7      </td>\n    <td class="y">  7           </td>\n    <td class="y">  14          </td>\n    <td class="y">  16          </td>\n    <td class="g">  23          </td>\n    <td class="g">  23 &lt;     </td>\n</tr>\n<tr>\n    <td>            20          </td>\n    <td>            12          </td>\n    <td class="r">  &lt; 12     </td>\n    <td class="y">  12          </td>\n    <td class="y">  21          </td>\n    <td class="y">  25          </td>\n    <td class="g">  35          </td>\n    <td class="g">  35 &lt;     </td>\n</tr>\n<tr>\n    <td>            25          </td>\n    <td>            15          </td>\n    <td class="r">  &lt; 19     </td>\n    <td class="y">  19          </td>\n    <td class="y">  34          </td>\n    <td class="y">  40          </td>\n    <td class="g">  55          </td>\n    <td class="g">  55 &lt;     </td>\n</tr>\n<tr>\n    <td>            30          </td>\n    <td>            18          </td>\n    <td class="r">  &lt; 32     </td>\n    <td class="y">  32          </td>\n    <td class="y">  57          </td>\n    <td class="y">  68          </td>\n    <td class="g">  94          </td>\n    <td class="g">  94 &lt;     </td>\n</tr>\n<tr>\n    <td>            35          </td>\n    <td>            21          </td>\n    <td class="r">  &lt; 63     </td>\n    <td class="y">  63          </td>\n    <td class="y">  111         </td>\n    <td class="y">  132         </td>\n    <td class="g">  181         </td>\n    <td class="g">  181 &lt;    </td>\n</tr>\n<tr>\n    <td>            40          </td>\n    <td>            24          </td>\n    <td class="r">  &lt; 157    </td>\n    <td class="y">  157         </td>\n    <td class="y">  274         </td>\n    <td class="y">  325         </td>\n    <td class="g">  443         </td>\n    <td class="g">  443 &lt;    </td>\n</tr>\n<tr>\n    <td>            45          </td>\n    <td>            27          </td>\n    <td class="r">  &lt; 729    </td>\n    <td class="y">  729         </td>\n    <td class="y">  1246         </td>\n    <td class="y">  1470         </td>\n    <td class="g">  1990         </td>\n    <td class="g">  1990 &lt;    </td>\n</tr>\n<tr>\n    <td>            46          </td>\n    <td>            27.6        </td>\n    <td class="r">  &lt; 1190   </td>\n    <td class="y">  1190        </td>\n    <td class="y">  2020        </td>\n    <td class="y">  2379        </td>\n    <td class="g">  3214        </td>\n    <td class="g">  3214 &lt;   </td>\n</tr>\n<tr>\n    <td>            47          </td>\n    <td>            28.2        </td>\n    <td class="r">  &lt; 2230   </td>\n    <td class="y">  2230        </td>\n    <td class="y">  3758        </td>\n    <td class="y">  4418        </td>\n    <td class="g">  5953        </td>\n    <td class="g">  5953 &lt;   </td>\n</tr>\n<tr>\n    <td>            48          </td>\n    <td>            28.8        </td>\n    <td class="r">  &lt; 5382   </td>\n    <td class="y">  5382        </td>\n    <td class="y">  8986        </td>\n    <td class="y">  10542       </td>\n    <td class="g">  14157       </td>\n    <td class="g">  14157 &lt;  </td>\n</tr>\n<tr>\n    <td>            49          </td>\n    <td>            29.4        </td>\n    <td class="r">  &lt; 24029  </td>\n    <td class="y">  24029       </td>\n    <td class="y">  39603       </td>\n    <td class="y">  46320       </td>\n    <td class="g">  61922       </td>\n    <td class="g">  61922 &lt;  </td>\n</tr>\n</table>',frontmatter:{path:"/cn/cardano/transaction-assurance/",doc_title:"交易确认层级",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-01-04-updater.md absPath of file >>> MarkdownRemark",excerpt:"Cardano SL Updater Implementation Overview Implementation of the update system can be found in the\n Pos.Update \nfamily of modules. The…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<!-- Updated at 6b5eda44e5942599a9781e5ad3f51eb820665b83 -->\n<h1>Cardano SL Updater Implementation Overview</h1>\n<p>Implementation of the update system can be found in the\n<a href="https://github.com/input-output-hk/cardano-sl/tree/6b5eda44e5942599a9781e5ad3f51eb820665b83/src/Pos/Update">Pos.Update</a>\nfamily of modules. The general approach to implementation is the same as in\nother subsystems of CSL, such as Txp, Ssc and Delegation. The update system has\nthe global state, stored in the database. The global state can be unambiguously\nderived from the information that is in the blockchain. The local state,\nsometimes referred to as “mempool”, is stored in the memory. The mempool is used\nfor data transfer and inclusion of transferred data into blocks. The network\nprotocol (built with standard <a href="https://github.com/input-output-hk/cardano-sl/tree/43a2d079a026b90ba860e79b5be52d1337e26c6f/infra/Pos/Communication/Relay">Inv/Req/Data\npattern</a>)\nis described in <a href="/technical/protocols/csl-application-level/">Application-level\ndocument</a> with the binary protocol\ndescribed in <a href="/technical/protocols/binary-protocols/">Binary protocols\ndocument</a>.</p>\n<p>Currently, everything is ready to add hard fork functionality via software\nupdate and then perform a hard fork as described in research section; soft forks\n(or software updates) are fully implemented.</p>\n<h2>Fields Updatable with a Soft Fork</h2>\n<p>An\n<a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/update/Pos/Update/Core/Types.hs#L110">UpdateProposal</a>\ncontains fields for changing some parameters used by Cardano SL (for instance,\nslot duration). Specifically, <code>upBlockVersion</code> is used to signify that a\nproposal performs such changes; if <code>upBlockVersion</code> is greater than the last\nused block version, the changes from <code>upBlockVersionData</code> will be applied.</p>\n<p><code>upBlockVersionData</code> has the type\n<a href="https://github.com/input-output-hk/cardano-sl/blob/fe5e6a377ab63c506173545fd4d8633cd1afbdc6/core/Pos/Core/Types.hs#L206">BlockVersionData</a>.</p>\n<p>Its fields are described below:</p>\n<ul>\n<li><code>bvdScriptVersion</code> – a script language version used to validate script\ntransactions. If the proposal increases <code>upBlockVersion</code>, it must also\nincrease <code>bvdScriptVersion</code> by 1 (and can\'t leave it unchanged).</li>\n<li><code>bvdSlotDuration</code> – slot duration (in milliseconds).</li>\n<li><code>bvdMaxBlockSize</code> – block size limit (in bytes). A proposal can\'t increase\nthe block size limit more than twofold compared to the previous limit.</li>\n<li><code>bvdMaxHeaderSize</code> - block header size limit (in bytes).</li>\n<li><code>bvdMaxTxSize</code> – transaction size limit (in bytes, <a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/core/constants.yaml#L17">currently\n4096</a>),\nlimits size of\n<a href="/technical/protocols/binary-protocols/#transaction-auxilary">TxAux</a></li>\n</ul>\n<p>The checks described above are made in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/893e3c838bf847613313e8dbf04330176a788af4/update/Pos/Update/Poll/Logic/Base.hs#L232">verifyNextBVData</a>.</p>\n<p>In addition, there are some fields that are unused right now, but will be used\nin the future. Their meaning is briefly described below:</p>\n<ul>\n<li><code>bvdMpcThd</code> – eligibility threshold for MPC.</li>\n<li><code>bvdHeavyDelThd</code> – threshold for heavyweight delegation.</li>\n<li><code>bvdUpdateVoteThd</code> – portion of total stake necessary to vote for or against\nan update.</li>\n<li><code>bvdUpdateProposalThd</code> – portion of total stake such that block containing\n<code>UpdateProposal</code> must contain positive votes for this proposal from\nstakeholders owning at least this amount of stake.</li>\n<li><code>bvdUpdateImplicit</code> – number of slots after which an update is implicitly\napproved (unless it has more negative votes than positive).</li>\n<li><code>bvdUpdateSoftforkThd</code> – portion of total stake such that if total stake of\nissuers of blocks with some block version is bigger than this portion, this\nblock version is adopted.</li>\n</ul>\n<h2>Mempool Structure</h2>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/update/Pos/Update/MemState/Types.hs#L29"><code>MemPool</code></a> consists of votes and proposals. Apart from that <a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/update/Pos/Update/MemState/Types.hs#L39"><code>MemState</code></a> contains\ntip, slot and <code>PollModifier</code> corresponding to <code>MemPool</code> (and to current\n<code>GState</code>, i. e. to application of <code>MemPool</code> to <code>GState</code>). No matter whether a\nchange in proposal state comes from the network/mempool, or from loading the\nblockchain, <code>PollModifier</code> represents modification of global state which will be\nmade if one applies mempool.</p>\n<h3>Updating the Mempool</h3>\n<p>As nodes deserialize <a href="/technical/protocols/binary-protocols/#update-system">payloads of update system\nmessages</a>, they modify\nmempool as implemented\n<a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/update/Pos/Update/MemState/Functions.hs#L35">here</a>.</p>\n<p><code>MemPool</code> is updated in three cases:</p>\n<ol>\n<li><strong>When a new proposal/vote is received</strong>. In this case, one of the\n<a href="https://github.com/input-output-hk/cardano-sl/blob/763822c4fd906f36fa97b6b1f973d31d52342f3f/update/Pos/Update/Logic/Local.hs#L186">process</a>\nfunctions is called, which in turn calls\n<a href="https://github.com/input-output-hk/cardano-sl/blob/dff5e00612c84af24964a98e5254602fa4f7fc17/update/Pos/Update/Poll/Logic/Apply.hs#L66"><code>verifyAndApplyUSPayload</code></a>\nand then updates current <code>PollModifier</code> and <code>MemPool</code>.</li>\n<li><strong>When a new slot starts</strong>. In this case some data in <code>MemPool</code> may become\ninvalid. In fact, it happens only when epoch changes. That can happen\nbecause stable stake distribution changes and some votes may have not enough\nstake for inclusion. It\'s done in the\n<a href="https://github.com/input-output-hk/cardano-sl/blob/763822c4fd906f36fa97b6b1f973d31d52342f3f/update/Pos/Update/Logic/Local.hs#L283"><code>processNewSlot</code></a>\nfunction.</li>\n<li><strong>When <code>GState</code> is updated</strong>. It is called\n<a href="https://github.com/input-output-hk/cardano-sl/blob/763822c4fd906f36fa97b6b1f973d31d52342f3f/update/Pos/Update/Logic/Local.hs#L248"><code>usNormalize</code></a>.\nSome data may become invalid as a result of block(s) application or\nrollback. For instance, we have a proposal in memory, apply block with this\nproposal and it becomes invalid (because it\'s already in block). We should\ndrop such proposals. Or we have a vote for proposal from some block, then\nrollback of this block happens and vote is no longer valid. It is\nimplemented by applying all local data to empty state, ignoring all data\nwhich is no longer valid.</li>\n</ol>\n<h3>Proposal and Votes Accumulation</h3>\n<p>To vote for a proposal, nodes should send their\n<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/update/Pos/Update/Core/Types.hs#L255">votes</a>.\nProposals and votes are stored in mempool (even if proposals don\'t have enough\nvotes for inclusion into blocks, this way votes can be collected automatically)\nor gathered from the blockchain in order to figure out which proposal is\nadopted.</p>\n<h2>Interaction With the Database</h2>\n<p>In order to verify update system data, we have to get this data from the global\nstate (database). To provide such interface, a well-documented type class\n<a href="https://github.com/input-output-hk/cardano-sl/blob/446444070ee09857603797a90af970fff215c8c5/update/Pos/Update/Poll/Class.hs#L29"><code>MonadPollRead</code></a>\nis presented. This type class is used not only for DB interaction, but also to\ntake mempool into account when the data received from the network are processed.\nIt is important that its implementation relies on functions found in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/update/Pos/Update/DB.hs"><code>Pos.Update.DB</code></a> module.</p>\n<h2>Core Types</h2>\n<p>Core types are mentioned in the <a href="/technical/protocols/binary-protocols/">Binary Protocols</a>\ndocument. Those types reflect the concepts from the research section in a straightforward way.\nPlease refer to the <a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/update/Pos/Update/Core/Types.hs">core types\nmodule</a>\nfor more information.</p>\n<h2>Update Proposal Approval</h2>\n<p>A very important part of implementation of the update mechanism is the part that\nworks with genesis blocks for epochs. This logic resides in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/6b5eda44e5942599a9781e5ad3f51eb820665b83/src/Pos/Update/Poll/Logic/Softfork.hs#L68"><code>processGenesisBlock</code></a> function.\nThe terminology related to this process is explained below.</p>\n<h3>Threshold</h3>\n<p>Suppose there is a block version <code>X</code>. And there are blocks with version <code>X</code>\ncreated in slots <code>S</code> (where <code>S</code> is a set of slots). If total relative stake of\nleaders of all slots in <code>S</code> is ≥ <code>softforkResolutionThreshold</code> (referred to as\n«threshold» in the code), then <code>X</code> becomes adopted. See the more detailed\ndescription in <a href="/cardano/update-mechanism/#soft-fork-updates">research overview</a>.</p>\n<h3>Proposal states</h3>\n<p>Update proposal can be in one of the states described below.</p>\n<h4>Undecided</h4>\n<p>It means that update proposal is contained in one of the blocks, but it doesn\'t\nhave <code>50%</code> votes for/against it (here <code>50%</code> means total stake of voters who are\nfor/against proposal relative to total stake of all stakeholders in system) and\nimplicit agreement rule hasn\'t been triggered yet.</p>\n<!-- TODO: **Important remark:** when we are talking about stake, we need to be clear about\nwhich stake distribution we are talking about. For each epoch we know stable distribution\nfor this epoch. It used in leaders selection (follow-the-satoshi) and also in many other\ncases. Stable distribution is distribution as it was \ufeff⁠⁠⁠⁠2k\ufeff⁠⁠⁠⁠ slots before the end of epoch.\nTo calculate stake of votes for proposal \ufeff⁠⁠⁠⁠p\ufeff⁠⁠⁠⁠ we use stake distribution as per epoch in\nwhich \ufeff⁠⁠⁠⁠p\ufeff⁠⁠⁠⁠ was added to blocks. I. e. distribution which was \ufeff⁠⁠⁠⁠2k\ufeff⁠⁠⁠⁠ slots before the\nend of that epoch. This ensures that nobody can transfer his funds to another address\nand vote from that address to increase total stake of voters.\n\n**Another important remark:** when we are talking about stake, it\'s also important to be\nclear whether we consider delegated stake. I. e. if Alice delegated to Bob, do we consider\nthat Alice\'s funds belong to Bob or Alice? When we use stake for votes, we consider delegated\nstake, i. e. we consider that Alice\'s funds belong to Bob. Note that here we consider\nonly heavyweight delegation. I hope it\'s covered in documentation, but I am not sure. -->\n<h4>Approved</h4>\n<p>It means that proposal has more than <code>50%</code> votes for it or it was added to block\nlong ago (according to implicit agreement rule) and it has more positive votes\nthan negative (comparison by stake of course).</p>\n<h4>Rejected</h4>\n<p>A proposal is called <strong>rejected</strong> if that proposal has more than <code>50%</code> votes\nagainst it or it was added to block long ago (according to implicit agreement\nrule) and it has more negative votes than positive (again, comparison by stake).</p>\n<h4>Confirmed</h4>\n<p>An <strong>approved</strong> proposal is called <strong>confirmed</strong> if at least <code>k</code> blocks ago\nproposal became <strong>Approved</strong>. At this point we can be sure that proposal won\'t\nbecome <strong>rejected</strong>, because rollbacks with depth more than <code>k</code> aren\'t possible.</p>\n<h4>Discarded</h4>\n<p>A <strong>rejected</strong> proposal is called <strong>discarded</strong>, if at least <code>k</code> blocks ago that\nproposal became <strong>rejected</strong>. At this point we can be sure that proposal won\'t\nbe approved, because rollbacks with depth more than <code>k</code> aren\'t possible.</p>\n<h2>Download New Version</h2>\n<p>In the\n<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/src/Pos/Update/Download.hs"><code>Pos.Update.Download</code></a>\nmodule, the following algorithms are implemented. Downloaded updates are applied\nusing a tool called\n<a href="https://github.com/input-output-hk/cardano-sl/blob/82ba83c3ffb670201b309ff47e3d0ab5f4a17455/src/launcher/Main.hs"><code>cardano-launcher</code></a>.</p>\n<h3>Download Confirmed Update</h3>\n<p>To download a confirmed update, we extract the update hash from\n<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/update/Pos/Update/Poll/Types.hs#L114"><code>ConfirmedProposalState</code></a>. It is extracted depending on whether or not we\'re\nusing an installer on given platform. If the update hash is extracted\nsuccessfully, the “Download Update by Hash” algorithm is invoked to download and\nsave the confirmed update.</p>\n<h3>Download Update by Hash</h3>\n<p>To <a href="https://github.com/input-output-hk/cardano-sl/blob/daa8b81785f38038187c45385c9a94510a5c3780/src/Pos/Update/Download.hs#L108">download an update by hash</a>, we loop through known update servers trying to\ndownload the update with given hash using <code>httpLBS</code> from HTTP. It\'s simple: in\nthe end, we will either have the update completely downloaded or server list\nexhausted and an error reported. URIs of the known update servers are defined\nusing <code>--update-server</code> argument of the <code>cardano-node</code> executable.</p>',frontmatter:{path:"/en/technical/cardano-sl-updater/",doc_title:"Cardano SL Updater",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-01-07-blocks.md absPath of file >>> MarkdownRemark",excerpt:"Blocks in Cardano SL This guide describes block design and the logic of the block handling. The block-related types are defined in\n Pos…",html:'<!-- Reviewed at ac0126b2753f1f5ca6fbfb555783fbeb1aa141bd -->\n<h1>Blocks in Cardano SL</h1>\n<p>This guide describes block design and the logic of the block handling.</p>\n<p>The block-related types are defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Types.hs">Pos.Block.Core.Main.Types</a>\nmodule and\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Genesis/Types.hs">Pos.Block.Core.Genesis.Types</a>.\nThe logic of work with blocks is defined in\n<a href="https://github.com/input-output-hk/cardano-sl/tree/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic">Pos.Block.Logic.*</a>\nmodules.</p>\n<h2>Design</h2>\n<p>A block is a fundamental part of the ledger. There are two types of blocks:\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Types.hs#L110"><strong>main</strong></a>\nblocks and\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Genesis/Types.hs#L66"><strong>genesis</strong></a>\nblocks.</p>\n<h3>Main Block</h3>\n<p>A main block consists of a <em>header</em> and a <em>body</em>. The\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/core/Pos/Core/Block.hs#L99">header</a>\ncontains meta-information about the block:</p>\n<ol>\n<li>A pointer to the header of previous block block signature.</li>\n<li>Proof of body.</li>\n<li>Consensus data to verify consensus algorithm.</li>\n<li>Some extra-data.</li>\n</ol>\n<p>The <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L64">block\'s\nbody</a>\ncontains payloads and some extra-data as well. Payloads include:</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L66">Transactions\npayload</a>.\nThis payload is the main one. Transactions are stored in the Merkle tree.\nThis payload includes <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Txp/Core/Types.hs#L283">list of\nwitnesses</a>\nas well. Please read about <a href="/cardano/transactions/">Transactions in Cardano\nSL</a> for more info about transaction and witnesses.</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L68">SSC\npayload</a>.\nSSC (Shared Seed Computation) is used for the <a href="/cardano/proof-of-stake/#follow-the-satoshi">Follow-the-Satoshi\nalgorithm</a>. Within every epoch,\nslot-leaders for the next epoch must be elected. These slot-leaders will be\nable to generate new main blocks and add them to the ledger. So SSC is used\nas a source of randomness for the leader election process.</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L70">Delegation\npayload</a>.\nThis payload consists of a <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Delegation/Types.hs#L49">list of heavyweight proxy signing\nkeys</a>.\nPlease read about <a href="/technical/delegation/">Stake Delegation in Cardano SL</a>\nfor more info.</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Chain.hs#L72">Update\npayload</a>.\nIt contains a\n<a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/update/Pos/Update/Core/Types.hs#L300">proposal</a>\nfor software update and a <a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/update/Pos/Update/Core/Types.hs#L301">list of\nvotes</a>\nfor the particular update. Please read about <a href="/cardano/update-mechanism/">Update System\nModel</a> for more info.</li>\n</ol>\n<h3>Genesis Block</h3>\n<p>A genesis block doesn\'t contain transactions, and there is just one genesis\nblock for each epoch. Genesis blocks have a header and a body, just like main\nblocks. The body of the block contains:</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Genesis/Chain.hs#L33">An index of the\nepoch</a>\nthis block is associated with.</li>\n<li>The list of slot-leaders for this epoch. This list <a href="https://github.com/input-output-hk/cardano-sl/blob/b4b2c282b0e2a2e4415163e70dcb559396a2237c/core/Pos/Core/Types.hs#L272">cannot be\nempty</a>.</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Genesis/Chain.hs#L35">Chain\ndifficulty</a>.\nIt represents efforts necessary to generate a chain, it\'s the number of main\nblocks in the chain.</li>\n</ol>\n<h2>Block Handling Logic</h2>\n<p>We work with blocks and block headers. Fundamentally, we can:</p>\n<ul>\n<li>create a block,</li>\n<li>verify a block,</li>\n<li>apply a block,</li>\n<li>rollback a block,</li>\n</ul>\n<p>and:</p>\n<ul>\n<li>get block headers by different criteria,</li>\n<li>classify block headers.</li>\n</ul>\n<h2>Block Creation</h2>\n<p>As mentioned above, there are two kinds of blocks: <strong>main</strong> blocks and\n<strong>genesis</strong> blocks. A main block is created with the\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L156"><code>createMainBlock</code></a>\nfunction, and a genesis block is created with the\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L92"><code>createGenesisBlock</code></a>\nfunction.</p>\n<h3>Main Block Creation</h3>\n<p>We try to create a new main block on top of the best chain if possible. A new\nblock can be created if the following conditions are met:</p>\n<ul>\n<li>We know the genesis block for the epoch from the given slot ID,</li>\n<li>The last known block is not more than\n<a href="https://github.com/input-output-hk/cardano-sl/blob/f571087e5b5af339767198141981c850227ca99c/core/Pos/Core/Constants.hs#L86"><code>slotSecurityParam</code></a>\nblocks away from given slot ID.</li>\n</ul>\n<p>The value of <code>slotSecurityParam</code> (which actually is a number of slots) depends\non maximum number of blocks which can be rolled back. This <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/core/Pos/Core/Constants.hs#L81">maximum\nnumber</a>\nis a security parameter from the <a href="/glossary/#paper">paper</a>.</p>\n<p>First of all, we have to check whether our software can create a block\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Update/Logic/Global.hs#L139">according to current global\nstate</a>.\nIf it can\'t, we\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L172">report</a>\nabout it. If it can, we <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L206">create and apply\nblock</a>.</p>\n<h3>Genesis Block Creation</h3>\n<p>A genesis block is created for the current epoch when the head of currently\nknown best chain is\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Core/Main/Types.hs#L112"><code>MainBlock</code></a>\ncorresponding to one of the last\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/core/Pos/Core/Constants.hs#L81"><code>slotSecurityParam</code></a>\nslots of (i - 1)-th epoch.</p>\n<p>First of all, we try to get the slot-leaders. If there\'s <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L99">no\nleaders</a>\nor <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L102">not enough blocks for\nLRC</a>\n(Leaders and Richmen Computation), an error is reported. Otherwise we\'re trying\nto actually create <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L115">a new genesis\nblock</a>.\nHowever, sometimes we <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L106">shouldn\'t create\none</a>.\nFor example, we shouldn\'t do it <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Creation.hs#L108">for the 0th\nepoch</a>\nbecause genesis block for 0th epoch is hardcoded.</p>\n<h2>Block Application</h2>\n<p>We apply blocks using the\n<a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/VAR.hs#L182"><code>applyBlocks</code></a>\nfunction. The sequence of blocks should be definitely valid: we must verify all\npredicates and data checks regarding blocks.</p>\n<p><strong>Important</strong>: all blocks in that sequence must be of the same epoch!</p>\n<p>If all conditions are met, we <a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/Internal.hs#L107">actually apply\nblocks</a>:</p>\n<ul>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/Internal.hs#L141">apply US (Update\nSystem)</a>,</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/Internal.hs#L142">apply\ndelegation</a>,</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/09e4fcf8a7f1a5a587d0241aa93f23e2d72c7c70/src/Pos/Block/Logic/Internal.hs#L143">apply\ntransactions</a>.</li>\n</ul>\n<p>Moreover, we can verify blocks before application (i.e. apply blocks only if\nthey\'re valid). We use\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/VAR.hs#L99"><code>verifyAndApplyBlocks</code></a>\nfunction for it. If some error occurred during application, there are two\noptions:</p>\n<ol>\n<li>All blocks applied inside this function will be <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/VAR.hs#L137">rolled\nback</a>.</li>\n<li>This function will try to apply <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/VAR.hs#L126">as many blocks as\npossible</a>.</li>\n</ol>\n<h2>Block Rollback</h2>\n<p>You can think about a rollback as the opposite of application: when a rollback\nis performed, all changes made by the application are cancelled. To do this, the\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/VAR.hs#L208"><code>rollbackBlocks</code></a>\nfunction is used.</p>\n<p>We get the tip and the first block to rollback. If they do not match, an error\nis reported. If they match, we <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Internal.hs#L167">actually rollback the sequence of\nblocks</a>:</p>\n<ul>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Internal.hs#L173">Rollback\ndelegation</a>,\nerases mempool of certificates,</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Internal.hs#L174">Rollback\nUS</a>,</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Internal.hs#L172">Rollback\ntransactions</a>.</li>\n</ul>\n<h2>Block Headers Classification</h2>\n<p>A header can be classified as:</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L51">Continues</a>,</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L54">Alternative</a>,</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L59">Invalid</a>,</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L57">Useless</a>.</li>\n</ol>\n<p>A header is treated as <strong>continues</strong> if <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L120">verification is\nsucceed</a>:\nheader is a direct continuation of the main chain (i.e. its parent is our tip).</p>\n<p>A header is treated as <strong>alternative</strong> if header\'s parent is not our tip and\n<a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L124">it\'s more difficult than our main\nchain</a>.</p>\n<p>A header is treated as <strong>invalid</strong> if there are <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L170">any errors in the chain of\nheaders</a>\nor if there is <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L172">no block corresponding to parent of oldest element in chain\n(should be one of\ncheckpoints)</a>.</p>\n<p>A header is treated as <strong>useless</strong> in different conditions (e.g. if header\'s\nslot is <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L94">less or equal than our tip\'s\nslot</a>,\nor header <a href="https://github.com/input-output-hk/cardano-sl/blob/11fdc35884368ba61ec32e3277c037e20dc1c266/src/Pos/Block/Logic/Header.hs#L129">doesn\'t continue main chain and is not more\ndifficult</a>).</p>',
  frontmatter:{path:"/en/technical/blocks-in-cardano-sl/",doc_title:"Blocks in Cardano SL",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-02-15-pvss.md absPath of file >>> MarkdownRemark",excerpt:'PVSS Implementation in Cardano SL Publicly Verifiable Secret Sharing (PVSS) Scheme used in Cardano SL is based on\n"SCRAPE: Scalable…',html:'<!-- Reviewed at 18852484704ff4a7ce3fcac2791499c340eb8e02 -->\n<h1>PVSS Implementation in Cardano SL</h1>\n<p>Publicly Verifiable Secret Sharing (PVSS) Scheme used in Cardano SL is based on\n"SCRAPE: Scalable Randomness Attested by Public Entities", <a href="https://eprint.iacr.org/2017/216.pdf">paper</a>\nby Ignacio Cascudo and Bernardo David. Further we\'ll refer to this paper\'s pages,\nfor example <code>[6]</code> means the 6-th page.</p>\n<p>This guide describes implementation details of <code>pvss-haskell</code>\n<a href="https://github.com/input-output-hk/pvss-haskell">library</a> used by\n<a href="https://github.com/input-output-hk/cardano-sl/blob/65e295599817ec1f52f225810264d856f882fbb7/core/Pos/Crypto/SecretSharing.hs#L1">cardano-sl</a>\nlibrary.</p>\n<h2>What is PVSS</h2>\n<p>The core idea of VSS Scheme is an ability of participants to verify their own\nshares, for successful reconstruction of the secret (previously distributed by a\ndealer among the participants). But core idea of PVSS Scheme is that not just\nthe participants can verify their shares, but that anybody can verify that the\nparticipants received correct shares. So it\'s required (for our reconstruction\nprotocol) that participants not only release their shares but also that they\nprovide a proof of correctness for each share released (<code>[9]</code>).</p>\n<p>We use <code>t-out-of-n</code> reconstruction scheme (<code>[8]</code>), where <code>n</code> is a number of\nparticipants and <code>t</code> is a threshold number, so any subset of <code>t+1</code> shares can be\nused to successfully recover the secret.</p>\n<p>So, the protocol consists of four fundamental phases (<code>[8]</code>):</p>\n<ol>\n<li>setup,</li>\n<li>distribution,</li>\n<li>verification,</li>\n<li>reconstruction.</li>\n</ol>\n<h2>Setup</h2>\n<p>Each participant <code>Pi</code> must generate its private key <code>SKi</code> and register its public key <code>PKi</code>.</p>\n<h2>Distribution</h2>\n<p>First of all, we prepare a new escrowing context. To do it we need a\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L76">threshold</a>\nvalue mentioned above and a list of <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L175">public\nkeys</a>\nof participants. Result of this operation is\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L120"><code>Escrow</code></a>\nvalue which includes:</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L85">Extra generator</a>,</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/Polynomial.hs#L24">Polynomial</a>,</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L89">Secret</a>,</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/DLEQ.hs#L39">Proof</a>.</li>\n</ol>\n<p>Extra generator is based on a\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L92">Point</a>\n(<a href="http://hackage.haskell.org/package/cryptonite-openssl-0.6/docs/Crypto-OpenSSL-ECC.html#t:EcPoint">Elliptic Curve\nPoint</a>).\nWe use <code>prime256v1</code> elliptic curve, see\n<a href="https://www.ietf.org/rfc/rfc5480.txt">RFC</a>.</p>\n<p>Polynomial is a group of coefficient starting from the smallest degree (these\ncoefficients are\n<a href="http://hackage.haskell.org/package/cryptonite-0.23/docs/Crypto-PubKey-ECC-P256.html#t:Scalar">Scalar</a>\nvalues).</p>\n<p>Secret is based on a\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L92">Point</a>\nas well, actually it\'s the <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L140">first\nelement</a>\nof polynomial mentioned above.</p>\n<p>Proof is\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/DLEQ.hs#L62">generated</a>\nfrom a\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L142">challenge</a>,\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L140">raw\nsecret</a>\nand\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L143">DLEQ-parameters</a>.</p>\n<p>Challenge is based on <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L125">cryptographic\nhash</a>.</p>\n<p>After that we have to <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L168">finish escrow\ncreation</a>.\nList of participants\' public keys is used to <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L202">create encrypted\nshares</a>\nand\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L188">commitments</a>.\nEncrypted share includes:</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L82">Share ID</a>,</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L99">Value</a>\nencrypted by participant\'s public key,</li>\n<li><a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L99">Proof</a>\nthat this share is valid (<code>[8]</code>).</li>\n</ol>\n<h2>Verification</h2>\n<p>Now commitments and encrypted shares can be published among participants. Due\nthe public nature of PVSS scheme anyone who knows public keys can <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L249">verify\ndecrypted\nshares</a>\nvia hashes matching (<code>[8]</code>).</p>\n<h2>Reconstruction</h2>\n<p>First of all, participant must <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L230">decrypt encrypted\nshare</a>\nusing <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L59">keys\npair</a>\nwith its\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L80">private</a>\nand\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L84">public</a>\nkeys. To obtain DLEQ value, we use <code>prime256v1</code> <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L156">curve\ngenerator</a>.\nAs a result, we get\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L109"><code>DecryptedShare</code></a>.\nIts structure is the same as encrypted share.</p>\n<p>Since decrypted share contains a proof, we can be sure that decrypted share is\nthe same as encrypted one, there\'s <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L260">verification\nfunction</a>\nfor it. To <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/DLEQ.hs#L74">do\nit</a>\nwe use DLEQ value and <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L263">proof from the decrypted\nshare</a>.\nActual verifying is a\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/DLEQ.hs#L77">comparison</a>\nof the\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS/ECC.hs#L146">hash</a>\nof DLEQ points.</p>\n<p>Now, if we have <code>t+1</code> decrypted shares we can <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L285">recover a\nsecret</a>.</p>\n<p>Recovered secret can be\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L267">verified</a>\nas well, so we can be sure that secret recovered is the same escrow. To do it,\nwe need not just a proof and a secret, but\n<a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L268">commitments</a>\nas well (actually, the <a href="https://github.com/input-output-hk/pvss-haskell/blob/3c3926142c017255aa683256a1c8dd0c36cb9365/src/Crypto/PVSS.hs#L278">first\none</a>.</p>\n<h2>VSS Certificate</h2>\n<p>As <a href="/cardano/differences/#coin-tossing-and-verifiable-secret-sharing">said\nearlier</a>, one\nof the challenges while using a PVSS scheme is associating the public key used\nfor signing with the <a href="https://github.com/input-output-hk/cardano-sl/blob/fefc39f058f5a053fc1e59bc3594bdadf7699ca0/core/Pos/Crypto/SecretSharing.hs#L57">public\nkey</a>\nused for VSS scheme. This is solved by introducing <a href="https://github.com/input-output-hk/cardano-sl/blob/f0de5f1dd31cc4afb0c67a24deca713cf6304814/core/Pos/Core/Vss/Types.hs#L46">VSS\ncertificate</a>.</p>\n<p>VSS certificate includes:</p>\n<ol>\n<li>Public key used for the VSS scheme (e.g. <a href="https://github.com/input-output-hk/cardano-sl/blob/fefc39f058f5a053fc1e59bc3594bdadf7699ca0/core/Pos/Crypto/SecretSharing.hs#L57">VSS\nkey</a>).</li>\n<li>Public key used for signing (e.g. <a href="https://github.com/input-output-hk/cardano-sl/blob/f0de5f1dd31cc4afb0c67a24deca713cf6304814/core/Pos/Core/Vss/Types.hs#L51">signing\nkey</a>).</li>\n<li>Index of an expiry epoch (e.g. the last epoch when this certificate was\nvalid).</li>\n<li>Signature of a pair <code>(A,B)</code>, where <code>A</code> is a VSS key and <code>B</code> is an epoch\nindex.</li>\n</ol>\n<p>Initially, all stakeholders with enough stake to participate in randomness\ngeneration (we call them <a href="/glossary/#richman">richmen</a>) <a href="https://github.com/input-output-hk/cardano-sl/blob/35c6bff7409472352140f5207a7c79c59d8eaa8f/ssc/Pos/Ssc/GodTossing/Workers.hs#L163">have their own\ncertificates</a>.\nWhen a new stakeholder having enough stake appears, or when an existing\ncertificate expires, a new certificate should be generated and <a href="https://github.com/input-output-hk/cardano-sl/blob/35c6bff7409472352140f5207a7c79c59d8eaa8f/ssc/Pos/Ssc/GodTossing/Workers.hs#L166">submitted to the\nnetwork</a>.\nOther nodes accept this certificate if it\'s valid and if the node has enough\nstake. Certificates are stored in blocks.</p>\n<p>Please note that VSS certificate must be stable before usage! If an epoch we\nretrieve certificates for is the first one (i.e. has index <code>0</code>), stable\ncertificates are <a href="https://github.com/input-output-hk/cardano-sl/blob/35c6bff7409472352140f5207a7c79c59d8eaa8f/ssc/Pos/Ssc/GodTossing/Functions.hs#L139">genesis\nones</a>.\nOtherwise stable certificate are <a href="https://github.com/input-output-hk/cardano-sl/blob/35c6bff7409472352140f5207a7c79c59d8eaa8f/ssc/Pos/Ssc/GodTossing/Functions.hs#L141">non-expired certificates for the last known\nslot</a>.</p>',frontmatter:{path:"/en/technical/cardano-sl-pvss/",doc_title:"Cardano SL PVSS",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-02-16-delegation.md absPath of file >>> MarkdownRemark",excerpt:"Stake Delegation in Cardano SL This chapter describes implementation details of the stake delegation process. As described earlier…",html:'<!-- Reviewed at c23493d7a33a82d559d5bd9d289486795cf6592f -->\n<h1>Stake Delegation in Cardano SL</h1>\n<p>This chapter describes implementation details of the stake delegation process.</p>\n<p>As described earlier, stakeholders selected as slot leaders must be online in\norder to generate new blocks. However, such a situation can be unattractive,\nbecause a majority of elected stakeholders must participate in the Coin Tossing\nprotocol for refreshing randomness (crucial attribute of the slot leader\nelection process). If there are a lot of elected stakeholders, this can put a\nstrain on the stakeholders and the network, since it might require broadcasting\nand storing a large number of commitments and shares.</p>\n<p>Delegation feature allows stakeholders called <em>issuers</em> <code>I1...In</code> to transfer their\n"committee participation" to some <em>delegates</em> <code>D1...Dm</code>. These delegates will represent\nstakeholders <code>S1...Sn</code> in the <a href="https://github.com/input-output-hk/cardano-sl/blob/4bd49d6b852e778c52c60a384a47681acec02d22/src/Pos/Ssc/GodTossing.hs">Coin Tossing protocol</a>. In this case the actual\nnumber of nodes participating in the Coin Tossing protocol can be much lower,\nsee <a href="/glossary/#paper">paper</a>, page 38.</p>\n<p>Moreover, delegates are able not only to generate new blocks or taking part in <a href="/technical/leader-selection/#follow-the-satoshi">MPC/SSC</a>, but also to vote in the <a href="/cardano/update-mechanism/">Update system</a>.</p>\n<h2>Schema</h2>\n<p>The slot leader can transfer its right to generate a new block to the delegate. To do\nit, the slot-leader uses a <em>delegation-by-proxy</em> scheme: the slot leader generates <a href="https://github.com/input-output-hk/cardano-sl/blob/4378a616654ff47faf828ef51ab2f455fa53d3a3/core/Pos/Crypto/SignTag.hs#L33">a proxy\nsigning key</a>, or PSK, and the delegate will use it <a href="https://github.com/input-output-hk/cardano-sl/blob/ed6db6c8a44489e2919cd0e01582f638f4ad9b72/src/Pos/Delegation/Listeners.hs#L65">to\nsign</a>\nmessages to authenticate a block. There are two kinds of PSKs, heavyweight and\nlightweight (see below).</p>\n<p>Specifically, the stakeholder forms a special certificate specifying the delegates\nidentity via its public key. So later the delegate can sign messages within the\nvalid message space by providing signatures for these messages under its own\npublic key along with the signed certificate.</p>\n<p>This is the format of a <a href="https://github.com/input-output-hk/cardano-sl/blob/d01d392d49db8a25e17749173ec9bce057911191/core/Pos/Crypto/Signing.hs#L256">proxy\nsignature</a>.\nIt includes:</p>\n<ol>\n<li>proxy secret key,</li>\n<li>signature.</li>\n</ol>\n<p>The proxy secret key includes:</p>\n<ol>\n<li>omega value,</li>\n<li>issuer\'s public key,</li>\n<li>delegate\'s public key,</li>\n<li>proxy certificate.</li>\n</ol>\n<p>Omega (or ω) is a special value from the <a href="/glossary/#paper">paper</a>. In our\nimplementation, it is a <a href="https://github.com/input-output-hk/cardano-sl/blob/f374a970dadef0fe62cf69e8b9a6b8cc606b5c7d/core/Pos/Core/Types.hs#L235">pair of epochs\'\nidentifiers</a>. These identifiers define the delegation validity period: the produced block is\nvalid if its epoch index is inside this range.</p>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/d01d392d49db8a25e17749173ec9bce057911191/core/Pos/Crypto/Signing.hs#L209">Proxy certificate</a>\nis a <a href="https://github.com/input-output-hk/cardano-crypto/blob/84f8c358463bbf6bb09168aac5ad990faa9d310a/src/Cardano/Crypto/Wallet.hs#L74">signature</a>\nof omega and delegate\'s public key.</p>\n<h2>Heavyweight Delegation</h2>\n<p>Heavyweight delegation is using stake threshold <code>T</code>. It means that stakeholder\nhas to posses not less than <code>T</code> in order to participate in heavyweight\ndelegation. The value of this threshold is defined in the <a href="https://github.com/input-output-hk/cardano-sl/blob/42f413b65eeacb59d0b439d04073edcc5adc2656/lib/configuration.yaml#L224">configuration file</a>. Thus, the value of threshold for Mainnet is 0.03% of\nthe total stake. This value can be changed by update system.</p>\n<p>Proxy signing certificates from heavyweight delegation are stored within the blockchain.\nPlease note that issuer can post only one certificate per one epoch.</p>\n<p>Please note that heavyweight delegation has transitive relation. Thus, if <code>A</code> delegates to <code>B</code>\nand after that <code>B</code> delegates to <code>C</code> then <code>C</code>\'s delegated stake is equal to the sum <code>A + B</code>, not\njust <code>B</code>.</p>\n<h3>Expiration</h3>\n<p>Heavyweight delegation certificates expire in the beginning of every epoch if\nstakeholder does not pass threshold <code>T</code> anymore. This is made to prevent delegation\npool bloat attacks where user commits a certificate and moves all his money (above threshold)\nto another account, and then repeats the operation.</p>\n<h2>Lightweight Delegation</h2>\n<p><strong>WARNING: Currently, lightweight delegation is disabled and will be reworked in <a href="https://cardanoroadmap.com/">Shelley release</a>,\nso information below can be outdated.</strong></p>\n<p>In contrast to heavyweight delegation, lightweight delegation doesn\'t require\nthat delegate posses <code>T</code>-or-more stake. So lightweight delegation is available\nfor any node. But proxy signing certificates for lightweight delegation are not\nstored in the blockchain, so lightweight delegation certificate must be broadcasted\nto reach delegate.</p>\n<p>Later lightweight PSK can be\n<a href="https://github.com/input-output-hk/cardano-sl/blob/42f413b65eeacb59d0b439d04073edcc5adc2656/lib/src/Pos/Delegation/Logic/Mempool.hs#L309">verified</a>\ngiven issuer\'s public key, signature and message itself.</p>\n<p>Please note that the rule "only one certificate per epoch" doesn\'t apply to lightweight delegation.\nSince lightweight delegation certificates are not stored in the blockchain it\'s possible to issue\na lot of lightweight certificates per epoch and blockchain won\'t be bloated.</p>\n<h3>Confirmation of proxy signature delivery</h3>\n<p>The delegate should take the proxy signing key he has and make a signature of PSK using\nPSK and delegate\'s key. If the signature is correct, then it was done by the delegate\n(guaranteed by the PSK scheme).</p>\n<h2>Why Two Delegations?</h2>\n<p>You can think of heavyweight and lightweight delegations as of strong and weak delegations correspondingly.</p>\n<p>Heavyweight certificates are stored in the blockchain, so delegated stake may participate in MPC\nby being added to the stake of delegate. So delegate by many heavyweight delegations may accumulate\nenough stake to pass eligibility threshold. Moreover, heavyweight delegates can participate in voting\nfor Cardano SL updates.</p>\n<p>On the contrary, stake for lightweight delegation won\'t be counted in delegate\'s MPC-related stake. So\nlightweight delegation can be used for block generation only.</p>\n<h2>Revocation Certificate</h2>\n<p>Revocation certificate is a special certificate that issuer creates to revoke delegation.\nBoth heavyweight and lightweight delegation can be revoked, but not in the same way.</p>\n<p>The revocation certificate is the same as standard PSK where issuer and delegate are the same\n(in other words, issuer delegates to himself).</p>\n<p>To revoke lightweight delegation issuer sends revocation certificate to the network and\n<em>asks</em> to revoke delegation, but it cannot <em>enforce</em> this revocation, since lightweight PSKs\nare not the part of the blockchain. So theoretically lightweight delegate can ignore revocation\ncertificate, and in this case it will remain a delegate until its delegation certificate expires.\nBut such a situation won\'t compromise the blockchain.</p>\n<p>Revocation of heavyweight delegation is handled other way. Since proxy signing certificates\nfrom heavyweight delegation are stored within the blockchain, revocation certificate will be\ncommitted in the blockchain as well. In this case the node removes heavyweight delegation\ncertificate which was issued before revocation certificate. But there are three important notes\nabout it:</p>\n<ol>\n<li>If the committed heavyweight delegation certificate is in the node\'s memory pool, and revocation\ncertificate was committed as well, the delegation certificate will be removed from the memory pool.\nObviously, in this case delegation certificate will never be added to the blockchain.</li>\n<li>If a user commits heavyweight delegation certificate and <em>after that</em> he loses its money, he still\ncan revoke that delegation, even if by that time he does not have enough money (i.e. amount of money\nhe has is less than threshold <code>T</code> mentioned above).</li>\n<li>Although an issuer can post only one certificate in the current epoch, he <em>can</em> revoke his heavyweight\ndelegation in the same epoch.</li>\n</ol>',frontmatter:{path:"/en/technical/stake-delegation-in-cardano-sl/",doc_title:"Stake Delegation in Cardano SL",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/protocols/2017-01-04-p2p.cn.md absPath of file >>> MarkdownRemark",excerpt:"P2P 层 要与其他节点开始进行通信，节点必须加入网络，为此，节点必须知道已经参与到协议的其他节点；这个节点被称为 启动节点 （bootstrap node…",html:'<!-- Reviewed at ef835a2334888eda7384da707c4077a8b576b192 -->\n<h1>P2P 层</h1>\n<p>要与其他节点开始进行通信，节点必须加入网络，为此，节点必须知道已经参与到协议的其他节点；这个节点被称为<em>启动节点</em>（bootstrap node）。</p>\n<p>连接到启动节点后，我们收到一个我们将用于网络通信的对等体列表。那些同伴被称为邻节点。邻节点列表以这些节点在线的方式进行维护，来自网络的任何节点都可以收到我们的信息。而且，信息应该被有效地传递。</p>\n<p>为实现这一点，卡尔达诺结算层使用 <em>Kademlia</em> DHT 协议，尽管 Kademlia 提供了更多的功能，我们只是将其作为对等发现的一种方法。</p>\n<h2>Kademlia 协议概述</h2>\n<p><em>另请参阅：<a href="/technical#p2p-network">P2P 网络部分</a>的技术概览</em> （TOREVIEW）</p>\n<p>在 Kademlia 中，每个节点都与一个32字节的 ID（详细信息见 <a href="#id-structure">ID 结构</a>）相关联。这些 ID 用于标识节点，但不必参考其网络地址。用于在 Kademlia 存储值的键也是32字节的标识符。</p>\n<p>Kademlia 使用 XOR 度量来定义节点之间的距离。键值对存储在 ID 与『密钥』接近的节点中。这个距离也被用来有效地定位给定 ID 的节点。</p>\n<p>在开始时，应该为 Kademlia 提供引导节点以加入网络。在实现中，该节点的地址可以是硬编码或由用户选择。之后，节点将尝试通过查询其邻节点（从引导节点发出的对等端的初始列表）来查找更多对等端。节点向对等节点发送信息，消息重新发送到靠近该 ID/key 的对等体。对等体的列表在启动之间保留。</p>\n<p>完成之后，我们用 <code>(Host, Port, ID)</code> 表示<em>地址</em>，而用 <code>(Host, Port)</code> 表示<em>网络地址</em>。</p>\n<p>Kademlia 使用 UDP 协议传输消息。</p>\n<p>要详细了解如何实现 Kademlia，请参考 <a href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf">Kademlia: 基于 XOR 度量的 P2P 信息系统</a>。</p>\n<h2>Kademlia 中使用的消息</h2>\n<p>每条消息被表示为一个最长长度为<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Config.hs#L61">1200 字节</a> 的二进制字符串（因此它不会超过 IPv6 数据包大小）。一个特殊情况是 <code>RETURN_NODES</code>：如果超过1200字节，节点列表被分成几个消息。消息的数量用一个字节表示。请参阅 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Protocol.hs#L41"><code>serialize</code></a> 功能的更多细节。</p>\n<h3>IDs, 键和值</h3>\n<p>在 Kademlia 中，ID 和键用相同的叫做 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/HashNodeId.hs#L32"><code>HashId</code></a> 的结构表示：</p>\n<p><a name="id-structure"></a></p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>18</td>\n<td><em>Hash</em>\n - \n<em>PBKDF2</em>\n key generated from \n<em>Nonce</em></td>\n</tr>\n<tr>\n<td>14</td>\n<td><em>Nonce</em>\n - an arbitrary 14-bytes long binary string</td>\n</tr>\n</tbody>\n</table>\n<p>请阅读<a href="#addressing">地址部分</a>了解更多详情。</p>\n<p>卡尔达诺结算层不使用 Kademlia 作为键值存储。因此，我们只使用空字符串作为值。</p>\n<h3>PING</h3>\n<p>检查一个对等点是否仍然可以访问。在发送这个消息之后，节点期望收到 <em>PONG</em> 消息作为回复。Kademlia 周期性地 PING 每一个对等点来维护一个对等点网络。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>0</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n</tbody>\n</table>\n<h3>PONG</h3>\n<p>用做对 <code>PING</code> 消息的回复。</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>1</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n</tbody>\n</table>\n<h3>STORE</h3>\n<p>在 Kademlia 中存储给定的值。该消息被禁用，并被节点忽略。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>2</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>Key</td>\n</tr>\n<tr>\n<td>0</td>\n<td></td>\n<td>Value (empty string in Cardano SL)</td>\n</tr>\n</tbody>\n</table>\n<h3>FIND_NODE</h3>\n<p>请求给定 ID 节点的网络地址。在发送这个消息之后，节点希望收到一个 <code>RETURN_NODES</code> 消息，其中包含最接近请求消息的节点列表（包括请求的节点本身）</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>3</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of node we are looking for</td>\n</tr>\n</tbody>\n</table>\n<h3>RETURN_NODES</h3>\n<p>发送一些节点的网络地址回复给 <code>FIND_VALUE</code> 的 <code>FIND_NODE</code>。答案被分成几个消息，因为节点列表可以超过 IPv6 数据包大小。</p>\n<p>首先，我们描述一个对等体的二进制表示：</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td></td>\n<td>Peer ID</td>\n</tr>\n<tr>\n<td>1-255</td>\n<td></td>\n<td>Peer host name</td>\n</tr>\n<tr>\n<td>1</td>\n<td>32</td>\n<td>Ascii code of " " to separate host name from port</td>\n</tr>\n<tr>\n<td>2</td>\n<td></td>\n<td>Peer port</td>\n</tr>\n</tbody>\n</table>\n<p>现在我们来描述 <code>RETURN_NODES</code> 消息的二进制表示。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>4</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>1</td>\n<td></td>\n<td>Total number of \n<code>RETURN_NODES</code>\n messages sent as answer to this request</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of node that requested nodes</td>\n</tr>\n<tr>\n<td>at most 1136</td>\n<td></td>\n<td>Several peers close to the requested ID (at most 1136 bytes to not exceed IPv6 datagram size)</td>\n</tr>\n</tbody>\n</table>\n<h3>FIND_VALUE</h3>\n<p>除了在查找成功的情况下也收到响应之外，其行为与 <code>FIND_NODE</code> 相同。目前它只用于卡尔达诺结算层寻找对等体。当节点开始工作时，它会生成一个随机密钥，并要求 Kademlia 找到他；这个搜索总是失败，但是它让节点发现一些初始的对等地址。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>5</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>Key we are looking for</td>\n</tr>\n</tbody>\n</table>\n<h3>RETURN_VALUE</h3>\n<p>对 <code>STORE</code> 请求的回复。卡尔达诺结算层没有使用此信息，因为它不会 Kademlia 中存储任何值。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>6</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of node that requested value</td>\n</tr>\n<tr>\n<td>0</td>\n<td></td>\n<td>Value (empty string in Cardano SL)</td>\n</tr>\n</tbody>\n</table>\n<h2>安全</h2>\n<p>因为 Kademlia 是开放式 P2P 网络协议，因此必须通过几种方式修改才能变得相当安全。</p>\n<h3>可能的攻击</h3>\n<p><strong>eclipse 攻击</strong>是节点被攻击者节点包围的情况。</p>\n<p>在 Kademlia 中，eclipse 攻击（针对特定的网络参与者）很难执行，但有可能。首先，启动靠近目标节点 ID 的100个节点 ID。这些节点将填充最低的 <code>k</code>（最初是空的），然后对目标节点 <code>k</code> 进行 DDoS 攻击（如果网络的拓扑结构变化不大，可以确定这些节点已经启动）。在成功的 DDoS 攻击之后，节点的剩余邻节点将称为攻击者代理。</p>\n<p>请注意，Kademlia 的结构意味着靠近目标的引导节点不足以将其噬灭，节点列表由节点存储在 <code>k</code>-buckets 里（第 i 个 <code>k</code> 节点包含的节点数量不超过相对距离 <code>2^i-1 &#x3C; d &#x3C; 2^i</code>），只有当这些对应的 bucket 不满的时候，才会将新节点添加到相应的 bucket 中。Kademlia 更乐于长期在列表中的节点，看着它们还在线。没有一些节点下线，不太可能噬灭一个节点。</p>\n<p>这种攻击是棘手的，在实践中不太可能发生，<a href="#%E8%A7%A3%E5%86%B3">解决</a>中的修改使得它更难。</p>\n<p><strong>100500攻击</strong>是一个比当前P2P网络节点数量大得多的攻击，或者说为了噬灭一些节点或通过泛洪网络拒绝服务的攻击。这种攻击不会对旧节点造成任何问题（不包括可能的网络开销），因为旧的节点保存它们的路由。但当一个新的节点加入到网络时，它就会被噬灭（孤立在敌对的子网中），因为旧的诚实的节点不会把它添加到它的 bucket 中（因为这些 bucket 已经被其他节点填充了），并且新的节点会只有攻击者才知道。</p>\n<p>防止100500攻击仍然是一个悬而未决的问题，现在，我们通过一个复杂的禁止系统/攻击者检测来让它们几乎不可行。</p>\n<h3>解决</h3>\n<p>我们使用所谓的 <code>HashId</code> 作为节点 ID。由于它<a href="#id-structure">包含</a>一个散列，因此为自己分配一个任意的 ID 是不可能的，这意味着100500攻击是进行噬灭攻击的唯一方法。</p>\n<h4>实现 Notes</h4>\n<p><code>HashId</code> 是一个固定长度（32字节）的二进制字符串，如下所示：</p>\n<pre><code>+---------------+------------+\n|    Hashing    |    Nonce   |\n+---------------+------------+\n\n|   18 bytes    |  14 bytes  |\n</code></pre>\n<p>其中：</p>\n<ul>\n<li><code>Nonce</code> 只是随机的14个字节（来自系统的熵源）。</li>\n<li><code>Hashing</code> 是哈希数据。</li>\n</ul>\n<p>哈希数据基于 <code>DerivingKey</code> 和 <code>Salt</code>，其中：</p>\n<ul>\n<li><code>DerivingKey</code> 由 PBKDF2 (<a href="https://en.wikipedia.org/wiki/PBKDF2">基于密码的密钥推导函数2</a>) 生成。</li>\n<li><code>Salt</code> 是上面提到的 <code>Nonce</code> 的 SHA-512摘要。</li>\n</ul>\n<p>为生成 <code>DerivingKey</code>，我们使用这些参数：</p>\n<ul>\n<li><code>prfPassword</code> - 使用 HMAC（<a href="https://en.wikipedia.org/wiki/Hash-based_message_authentication_code">基于哈希的消息认证码</a>）和 SHA-256 算法为 PBKDF2 提供 PRF（伪随机函数） </li>\n<li><code>parameters</code> - PBKDF2 参数：500次迭代，32字节作为结果输出。</li>\n<li><code>Nonce</code> 如上所述 - 如 <code>password</code>。</li>\n<li><code>Salt</code> 如上所述 - 如 <code>Salt</code>。</li>\n</ul>\n<h3>路由数据防伪</h3>\n<p>在 Kademlia 中，一个节点向其邻节点请求一个对等体列表，并接受它收到的第一个消息。攻击者可以伪造这些答复，提供攻击者节点的地址作为给定 ID 的最近节点。为了解决这个问题，我们让节点等待一段时间来收集尽可能多的回复，然后，这些回复被合并，<code>k</code> 节点从结果集合中选择最近的节点。这样，攻击者就被不得不为了伪造它所接收的对等体列表而噬灭一个节点。</p>\n<h4>实现笔记</h4>\n<p>为实现这个想法，我们在每个 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L48">lookup</a>（<code>lookup</code> 是一个被 <code>FIND_NODE</code> 或 <code>FIND_VALUE</code> 用来找 <code>k</code> 个离给定 ID 最近的节点的函数）增加 <code>k</code> 个邻节点的<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L243">待处理</a>集合中。当我们收到 <code>RETURN_NODES</code> 信息，我们更新<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L242">已知</a>列表，使其包含当前最接近目标 ID 的 <code>k</code> 个节点。当没有挂起的节点时，该循环结束。我们在任何时期都不收集邻节点的答复。如果任何邻节点不给我们 <code>RETURN_NODES</code> 答复，我们收到 <code>Timeout</code> 信号，这个邻节点会由 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L286"><code>waitForReply</code></a>  函数处理。</p>\n<p>请参阅 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L371"><code>continueLookup</code></a>  功能。这是 <em>pending</em> 和 <em>known</em> 字段更新的地方，因此也是这个特性的核心逻辑。</p>\n<h3>路由表共享</h3>\n<p>当一个节点刚刚加入到网络时，它会请求一个邻节点列表（最靠近它的一组节点）。我们修改了 Kademlia，在这个列表中包含了一些额外的节点。具体来说，目前我们会随同邻节点选择一些随机节点并返回它们。这让被攻击节点包围的节点有额外的信息来恢复。</p>\n<h4>实现笔记</h4>\n<p>在我们的 Kademlia 实现中，有一个 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Tree.hs#L195"><code>findClosest</code></a> 函数来寻找给定 ID 节点的 <code>k</code> 个节点。增加了 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Tree.hs#L180"><code>pickupRandom</code></a> 功能。这个函数从 Kademlia 树中获取给定数量的随机节点。共享随机节点的确切数量是通过 Kademlia 配置中的 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Config.hs#L63"><code>routingSharingN</code></a> 字段来获得的。这样，<code>RETURN_NODES</code> 包含了 <code>findClosest</code> 和 <code>pickupRandom</code> 调用的结果。</p>\n<h3>禁止节点</h3>\n<p>我们为 Kademlia 引入了禁止节点的功能。当我们检测到恶意行为时，我们将使用这个来禁止节点。</p>\n<h4>实现笔记</h4>\n<p>节点有三种可能的状态：</p>\n<ol>\n<li><code>NoBan</code>，</li>\n<li><code>BanTill</code>，</li>\n<li><code>BanForever</code>。</li>\n</ol>\n<p>请看 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Instance.hs#L66"><code>BanState</code></a>  类型。这种类型的值会传给 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Instance.hs#L165"><code>banNode</code></a> 函数。</p>\n<p><code>NoBan</code> 用于接触已经被禁止的节点。但是，该操作不会将此节点重新插入到树结构，但可以使次节点再次出现在同级中。</p>\n<p><code>BanTill</code> 禁止某个节点（定义为 POSIX 时间）。</p>\n<p><code>BanForever</code> 永远禁止一个节点。</p>\n<p><code>banNode</code> 添加给定的节点到 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Instance.hs#L73"><code>KademliaState</code></a> 类型的 <code>banned</code> 字段，并从树中删除它。<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Instance.hs#L150"><code>isNodeBanned</code></a> 功能检查当前是否禁止节点，如果节点已经解除禁止，或禁止已经过期，则删除节点。</p>\n<p>如何处理禁止的节点：</p>\n<ul>\n<li>我们不能使用它作为我们的引导节点加入网络。请查看 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L152"><code>joinNetwork</code></a>  功能。</li>\n<li>我们忽略从禁止的节点收到的所有消息。请看 <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L286"><code>waitForReply</code></a>  功能。</li>\n<li>我们不会把这个节点包含在树中，不会发任何消息给它，也不会把这个节点加入到 <code>RETURN_NODES</code> 消息中。</li>\n</ul>',
  frontmatter:{path:"/cn/technical/protocols/p2p/",doc_title:"P2P 层",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/protocols/2017-01-07-time-warp-nt.cn.md absPath of file >>> MarkdownRemark",excerpt:"Time-Warp-NT 层 time-warp  是为提供不同抽象层次方法的可靠网络层而开发的。 time-warp…",html:'<!-- Reviewed at dcf5509d8fc93ac4c221726d076dafe632d32b70 -->\n<h1>Time-Warp-NT 层</h1>\n<p><a href="https://github.com/serokell/time-warp-nt/"><code>time-warp</code></a> 是为提供不同抽象层次方法的可靠网络层而开发的。<code>time-warp</code> 另一个重要的目标是提供一种使用仿真模式编写和运行分布式系统测试的简单方法，该模式可以足够灵活地支持各种情况（可调节网络延迟，断开连接和其他实时情况）。</p>\n<p><code>time-warp</code> 主要分为两个部分：</p>\n<ol>\n<li><code>Mockable</code> 接口。</li>\n<li>网络功能。</li>\n</ol>\n<h2>Mockable</h2>\n<p><a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Class.hs#L30"><code>Mockable</code></a> 接口允许从基本功能实现的语言特定细节中抽象出来。</p>\n<p>他们分成几个类别。例如，<a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Monad.hs#L21"><code>Mockable Delay</code></a> 包含 <code>delay</code> 操作，而 <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Monad.hs#L23"><code>Mockable Fork</code></a>  保留基本功能来操作线程。</p>\n<p>这个创新允许在生产和测试环境中启动相同的代码，后者允许模拟时间，线程，网络等。</p>\n<p><a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Production.hs#L42"><code>Production</code></a> <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Production.hs#L54-L219">实现了这些接口</a> ，并引用了各自功能的原型。</p>\n<h2>网络</h2>\n<p>该层写在<a href="https://github.com/serokell/network-transport/">网络传输</a>之上，为应用层提供网络功能。它被分成两个子层：<strong>低层</strong>和<strong>高层</strong>。</p>\n<h3>低层</h3>\n<p>这个子层是 <a href="https://github.com/serokell/network-transport/"><code>network-transport</code></a> 包的直接封装，它提供了一个方便的接口，允许发起轻量级的链接和发送/接收数据。请阅读<a href="/technical/protocols/network-transport">网络层传输指南</a>了解更多信息。</p>\n<p>它支持两种类型的连接，<strong>单向</strong>和<strong>双向</strong>。</p>\n<h4>单向连接</h4>\n<p>单向连接允许发送一个字节流而不用等待对方的响应。</p>\n<p><a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1465"><code>withOutChannel</code></a> 功能执行给定的操作，为其提供<a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1828">一次性的轻量级连接</a>。</p>\n<p>单向连接初始化时，节点<a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1376">发送 <code>U</code></a>。</p>\n<pre><code>+------------------+\n|       UNI        |\n+------------------+\n\n|   \'U\' :: Word8   |\n</code></pre>\n<p><code>Word8</code> 表示8位无符号整数值。</p>\n<h4>双向连接</h4>\n<p>双向连接允许两个节点相互发送和接收字节。</p>\n<p><a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1405"><code>withInOutChannel</code></a>  函数建立连接，用给定的句柄执行给定的动作，以在连接上发送和接收字节，并在动作结束时自动关闭连接。它的使用需要握手，其中包含以下步骤。</p>\n<p>首先，发起者<a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1443">发送</a>一个<strong>连接请求</strong>，其具有以下结构：</p>\n<pre><code>+------------------+-----------------+\n|     `BI_SYN`     |      Nonce      |\n+------------------+-----------------+\n\n|   \'S\' :: Word8   |   Word64 (BE)   |\n</code></pre>\n<p>其中 <code>Nonce</code> 是<a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1421">随机生成的</a>。</p>\n<p>然后对方<a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1072">发送</a>以如下结构发送<strong>确认</strong>：</p>\n<pre><code>+------------------+-----------------+--------------+\n|     `BI_ACK`     |      Nonce      |   PeerData   |\n+------------------+-----------------+--------------+\n\n|   \'A\' :: Word8   |   Word64 (BE)   |   Generic    |\n</code></pre>\n<p>其中 <code>Nonce</code> 是<a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1067">来自请求的相同随机数</a></p>\n<p>如果发起者已正确地随机数接收到确认，则开始对话。</p>\n<p>如果节点从未发送过任何请求（对等点发生协议错误），则会发生相反的情况。也有可能是节点确实发送了 <code>BI_SYN</code>，但对话的处理程序已经完成了。这是正常的，节点应该忽略这个确认。</p>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/4378a616654ff47faf828ef51ab2f455fa53d3a3/infra/Pos/Communication/Types/Protocol.hs#L58"><code>PeerData</code></a>  是由对等体发送并由发起者解析的一些附加信息。<code>time-warp</code> 使您能够在握手过程中提供一些二进制数据，然后以不同的方式使用您的应用程序。这个数据的结构是互通的，<a href="/technical/protocols/csl-application-level/#message-names"><em>应用程序级别</em>\n章节</a>描述了卡尔达诺结算层如何使用 <code>PeerData</code>。</p>\n<h3>消息</h3>\n<p>在讨论上层之前，我们来描述消息。</p>\n<p>为了让不同的消息类型指定不同的处理程序，发送的消息应该实现 <a href="https://github.com/serokell/time-warp-nt/blob/724769fe102752050e31ed8f609316a8a3e59589/src/Node/Message/Class.hs#L54"><code>Message</code></a>  接口，定义两种方法：</p>\n<ol>\n<li><code>messageName</code>，它将返回唯一的消息标识符，该标识符与消息本身一起发送，并允许接收者选择正确的处理程序来处理此消息。</li>\n<li><code>formatMessage</code>， 它提供消息的描述，用于调试。</li>\n</ol>\n<p>请查看 <code>Message</code> <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/test/Test/Util.hs#L133">实例</a>的 <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/test/Test/Util.hs#L127"><code>Parcel</code> 数据类型</a>作为例子。</p>\n<h3>上层</h3>\n<p>这个子层实现了数据交换。它提供了交流的<em>沟通方式</em>。该类型使用双向连接的功能，并允许发送/接收信息（一个或多个）。对于单个对话，输入和输出消息的类型是固定的。在这种情况下，发起方节点只发送一次消息名称，然后发起方和对方发送所需的消息。</p>\n<p>网络事件处理由 <a href="https://github.com/serokell/time-warp-nt/blob/e39f6b2c4a2aaaab308eddb9efee0503af73d927/src/Node.hs#L366"><code>node</code></a> 功能启动。这个函数使用了两个重要的概念：worker\n和 listener。</p>\n<p><strong>Worker</strong> 是作为所有通信发起者执行的一些动作，被用于提供提供 <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node.hs#L163"><code>withConnectionTo</code></a> 功能的 <a href="https://github.com/serokell/time-warp-nt/blob/e39f6b2c4a2aaaab308eddb9efee0503af73d927/src/Node.hs#L160"><code>SendActions</code> 类型</a>。这个函数启动<em>对话</em>，执行 <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node/Conversation.hs#L26"><code>ConversationActions</code></a> 给定的动作，一旦动作完成关闭会话。反过来，<code>ConversationActions</code> 提供 <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node/Conversation.hs#L28"><code>send</code></a> 和 <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node/Conversation.hs#L35"><code>recv</code></a> 功能来与对等点对话。</p>\n<p><strong><em>Listener</em></strong> 是一个消息的 <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node.hs#L117">handler</a>。每个相关消息的 listener 成员类型，以及几个不重复消息类型的 listeners 可以被定义。</p>\n<p>请查看<a href="https://github.com/serokell/time-warp-nt/blob/e39f6b2c4a2aaaab308eddb9efee0503af73d927/examples/PingPong.hs">完整例子</a>获取技术细节。</p>\n<h3>序列化</h3>\n<p><code>time-warp</code> 不依赖任何预定义的序列化策略，而是允许用户使用自己的。</p>\n<p>要定义自定义序列化，用户应该可以创建特殊的数据类型，即所谓的<em>打包类型</em>，并为其实现 <a href="https://github.com/serokell/time-warp-nt/blob/724769fe102752050e31ed8f609316a8a3e59589/src/Node/Message/Class.hs#L77"><code>Serializable</code></a>  接口。这个接口定义了两个方法：</p>\n<ol>\n<li><code>packMsg</code>，展示将数据压缩到原始字符串。</li>\n<li><code>unpackMsg</code>， 展示将数据解压缩。</li>\n</ol>\n<p>请查阅 <code>Serializable</code> <a href="https://github.com/serokell/time-warp-nt/blob/fef2c9943d279403386d204554b1c08fc357f196/src/Node/Message/Binary.hs#L43">实例</a>作为 <a href="https://github.com/serokell/time-warp-nt/blob/fef2c9943d279403386d204554b1c08fc357f196/src/Node/Message/Binary.hs#L20"><code>BinaryP</code> 数据类型</a>的例子。</p>',frontmatter:{path:"/cn/technical/protocols/time-warp-nt/",doc_title:"Time-Warp-NT 层",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/protocols/2017-01-10-network-transport.cn.md absPath of file >>> MarkdownRemark",excerpt:"网络传输层 本指南适用于想为卡尔达诺结算层构建自己的客户端的开发人员。请阅读 卡尔达诺结算层实现概述 了解更多信息。本指南涵盖了卡尔达诺结算层节点中使用的网络传输层。 传输层是一个位于 TCP…",html:'<!-- Reviewed at ef835a2334888eda7384da707c4077a8b576b192 -->\n<h1>网络传输层</h1>\n<p>本指南适用于想为卡尔达诺结算层构建自己的客户端的开发人员。请阅读<a href="/technical/">卡尔达诺结算层实现概述</a>了解更多信息。本指南涵盖了卡尔达诺结算层节点中使用的网络传输层。</p>\n<p>传输层是一个位于 TCP 和应用程序级协议的层。原则上独立于应用程序协议（事实上，参考实现被具有不同应用程序级协议的多个不同应用程序使用）。</p>\n<p>传输层的重点在于它提供了在单个 TCP 连接上复用的多个轻量级逻辑连接。每个轻量级连接都是单向的，并提供可靠的有序消息传输（即，它在 TCP 之上提供数据帧）</p>\n<p>传输协议的属性：</p>\n<ul>\n<li><strong>单个 TCP 连接</strong>。任何一对对等点之间一次只能使用一个 TCP 连接。这些连接可能是长期存在的。一旦建立了与对等节点的连接，它将用于发送/接收信息，直到 TCP 连接被<em>明确</em>关闭或发生一些不可恢复的错误。</li>\n</ul>\n<p>实现的属性：</p>\n<ul>\n<li><strong>报告网络故障</strong>。网络故障不会从应用程序层隐藏。如果 TCP 连接意外断开，传输层应通知应用层。在卡尔达诺结算层中，策略是尝试重新连接，如果重新连接也失败，则只声明对等方无法访问。</li>\n</ul>\n<h2>概要</h2>\n<p>传输层的典型用途包括：</p>\n<ol>\n<li>监听来自对等点的 TCP 连接。</li>\n<li>建立到其他对等点的 TCP 连接。</li>\n<li>在建立的 TCP 连接上创建轻型连接。</li>\n<li>发送消息到对等节点（在一个或多个轻量级连接上）。</li>\n<li>接收来自对等节点（在一个或多个轻量级连接上）的消息。</li>\n<li>关闭轻量级连接</li>\n<li>关闭 TCP 连接。</li>\n</ol>\n<p>在卡尔达诺结算层中，使用多个轻量级连接来支持应用程序级的消息传递协议。可以同时发送多个应用程序级别的消息，多个对话可以一次进行。大多数应用程序消息是在新创建的轻量级连接上发送的，如果需要的话，较大的应用程序级别消息被分解为多个传输级别消息以便于传输，其他应用程序级别的消息是作为一对单向轻量级连接组成的对话的一部分发送的。</p>\n<h2>概观</h2>\n<p>传输层的基本概念有：</p>\n<ul>\n<li>传输</li>\n<li>接入点</li>\n<li>连接</li>\n<li>事件</li>\n<li>错误</li>\n</ul>\n<p>传输指本文档描述的整个层和协议。</p>\n<p><strong>传输</strong>是指本文档描述的整个层和协议。一个传输实例指的是传输实现的配置和状态，特别是包括绑定到本地网络特定接口的TCP监听套接字，如 <code>192.168.0.1:3010</code>。</p>\n<p><strong>接入点</strong>是传输实例的逻辑端点。这意味着它又有一个地址，连接在端点之间。在实践中，它只是一个 TCP/IP 的简单抽象，通过主机名和端口进行寻址。</p>\n<p>端口地址是具有结构如 <code>HOST:PORT:LOCAL_ID</code> 的二进制字符串，例如 <code>192.168.0.1:3010:0</code>。</p>\n<p>注意，传输实例监听单个端口时，原则上在单个传输实例中可能有多个可寻址的接入点，这就是 <code>LOCAL_ID</code> 的作用，然而，卡尔达诺结算层目前还没有这个功能，所以它总是使用 <code>LOCAL_ID</code> 0。</p>\n<p><strong>重量级连接</strong>是指两个端点之前的 TCP 连接。两个接入点只使用一次 TCP 连接。</p>\n<p><strong>连接</strong>（或者更明确地说是<em>轻量级连接</em>）是端点之前的单向连接。端点之前的所有轻量级连接都在单个重量级连接（即单个TCP连接上）进行复用。</p>\n<p>轻量级连接是在 TCP 之上分层的逻辑概念。每个连接都有一个整数 ID。原则上可以在单个重量级 TCP 连接上复用数千个轻量级连接。</p>\n<p>典型的操作方式是应用层希望建立到端点的轻量级连接，如果还没有重量级连接，则创建一个。同样，当最后一个轻量级连接关闭时，真正的 TCP 连接将被彻底关闭。</p>\n<p>轻量级连接时单向的：轻量级连接上的消息仅在一个方向流动。但是，轻量级连接可以在任何方向上建立。同样的重量级连接用于双向的轻量级连接；哪个端点先建立重量级连接并不重要。</p>\n<p>双向会话可以通过使用一对单向轻量级连接来建立。卡尔达诺结算层遵循这种模式。请查阅 <code>time-warp-nt</code> 获取详细信息。但请注意，这个传输层没有双向对话的特殊概念，只有单向连接的集合。</p>\n<h2>网络字节顺序</h2>\n<p>在一下对控制消息的描述中，所有整数都是按<a href="https://en.wikipedia.org/wiki/Endianness#Networking">网络字节顺序</a>编码的。</p>\n<p>下面的消息定义使用的 <code>Int32</code> 指的是32位的以网络字节顺序的整数值。</p>\n<h2>设置传输实例</h2>\n<p>每个传输实例都必须建立一个 TCP 监听套接字。使用的本地端口和端口号由使用传输的应用程序确定。</p>\n<p>实现可以随时接收新的 TCP 连接（可能受限于资源策略），然后执行下面描述的新重量级连接的初始步骤。</p>\n<h2>建立重量级连接（初始化）</h2>\n<p>假设在接入点 A，B 之前建立重量级连接，端点 A 发起连接。两个端点都有端点地址，如前所述，端点地址是这种形式：<code>HOST:PORT:LOCAL_ID</code>。</p>\n<p>从 A 到 B 建立的一个重量级连接的过程如下。首先 A 必须在本地记录它正在初始化一个到 B 的重量级连接。在交叉连接请求的情况下（见下文）这是必须的，由端点 A 向端点 B 打开 <code>HOST</code> 和 <code>PORT</code> 连接。</p>\n<p>端点 A 发送具有如下结构的<strong>连接请求</strong>消息：</p>\n<pre><code>+-----------+-------------+--------------------+\n|   B-LID   |   A-EIDlen  |       A-EID        |\n+-----------+-------------+--------------------+\n|   Int32   |   Int32     |       bytes        |\n</code></pre>\n<p>其中：</p>\n<ul>\n<li><code>B-LID</code> - <code>B</code> 端点的本地 ID；</li>\n<li><code>A-EIDlen</code> - <code>A</code> 端点的地址；</li>\n<li><code>A-EID</code> - <code>A</code> 端口的地址。</li>\n</ul>\n<p>因此 A 发送它希望连接的本地接入点 ID，它自身的地址来初始化节点。A 发送的地址应该是规范化的公共地址。主机部分可以是 IP 地址或 DNS 名称。它用于避免在端点之间建立多个 TCP 连接。在卡尔达诺结算层协议中，本地端点 ID 始终为0。</p>\n<p>然后接入点 A 期望一个<strong>连接请求响应</strong>信息，它是下面的响应之一，一个简单的 <code>Int32</code> 编码。</p>\n<p>当本地接入点 ID 所标识的端点不存在时，会返回 <code>ConnectionRequestInvalid</code> 响应。例如，如果 A 发送给 B，它希望连接到本地接入点 ID 1，那么只有 ID 0 存在时才会发生。在这种情况下，两个端点必须关闭 TCP 连接。</p>\n<p>当端点 B 确定 A 与 B 之间或 B 与 A 之间，或两者同时有了一个 TCP 连接，会返回 <code>ConnectionRequestCrossed</code> 响应。在这种情况下，两个端点都必须关闭 TCP 连接。</p>\n<h2>建立重量级连接 (接收)</h2>\n<p>假设如前所述，在标记为 A 和 B 的端点之前建立重量级连接，并且端点 A 发起连接。我们现在从端点 B 的角度来考虑这个问题。</p>\n<p>两个端点都有 <code>HOST:PORT:LOCAL_ID</code> 形式的接入点地址。具体来说，假设 B 只有一个接入点，其中 <code>LOCAL_ID</code> 为 0。</p>\n<p>B 的传输实例在对应的接入点 IDs 上相应的 host 和 port 有监听套接字。它接受来自某个对等点的新的 TCP 连接。期望在该 TCP 连接上接收<strong>连接请求</strong>信息（以上述格式）。</p>\n<p>传输实例 B 必须根据以下规则以<strong>连接请求响应</strong>消息（采用上述格式）进行响应。</p>\n<p>如果连接请求要求本地接入点 ID 不存在（在本例中即不是0），则它必须以 <code>ConnectionRequestInvalid</code> 响应并关闭 TCP 连接。</p>\n<p><code>ConnectionRequestCrossed</code> 的规则将在下面更详细地描述。</p>\n<p>否则，当接入点 ID 有效并且没有现有的 TCP 连接时，它应该以 <code>ConnectionRequestAccepted</code> 回复，并记录它已经与 A 建立了重量级连接的本地状态。然后它就可以继续协议的主要部分。</p>\n<h2>交叉连接请求</h2>\n<p>如前所述，该协议试图确保在两个接入点之间只使用一个 TCP 连接。典型的情况是，端点可以简单地确定它是否具有与对等体的重量级连接。因为它启动它或接收它，并且知道现有的 TCP 连接是否仍然打开。难处理的情况是两个端点<em>同时</em>建立重量级连接（分布式系统意义上的『同一时间』）。</p>\n<p>每个端点初始化重量级连接的过程都记录在本地状态中。每个端点都将照常发送连接请求消息。当每个端点接受传入的 TCP 连接时，它会从连接请求消息获取端点 ID。</p>\n<p>额外的规则是，它必须在其本地状态查到，对等点的连接1. 已经建立（TODO）2. 已经完全确立。在第一种情况下，我们处于交叉连接的情况。第二种情况是当一个对等房发现现有的 TCP 连接失败（即它的端点被关闭），并且正尝试建立一个新的 TCP 连接，而其他的对等点没有发现已有的 TCP 连接已经失效了。</p>\n<h3>交叉连接情况</h3>\n<p>在交叉连接的情况下，到目前为止，这在端点之间是完全对称的，但我们必须打破对称来解决使用哪个 TCP 连接以及需要关闭哪个。协议用来打破对称性的解决方案的对端点地址进行排序（以二进制字符串形式按字典顺序排序）。因此，每个节点必须采用的用来决定是否接受传入连接请求的规则是：<code>ConnectionRequestAccepted</code>，如果对等点的 ID 小于本地端点 ID，则应答，否则回复 <code>ConnectionRequestCrossed</code>，关闭 TCP 连接。</p>\n<h3>连接断开/重建请求</h3>\n<p>在第二种情况下，处理传入 TCP 连接的端点已经确定在两个端点之前已经存在已建立的连接，该协议如下。发送一个 <code>ConnectionRequestCrossed</code> 回复，关闭 TCP 连接。此外，端点尝试验证现有连接的活跃性，目的是验证它是否处于活动状态，或确定它不是为了关闭断开的链接（这将允许打开新连接）。</p>\n<p>为了验证活跃性，接入点发送一个 <strong>ProbeSocket</strong> 信息。如果在实现定义的时间段内未收到 <strong>ProbeSocket</strong> 消息，则接入点应关闭 TCP 连接并相应地更新其本地状态，以使端点能够建立新的连接。</p>\n<p>接收 ProbeSocket 消息的接入点应该使用 ProbeSocketAck 回复。</p>\n<p>这些消息的编码很简单：</p>\n<pre><code>+-------------+\n| ProbeSocket |\n+-------------+\n|    Int32    |\n\n+----------------+\n| ProbeSocketAck |\n+----------------+\n|     Int32      |\n</code></pre>\n<p>其中控制头消息的值分别是 4 和 5。</p>\n<h2>协议主体</h2>\n<p>一旦在两个端点之间建立了一个重量级连接，协议的主要部分就开始了。</p>\n<p>两个端点之间的主要协议包括发送/接收一系列消息：控制消息和数据消息。每个都有一个标识消息的头部和适合消息类的主体部分。主协议的消息是用于创建和关闭轻量级连接的控制消息，以及用于在轻量级连接上发送数据的数据消息。</p>\n<p>轻量级连接时单向的。在 TCP 连接的每个方向都有独立的轻量级连接集合。<em>发送方</em>管理每个方向的轻量级连接。接收方不能直接控制轻量级连接的分配。</p>\n<p>轻量级连接由轻量级连接 ID 区分，这是一个 32 位的有符号整数。轻量级连接 ID 必须大于1024。轻量级连接 ID 号应该按顺序使用。</p>\n<p>用于创建或关闭轻量级连接的控制消息只是简单的区分它们所处的轻量级连接 ID。同样，数据消息根据正在发送的轻量级连接标识 ID。</p>\n<p>用于不同连接 ID 的消息可以任意交织（实现不同轻量级连接的复用）。唯一的约束是很显然的：对于任意连接 ID，消息序列必须是创建的连接消息，任意数量的数据消息以及关闭连接消息。</p>\n<p>这些消息的格式如下：</p>\n<pre><code>+-----------+-----------+\n| CreateCon |   LWCId   |\n+-----------+-----------+\n|   Int32   |   Int32   |\n\n+-----------+-----------+\n|  CloseCon |   LWCId   |\n+-----------+-----------+\n|   Int32   |   Int32   |\n\n+-----------+-----------+-------------------+\n|   LWCId   |    Len    |       Data        |\n+-----------+-----------+-------------------+\n|   Int32   |   Int32   |     Len-bytes     |\n</code></pre>\n<p>其中：</p>\n<ul>\n<li>CreateCon 控制头是 0；</li>\n<li>CloseCon 控制头是 1；</li>\n<li>LWCId 是轻量级的连接ID, 它 >= 1024。</li>\n</ul>\n<p>头部 Int32 是控制消息头部和数据消息的轻量级连接 ID 的别名，这就是为什么连接 ID 必须是1024或更大的原因。</p>\n<p>数据消息由轻量级连接 ID 和以长度为前缀的数据帧组成。这个协议的实现可能希望最大化这些数据帧，例如为了因资源考虑而确保连接之前合理的复用。</p>\n<p>请注意，这些数据边界和 TCP 套接字或数据包上的读取/写入之间不需要直接对应。为性能和网络效率考虑，在单一的写中管理连接开启，小数据消息和连接关闭是合理的。</p>\n<h2>关闭重量级连接</h2>\n<p>关闭重量级连接并不简单。这是因为只有在两个方向上的轻量级连接都关闭时，才能关闭重量级连接。鉴于轻量级连接的分配由每个端点独立控制，因此两个端点之间需要进行一些同步，以便两个端点在任意方向上不再有轻量级连接达到一致。</p>\n<p>当一个端点确定它没有更多的输出的轻量级连接，并且它知道传入的连接集是空的，那么它可以启动协议来关闭重量级连接。它通过发送一个 <strong>CloseSocket</strong> 来实现。该信息携带了该端点能看到的最大传入轻量级连接 ID：即由本地端点迄今为止已看到的远程端点分配的最高连接 ID。本地端点更新它用于跟踪远程端点的状态，以表明它现在正在关闭。如果本地端点现在收到来自远程端点的创建连接消息，而远程端点被标记为处于关闭过程中，则它将状态重置为正常连接建立状态。如果远程端点在收到关闭套接字消息之前打开一个新的轻量级连接，则会发生这种情况，因此应该尝试关闭应被禁止的套接字。</p>\n<p>当一个端点收到 <strong>CloseSocket</strong> 消息，检查其本地状态，已检查出站轻量级连接的数量以及它用于传出连接的最大轻量级连接 ID。如果仍然有出站连接，则关闭套接字消息将被忽略。此外，如果本地节点到目前为止使用的最大出站轻量级连接 ID 高于关闭套接字消息中收到的最大出站轻量级连接 ID，则关闭套接字消息将被忽略。即使出站连接数目前为零，如果出站连接被创建并在关闭套接字消息到达之前被关闭，也会发生这种情况。在这两种情况下发生的事情是，重量级连接再次变得活跃，而一方则由于不活跃而试图关闭它，因此放弃尝试关闭它是合适的。</p>\n<p>另一方面，如果没有出站连接，并且远程端点看到的最后一个新的连接 ID 与本地相同，则双方都同意，并且应该关闭 TCP 连接。</p>\n<p>消息结构是：</p>\n<pre><code>+-------------+-----------+\n| CloseSocket |   LWCId   |\n+-------------+-----------|\n|    Int32    |   Int32   |\n</code></pre>\n<p>其中：</p>\n<ul>\n<li><code>CloseSocket</code> - 关闭连接控制消息，值为 <code>2</code>;</li>\n<li><code>LWCId</code> - 迄今使用的最大轻量级连接 ID。</li>\n</ul>\n<h2>流量控制和背压（TODO）</h2>\n<p>轻量级连接不提供任何超出 TCP 提供的流量控制。该协议不提供任何设施来拒绝传入的轻量级连接。任何这样的设施都必须在顶层，在应用层或另一个中间层。</p>\n<p>实现应该考虑背压和头部堵塞问题。Head of line？是许多 TCP 协议层面的共同问题，例如 HTTP 1.x，其中一个较大的响应可以『阻塞』其他 URL 的较小的响应，因为这些响应式按顺序发送的。这个问题在这个传输协议中没那么严重，因为连接是复用的，所以小消息不需要被大消息阻塞。尽管如此，还是必须按顺序接收所有连接的多路复用数据流：不可能在整个重量级连接上返回一个轻量级连接。</p>',frontmatter:{path:"/cn/technical/protocols/network-transport/",doc_title:"网络传输层",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/protocols/2017-01-07-time-warp-nt.md absPath of file >>> MarkdownRemark",excerpt:"Time-Warp-NT Layer time-warp  is developed to provide\na reliable networking layer with different levels of abstractions. Another\nimportant…",html:'<!-- Reviewed at dcf5509d8fc93ac4c221726d076dafe632d32b70 -->\n<h1>Time-Warp-NT Layer</h1>\n<p><a href="https://github.com/serokell/time-warp-nt/"><code>time-warp</code></a> is developed to provide\na reliable networking layer with different levels of abstractions. Another\nimportant objective of <code>time-warp</code> is to provide an easy way to write and run\ntests for distributed systems using emulation mode, which should be flexible\nenough to support various scenarios (tunable network delays, disconnects,\nother real-time conditions).</p>\n<p><code>time-warp</code> is split up into two main parts:</p>\n<ol>\n<li><code>Mockable</code> interfaces.</li>\n<li>Network functionality.</li>\n</ol>\n<h2>Mockable</h2>\n<p><a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Class.hs#L30"><code>Mockable</code></a>\ninterfaces allow to abstract from language-specific details of implementation\nof the basic functions.</p>\n<p>They are split into several categories. For instance, <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Monad.hs#L21"><code>Mockable Delay</code></a> contains\n<code>delay</code> operation, while <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Monad.hs#L23"><code>Mockable Fork</code></a> keeps elementary functions to manipulate threads.</p>\n<p>This innovation allows to launch the same code both in production and testing\nenvironment, where the latter allows to emulate time, threads, networking, etc.</p>\n<p><a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Production.hs#L42"><code>Production</code></a> implements <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Mockable/Production.hs#L54-L219">all those interfaces</a> with references to respective prototypes of the functions.</p>\n<h2>Networking</h2>\n<p>This layer is written on top of <a href="https://github.com/serokell/network-transport/">network-transport</a>\nand provides network capabilities for the application layer. It is split up into two sub-layers:\n<strong>lower</strong> and <strong>upper</strong>.</p>\n<h3>Lower Layer</h3>\n<p>This sub-layer is a direct wrapper over <a href="https://github.com/serokell/network-transport/"><code>network-transport</code></a>\npackage, and it provides a convenient interface which allows to initiate lightweight\nconnection and send/receive data on it. Please read <a href="/technical/protocols/network-transport">Network Transport Layer\nguide</a> for more info.</p>\n<p>It supports two types of connections, <strong>unidirectional</strong> and <strong>bidirectional</strong>.</p>\n<h4>Unidirectional Connections</h4>\n<p>Unidirectional connections allow to send a stream of bytes without waiting for\npeer\'s response.</p>\n<p>The function <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1465"><code>withOutChannel</code></a> executes given action, providing it with <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1828">one-shot\nlightweight connection</a>.</p>\n<p>Upon unidirectional connection initialization, node <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1376">sends <code>U</code></a>:</p>\n<pre><code>+------------------+\n|       UNI        |\n+------------------+\n\n|   \'U\' :: Word8   |\n</code></pre>\n<p><code>Word8</code> represents 8-bit unsigned integer value.</p>\n<h4>Bidirectional Сonnections</h4>\n<p>Bidirectional connections allow both nodes to send and receive bytes to each\nother.</p>\n<p>The function <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1405"><code>withInOutChannel</code></a> establishes connection, executes given action\nwith given handle to send and receive bytes on connection, and automatically\ncloses connection on action\'s end. Its usage requires a handshake, which\ncontains the following steps.</p>\n<p>First, the initiator <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1443">sends</a> a <strong>connection request</strong>, which has the following\nstructure:</p>\n<pre><code>+------------------+-----------------+\n|     `BI_SYN`     |      Nonce      |\n+------------------+-----------------+\n\n|   \'S\' :: Word8   |   Word64 (BE)   |\n</code></pre>\n<p>where <code>Nonce</code> is <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1421">randomly generated</a>.</p>\n<p>Then the peer <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1072">sends</a> <strong>acknowledgement</strong>, with the following structure:</p>\n<pre><code>+------------------+-----------------+--------------+\n|     `BI_ACK`     |      Nonce      |   PeerData   |\n+------------------+-----------------+--------------+\n\n|   \'A\' :: Word8   |   Word64 (BE)   |   Generic    |\n</code></pre>\n<p>where <code>Nonce</code> is the <a href="https://github.com/serokell/time-warp-nt/blob/dfefb3ccbcd746909b10048e9f49641e1885a4ec/src/Node/Internal.hs#L1067">same nonce which came from request</a>.</p>\n<p>If the initiator receives the acknowledgement with correct nonce, a conversation\nis started.</p>\n<p>The opposite case could take place if the node have never sent any request on\nthat nonce (peer made a protocol error). It could also be that the node did send\nthe <code>BI_SYN</code>, but its handler for that conversation had already finished. That\'s\nnormal, and the node should ignore this acknowledgement.</p>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/4378a616654ff47faf828ef51ab2f455fa53d3a3/infra/Pos/Communication/Types/Protocol.hs#L58"><code>PeerData</code></a> is some additional information that is sent from the peer and parsed\nby the initiator. <code>time-warp</code> gives you an ability to provide some binary data\nduring handshake which then can be used by your application in different ways.\nThe structure of this data is generic. <a href="/technical/protocols/csl-application-level/#message-names"><em>Application Level</em>\nsection</a> describes\nhow Cardano SL uses <code>PeerData</code>.</p>\n<h3>Messaging</h3>\n<p>Before talking about upper layer, let\'s describe messaging.</p>\n<p>In order to specify different handlers for various message types, sent messages\nshould implement <a href="https://github.com/serokell/time-warp-nt/blob/724769fe102752050e31ed8f609316a8a3e59589/src/Node/Message/Class.hs#L54"><code>Message</code></a> interface, defining two methods:</p>\n<ol>\n<li><code>messageName</code>, it returns unique message identifier, which is sent along\nwith the message itself and allows receiver to select correct handler to\nprocess this message.</li>\n<li><code>formatMessage</code>, it provides description of message, for debug purposes.</li>\n</ol>\n<p>Please see <code>Message</code> <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/test/Test/Util.hs#L133">instance</a> for the <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/test/Test/Util.hs#L127"><code>Parcel</code> data type</a> as an example.</p>\n<h3>Upper Layer</h3>\n<p>This sub-layer enables message exchange. It provides <em>conversation style</em> of\ncommunication. This style uses capabilities of bidirectional connection and allows\nto send/receive messages (one or more). For a single conversation, types of incoming\nand outgoing messages are fixed. In this case, the initiator node sends the message\nname once, and then both the initiator and the peer send required messages.</p>\n<p>Network events processing is initiated by <a href="https://github.com/serokell/time-warp-nt/blob/e39f6b2c4a2aaaab308eddb9efee0503af73d927/src/Node.hs#L366"><code>node</code></a> function. This function uses two important concepts: worker\nand listener.</p>\n<p><strong><em>Worker</em></strong> is some action which performs as the initiator of all\ncommunication, being supplied with <a href="https://github.com/serokell/time-warp-nt/blob/e39f6b2c4a2aaaab308eddb9efee0503af73d927/src/Node.hs#L160"><code>SendActions</code> type</a> which provides\nfunction <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node.hs#L163"><code>withConnectionTo</code></a>.\nThis function initiates <em>conversation</em>, executing given action with\n<a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node/Conversation.hs#L26"><code>ConversationActions</code></a>\nprovided and closing conversation once action completes. In turn,\n<code>ConversationActions</code> provides <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node/Conversation.hs#L28"><code>send</code></a> and <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node/Conversation.hs#L35"><code>recv</code></a> functions to communicate with peer.</p>\n<p><strong><em>Listener</em></strong> is a <a href="https://github.com/serokell/time-warp-nt/blob/8a4c8792049a589cdc3e87f6a863b026430b266e/src/Node.hs#L117">handler</a>\nfor a message. Each listener remembers type of related message, and\nseveral listeners with non-overlapping message types could be defined.</p>\n<p>Please see <a href="https://github.com/serokell/time-warp-nt/blob/e39f6b2c4a2aaaab308eddb9efee0503af73d927/examples/PingPong.hs">complete example</a> for technical details.</p>\n<h3>Serialization</h3>\n<p><code>time-warp</code> doesn\'t rely on any predefined serialization strategy, but rather\nallows users to use their own.</p>\n<p>To define custom serialization, a user should create special data type, the\nso-called <em>packing type</em>, and implement <a href="https://github.com/serokell/time-warp-nt/blob/724769fe102752050e31ed8f609316a8a3e59589/src/Node/Message/Class.hs#L77"><code>Serializable</code></a> interface for it. This interface defines\ntwo methods:</p>\n<ol>\n<li><code>packMsg</code>, represents the way how to pack the data to raw bytestring.</li>\n<li><code>unpackMsg</code>, represents the way how to unpack the data.</li>\n</ol>\n<p>Please see <code>Serializable</code> <a href="https://github.com/serokell/time-warp-nt/blob/fef2c9943d279403386d204554b1c08fc357f196/src/Node/Message/Binary.hs#L43">instance</a> for the <a href="https://github.com/serokell/time-warp-nt/blob/fef2c9943d279403386d204554b1c08fc357f196/src/Node/Message/Binary.hs#L20"><code>BinaryP</code> data type</a> as an example.</p>',frontmatter:{path:"/en/technical/protocols/time-warp-nt/",doc_title:"Time-Warp-NT Layer",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical-protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/protocols/2017-01-01-application-level.cn.md absPath of file >>> MarkdownRemark",excerpt:"CSL 应用层消息 在本章中，我们探讨卡尔达诺结算层的消息传递。本章的目的是如何将所有的部分（如 Time-Warp, Network-Transport, 和\nKademlia DHT…",html:'<!-- Reviewed at 721474b760466b888cf26545b52b35989b2162de -->\n<h1>CSL 应用层消息</h1>\n<p>在本章中，我们探讨卡尔达诺结算层的消息传递。本章的目的是如何将所有的部分（如 Time-Warp, Network-Transport, 和\nKademlia DHT）组合在一起，实现完整的卡尔达诺结算层节点。</p>\n<h2>消息类型类和消息类型</h2>\n<p>阅读源代码时，你经常会遇到<a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L42">这样</a>的东西：</p>\n<pre><code class="language-haskell">-- | \'GetHeaders\' message (see protocol specification).\ndata MsgGetHeaders = MsgGetHeaders\n    { -- not guaranteed to be in any particular order\n      mghFrom :: ![HeaderHash]\n    , mghTo   :: !(Maybe HeaderHash)\n    } deriving (Generic, Show, Eq)\n\ninstance Message MsgGetHeaders where\n    messageName _ = varIntMName 4\n    formatMessage _ = "GetHeaders"\n</code></pre>\n<p>怎么阅读这些？首先，我们来看看这个 <code>instance</code> 部分。这个特定的片段是说，有类型定义的数据结构 <code>MsgGetHeaders</code> 被当做消息有效载荷。这样的消息的名字是 <code>"GetHeaders"</code>。</p>\n<p>在这个特定的案例中，数据结构有两个字段：<code>mghFrom</code> 和 <code>mghTo</code>。使用 <code>mgh</code> 这样的前缀，是因为 Haskell 把记录字段的符号放在全局名字空间中，所有程序员有责任避免冲突。</p>\n<p>应该指出的是，有时你会看到使用类型变量 <code>ssc</code> 进行参数化的消息。这是为了使与我们进行共享种子计算的方式在代码上是多态的。<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/src/Pos/Block/Network/Types.hs#L65-L67">这里</a>是一个消息的例子，首先发送最新的头部，记作 <code>ssc</code>。</p>\n<p>消息序列化的方式可以在 <a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/src/Pos/Binary/Communication.hs"><code>Pos.Binary.Communication</code></a> 模块看到。</p>\n<p>每个消息类型都应该有一个 <code>Message</code> 类型类的实例。请参阅 <a href="/technical/protocols/time-warp-nt/#messaging">Time-Warp-NT 指南</a>了解更多信息。</p>\n<h2>Inv/Req/Data 和 MessagePart</h2>\n<p>卡尔达诺结算层的大部分消息都是 <code>Inv/Req/Data</code> 标准化的（参见 <a href="https://github.com/input-output-hk/cardano-sl/blob/4378a616654ff47faf828ef51ab2f455fa53d3a3/infra/Pos/Communication/Types/Relay.hs#L23"><code>Pos.Communication.Relay</code></a> 模块）。在这个框架内，我们定义了三种数据类型：</p>\n<pre><code class="language-haskell">-- | Inventory message. Can be used to announce the fact that you have\n-- some data.\ndata InvMsg key = InvMsg\n    { imKey :: !key\n    }\n    deriving (Show, Eq)\n\n-- | Request message. Can be used to request data (ideally data which\n-- was previously announced by inventory message).\ndata ReqMsg key = ReqMsg\n    { rmKey :: !key\n    }\n    deriving (Show, Eq)\n\n-- | Data message. Can be used to send actual data.\ndata DataMsg contents = DataMsg\n    { dmContents :: !contents\n    }\n    deriving (Show, Eq)\n</code></pre>\n<p>这里：</p>\n<ul>\n<li><code>key</code> 表示节点标示符的类型。</li>\n<li><code>contents</code> 表示实际消息有效载荷的类型。</li>\n</ul>\n<p>为了通过 <code>Inv/Req/Data</code> 引入新消息，应该创建两种类型：这个消息的 <code>key</code> 和 <code>contents</code>，然后为它们都实现 <a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/infra/Pos/Communication/MessagePart.hs#L9"><code>MessagePart</code></a>。</p>\n<pre><code class="language-haskell">class MessagePart a where\n    pMessageName :: Proxy a -> MessageName\n</code></pre>\n<p>这里，<code>pMessageName</code> 是一个特定消息类型的标识符。</p>\n<p><code>InvMsg key</code> 的 <code>Message</code> 的类型类，<code>ReqMsg key</code> 和 <code>DataMsg contents</code> 自动从 <code>MessagePart</code> 类型类派生出特定的键和内容。</p>\n<p>请参阅 <a href="https://github.com/input-output-hk/cardano-sl/blob/3d695fd804814647f50abe452a81a678aad080cc/src/Pos/Communication/Message.hs"><code>Pos.Communication.Message</code></a> 模块了解使用 <code>Inv/Req/Data</code> 的消息例子。</p>\n<h2>区块交换信息</h2>\n<!-- Updated at 3b657302dede832b908f7ba792a164c83b362712 -->\n<p>该表格解释了 <a href="https://github.com/input-output-hk/cardano-sl/blob/309142c899ed898eaa877d959818a06fbbb37db0/src/Pos/Block/Network/Types.hs"><code>Pos.Block.Network.Types</code></a> 模块。</p>\n<table>\n<thead>\n<tr>\n<th>Message type</th>\n<th>Payload</th>\n<th>Comments</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>MsgGetHeaders</code></td>\n<td>Header hash checkpoints (optional newest hash we\'re interested in)</td>\n<td>Expect newest header first</td>\n</tr>\n<tr>\n<td><code>MsgGetBlocks</code></td>\n<td>Oldest header hash (newest hash)</td>\n<td>Both hashes have to be present</td>\n</tr>\n<tr>\n<td><code>MsgHeaders</code></td>\n<td>Non-empty collection of block headers, newest first</td>\n<td>Polymorphic in \n<code>ssc</code></td>\n</tr>\n<tr>\n<td><code>MsgBlock</code></td>\n<td>A single block</td>\n<td>Polymorphic in \n<code>ssc</code></td>\n</tr>\n</tbody>\n</table>\n<p>有关详细信息，请参阅<a href="/technical/protocols/binary-protocols/#block-exchange-messages">二进制协议</a>。</p>\n<h2>消息名称</h2>\n<p>所有消息都有给定的名字，因为使用完整的类型名称超过了限度。每个名称是一个或两个 <code>UnsignedVarInt</code> 编码的串联。</p>\n<p>该表包含所有使用的消息部分的名称。这些名字也可以在 <a href="https://github.com/input-output-hk/cardano-sl/blob/0906d8abc8e4ba8e1366defc3af0f5363e530146/src/Pos/Communication/Message.hs"><code>Pos.Communication.Message</code></a> 模块中找到。为了区分整数加法，连接在这里表示为 <code>(++)</code></p>\n<table>\n<thead>\n<tr>\n<th>Message type</th>\n<th>Message name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>MsgGetHeaders</td>\n<td><code>4</code></td>\n</tr>\n<tr>\n<td>MsgHeaders</td>\n<td><code>5</code></td>\n</tr>\n<tr>\n<td>MsgGetBlocks</td>\n<td><code>6</code></td>\n</tr>\n<tr>\n<td>MsgBlock</td>\n<td><code>7</code></td>\n</tr>\n<tr>\n<td>ReqMsg</td>\n<td><code>9</code>\n ++ \n<code>pMessageName key</code></td>\n</tr>\n<tr>\n<td>MempoolMsg</td>\n<td><code>10</code>\n ++ \n<code>pMessageName tag</code></td>\n</tr>\n<tr>\n<td>DataMsg</td>\n<td><code>11</code>\n ++ \n<code>pMessageName contents</code></td>\n</tr>\n<tr>\n<td>InvMsg</td>\n<td><code>12</code>\n ++ \n<code>pMessageName key</code></td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th>Message part type</th>\n<th>Name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>TxMsgContents</code></td>\n<td><code>0</code></td>\n</tr>\n<tr>\n<td>(\n<code>UpdateProposal</code>\n, \n[\n<code>UpdateVote</code>\n]\n)</td>\n<td><code>1</code></td>\n</tr>\n<tr>\n<td><code>UpdateVote</code></td>\n<td><code>2</code></td>\n</tr>\n</tbody>\n</table>\n<p>因为 <code>cardano-sl</code> 随附系统更新协议，消息格式也可以改变。所以节点应该知道其他节点正在运行的协议。了解这些信息，节点可以选择一个消息名称发送给对等体。该消息表名 <a href="/technical/protocols/time-warp-nt/#bidirectional-%D1%81onnections"><code>PeerData</code></a> 会在握手期间的每个对话动作之前被发送。<a href="/technical/protocols/binary-protocols/#peer-data">二进制协议</a>章节中 <code>PeerData</code> 描述了确切的二进制格式。</p>\n<h2>消息限制</h2>\n<p>消息具有最大长度限制。不同类型的消息具有不同的限制，在 <a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/src/Pos/Communication/Limits.hs"><code>Pos.Communication.Limits</code></a> 模块中有定义。 </p>\n<h2>委派消息</h2>\n<p>委派是这样一个功能，它允许一个叫做 <em>issuer</em> 的权益所有人让另一个权益所有人（称为委托人）来代表它来生成块。</p>\n<p>为此，issuer 应该创建代理签名密钥，允许委托人签署代替 issuer 的区块。任何权益所有人都可以验证代理签名密钥实际上是由特定权益所有人通过特定代理发布的，并且该密钥在某个时间段是有效的。</p>\n<p>委派可以有两种类型：per-epoch 委派和可撤销的长期证书的授权。每个 Per-epoch 委派称为『轻量级』，而长期的委派称为『重量级』。</p>\n<p>请阅读『<a href="/technical/delegation/">卡尔达诺结算层的权益委派</a>』获取更多信息。</p>\n<h3>轻量级委派</h3>\n<p><strong>警告：目前，轻量级委派已被禁用，并将在 <a href="https://cardanoroadmap.com/">Shelley 版本</a>进行重新整理，因此下面的信息可能已过时</strong>。</p>\n<p>轻量级委派允许委派人替代 issuer 在一定范围内的 epochs 生成区块（这个范围是签名密钥指定的）</p>\n<p>为此，issuer 应该通过网络发送包含时间范围的消息，issuer 密钥，委派公钥和证书。来自网络的每个节点都会收到这条消息，并可以稍后检查生成该块的人是否合适。轻量级委派数据存储在内存中，在一段时间后会被删除（<a href="https://github.com/input-output-hk/cardano-sl/blob/acc53f53a20c7985d6550b4812117e44db08a70b/core/constants.yaml#L55">在配置文件中定义</a>)。</p>\n<p>这种授权类型可以用于在发行人知道某个时间范围内不存在的情况下将生成区块的权利委托给某个可信任的节点。</p>\n<h3>重量级委派</h3>\n<p>重量级委派有两个目的：</p>\n<ol>\n<li>就像轻量级委派那样，委派生成区块的权利。</li>\n<li>与一些代表分享股份，从而允许代表参与<a href="/glossary/#follow-the-satoshi">追随中本聪算法</a>。没有真正的金钱转移；在为<a href="/glossary/#follow-the-satoshi">追随中本聪算法</a>计算权益所有人时，issuer 的权益被加到代表的权益中。</li>\n</ol>\n<p>每一个特定的权益所有人最多能与一个代表分享权益。为了撤销证书，节点应该创建一个新的证书，并将其自身同时作为颁发者和委托者。</p>\n<h3>消息列表</h3>\n<p>在 <a href="https://github.com/input-output-hk/cardano-sl/blob/6e8f8a98fd1537d084341a27a843e08dacc9f1eb/src/Pos/Delegation/Types.hs"><code>Pos.Delegation.Types</code></a> 模块中有与委托相关的消息。授权消息的格式在<a href="/technical/protocols/binary-protocols/#delegation">二进制协议</a>章节有描述。</p>\n<h2>更新系统消息</h2>\n<p>你可以在 <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Communication/Methods.hs"><code>Pos.Communication.Methods</code></a> 模块的 <code>WorkMode</code> 看到消息系统是怎么实现的。</p>\n<table>\n<thead>\n<tr>\n<th>Message type</th>\n<th>Comments</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>UpdateProposal</code></td>\n<td>Serialized update proposal, sent to a DHT peers</td>\n</tr>\n<tr>\n<td><code>UpdateVote</code></td>\n<td>Message, payload of which contains the actual vote</td>\n</tr>\n</tbody>\n</table>\n<p>请参阅 <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Communication/Methods.hs#L47"><code>sendUpdateProposal</code></a> 和 <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Communication/Methods.hs#L40"><code>sendVote</code></a> 功能的更多细节。</p>\n<h1>Workers, Listeners 和 Handlers</h1>\n<p>你可以把它们视为消息的『操作人员』</p>\n<p><strong>Workers</strong> 发起消息交换，因此 worker 是卡尔达诺结算层的积极通信部分。<strong>Listeners</strong> 可以从 workers 接收信息，且可能会发送一些消息作为回复。因此 listener 是卡尔达诺结算层的被动通信部分，收到信息后，listener 使用一种叫做 <strong>handler</strong> 的函数来实际执行相应的作业。根据收到的信息的类型使用特定的处理程序（如上所述，消息具有不同的类型）。</p>\n<p>为了能够执行必要的操作，所有的 workers 和 handlers 在 <code>WorkMode</code> 进行工作（见下文）。</p>\n<h2>区块处理</h2>\n<p>上面描述了区块交换信息。</p>\n<h3>区块处理 Workers</h3>\n<p>获取块在 <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs"><code>Pos.Block.Network.Retrieval</code></a> 模块中进行处理。</p>\n<p>这个 <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs#L50"><code>retrievalWorker</code></a> 非常重要：它是一个在<a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs#L84">区块检索队列</a>上验证头文件的服务器，这些区块形成一个合适的链。它发送一个 <code>MsgGetBlocks</code> 类型的信息给 listener，<a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs#L284">此时</a>它从这个 listener 接收一个类型为 <code>MsgBlock</code> 信息的回答。</p>\n<p>这是另一个例子 - <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Logic.hs#L261"><code>requestHeaders</code></a> 功能。这个函数处理预期的区块头，并在本地跟踪它们。在<a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Logic.hs#L271">这个地方</a>，它向 listener 发送一种类型为 <code>MsgGetHeaders</code> 的信息，而<a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Logic.hs#L275">在这</a>，它从这个 listener 接收一个类型为 <code>MsgHeaders</code> 的回答。</p>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/d564b3f5a7e03e086b62c88212870b5ea89f5e8b/src/Pos/Block/Worker.hs"><code>Pos.Block.Worker</code></a> 模块中定义了用于区块处理的其他 worker。我们重用了上述的 <code>retrievalWorker</code>（TODO：and define a\n<a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Worker.hs#L82">well-documented</a>），并记载了一个记录良好的 <code>blkOnNewSlot</code> worker。它代表了一个新 slot 开始时应该完成的操作，这个操作包括以下步骤：</p>\n<ol>\n<li>如有必要，生成一个<a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Worker.hs#L100">创始区块</a>。</li>\n<li>获取当前 epoch 的 leader。</li>\n<li>如果我们是 slot 领导者，或者我们委派这么做，<a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Worker.hs#L114">生成起始区块</a>（可选）。</li>\n</ol>\n<h3>逻辑</h3>\n<p>处理区块的方式在 <a href="https://github.com/input-output-hk/cardano-sl/tree/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Logic"><code>Pos.Block.Logic</code></a> 模块中定义。请阅读<a href="/technical/blocks/">卡尔达诺结算层中的区块</a>获取关于区块的更多信息。</p>\n<h3>区块处理 Listeners</h3>\n<p>区块处理的 Listeners 在 <a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Network/Listeners.hs"><code>Pos.Block.Network.Listeners</code></a> 模块中定义。</p>\n<p>处理程序 <a href="https://github.com/input-output-hk/cardano-sl/blob/fa5d01c08124934f01f2df22f2bc8784198f56c0/src/Pos/Block/Network/Listeners.hs#L46"><code>handleGetHeaders</code></a> 发送区块头部：<a href="https://github.com/input-output-hk/cardano-sl/blob/fa5d01c08124934f01f2df22f2bc8784198f56c0/src/Pos/Block/Network/Listeners.hs#L89">在这</a>，它从 worker 收到一个 <code>MsgGetHeaders</code> 类型的信息，<a href="https://github.com/input-output-hk/cardano-sl/blob/fa5d01c08124934f01f2df22f2bc8784198f56c0/src/Pos/Block/Network/Listeners.hs#L95">获取头部</a>，然后<a href="https://github.com/input-output-hk/cardano-sl/blob/92cf690dc3be9af29502f493cbf9e8072b56cb67/src/Pos/Block/Network/Logic.hs#L140">在这</a>，它向 worker 发送 <code>MsgHeaders</code> 类型的回复信息。</p>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/fa5d01c08124934f01f2df22f2bc8784198f56c0/src/Pos/Block/Network/Listeners.hs#L54"><code>handleGetBlocks</code></a> 处理程序发送区块。这个处理程序对应 <a href="https://github.com/input-output-hk/cardano-sl/blob/08fa863502baeb399e15f525540050a117430d95/src/Pos/Block/Network/Retrieval.hs#L50"><code>retrievalWorker</code></a> 的 <a href="https://github.com/input-output-hk/cardano-sl/blob/08fa863502baeb399e15f525540050a117430d95/src/Pos/Block/Network/Retrieval.hs#L319"><code>retrieveBlocks</code></a>，因此，它从 worker <a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Network/Listeners.hs#L60">这里</a>接收 <code>MsgGetBlocks</code> 类型的信息，<a href="https://github.com/input-output-hk/cardano-sl/blob/7fdf6c8d0d2f62948f4685b923b7671db137d7b3/src/Pos/Block/Logic/Header.hs#L331">获得对应的头部</a> ，然后<a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Network/Listeners.hs#L71">在这里</a>向这个 worker 发送 <code>MsgBlock</code> 类型的响应信息。</p>\n<p>处理程序 <a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Block/Network/Listeners.hs#L85"><code>handleBlockHeaders</code></a> 以类似的方式发送未经请求的用例的区块头部：它接收来自 worker 的 <a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Block/Network/Listeners.hs#L95"><code>MsgHeaders</code></a> 类型，并处理它。</p>\n<h2>委派</h2>\n<p>另一个例子是使用上述的委派信息</p>\n<h3>Workers</h3>\n<p>委派信息的 Worker 在 <a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Delegation/Worker.hs"><code>Pos.Delegation.Worker</code></a> 模块中定义。</p>\n<p>所有这些 workers 不会发送信息到一个特定的节点。他们发送信息给所有的邻节点。</p>\n<h3>Listeners</h3>\n<p>委派消息的 Listeners 在 <a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Delegation/Listeners.hs"><code>Pos.Delegation.Listeners</code></a> 模块中定义。</p>\n<h2>安全</h2>\n<p>进行安全操作的 workers 在 <a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Security/Workers.hs"><code>Pos.Security.Workers</code></a> 模块中定义。</p>\n<h2>更新系统</h2>\n<p>以下是与更新系统相关的工作人员和听众列表。</p>\n<h3>Workers</h3>\n<p>更新系统的 worker 在 <a href="https://github.com/input-output-hk/cardano-sl/blob/73cf4fc35d3cfb068458f2b6982990d08a99906e/src/Pos/Update/Worker.hs"><code>Pos.Update.Worker</code></a> 模块中定义。更新系统所做的唯一事情是在每个 slot 上<a href="https://github.com/input-output-hk/cardano-sl/blob/73cf4fc35d3cfb068458f2b6982990d08a99906e/src/Pos/Update/Worker.hs#L27">检查</a>新的已批准更新。</p>\n<h3>Listeners</h3>\n<p>更新系统的 Listeners 在 <a href="https://github.com/input-output-hk/cardano-sl/blob/22360aa45e5dd82d0c87872d8530217fc3d08f4a/src/Pos/Update/Network/Listeners.hs"><code>Pos.Update.Network.Listeners</code></a> 模块中定义。</p>\n<p><code>UpdateProposal</code> 中继器:</p>\n<ul>\n<li><code>Req</code> — 本地节点回答关于更新提案的请求，并针对此提案进行一组投票。</li>\n<li><code>Inv</code> — 检查我们是否需要提供的提案，并记录数据是否与此库存消息相关。</li>\n<li><code>Data</code> — 将提案信息与投票一起进行验证和记录。</li>\n</ul>\n<p><code>UpdateVote</code> listeners:</p>\n<ul>\n<li><code>Req</code> — 把<em>我们</em>的投票发给任何人。</li>\n<li><code>Inv</code> — 检查我们是否需要提供的投票，并记录相关的。</li>\n<li><code>Data</code> — 进行一次投票，核实和记录。</li>\n</ul>\n<h2>WorkMode 和 MinWorkMode</h2>\n<p>有一个特殊的类型称为 <a href="https://github.com/input-output-hk/cardano-sl/blob/73cf4fc35d3cfb068458f2b6982990d08a99906e/src/Pos/WorkMode/Class.hs#L65"><code>WorkMode</code></a>，<a href="https://github.com/input-output-hk/cardano-sl/blob/73cf4fc35d3cfb068458f2b6982990d08a99906e/src/Pos/WorkMode/Class.hs#L107"><code>MinWorkMode</code></a>  表示一系列执行真实世界的分布式系统的工作的约束条件。你可以把约束看做<em>运行时保证</em>，它可以在特定的上下文执行特定的操作。例如，如果我们根据 <strong>logging</strong> 约束定义一些函数 <code>f</code> 的类型，我们肯定知道我们在这个函数 <code>f</code> 里面记录不同的信息。</p>\n<p>上面描述的所有 workers 和 handlers 都受 <code>WorkMode</code> 的限制。</p>',
  frontmatter:{path:"/cn/technical/protocols/csl-application-level/",doc_title:"CSL 应用层消息",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/protocols/2017-01-01-application-level.md absPath of file >>> MarkdownRemark",excerpt:"CSL Application-Level Messaging In this chapter we explore messaging in Cardano SL. The goal of this chapter\nis to explain how all the…",html:'<!-- Reviewed at 721474b760466b888cf26545b52b35989b2162de -->\n<h1>CSL Application-Level Messaging</h1>\n<p>In this chapter we explore messaging in Cardano SL. The goal of this chapter\nis to explain how all the pieces, such as Time-Warp, Network-Transport, and\nKademlia DHT, click together and make implementing a full Cardano SL node\npossible.</p>\n<h2>Message Typeclass and Message Types</h2>\n<p>When reading the source code, you often encounter things like\n<a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L42">this</a></p>\n<pre><code class="language-haskell">-- | \'GetHeaders\' message (see protocol specification).\ndata MsgGetHeaders = MsgGetHeaders\n    { -- not guaranteed to be in any particular order\n      mghFrom :: ![HeaderHash]\n    , mghTo   :: !(Maybe HeaderHash)\n    } deriving (Generic, Show, Eq)\n\ninstance Message MsgGetHeaders where\n    messageName _ = varIntMName 4\n    formatMessage _ = "GetHeaders"\n</code></pre>\n<p>How do you read this? First, let\'s examine the <code>instance</code> part. This particular\nsnippet says that the data structure defined by type <code>MsgGetHeaders</code> is used as\na message payload. The name of such message is <code>"GetHeaders"</code>.</p>\n<p>In this particular case, the data structure has two fields: <code>mghFrom</code> and\n<code>mghTo</code>. Prefixes like <code>mgh</code> are used because Haskell puts symbols for record\nfields in the global namespace, so it is programmer\'s duty to avoid clashes.</p>\n<p>It should be noted that sometimes you see messages that are parametrized with a\ntype variable <code>ssc</code>. That is done for the code to be polymorphic with respect to\nthe way we carry out shared seed computation.\n<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/src/Pos/Block/Network/Types.hs#L65-L67">Here</a> is an example of a message that sends newest headers first, minding <code>ssc</code>.</p>\n<p>The way messages are serialized can be seen in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/04dc8e4a640a62f0d82633f3a78ab3d8540fd5e6/src/Pos/Binary/Communication.hs"><code>Pos.Binary.Communication</code></a> module.</p>\n<p>Every message type should have an instance of the <code>Message</code> typeclass. Please\nsee <a href="/technical/protocols/time-warp-nt/#messaging">Time-Warp-NT guide</a> for more info.</p>\n<h2>Inv/Req/Data and MessagePart</h2>\n<p>Most of messages in Cardano SL are generalized with <code>Inv/Req/Data</code> standard (see\n<a href="https://github.com/input-output-hk/cardano-sl/blob/4378a616654ff47faf828ef51ab2f455fa53d3a3/infra/Pos/Communication/Types/Relay.hs#L23"><code>Pos.Communication.Relay</code></a>\nmodule). Within this framework we define three data types:</p>\n<pre><code class="language-haskell">-- | Inventory message. Can be used to announce the fact that you have\n-- some data.\ndata InvMsg key = InvMsg\n    { imKey :: !key\n    }\n    deriving (Show, Eq)\n\n-- | Request message. Can be used to request data (ideally data which\n-- was previously announced by inventory message).\ndata ReqMsg key = ReqMsg\n    { rmKey :: !key\n    }\n    deriving (Show, Eq)\n\n-- | Data message. Can be used to send actual data.\ndata DataMsg contents = DataMsg\n    { dmContents :: !contents\n    }\n    deriving (Show, Eq)\n</code></pre>\n<p>Here:</p>\n<ul>\n<li><code>key</code> is a type representing the node identifier.</li>\n<li><code>contents</code> is a type representing actual message payload.</li>\n</ul>\n<p>To introduce a new message using <code>Inv/Req/Data</code> one should create two types: <code>key</code>\ntype and <code>contents</code> type for this message, and then implement <a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/infra/Pos/Communication/MessagePart.hs#L9"><code>MessagePart</code></a>\ntypeclass for both of them.</p>\n<pre><code class="language-haskell">class MessagePart a where\n    pMessageName :: Proxy a -> MessageName\n</code></pre>\n<p>Here, <code>pMessageName</code> is an identifier for a particular message type.</p>\n<p><code>Message</code> typeclass for <code>InvMsg key</code>, <code>ReqMsg key</code> and <code>DataMsg contents</code>\nis automatically derived from the <code>MessagePart</code> typeclass for particular\nkey and contents.</p>\n<p>Please see\n<a href="https://github.com/input-output-hk/cardano-sl/blob/3d695fd804814647f50abe452a81a678aad080cc/src/Pos/Communication/Message.hs"><code>Pos.Communication.Message</code></a>\nmodule for the examples of messages that are using <code>Inv/Req/Data</code>.</p>\n<h2>Block Exchange Messages</h2>\n<!-- Updated at 3b657302dede832b908f7ba792a164c83b362712 -->\n<p>This table explains\n<a href="https://github.com/input-output-hk/cardano-sl/blob/309142c899ed898eaa877d959818a06fbbb37db0/src/Pos/Block/Network/Types.hs"><code>Pos.Block.Network.Types</code></a>\nmodule.</p>\n<table>\n<thead>\n<tr>\n<th>Message type</th>\n<th>Payload</th>\n<th>Comments</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>MsgGetHeaders</code></td>\n<td>Header hash checkpoints (optional newest hash we\'re interested in)</td>\n<td>Expect newest header first</td>\n</tr>\n<tr>\n<td><code>MsgGetBlocks</code></td>\n<td>Oldest header hash (newest hash)</td>\n<td>Both hashes have to be present</td>\n</tr>\n<tr>\n<td><code>MsgHeaders</code></td>\n<td>Non-empty collection of block headers, newest first</td>\n<td>Polymorphic in \n<code>ssc</code></td>\n</tr>\n<tr>\n<td><code>MsgBlock</code></td>\n<td>A single block</td>\n<td>Polymorphic in \n<code>ssc</code></td>\n</tr>\n</tbody>\n</table>\n<p>For more details please see <a href="/technical/protocols/binary-protocols/#block-exchange-messages">binary\nprotocols</a>.</p>\n<h2>Message names</h2>\n<p>All messages are given custom names, since using full type names would be\nexcessive. Each name is concatenation of one or two encoded <code>UnsignedVarInt</code>s.</p>\n<p>This table contains names for all used messages/message parts. These names could also\nbe found in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/0906d8abc8e4ba8e1366defc3af0f5363e530146/src/Pos/Communication/Message.hs"><code>Pos.Communication.Message</code></a>\nmodule. To distinguish from integers addition, concatenation is denoted here as\n<code>(++)</code>.</p>\n<table>\n<thead>\n<tr>\n<th>Message type</th>\n<th>Message name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>MsgGetHeaders</td>\n<td><code>4</code></td>\n</tr>\n<tr>\n<td>MsgHeaders</td>\n<td><code>5</code></td>\n</tr>\n<tr>\n<td>MsgGetBlocks</td>\n<td><code>6</code></td>\n</tr>\n<tr>\n<td>MsgBlock</td>\n<td><code>7</code></td>\n</tr>\n<tr>\n<td>ReqMsg</td>\n<td><code>9</code>\n ++ \n<code>pMessageName key</code></td>\n</tr>\n<tr>\n<td>MempoolMsg</td>\n<td><code>10</code>\n ++ \n<code>pMessageName tag</code></td>\n</tr>\n<tr>\n<td>DataMsg</td>\n<td><code>11</code>\n ++ \n<code>pMessageName contents</code></td>\n</tr>\n<tr>\n<td>InvMsg</td>\n<td><code>12</code>\n ++ \n<code>pMessageName key</code></td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th>Message part type</th>\n<th>Name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>TxMsgContents</code></td>\n<td><code>0</code></td>\n</tr>\n<tr>\n<td>(\n<code>UpdateProposal</code>\n, \n[\n<code>UpdateVote</code>\n]\n)</td>\n<td><code>1</code></td>\n</tr>\n<tr>\n<td><code>UpdateVote</code></td>\n<td><code>2</code></td>\n</tr>\n</tbody>\n</table>\n<p>Hence <code>cardano-sl</code> is shipped with Update system protocol, and message formats also\ncan be changed. So nodes should be aware of the protocol other peers are\nrunning. Knowing this information, nodes can choose a message name to send to a\npeer. This message name table is sent as\n<a href="/technical/protocols/time-warp-nt/#bidirectional-%D1%81onnections"><code>PeerData</code></a> during\nhandshake before every conversation action between handshake. The exact binary\nformat of <code>PeerData</code> is described in <a href="/technical/protocols/binary-protocols/#peer-data">binary protocols</a>\nchapter.</p>\n<h2>Message limits</h2>\n<p>Messages have maximum length limits. Different types of messages have different limits, as defined in <a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/src/Pos/Communication/Limits.hs"><code>Pos.Communication.Limits</code></a> module.</p>\n<h2>Delegation Messages</h2>\n<p><em>Delegation</em> is a feature that allows one stakeholder, called <em>issuer</em>, to let\nanother stakeholder, called <em>delegate</em>, generate blocks on her behalf.</p>\n<p>To do this, issuer should create <em>proxy signing key</em> that allows delegate to\nsign blocks instead of issuer. Any stakeholder can verify that a proxy signing\nkey was actually issued by a specific stakeholder to a specific delegate and\nthat this key is valid at time.</p>\n<p>Delegation can be of two types: per-epoch delegation and delegation with\nrevocable long-lived certificates. Per-epoch delegation is called “lightweight”,\nand the long-lived delegation is called “heavyweight”.</p>\n<p>Please read about <a href="/technical/delegation/">Stake Delegation in Cardano SL</a> for\nmore information.</p>\n<h3>Lightweight Delegation</h3>\n<p><strong>WARNING: Currently, lightweight delegation is disabled and will be reworked in\n<a href="https://cardanoroadmap.com/">Shelley release</a>, so information below can be outdated.</strong></p>\n<p>Lightweight delegation allows delegate to sign blocks instead of issuer for some\nrange of epochs (this range is specified for a signing key created).</p>\n<p>To do this, issuer should send message containing time range, issuer public key,\ndelegate public key and certificate over network. Every node from network\nreceives this message and can check later if the one who generated the block had\nright for it. Lightweight delegation data is stored in memory and gets deleted\nafter some time <a href="https://github.com/input-output-hk/cardano-sl/blob/acc53f53a20c7985d6550b4812117e44db08a70b/core/constants.yaml#L55">defined in configuration file</a>.</p>\n<p>This delegation type can be used to delegate blocks generating right to some\ntrusted node when an issuer knows it will be absent in some time range.</p>\n<h3>Heavyweight Delegation</h3>\n<p>Heavyweight delegation serves two purposes:</p>\n<ol>\n<li>Delegate block generation right, like lightweight delegation.</li>\n<li>Share stake with some delegate, thus allowing delegate to take part in\n<a href="/glossary/#follow-the-satoshi">Follow-The-Satoshi</a>. No real money is transferred; stake of issuer is added\nto stake of delegate when calculating stakeholders for <a href="/glossary/#follow-the-satoshi">Follow-The-Satoshi</a>.</li>\n</ol>\n<p>Every particular stakeholder can share stake with one and only one delegate. To\nrevoke certificate, a node should create a new certificate and put itself as\nboth issuer and delegate.</p>\n<h3>Messages table</h3>\n<p>There are delegation-related messages, found in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/6e8f8a98fd1537d084341a27a843e08dacc9f1eb/src/Pos/Delegation/Types.hs"><code>Pos.Delegation.Types</code></a>\nmodule. The format of delegation messages is described in\n<a href="/technical/protocols/binary-protocols/#delegation">binary protocols</a>\nchapter.</p>\n<h2>Update System Messages</h2>\n<p>You can see how system messages are implemented under <code>WorkMode</code>\nin <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Communication/Methods.hs"><code>Pos.Communication.Methods</code></a> module.</p>\n<table>\n<thead>\n<tr>\n<th>Message type</th>\n<th>Comments</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>UpdateProposal</code></td>\n<td>Serialized update proposal, sent to a DHT peers</td>\n</tr>\n<tr>\n<td><code>UpdateVote</code></td>\n<td>Message, payload of which contains the actual vote</td>\n</tr>\n</tbody>\n</table>\n<p>Plea see <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Communication/Methods.hs#L47"><code>sendUpdateProposal</code></a>\nand <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Communication/Methods.hs#L40"><code>sendVote</code></a>\nfunctions for more details.</p>\n<h1>Workers, Listeners and Handlers</h1>\n<p>You can think about them as «operating personnel» for messages.</p>\n<p><strong>Workers</strong> initiate messages exchange, so a worker is an <em>active</em> communication\npart of Cardano SL. <strong>Listeners</strong> accept messages from the workers and may send\nsome messages as answers, so a listener is a <em>passive</em> communication part of\nCardano SL. After a message was received, a listener uses the function called\n<strong>handler</strong> to actually perform the corresponding job. A particular handler is\nused based on the type of received message (as it has been said above, messages\nhave different types).</p>\n<p>To be able to perform necessary actions, all workers and handlers work in the\n<code>WorkMode</code>\'s constraints (see below).</p>\n<h2>Block Processing</h2>\n<p>Block exchange messages are described above.</p>\n<h3>Block Processing Workers</h3>\n<p>Block acquisition is handled in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs"><code>Pos.Block.Network.Retrieval</code></a>\nmodule.</p>\n<p>The <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs#L50"><code>retrievalWorker</code></a>\nfunction is very important: it\'s a server that operates on <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs#L84">block retrieval\nqueue</a>\nvalidating headers, and these blocks form a proper chain. Thus, at <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs#L284">this\npoint</a>\nit sends a message of type <code>MsgGetBlocks</code> to the listener, and at <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Retrieval.hs#L345">this\npoint</a>\nit receives an answer from this listener, a message of <code>MsgBlock</code> type.</p>\n<p>Here\'s another example — the <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Logic.hs#L261"><code>requestHeaders</code></a> function. This function handles\nexpected block headers, tracking them locally. So at <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Logic.hs#L271">this\npoint</a>\nit sends a message of type <code>MsgGetHeaders</code> to the listener, and at <a href="https://github.com/input-output-hk/cardano-sl/blob/83fbebb3eec16c30a96c499301250c5a3756c0c1/src/Pos/Block/Network/Logic.hs#L275">this\npoint</a>\nit receives an answer from that listener, a message of <code>MsgHeaders</code> type.</p>\n<p>Additional worker for the block processing is defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/d564b3f5a7e03e086b62c88212870b5ea89f5e8b/src/Pos/Block/Worker.hs"><code>Pos.Block.Worker</code></a>\nmodule. We reuse [<code>retrievalWorker</code>] described above and define a\n<a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Worker.hs#L82">well-documented</a>\n<code>blkOnNewSlot</code> worker. It represents an action which should be done when a new\nslot starts. This action includes the following steps:</p>\n<ol>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Worker.hs#L100">Generating a genesis block</a>, if necessary.</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Worker.hs#L110">Getting leaders</a> for the current epoch.</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Worker.hs#L114">Initiation block generation</a>, if we\'re the slot leader or we\'re delegated to\ndo so (optional).</li>\n</ol>\n<h3>Logic</h3>\n<p>The way in which blocks are processed is specified in the\n<a href="https://github.com/input-output-hk/cardano-sl/tree/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Logic"><code>Pos.Block.Logic</code></a>\nmodules. Please read about <a href="/technical/blocks/">blocks in Cardano SL</a> for more\ninfo.</p>\n<h3>Block Processing Listeners</h3>\n<p>Listeners for the block processing are defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Network/Listeners.hs"><code>Pos.Block.Network.Listeners</code></a>\nmodule.</p>\n<p>Handler\n<a href="https://github.com/input-output-hk/cardano-sl/blob/fa5d01c08124934f01f2df22f2bc8784198f56c0/src/Pos/Block/Network/Listeners.hs#L46"><code>handleGetHeaders</code></a>\nsends out the block headers: at <a href="https://github.com/input-output-hk/cardano-sl/blob/fa5d01c08124934f01f2df22f2bc8784198f56c0/src/Pos/Block/Network/Listeners.hs#L89">this\npoint</a>\nit receives a message of type <code>MsgGetHeaders</code> from the worker, <a href="https://github.com/input-output-hk/cardano-sl/blob/fa5d01c08124934f01f2df22f2bc8784198f56c0/src/Pos/Block/Network/Listeners.hs#L95">get the\nheaders</a>\nand then, at <a href="https://github.com/input-output-hk/cardano-sl/blob/92cf690dc3be9af29502f493cbf9e8072b56cb67/src/Pos/Block/Network/Logic.hs#L140">this\npoint</a>,\nit sends a response message of type <code>MsgHeaders</code> to that worker.</p>\n<p>A handler\n<a href="https://github.com/input-output-hk/cardano-sl/blob/fa5d01c08124934f01f2df22f2bc8784198f56c0/src/Pos/Block/Network/Listeners.hs#L54"><code>handleGetBlocks</code></a>\nsends out blocks. This handler corresponds to\n<a href="https://github.com/input-output-hk/cardano-sl/blob/08fa863502baeb399e15f525540050a117430d95/src/Pos/Block/Network/Retrieval.hs#L319"><code>retrieveBlocks</code></a>\nfrom main\n<a href="https://github.com/input-output-hk/cardano-sl/blob/08fa863502baeb399e15f525540050a117430d95/src/Pos/Block/Network/Retrieval.hs#L50"><code>retrievalWorker</code></a>.\nThus, it receives a message of type <code>MsgGetBlocks</code> from the worker\n<a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Network/Listeners.hs#L60">here</a>,\n<a href="https://github.com/input-output-hk/cardano-sl/blob/7fdf6c8d0d2f62948f4685b923b7671db137d7b3/src/Pos/Block/Logic/Header.hs#L331">gets corresponding\nheaders</a>,\nand then it sends response message of type <code>MsgBlock</code> to that worker\n<a href="https://github.com/input-output-hk/cardano-sl/blob/a5f7991ff03a1e45114b901bfbbbb1ee3cd4d194/src/Pos/Block/Network/Listeners.hs#L71">here</a>.</p>\n<p>A handler\n<a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Block/Network/Listeners.hs#L85"><code>handleBlockHeaders</code></a>\nsends out block headers for unsolicited use case in a similar way: it receives a\nmessage of\n<a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Block/Network/Listeners.hs#L95"><code>MsgHeaders</code></a>\ntype from the worker and handles it.</p>\n<h2>Delegation</h2>\n<p>Another example is working with delegation messages described above.</p>\n<h3>Workers</h3>\n<p>Workers for delegation messages are defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Delegation/Worker.hs"><code>Pos.Delegation.Worker</code></a>\nmodule.</p>\n<p>All these workers do not send messages to one particular node. They send\nmessages to all neighbors.</p>\n<h3>Listeners</h3>\n<p>Listeners for delegation messages are defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Delegation/Listeners.hs"><code>Pos.Delegation.Listeners</code></a>\nmodule.</p>\n<h2>Security</h2>\n<p>Workers for security operations are defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/0d28e6133bd6349f5236bcebab39ea6bfc4c2b7e/src/Pos/Security/Workers.hs"><code>Pos.Security.Workers</code></a>\nmodule.</p>\n<h2>Update System</h2>\n<p>Below is the list of workers and listeners related to update system.</p>\n<h3>Workers</h3>\n<p>Workers for update system are defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/73cf4fc35d3cfb068458f2b6982990d08a99906e/src/Pos/Update/Worker.hs"><code>Pos.Update.Worker</code></a> module.\nThe only thing that the update system does is <a href="https://github.com/input-output-hk/cardano-sl/blob/73cf4fc35d3cfb068458f2b6982990d08a99906e/src/Pos/Update/Worker.hs#L27">checking</a>\nfor a new <em>approved</em> update on each slot.</p>\n<h3>Listeners</h3>\n<p>Listeners for update system are defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/22360aa45e5dd82d0c87872d8530217fc3d08f4a/src/Pos/Update/Network/Listeners.hs"><code>Pos.Update.Network.Listeners</code></a> module.</p>\n<p><code>UpdateProposal</code> relays:</p>\n<ul>\n<li><code>Req</code> — local node answers to a request about update proposal with the set\nof votes for/against this proposal.</li>\n<li><code>Inv</code> — checks if we need the offered proposal, and records the data if this\ninventory message is relevant.</li>\n<li><code>Data</code> — carries the proposal information along with votes, which is\nverified and recorded.</li>\n</ul>\n<p><code>UpdateVote</code> listeners:</p>\n<ul>\n<li><code>Req</code> — sends <em>our</em> vote to whoever requests it.</li>\n<li><code>Inv</code> — checks if we need the offered vote, and records it if relevant.</li>\n<li><code>Data</code> — carries a single vote, which is verified and recorded.</li>\n</ul>\n<h2>WorkMode and MinWorkMode</h2>\n<p>A special types called <a href="https://github.com/input-output-hk/cardano-sl/blob/73cf4fc35d3cfb068458f2b6982990d08a99906e/src/Pos/WorkMode/Class.hs#L65"><code>WorkMode</code></a> and <a href="https://github.com/input-output-hk/cardano-sl/blob/73cf4fc35d3cfb068458f2b6982990d08a99906e/src/Pos/WorkMode/Class.hs#L107"><code>MinWorkMode</code></a> represent a bunch of constraints\nto perform work for the real world distributed system. You can think about a constraint\nas a <em>compile-time guarantee</em> that particular actions can be performed in the\nparticular context. For example, if we define type of some function <code>f</code> in the\nterms of <strong>logging</strong> constraint, we definitely know that we can log different\ninfo inside of this function <code>f</code>.</p>\n<p>All workers and handlers described above work in the <code>WorkMode</code>\'s constraints.</p>',frontmatter:{path:"/en/technical/protocols/csl-application-level/",doc_title:"CSL Application Level",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical-protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/protocols/2017-01-04-p2p.md absPath of file >>> MarkdownRemark",excerpt:"P2P Layer To start communicating with other nodes, a node has to join the network. To do\nthis, the node has to know some other node that…",html:'<!-- Reviewed at ef835a2334888eda7384da707c4077a8b576b192 -->\n<h1>P2P Layer</h1>\n<p>To start communicating with other nodes, a node has to join the network. To do\nthis, the node has to know some other node that already participates in the\nprotocol; this node is called a <em>bootstrap node</em>.</p>\n<p>After connecting to the bootstrap node, we receive a list of peers which we\'ll\nuse for network communication. Those peers are called <em>neighbors</em>. The list of\nneighbors should be maintained in such a way that these nodes are online and any\nnode from the network can receive our messages. Moreover, messages should be\ndelivered efficiently.</p>\n<p>To achieve this, Cardano SL uses the <em>Kademlia</em> DHT protocol. Even though\nKademlia provides more features, we only use it as a method of peer discovery.</p>\n<h2>Overview of Kademlia Protocol</h2>\n<p><em>See also: the <a href="/technical#p2p-network">P2P Network section</a> of the technical\noverview.</em></p>\n<p>In Kademlia, every node is associated with a 32-byte ID (see <a href="#id-structure">ID\nstructure</a> for more details). These IDs are used to identify\nnodes without having to refer to their network addresses. The keys used to\nstore values in Kademlia are also 32-byte identifiers.</p>\n<p>Kademlia uses the XOR metric to define the distance between nodes. Key-value\npairs are stored in nodes with IDs that are “close” to the keys. This distance\nis also used to efficiently locate a node with the given ID.</p>\n<p>At start, a bootstrap node should be provided to Kademlia in order to join the\nnetwork. The address of this node can be hardcoded in the implementation or\nchosen by the user. Later, the node will attempt to find more peers by querying\nits neighbors (from the initial list of peers sent by the bootstrap node). A\nnode sends messages to its peers, which resend messages to their peers close to\nthe needed ID/key. The list of known peers is preserved between launches.</p>\n<p>Here and later, by <em>address</em> we mean tuple <code>(Host, Port, ID)</code>, while <em>network\naddress</em> denotes just the pair <code>(Host, Port)</code>.</p>\n<p>Kademlia uses the UDP protocol for transmitting messages.</p>\n<p>To learn more about how Kademlia is implemented, please refer to the paper\n<a href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf">Kademlia: a Peer-to-peer Information System Based on the XOR\nMetric</a>.</p>\n<h2>Messages Used in Kademlia</h2>\n<p>Every message is represented as a binary string with the maximum length of <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Config.hs#L61">1200\nbytes</a>\n(so that it wouldn\'t exceed IPv6 datagram size). A special case is\n<code>RETURN_NODES</code>: if it exceeds 1200 bytes, the node list is split into several\nmessages. The number of messages is represented with a single byte. Please see\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Protocol.hs#L41"><code>serialize</code></a>\nfunction for more details.</p>\n<h3>IDs, Keys and Values</h3>\n<p>IDs and keys in Kademlia are represented with the same structure called\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/HashNodeId.hs#L32"><code>HashId</code></a>:</p>\n<p><a name="id-structure"></a></p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>18</td>\n<td><em>Hash</em>\n - \n<em>PBKDF2</em>\n key generated from \n<em>Nonce</em></td>\n</tr>\n<tr>\n<td>14</td>\n<td><em>Nonce</em>\n - an arbitrary 14-bytes long binary string</td>\n</tr>\n</tbody>\n</table>\n<p>Please see <a href="#addressing">Addressing</a> section for more details.</p>\n<p>Cardano SL do not use Kademlia as key-value storage. Thus we just use empty\nstrings as values.</p>\n<h3>PING</h3>\n<p>Check if a peer is still accessible. After sending this message, the node would\nexpect to receive a <em>PONG</em> message as the reply. Kademlia pings every peer\nperiodically to maintain a correct peer list.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>0</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n</tbody>\n</table>\n<h3>PONG</h3>\n<p>Used as a reply to <code>PING</code> messages.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>1</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n</tbody>\n</table>\n<h3>STORE</h3>\n<p>Store given value in Kademlia. This message is disabled and would be ignored by\nnodes.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>2</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>Key</td>\n</tr>\n<tr>\n<td>0</td>\n<td></td>\n<td>Value (empty string in Cardano SL)</td>\n</tr>\n</tbody>\n</table>\n<h3>FIND_NODE</h3>\n<p>Request network address of node with given ID. After sending this message the\nnode would expect to receive a <code>RETURN_NODES</code> message with a list of nodes\nclosest to the requested one (including the requested node itself).</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>3</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of node we are looking for</td>\n</tr>\n</tbody>\n</table>\n<h3>RETURN_NODES</h3>\n<p>Send network addresses of some nodes in reply to <code>FIND_NODE</code> of <code>FIND_VALUE</code>.\nAnswer is split into several messages because list of nodes can exceed IPv6\ndatagram size.</p>\n<p>First, let\'s describe binary representation of single <em>peer</em>:</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td></td>\n<td>Peer ID</td>\n</tr>\n<tr>\n<td>1-255</td>\n<td></td>\n<td>Peer host name</td>\n</tr>\n<tr>\n<td>1</td>\n<td>32</td>\n<td>Ascii code of " " to separate host name from port</td>\n</tr>\n<tr>\n<td>2</td>\n<td></td>\n<td>Peer port</td>\n</tr>\n</tbody>\n</table>\n<p>Now, let\'s describe binary representation of <code>RETURN_NODES</code> message:</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>4</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>1</td>\n<td></td>\n<td>Total number of \n<code>RETURN_NODES</code>\n messages sent as answer to this request</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of node that requested nodes</td>\n</tr>\n<tr>\n<td>at most 1136</td>\n<td></td>\n<td>Several peers close to the requested ID (at most 1136 bytes to not exceed IPv6 datagram size)</td>\n</tr>\n</tbody>\n</table>\n<h3>FIND_VALUE</h3>\n<p>Behaves in the same way as <code>FIND_NODE</code>, except that it can also receive a\n<code>RETURN_VALUE</code> response if the lookup was successful. Currently it\'s only used\nin Cardano SL for finding peers. When the node starts working, it generates a\nrandom key and asks Kademlia to find it; this search always fails, but it lets\nthe node discover some initial peer addresses.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>5</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>Key we are looking for</td>\n</tr>\n</tbody>\n</table>\n<h3>RETURN_VALUE</h3>\n<p>A reply to a <code>STORE</code> request. This message is not used in Cardano SL because it\ndoes not store any values in Kademlia.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>6</td>\n<td>1-byte value to determine message type</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of our node</td>\n</tr>\n<tr>\n<td>32</td>\n<td></td>\n<td>ID of node that requested value</td>\n</tr>\n<tr>\n<td>0</td>\n<td></td>\n<td>Value (empty string in Cardano SL)</td>\n</tr>\n</tbody>\n</table>\n<h2>Security</h2>\n<p>Since Kademlia is a protocol for open P2P networks, it had to be modified in\nseveral other ways to become reasonably secure.</p>\n<h3>Possible Attacks</h3>\n<p>An <strong>eclipse attack</strong> is a situation when a node is surrounded by adversary\nnodes.</p>\n<p>In Kademlia, eclipse attacks (targeted at the particular participant of the\nnetwork) are hard to perform, but possible. First, launch a hundred nodes with\nnode IDs close to target node ID. These nodes would fill the node\'s lowest\n<code>k</code>-buckets (which are expected to be empty, at a first sight), then perform a\nDDoS attack on nodes from target\'s <code>k</code>-buckets (it\'s possible to determine those\nnodes if network\'s topology haven\'t changed much since the node was started).\nAfter a successful DDoS attack, the node\'s remaining neighbors would be\nadversary agents.</p>\n<p>Please note that Kademlia’s structure implies that launching nodes close to the\ntarget is not enough to eclipse it. Node lists are stored by node in <code>k</code>-buckets\n(the i-th bucket contains no more than <code>k</code> nodes with relative distance\n<code>2^i-1 &#x3C; d &#x3C; 2^i</code>), and new nodes are added to corresponding buckets only if\nthese buckets are not already full. Kademlia prefers nodes that have been in\nlists for a long time and were recently seen alive. Without getting some nodes\ndown, it\'s impossible to eclipse a node.</p>\n<p>This attack is tricky and unlikely to happen in practice. The\n<a href="#addressing">Addressing</a> modification makes it even harder.</p>\n<p>A <strong>100500 attack</strong> is an attack that launches significantly more nodes than the\namount of nodes in the current P2P network, either in order to eclipse some\nnodes or to deny service by flooding the network. The attack wouldn\'t cause any\nproblems for old nodes (not counting possible network overhead), because old\nnodes preserve their routes. But when a new node joins the network, it would get\neclipsed (isolated in an adversarial subnet), because old honest nodes won\'t add\nit to their buckets (as these buckets are already filled by other nodes), and\nthe new node would be known to adversaries only.</p>\n<p>Defending against 100500 attacks remains an open problem. For now, we\'re going\nto make them practically infeasible with a sophisticated ban system / adversary\ndetection.</p>\n<h3>Addressing</h3>\n<p>We use so-called <code>HashId</code>s as node IDs. Since it <a href="#id-structure">contains</a> a\nhash, assigning yourself an arbitrary ID is impossible, and this means that a\n100500 attack is the only way to perform an eclipse attack.</p>\n<h4>Implementation Notes</h4>\n<p><code>HashId</code> is a binary string with a fixed length (32 bytes) formed like this:</p>\n<pre><code>+---------------+------------+\n|    Hashing    |    Nonce   |\n+---------------+------------+\n\n|   18 bytes    |  14 bytes  |\n</code></pre>\n<p>where:</p>\n<ul>\n<li><code>Nonce</code> is just random 14 bytes (from the system source of entropy),</li>\n<li><code>Hashing</code> is hashing data.</li>\n</ul>\n<p>Hashing data is generated based on <code>DerivingKey</code> and <code>Salt</code>, where:</p>\n<ul>\n<li><code>DerivingKey</code> is generated by PBKDF2 (<a href="https://en.wikipedia.org/wiki/PBKDF2">Password Based Key Derivation\nFunction 2</a>).</li>\n<li><code>Salt</code> is a SHA-512 digest from <code>Nonce</code> mentioned above.</li>\n</ul>\n<p>For <code>DerivingKey</code> generation we use these arguments:</p>\n<ul>\n<li><code>prfPassword</code> - PRF (pseudorandom function) for PBKDF2 using HMAC\n(<a href="https://en.wikipedia.org/wiki/Hash-based_message_authentication_code">Hash-based Message Authentication\nCode</a>)\nwith SHA-256 algorithm.</li>\n<li><code>parameters</code> - PBKDF2 parameters: 500 iterations, for 32 bytes as a result\noutput.</li>\n<li><code>Nonce</code> mentioned above - as <code>password</code>.</li>\n<li><code>Salt</code> mentioned above - as <code>salt</code>.</li>\n</ul>\n<h3>Routing Data Anti-forging</h3>\n<p>In Kademlia, a node requests a list of peers from its neighbors and accepts the\nfirst message it receives. An adversary may forge those replies, providing\naddresses of adversary nodes as closest nodes to given ID. To overcome this\nissue, we make nodes wait for some period to gather as many replies as possible,\nand after that, the replies get merged and the node selects <code>k</code> closest nodes from\nthe resulting set. This way, an adversary would have to eclipse a node in order\nto forge the list of peers it receives.</p>\n<h4>Implementation Notes</h4>\n<p>To implement this idea, we just add <code>k</code> neighbors nodes closest to the\ndestination at the beginning of each\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L48">lookup</a>\n(<code>lookup</code> is a function used by <code>FIND_NODE</code> or <code>FIND_VALUE</code> to find <code>k</code> nodes\nclosest to the given ID) to the\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L243">pending</a>\nset. When we receive a <code>RETURN_NODES</code> message, we update\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L242">known</a>\nlist to make it contain <code>k</code> nodes currently known that are closest to the\ndestination ID. This loop ends when no <em>pending</em> nodes are left. We do not\nintroduce any specific period to collect neighbors replies. If any neighbors do\nnot send us <code>RETURN_NODES</code> reply, we receive <code>Timeout</code> signal and this neighbor\nis handled by\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L286"><code>waitForReply</code></a> function.</p>\n<p>See also\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L371"><code>continueLookup</code></a> function.\nIt is the place where <em>pending</em> and <em>known</em> fields are updated, so this is where\nthe core logic of this enhancement is located.</p>\n<h3>Routing Tables Sharing</h3>\n<p>When a node has just joined the network, it requests a list of neighbors (set of\nnodes closest to it). We have modified Kademlia to include some extra nodes into\nthis list; specifically, now we pick some random nodes along with neighbors and\nreturn them. This gives the node additional knowledge to recover in case it\'s\nsurrounded with adversary nodes.</p>\n<h4>Implementation Notes</h4>\n<p>There is the function\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Tree.hs#L195"><code>findClosest</code></a>\nin our Kademlia implementation which finds <code>k</code> nodes closest to the given ID.\nThe function\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Tree.hs#L180"><code>pickupRandom</code></a>\nwas added. This function picks up given number of random nodes from Kademlia\ntree. The exact number of shared random nodes is specified through\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Config.hs#L63"><code>routingSharingN</code></a> field from Kademlia config. This way, <code>RETURN_NODES</code> message\nincludes the results of <code>findClosest</code> and <code>pickupRandom</code> calls.</p>\n<h3>Banning Nodes</h3>\n<p>We introduce a feature to ban nodes to Kademlia. We will use this to ban nodes\nwhen we detect them to act maliciously.</p>\n<h4>Implementation Notes</h4>\n<p>There are three possible states for a node:</p>\n<ol>\n<li><code>NoBan</code>,</li>\n<li><code>BanTill</code>,</li>\n<li><code>BanForever</code>.</li>\n</ol>\n<p>Please see\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Instance.hs#L66"><code>BanState</code></a> type. Values of this type are passed to\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Instance.hs#L165"><code>banNode</code></a>\nfunction.</p>\n<p><code>NoBan</code> is used to unban the already banned nodes. However, this action does\nnot insert this node back into tree structure, but makes possible for this\nnode to appear in peers again.</p>\n<p><code>BanTill</code> bans a node till some time (defined as a POSIX time).</p>\n<p><code>BanForever</code> bans a node forever.</p>\n<p>The function <code>banNode</code> adds given node to the <code>banned</code> field of\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Instance.hs#L73"><code>KademliaState</code></a>\ntype and deletes it from the tree.\nThe function <a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Instance.hs#L150"><code>isNodeBanned</code></a>\nchecks if node is banned at the moment and deletes node from <code>banned</code> field if\nit was unbanned, or if the ban expired.</p>\n<p>How a banned node is treated:</p>\n<ul>\n<li>\n<p>We cannot use it as our initial peer to join the network. Please see\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L152"><code>joinNetwork</code></a> function.</p>\n</li>\n<li>\n<p>We ignore all messages received from a banned node. Please see\n<a href="https://github.com/serokell/kademlia/blob/7120bb4d28e708acd52dfd61d3dca7914fac7d7f/src/Network/Kademlia/Implementation.hs#L286"><code>waitForReply</code></a> function.</p>\n</li>\n<li>\n<p>We do not include this node to the tree, do not send any messages to it and\ndo not include this node to the <code>RETURN_NODES</code> messages.</p>\n</li>\n</ul>',
  frontmatter:{path:"/en/technical/protocols/p2p/",doc_title:"P2P Layer",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical-protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/plutus/2017-01-02-types.md absPath of file >>> MarkdownRemark",excerpt:"Plutus Types This chapter contains a reference for the types in the Plutus language. It uses\nsome informal type theory, which hopefully is…",html:'<!-- Reviewed at 25dc86c0fd9741b2f1c59d3a594c48844bbc73f5 -->\n<h1>Plutus Types</h1>\n<p>This chapter contains a reference for the types in the Plutus language. It uses\nsome informal type theory, which hopefully is understandable to everyone reading\nthis document.</p>\n<p>Plutus comes with a handful of built-in types (ints, floats, bytestrings), and a\nsingle built-in type operator (functions). Other types are defined by the\nauthors of programs. We\'ll discuss each of these in turn.</p>\n<h2>Ints, Floats, and Byte Strings</h2>\n<p><code>Int</code>, <code>Float</code>, and <code>ByteString</code> are primitive types, with constructor forms\ngiven by various constants specified by the following grammar.</p>\n<pre><code>&#x3C;int> ::= "-"? &#x3C;digit>+\n&#x3C;float> ::= "-"? &#x3C;digit>+ &#x3C;fractExponent>\n&#x3C;digit> = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"\n&#x3C;fractExponent> ::= &#x3C;fraction> &#x3C;exponent>? | &#x3C;exponent>\n&#x3C;fraction> ::= "." &#x3C;digit>+\n&#x3C;exponent> ::= ("e" | "E") ("-" | "+") &#x3C;digit>+\n\n&#x3C;bytestring> ::= "#" &#x3C;byte>*\n&#x3C;byte> ::= &#x3C;nybble> &#x3C;nybble>\n&#x3C;nybble> ::= &#x3C;digit>\n           | "a" | "b" | "c" | "d" | "e" | "f"\n           | "A" | "B" | "C" | "D" | "E" | "F"\n</code></pre>\n<p>There are no true eliminator forms for these types, but there are a number of\nbuilt-in operations which can be applied to these types. We write the signatures\nof built-ins as follows: <code>f : (A,B) ⇀ C</code> indicates that a built-in name <code>f</code> can\nbe applied to an <code>A</code> and a <code>B</code> to produce a <code>C</code>. The built-ins for these\nprimitive types are as follows, with implementations in terms of Haskell\nfunctions:</p>\n<pre><code>addInt : (Int,Int) ⇀ Int\n  implemented as `(+) :: Int -> Int -> Int`\n\nsubtractInt : (Int,Int) ⇀ Int\n  implemented as `(-) :: Int -> Int -> Int`\n\nmultiplyInt : (Int,Int) ⇀ Int\n  implemented as `(*) :: Int -> Int -> Int`\n\ndivideInt : (Int,Int) ⇀ Int\n  implemented as `div :: Int -> Int -> Int`\n\nremainderInt : (Int,Int) ⇀ Int\n  implemented as `(%) :: Int -> Int -> Int`\n\nlessThanInt : (Int,Int) ⇀ Bool\n  implemented as `(&#x3C;) :: Int -> Int -> Bool`\n\nequalsInt : (Int,Int) ⇀ Bool\n  implemented as `(==) :: Int -> Int -> Bool`\n\nintToFloat : (Int) ⇀ Float\n  implemented as `fromInteger . toInteger :: Int -> Float`\n\nintToByteString : (Int) ⇀ ByteString\n  implemented as `encode :: Int -> ByteString`\n\naddFloat : (Float,Float) ⇀ Float\n  implemented as `(+) :: Float -> Float -> Float`\n\nsubtractFloat : (Float,Float) ⇀ Float\n  implemented as `(-) :: Float -> Float -> Float`\n\nmultiplyFloat : (Float,Float) ⇀ Float\n  implemented as `(*) :: Float -> Float -> Float`\n\ndivideFloat : (Float,Float) ⇀ Float\n  implemented as `(/) :: Float -> Float -> Float`\n\nlessThanFloat : (Float,Float) ⇀ Bool\n  implemented as `(&#x3C;) :: Float -> Float -> Bool`\n\nequalsFloat : (Float,Float) ⇀ Bool\n  implemented as `(==) :: Float -> Float -> Bool`\n\nceiling : (Float) ⇀ Float\n  implemented as `ceiling:: Float -> Float`\n\nfloor : (Float) ⇀ Float\n  implemented as `floor :: Float -> Float`\n\nround : (Float) ⇀ Float\n  implemented as `round :: Float -> Float`\n\nconcatenate : (ByteString,ByteString) ⇀ ByteString\n  implemented via `concat :: [ByteString] -> ByteString`\n\ndrop : (Int,ByteString) ⇀ ByteString\n  implemented via `drop :: Integer -> ByteString -> ByteString`\n\ntake : (Int,ByteString) ⇀ ByteString\n  implemented via `take :: Integer -> ByteString -> ByteString`\n\nsha2_256 : (ByteString) ⇀ ByteString\n  implemented via `hash : [Char8] -> Digest SHA256`\n\nsha3_256 : (ByteString) ⇀ ByteString\n  implemented via `hash : [Char8] -> Digest SHA3_256`\n\nequalsByteString : (ByteString,ByteString) ⇀ Bool\n  implemented as `(==) :: ByteString -> ByteString -> Bool`\n</code></pre>\n<p>The use of these built-in functions is by prefixing the name with <code>!</code> and fully\napplying them to arguments. E.g., adding 2 and 3 would be <code>!addInt 2 3</code>.</p>\n<h2>Function Types</h2>\n<p>Given any <code>A</code> and <code>B</code> types, there is a function type <code>A -> B</code>. To get a term of\nthis type, we can use the lambda introduction form as follows: if <code>M</code> has type\n<code>B</code> and has a free variable <code>x</code> that has type <code>A</code>, then <code>\\x -> M</code> has type\n<code>A -> B</code>. We can use a term with a function type as follows: if <code>M</code> has type\n<code>A -> B</code> and <code>N</code> has type <code>A</code>, then <code>M N</code> has type <code>B</code>. The computation for\nfunctions is standard beta reduction: <code>(\\x -> M) N</code> reduces to <code>[N/x]M</code>, i.e. to\n<code>M</code> with <code>N</code> substituted for <code>x</code>. Computation in Plutus is performed eagerly, so\n<code>N</code> is evaluated before substitution is performed.</p>\n<h2>User Declared Types</h2>\n<p>When a user declares a new data type, for example</p>\n<pre><code>data Foo a = { Bar | Baz a }\n</code></pre>\n<p>this defines a new type constructor, in this case <code>Foo</code>, which has the following\ninference rule associated with it: given any type <code>A</code>, <code>Foo A</code> is also a type.</p>\n<p>It also comes with inference rules for the constructors, as follows: <code>Bar</code> has\ntype <code>Foo A</code>, for any choice of <code>A</code>; and if <code>M</code> has type <code>A</code>, then <code>Baz M</code> has\ntype <code>Foo A</code>.</p>\n<p>The eliminator form for user declared types is the case construct, which is used\nfor all such types. Case analysis is the same as in Haskell, for example, we\ncould write</p>\n<pre><code>case foo of { Bar -> 0 | Baz x -> x }\n</code></pre>\n<p>to analyze an element of type <code>Foo Int</code>, computing an <code>Int</code>. There is a minor\ndifference from Haskell, however: we can analyze multiple terms at the same\ntime, by separating them (and their corresponding patterns) with <code>|</code>:</p>\n<pre><code>case foo0 | foo1 of { Bar | Bar -> 0 ; Baz x | Baz y -> !addInt x y }\n</code></pre>\n<p>Case analysis is not required to be total, that is to say, there may be missing\npatterns. Any failed match causes the entire program to fail to run, and will\ncause a transaction to be considered invalid.</p>\n<p><code>Int</code>, <code>Float</code>, and <code>ByteString</code> literals can be patterns as well; for example,\nwe can define the factorial function using case in this way:</p>\n<pre><code>facInt : Int -> Int {\n  facInt n = case n of {\n    0 -> 1 ;\n    _ -> !multiplyInt n (!subtractInt n 1)\n  }\n}\n</code></pre>',frontmatter:{path:"/en/technical/plutus/types/",doc_title:"Types",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical-plutus"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/plutus/2017-01-03-examples.md absPath of file >>> MarkdownRemark",excerpt:"Plutus Examples Here we'll take a look at some of the common examples of programs to give you a\nbetter feel of how the Plutus language works…",html:"<!-- Reviewed at 25dc86c0fd9741b2f1c59d3a594c48844bbc73f5 -->\n<h1>Plutus Examples</h1>\n<p>Here we'll take a look at some of the common examples of programs to give you a\nbetter feel of how the Plutus language works. We'll implement Peano numerals,\ncons lists, and binary trees, as well as some common functions relating them.</p>\n<p>To start with, let's define Peano numerals:</p>\n<pre><code>data Nat = { Zero | Suc Nat }\n</code></pre>\n<p>The naturals support a variety of functions, of course, such as addition,\nmultiplication, factorial, and Fibonacci, which are typical examples of\nprograms.</p>\n<pre><code>add : Nat -> Nat -> Nat {\n  add Zero n = n ;\n  add (Suc m) n = Suc (add m n)\n}\n\nmul : Nat -> Nat -> Nat {\n  mul Zero _ = Zero ;\n  mul (Suc m) n = add (mul m n) n\n}\n\nfac : Nat -> Nat {\n  fac Zero = Suc Zero ;\n  fac (Suc n) = mul (Suc n) (fac n)\n}\n\nfib : Nat -> Nat {\n  fib Zero = Suc Zero ;\n  fib (Suc Zero) = Suc Zero ;\n  fib (Suc (Suc n)) = add (fib n) (fib (Suc n))\n}\n</code></pre>\n<p>Cons lists are also a familiar type:</p>\n<pre><code>data List a = { Nil | Cons a (List a) }\n</code></pre>\n<p>This demonstrates the use of parametric types, where <code>List a</code> has a type\nparameter <code>a</code> for the type of elements. So, for example, <code>List Nat</code> is the type\nof lists of Peano numerals.</p>\n<p>Lists support a variety of functions, such as <code>length</code>, <code>append</code>, and <code>map</code>:</p>\n<pre><code>length : forall a. List a -> Nat {\n  length Nil = Zero ;\n  length (Cons _ xs) = Suc (length xs)\n}\n\nappend : forall a. List a -> List a -> List a {\n  append Nil ys = ys ;\n  append (Cons x xs) ys = Cons x (append xs ys)\n}\n\nmap : forall a b. (a -> b) -> List a -> List b {\n  map _ Nil = Nil ;\n  map f (Cons x xs) = Cons (f x) (map f xs)\n}\n</code></pre>\n<p>Here we can see the use of polymorphism principle in Plutus. These functions\nwork for any list, regardless of the element type, so we can abstract over the\nelement type by using <code>forall</code>. For instance, the type of <code>length</code> says that for\nany choice of <code>a</code>, we have a function of type <code>List a -> Nat</code>.</p>\n<p>It's important to note that in Plutus, this polymorphism exists only for the\ndeclaration of values. Any time you use a polymorphically declared value, the\nchoice of the type variable must be fixed at the use site. You can't treat these\ndeclarations as giving polymorphic values in general, as in System-F. Rather, a\npolymorphic type in a declaration is an abbreviation for an infinite family of\nidentical definitions that differ only in the choice of that type variable. For\nexample, we could define multiple <code>length</code> functions like so:</p>\n<pre><code>lengthNat : List Nat -> Nat {\n  lengthNat Nil = Zero ;\n  lengthNat (Cons _ xs) = Suc (lengthNat xs)\n}\n\nlengthBool : List Bool -> Nat {\n  lengtBool Nil = Zero ;\n  lengthBool (Cons _ xs) = Suc (lengthBool xs)\n}\n\nlengthListNat : List (List Nat) -> Nat {\n  lengthListNat Nil = Zero ;\n  lengthListNat (Cons _ xs) = Suc (lengthListNat xs)\n}\n</code></pre>\n<p>And they're all identical except the name and the choice for <code>a</code>. This is of\ncourse redundant, so we can use the polymorphic declaration given above. But\nthis declaration does not give us a value <code>length</code> with the type\n<code>forall a. List a -> Nat</code>. Instead, it gives us that entire infinite family of\ndeclarations, but with a convenient abbreviation syntax. This is why the use of\nsuch polymorphic declarations requires the choice of the type variables to be\nfixed at the use site.</p>\n<p>Another common type is the type of binary trees with data in the branches:</p>\n<pre><code>data Tree a = { Leaf | Branch a (Tree a) (Tree a) }\n</code></pre>\n<p>Such trees support functions such as <code>count</code>, <code>traversal</code>, and <code>reverse</code>:</p>\n<pre><code>count : forall a. Tree a -> Nat {\n  count Leaf = Zero ;\n  count (Branch _ l r) = Suc (add (count l) (count r))\n}\n\ntraversal : forall a. Tree a -> List a {\n  traversal Leaf = Nil ;\n  traversal (Branch x l r) = Cons x (append (traversal l) (traversal r))\n}\n\nreverse : forall a. Tree a -> Tree a {\n  reverse Leaf = Leaf ;\n  reverse (Branch x l r) = Branch x (reverse r) (reverse l)\n}\n</code></pre>",frontmatter:{path:"/en/technical/plutus/examples/",doc_title:"Examples",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical-plutus"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/2017-01-01-cli-options.cn.md absPath of file >>> MarkdownRemark",excerpt:"卡尔达诺结算层命令行选项 这份文档描述了卡尔达诺结算层的所有可执行文件以及所有相应的命令行参数。 cardano-node cardano-keygen cardano-explorer-swagger cardano-node-simple cardano-launcher…",html:"<!-- THIS IS AUTOGENERATED CHAPTER. DO NOT CHANGE IT MANUALLY! -->\n<h2>卡尔达诺结算层命令行选项</h2>\n<p>这份文档描述了卡尔达诺结算层的所有可执行文件以及所有相应的命令行参数。</p>\n<h2>cardano-node</h2>\n<pre><code>Cardano SL node.\n\nUsage: cardano-node [--version] [--db-path FILEPATH] [--rebuild-db]\n                    [--genesis-secret INT] [--keyfile FILEPATH]\n                    [--backup-phrase PHRASE] [--topology FILEPATH]\n                    [--kademlia FILEPATH] [--node-id NODE_ID]\n                    [--default-port PORT] [--policies FILEPATH]\n                    [--address IP:PORT] [--listen IP:PORT] [--json-log FILEPATH]\n                    [--log-config FILEPATH] [--logs-prefix FILEPATH]\n                    [--report-server URI] [--update-server URI]\n                    [--configuration-file FILEPATH] [--configuration-key TEXT]\n                    [--system-start TIMESTAMP] [--configuration-seed INTEGER]\n                    [--update-latest-path FILEPATH] [--update-with-package]\n                    [--no-ntp] [--route53-health-check IP:PORT] [--metrics]\n                    [--ekg-server IP:PORT] [--statsd-server IP:PORT]\n                    [--statsd-interval MILLISECONDS] [--statsd-debug BOOL]\n                    [--statsd-prefix TEXT] [--statsd-suffix TEXT]\n                    [--dump-genesis-data-to ARG] [--web] [--web-port PORT]\n                    [--tlscert FILEPATH] [--tlskey FILEPATH] [--tlsca FILEPATH]\n                    [--wallet-address IP:PORT] [--wallet-db-path ARG]\n                    [--wallet-rebuild-db]\n                    [--wallet-acid-cleanup-interval MINUTES] [--wallet-debug]\n                    [--flush-wallet-db]\n  Cardano SL main server node w/ wallet.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --db-path FILEPATH       Path to directory with all DBs used by the node. If\n                           specified path doesn’t exist, a directory will be\n                           created.\n  --rebuild-db             If node's database already exists, discard its\n                           contents and create a new one from scratch.\n  --genesis-secret INT     Used genesis secret key index.\n  --keyfile FILEPATH       Path to file with secret key (we use it for\n                           Daedalus).\n  --backup-phrase PHRASE   12-word phrase to recover the wallet. Words should be\n                           separated by spaces.\n  --topology FILEPATH      Path to a YAML file containing the network topology\n  --kademlia FILEPATH      Path to a YAML file containing the kademlia\n                           configuration\n  --node-id NODE_ID        Identifier for this node within the network\n  --default-port PORT      Port number for IP address to node ID translation\n  --policies FILEPATH      Path to a YAML file containing the network policies\n  --address IP:PORT        IP and port of external address. Please make sure\n                           these IP and port (on which node is running) are\n                           accessible otherwise proper work of CSL isn't\n                           guaranteed. 0.0.0.0 is not accepted as a valid host.\n  --listen IP:PORT         IP and port on which to bind and listen. Please make\n                           sure these IP and port are accessible, otherwise\n                           proper work of CSL isn't guaranteed.\n  --json-log FILEPATH      Path to JSON log file.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n  --update-latest-path FILEPATH\n                           Path to update installer file, which should be\n                           downloaded by Update System.\n  --update-with-package    Enable updating via installer.\n  --no-ntp                 Whether to use real NTP servers to synchronise time\n                           or rely on local time\n  --route53-health-check IP:PORT\n                           Host and port for the Route53 DNS health check.\n  --metrics                Enable metrics (EKG, statsd)\n  --ekg-server IP:PORT     Host and port for the EKG server\n  --statsd-server IP:PORT  Host and port for the statsd server\n  --statsd-interval MILLISECONDS\n                           Polling interval for statsd (milliseconds)\n  --statsd-debug BOOL      Enable statsd debug mode\n  --statsd-prefix TEXT     Prefix for statsd\n  --statsd-suffix TEXT     Suffix for statsd\n  --dump-genesis-data-to ARG\n                           Dump genesis data in canonical JSON format to this\n                           file.\n  --web                    Activate web API (it’s not linked with a wallet web\n                           API).\n  --web-port PORT          Port for web API. (default: 8080)\n  --tlscert FILEPATH       Path to file with TLS certificate\n  --tlskey FILEPATH        Path to file with TLS key\n  --tlsca FILEPATH         Path to file with TLS certificate authority\n  --wallet-address IP:PORT IP and port for backend wallet\n                           API. (default: (\"127.0.0.1\",8090))\n  --wallet-db-path ARG     Path to the wallet's database.\n  --wallet-rebuild-db      If wallet's database already exists, discard its\n                           contents and create a new one from scratch.\n  --wallet-acid-cleanup-interval MINUTES\n                           Interval on which to execute wallet cleanup action\n                           (create checkpoint and archive and cleanup archive\n                           partially)\n  --wallet-debug           Run wallet with debug params (e.g. include all the\n                           genesis keys in the set of secret keys).\n  --flush-wallet-db        Flushes all blockchain-recoverable data from DB\n                           (everything excluding wallets/accounts/addresses,\n                           metadata)\n\nCommand example:\n\n  stack exec -- cardano-node                                             \\\n    --db-path node-db0                                                   \\\n    --rebuild-db                                                         \\\n    --keyfile secrets/secret-1.key                                       \\\n    --kademlia-id a_P8zb6fNP7I2H54FtGuhqxaMDAwMDAwMDAwMDAwMDA=           \\\n    --address 127.0.0.1:3000                                             \\\n    --listen 127.0.0.1:3000                                              \\\n    --kademlia-address 127.0.0.1:3000                                    \\\n    --json-log=/tmp/logs/2017-05-22_181224/node0.json                    \\\n    --logs-prefix /tmp/logs/2017-05-22_181224                            \\\n    --log-config /tmp/logs/2017-05-22_181224/conf/node0.log.yaml         \\\n    --kademlia-dump-path /tmp/logs/2017-05-22_181224/dump/kademlia0.dump \\\n    --system-start 1495462345\n</code></pre>\n<h2>cardano-keygen</h2>\n<pre><code>Tool to generate keyfiles-related data\n\nUsage: cardano-keygen [--version] COMMAND [--configuration-file FILEPATH]\n                      [--configuration-key TEXT] [--system-start TIMESTAMP]\n                      [--configuration-seed INTEGER]\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n\nAvailable commands:\n  rearrange                Rearrange keyfiles.\n  generate-key             Generate keyfile.\n  generate-vss             Generate VSS certificate.\n  read-key                 Dump keyfile contents.\n  generate-avvm-seeds      Generate avvm seeds with public keys.\n  generate-keys-by-spec    Generate secret keys and avvm seed by\n                           genesis-spec.yaml\n  dump-genesis-data        Dump genesis data (as per configuration) in json\n                           format\n</code></pre>\n<h2>cardano-explorer-swagger</h2>\n<pre><code>Cardano SL Explorer web API docs generator.\n\nUsage: cardano-explorer-swagger [--version]\n  Generate Swagger specification for Explorer web API.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n\nThis program runs during 'cardano-sl' building on Travis CI. Generated file\n'explorer-web-api-swagger.json' will be used to produce HTML documentation. This\ndocumentation will be published at cardanodocs.com using\n'update-explorer-web-api-docs.sh'.\n</code></pre>\n<h2>cardano-node-simple</h2>\n<pre><code>Cardano SL node.\n\nUsage: cardano-node-simple [--version] [--db-path FILEPATH] [--rebuild-db]\n                           [--genesis-secret INT] [--keyfile FILEPATH]\n                           [--backup-phrase PHRASE] [--topology FILEPATH]\n                           [--kademlia FILEPATH] [--node-id NODE_ID]\n                           [--default-port PORT] [--policies FILEPATH]\n                           [--address IP:PORT] [--listen IP:PORT]\n                           [--json-log FILEPATH] [--log-config FILEPATH]\n                           [--logs-prefix FILEPATH] [--report-server URI]\n                           [--update-server URI] [--configuration-file FILEPATH]\n                           [--configuration-key TEXT] [--system-start TIMESTAMP]\n                           [--configuration-seed INTEGER]\n                           [--update-latest-path FILEPATH]\n                           [--update-with-package] [--no-ntp]\n                           [--route53-health-check IP:PORT] [--metrics]\n                           [--ekg-server IP:PORT] [--statsd-server IP:PORT]\n                           [--statsd-interval MILLISECONDS]\n                           [--statsd-debug BOOL] [--statsd-prefix TEXT]\n                           [--statsd-suffix TEXT] [--dump-genesis-data-to ARG]\n                           [--behavior FILE]\n  Cardano SL main server node.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --db-path FILEPATH       Path to directory with all DBs used by the node. If\n                           specified path doesn’t exist, a directory will be\n                           created.\n  --rebuild-db             If node's database already exists, discard its\n                           contents and create a new one from scratch.\n  --genesis-secret INT     Used genesis secret key index.\n  --keyfile FILEPATH       Path to file with secret key (we use it for\n                           Daedalus).\n  --backup-phrase PHRASE   12-word phrase to recover the wallet. Words should be\n                           separated by spaces.\n  --topology FILEPATH      Path to a YAML file containing the network topology\n  --kademlia FILEPATH      Path to a YAML file containing the kademlia\n                           configuration\n  --node-id NODE_ID        Identifier for this node within the network\n  --default-port PORT      Port number for IP address to node ID translation\n  --policies FILEPATH      Path to a YAML file containing the network policies\n  --address IP:PORT        IP and port of external address. Please make sure\n                           these IP and port (on which node is running) are\n                           accessible otherwise proper work of CSL isn't\n                           guaranteed. 0.0.0.0 is not accepted as a valid host.\n  --listen IP:PORT         IP and port on which to bind and listen. Please make\n                           sure these IP and port are accessible, otherwise\n                           proper work of CSL isn't guaranteed.\n  --json-log FILEPATH      Path to JSON log file.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n  --update-latest-path FILEPATH\n                           Path to update installer file, which should be\n                           downloaded by Update System.\n  --update-with-package    Enable updating via installer.\n  --no-ntp                 Whether to use real NTP servers to synchronise time\n                           or rely on local time\n  --route53-health-check IP:PORT\n                           Host and port for the Route53 DNS health check.\n  --metrics                Enable metrics (EKG, statsd)\n  --ekg-server IP:PORT     Host and port for the EKG server\n  --statsd-server IP:PORT  Host and port for the statsd server\n  --statsd-interval MILLISECONDS\n                           Polling interval for statsd (milliseconds)\n  --statsd-debug BOOL      Enable statsd debug mode\n  --statsd-prefix TEXT     Prefix for statsd\n  --statsd-suffix TEXT     Suffix for statsd\n  --dump-genesis-data-to ARG\n                           Dump genesis data in canonical JSON format to this\n                           file.\n  --behavior FILE          Path to the behavior config\n\nCommand example:\n\n  stack exec -- cardano-node                                             \\\n    --db-path node-db0                                                   \\\n    --rebuild-db                                                         \\\n    --keyfile secrets/secret-1.key                                       \\\n    --kademlia-id a_P8zb6fNP7I2H54FtGuhqxaMDAwMDAwMDAwMDAwMDA=           \\\n    --address 127.0.0.1:3000                                             \\\n    --listen 127.0.0.1:3000                                              \\\n    --kademlia-address 127.0.0.1:3000                                    \\\n    --json-log=/tmp/logs/2017-05-22_181224/node0.json                    \\\n    --logs-prefix /tmp/logs/2017-05-22_181224                            \\\n    --log-config /tmp/logs/2017-05-22_181224/conf/node0.log.yaml         \\\n    --kademlia-dump-path /tmp/logs/2017-05-22_181224/dump/kademlia0.dump \\\n    --system-start 1495462345\n</code></pre>\n<h2>cardano-launcher</h2>\n<pre><code>Tool to launch Cardano SL.\n\nUsage: cardano-launcher [--version] --node PATH [-n ARG]\n                        [--node-log-config PATH] [--node-log-path PATH]\n                        [--wallet PATH] [-w ARG] --updater PATH [-u ARG]\n                        [--update-archive PATH] [--updater-windows-runner PATH]\n                        --node-timeout SEC [--report-server URL]\n                        [--configuration-file FILEPATH]\n                        [--configuration-key TEXT] [--system-start TIMESTAMP]\n                        [--configuration-seed INTEGER]\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --node PATH              Path to the node executable.\n  -n ARG                   An argument to be passed to the node.\n  --node-log-config PATH   Path to log config that will be used by the node.\n  --node-log-path PATH     File where node stdout/err will be redirected (def:\n                           temp file).\n  --wallet PATH            Path to the wallet executable.\n  -w ARG                   An argument to be passed to the wallet.\n  --updater PATH           Path to the updater executable.\n  -u ARG                   An argument to be passed to the updater.\n  --update-archive PATH    Path to the update archive, it will be passed to the\n                           updater.\n  --updater-windows-runner PATH\n                           Path to write the Windows batch file executing\n                           updater\n  --node-timeout SEC       How much to wait for the node to exit before killing\n                           it.\n  --report-server URL      Where to send logs in case of failure.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n\nCommand example:\n\n  stack exec -- cardano-launcher                                   \\\n    --node binaries_v000/cardano-node                              \\\n    --node-log-config scripts/log-templates/update-log-config.yaml \\\n    -n \"--update-server\"                                           \\\n    -n \"http://localhost:3001\"                                     \\\n    -n \"--update-latest-path\"                                      \\\n    -n \"updateDownloaded.tar\"                                      \\\n    -n \"--listen\"                                                  \\\n    -n \"127.0.0.1:3004\"                                            \\\n    -n \"--kademlia-id\"                                             \\\n    -n \"a_P8zb6fNP7I2H54FtGuhqxaMDAwMDAwMDAwMDAwMDA=\"              \\\n    -n \"--flat-distr\"                                              \\\n    -n \"(3,100000)\"                                                \\\n    -n \"--rebuild-db\"                                              \\\n    -n \"--wallet\"                                                  \\\n    -n \"--web-port\"                                                \\\n    -n 8080                                                        \\\n    -n \"--wallet-rebuild-db\"                                       \\\n    --updater cardano-updater                                      \\\n    -u \"dir\"                                                       \\\n    -u \"binaries_v000\"                                             \\\n    --node-timeout 5                                               \\\n    --update-archive updateDownloaded.tar\n</code></pre>\n<h2>cardano-block-gen</h2>\n<pre><code>Cardano SL blockchain generator\n\nUsage: cardano-block-gen [--version] --blocks INT --nodes INT\n                         [--generated-db FILEPATH] [--append] [--seed INT]\n                         [--tx-count (INT,INT)] [--tx-max-outs INT]\n  It generates database of node, corresponding to some correct blockchain\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --blocks INT             Length of blockchain.\n  --nodes INT              Number of nodes.\n  --generated-db FILEPATH  Location of generated database.\n  --append                 If database already exists, append to it.\n  --seed INT               Custom seed to generate blocks.\n  --tx-count (INT,INT)     Tx count range.\n  --tx-max-outs INT        Max number of outputs in tx\n\nCommand example:\n\n  stack exec -- cardano-block-gen           \\\n    --blocks 5000                           \\\n    --nodes 3                               \\\n    --coins 100                             \\\n    --generated-db /path/to/existed/db      \\\n    --seed 123                              \\\n    --append\n</code></pre>\n<h2>cardano-report-server</h2>\n<pre><code>CardanoSL report server\n\nUsage: cardano-report-server [-p|--port INTEGER] [--logsdir FILEPATH]\n                             [--severity SEVERITY] [--size-limit BYTES]\n                             [--version]\n  CardanoSL reporting server daemon\n\nAvailable options:\n  -p,--port INTEGER        Port server is running on\n  --logsdir FILEPATH       Directory server will be saving logs in\n  --severity SEVERITY      Logging severity\n  --size-limit BYTES       Maximum body size allowed (will send 413 responses if\n                           bigger)\n  -h,--help                Show this help text\n  --version                Show version\n</code></pre>\n<h2>cardano-dht-keygen</h2>\n<pre><code>Generator of random key for Kademlia DHT.\n\nUsage: cardano-dht-keygen [--version] (-n|--nonce STRING)\n  Generated key will be print to stdout.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  -n,--nonce STRING        14-characters string.\n</code></pre>\n<h2>cardano-explorer-mock</h2>\n<pre><code>Cardano SL Explorer web mock.\n\nUsage: cardano-explorer-mock [--version]\n  Run mock for Explorer web API.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n\nThis program returns just the mocked data. It doesn't call any CSL functions and\ndoesn't interact with it. It just implements the API and returns simeple test\ndata.\n</code></pre>\n<h2>cardano-addr-convert</h2>\n<pre><code>Tool to convert vending addresses into testnet addresses.\n\nUsage: cardano-addr-convert [--version] [-a|--address STRING]\n  Produce public key and write it in stdout.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  -a,--address STRING      Address to convert. It must be in base64(url) format.\n\nCommand example:\n\n  stack exec -- cardano-addr-convert -a 2HF83bvYCTzoCbVta6t64W8rFEnvnkJbIUFoT5tOyoU=\n\nOutput example:\n\n  3mhNKjfhaCT13DjcQ9eMK4VHfZrFxmyXq8SjVPRtz7SWfP\n\nYou can also run it without arguments to switch to interactive mode.\nIn this case each entered vending address is echoed with a testnet address.\n</code></pre>\n<h2>cardano-blockchain-analyser</h2>\n<pre><code>Cardano SL blockchain generator\n\nUsage: cardano-blockchain-analyser --db FILEPATH ([-k] | [-m] | [-g] | [-a] |\n                                   [-b]) [--print-mode [human|csv|table]]\n                                   [-i|--incremental] [--log-config FILEPATH]\n                                   [--logs-prefix FILEPATH]\n                                   [--report-server URI] [--update-server URI]\n                                   [--configuration-file FILEPATH]\n                                   [--configuration-key TEXT]\n                                   [--system-start TIMESTAMP]\n                                   [--configuration-seed INTEGER]\n  Analyse a blockchain and spit out useful metrics.\n\nAvailable options:\n  -h,--help                Show this help text\n  --db FILEPATH            Location of the database where the blockchain is\n                           stored.\n  -k                       Display block counts in kilobytes (KB).\n  -m                       Display block counts in megabytes (MB).\n  -g                       Display block counts in gigabytes (GB).\n  -a                       Display block counts using an adaptive multiplier.\n  -b                       Display block counts in bytes (B).\n  --print-mode [human|csv|table]\n                           Select the desidered rendering mode, one between\n                           'human', 'csv' or 'table'.\n  -i,--incremental         Run in incremental mode. In this mode, table output\n                           will be disabled and rendered as a .csv, as is not\n                           possible to generate nice-looking tables whilst\n                           reading the blockchain one block at time. You almost\n                           always want to be using this mode for huge\n                           blockchains, as it's much more memory efficient.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n\nCommand example:\n\n  cardano-blockchain-analyser --db /path/to/existing/db\n</code></pre>\n<h2>cardano-auxx</h2>\n<pre><code>CLI-based utilities (auxx).\n\nUsage: cardano-auxx [--version] COMMAND [--db-path FILEPATH] [--rebuild-db]\n                    [--genesis-secret INT] [--keyfile FILEPATH]\n                    [--backup-phrase PHRASE] [--topology FILEPATH]\n                    [--kademlia FILEPATH] [--node-id NODE_ID]\n                    [--default-port PORT] [--policies FILEPATH]\n                    [--address IP:PORT] [--listen IP:PORT] [--json-log FILEPATH]\n                    [--log-config FILEPATH] [--logs-prefix FILEPATH]\n                    [--report-server URI] [--update-server URI]\n                    [--configuration-file FILEPATH] [--configuration-key TEXT]\n                    [--system-start TIMESTAMP] [--configuration-seed INTEGER]\n                    [--update-latest-path FILEPATH] [--update-with-package]\n                    [--no-ntp] [--route53-health-check IP:PORT] [--metrics]\n                    [--ekg-server IP:PORT] [--statsd-server IP:PORT]\n                    [--statsd-interval MILLISECONDS] [--statsd-debug BOOL]\n                    [--statsd-prefix TEXT] [--statsd-suffix TEXT]\n                    [--dump-genesis-data-to ARG] [--peer HOST:PORT]\n                    [--node-enabled]\n  Cardano SL CLI utilities.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --db-path FILEPATH       Path to directory with all DBs used by the node. If\n                           specified path doesn’t exist, a directory will be\n                           created.\n  --rebuild-db             If node's database already exists, discard its\n                           contents and create a new one from scratch.\n  --genesis-secret INT     Used genesis secret key index.\n  --keyfile FILEPATH       Path to file with secret key (we use it for\n                           Daedalus).\n  --backup-phrase PHRASE   12-word phrase to recover the wallet. Words should be\n                           separated by spaces.\n  --topology FILEPATH      Path to a YAML file containing the network topology\n  --kademlia FILEPATH      Path to a YAML file containing the kademlia\n                           configuration\n  --node-id NODE_ID        Identifier for this node within the network\n  --default-port PORT      Port number for IP address to node ID translation\n  --policies FILEPATH      Path to a YAML file containing the network policies\n  --address IP:PORT        IP and port of external address. Please make sure\n                           these IP and port (on which node is running) are\n                           accessible otherwise proper work of CSL isn't\n                           guaranteed. 0.0.0.0 is not accepted as a valid host.\n  --listen IP:PORT         IP and port on which to bind and listen. Please make\n                           sure these IP and port are accessible, otherwise\n                           proper work of CSL isn't guaranteed.\n  --json-log FILEPATH      Path to JSON log file.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n  --update-latest-path FILEPATH\n                           Path to update installer file, which should be\n                           downloaded by Update System.\n  --update-with-package    Enable updating via installer.\n  --no-ntp                 Whether to use real NTP servers to synchronise time\n                           or rely on local time\n  --route53-health-check IP:PORT\n                           Host and port for the Route53 DNS health check.\n  --metrics                Enable metrics (EKG, statsd)\n  --ekg-server IP:PORT     Host and port for the EKG server\n  --statsd-server IP:PORT  Host and port for the statsd server\n  --statsd-interval MILLISECONDS\n                           Polling interval for statsd (milliseconds)\n  --statsd-debug BOOL      Enable statsd debug mode\n  --statsd-prefix TEXT     Prefix for statsd\n  --statsd-suffix TEXT     Suffix for statsd\n  --dump-genesis-data-to ARG\n                           Dump genesis data in canonical JSON format to this\n                           file.\n  --peer HOST:PORT         Address of a peer.\n  --node-enabled           Run auxx as a plugin for the node, as opposed to\n                           running it standalone (default: standalone).\n\nAvailable commands:\n  repl                     Run REPL in console to evaluate the commands.\n  cmd                      Execute a list of predefined commands.\n\nCommand example:\n\n  stack exec -- cardano-auxx                                     \\\n    --db-path run/auxx-db                                        \\\n    --rebuild-db                                                 \\\n    --json-log=/tmp/logs/2017-05-22_181224/node0.json            \\\n    --logs-prefix /tmp/logs/2017-05-22_181224                    \\\n    --log-config /tmp/logs/2017-05-22_181224/conf/node0.log.yaml \\\n    --system-start 1495462345                                    \\\n    --peer 127.0.0.1:3001                                        \\\n    repl\n</code></pre>\n<h2>cardano-cli-docs</h2>\n<pre><code>Tool to generate CLI-docs for Cardano SL executable files.\n\nUsage: cardano-cli-docs [--version] --bin-dir PATH\n  Generate Markdown chapter for cardanodocs.com.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --bin-dir PATH           Path to the directory with Cardano SL executable\n                           files.\n\nAssumed that this program will run on Travis CI. Produced file\n'cardano-cli-docs.md' will be renamed in a chapter and pushed in cardanodocs.com\nrepository.\n</code></pre>\n<h2>cardano-genupdate</h2>\n<pre><code>Cardano SL updates generator.\n\nUsage: cardano-genupdate [--version] --old PATH --new PATH (-o|--output PATH)\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --old PATH               Path to directory with old program.\n  --new PATH               Path to directory with new program.\n  -o,--output PATH         Path to output .tar-file with diff.\n\nCommand example:\n\n  stack exec -- cardano-genupdate --old /tmp/app-v000 --new /tmp/app-v001 -o /tmp/app-update.tar\n\nBoth directories must have equal file structure (e.g. they must contain the same\nfiles in the same subdirectories correspondingly), otherwise 'cardano-genupdate' will fail.\n\nPlease note that 'cardano-genupdate' uses 'bsdiff' program, so make sure 'bsdiff' is available in the PATH.\n</code></pre>\n<h2>cardano-explorer</h2>\n<pre><code>Cardano SL explorer.\n\nUsage: cardano-explorer [--version] [--db-path FILEPATH] [--rebuild-db]\n                        [--genesis-secret INT] [--keyfile FILEPATH]\n                        [--backup-phrase PHRASE] [--topology FILEPATH]\n                        [--kademlia FILEPATH] [--node-id NODE_ID]\n                        [--default-port PORT] [--policies FILEPATH]\n                        [--address IP:PORT] [--listen IP:PORT]\n                        [--json-log FILEPATH] [--log-config FILEPATH]\n                        [--logs-prefix FILEPATH] [--report-server URI]\n                        [--update-server URI] [--configuration-file FILEPATH]\n                        [--configuration-key TEXT] [--system-start TIMESTAMP]\n                        [--configuration-seed INTEGER]\n                        [--update-latest-path FILEPATH] [--update-with-package]\n                        [--no-ntp] [--route53-health-check IP:PORT] [--metrics]\n                        [--ekg-server IP:PORT] [--statsd-server IP:PORT]\n                        [--statsd-interval MILLISECONDS] [--statsd-debug BOOL]\n                        [--statsd-prefix TEXT] [--statsd-suffix TEXT]\n                        [--dump-genesis-data-to ARG] [--web-port PORT]\n                        [--notifier-port PORT]\n  Cardano SL main server node w/ explorer.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --db-path FILEPATH       Path to directory with all DBs used by the node. If\n                           specified path doesn’t exist, a directory will be\n                           created.\n  --rebuild-db             If node's database already exists, discard its\n                           contents and create a new one from scratch.\n  --genesis-secret INT     Used genesis secret key index.\n  --keyfile FILEPATH       Path to file with secret key (we use it for\n                           Daedalus).\n  --backup-phrase PHRASE   12-word phrase to recover the wallet. Words should be\n                           separated by spaces.\n  --topology FILEPATH      Path to a YAML file containing the network topology\n  --kademlia FILEPATH      Path to a YAML file containing the kademlia\n                           configuration\n  --node-id NODE_ID        Identifier for this node within the network\n  --default-port PORT      Port number for IP address to node ID translation\n  --policies FILEPATH      Path to a YAML file containing the network policies\n  --address IP:PORT        IP and port of external address. Please make sure\n                           these IP and port (on which node is running) are\n                           accessible otherwise proper work of CSL isn't\n                           guaranteed. 0.0.0.0 is not accepted as a valid host.\n  --listen IP:PORT         IP and port on which to bind and listen. Please make\n                           sure these IP and port are accessible, otherwise\n                           proper work of CSL isn't guaranteed.\n  --json-log FILEPATH      Path to JSON log file.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n  --update-latest-path FILEPATH\n                           Path to update installer file, which should be\n                           downloaded by Update System.\n  --update-with-package    Enable updating via installer.\n  --no-ntp                 Whether to use real NTP servers to synchronise time\n                           or rely on local time\n  --route53-health-check IP:PORT\n                           Host and port for the Route53 DNS health check.\n  --metrics                Enable metrics (EKG, statsd)\n  --ekg-server IP:PORT     Host and port for the EKG server\n  --statsd-server IP:PORT  Host and port for the statsd server\n  --statsd-interval MILLISECONDS\n                           Polling interval for statsd (milliseconds)\n  --statsd-debug BOOL      Enable statsd debug mode\n  --statsd-prefix TEXT     Prefix for statsd\n  --statsd-suffix TEXT     Suffix for statsd\n  --dump-genesis-data-to ARG\n                           Dump genesis data in canonical JSON format to this\n                           file.\n  --web-port PORT          Port for web API. (default: 8100)\n  --notifier-port PORT     Port for update notifier, the socket.io\n                           backend. (default: 8110)\n</code></pre>\n<h2>cardano-swagger</h2>\n<pre><code>Cardano SL Wallet web API docs generator.\n\nUsage: cardano-swagger [--version]\n  Generate Swagger specification for Wallet web API.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n\nThis program runs during 'cardano-sl' building on Travis CI. Generated file\n'wallet-web-api-swagger.json' will be used to produce HTML documentation. This\ndocumentation will be published at cardanodocs.com using\n'update_wallet_web_api_docs.sh'.\n</code></pre>\n<h2>cardano-post-mortem</h2>\n<pre><code>cardano-post-mortem\n\nUsage: cardano-post-mortem COMMAND\n  analyzes the json logs from several directories or focusses on a single\n  transaction\n\nAvailable options:\n  -h,--help                Show this help text\n\nAvailable commands:\n  overview                 analyzes the json logs from LOGDIRS...\n  focus                    analyzes transaction FOCUS in log folder LOGDIR\n  txrelay                  analyzes transaction relays in the json logs from\n                           LOGDIRS...\n  throughput               analyzes transaction throughput and waiting time per\n                           time windows TXWINDOW and WAITWINDOW in the json logs\n                           from LOGDIRS...\n</code></pre>",
  frontmatter:{path:"/cn/technical/cli-options/",doc_title:"卡尔达诺结算层命令行选项",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/2017-01-01-cli-options.md absPath of file >>> MarkdownRemark",excerpt:"Cardano SL CLI Options This guide describes all executable files that are used in Cardano SL and all corresponding CLI-options/parameters…",html:"<!-- THIS IS AUTOGENERATED CHAPTER. DO NOT CHANGE IT MANUALLY! -->\n<h2>Cardano SL CLI Options</h2>\n<p>This guide describes all executable files that are used in Cardano SL and all corresponding CLI-options/parameters.</p>\n<h2>cardano-node</h2>\n<pre><code>Cardano SL node.\n\nUsage: cardano-node [--version] [--db-path FILEPATH] [--rebuild-db]\n                    [--genesis-secret INT] [--keyfile FILEPATH]\n                    [--backup-phrase PHRASE] [--topology FILEPATH]\n                    [--kademlia FILEPATH] [--node-id NODE_ID]\n                    [--default-port PORT] [--policies FILEPATH]\n                    [--address IP:PORT] [--listen IP:PORT] [--json-log FILEPATH]\n                    [--log-config FILEPATH] [--logs-prefix FILEPATH]\n                    [--report-server URI] [--update-server URI]\n                    [--configuration-file FILEPATH] [--configuration-key TEXT]\n                    [--system-start TIMESTAMP] [--configuration-seed INTEGER]\n                    [--update-latest-path FILEPATH] [--update-with-package]\n                    [--no-ntp] [--route53-health-check IP:PORT] [--metrics]\n                    [--ekg-server IP:PORT] [--statsd-server IP:PORT]\n                    [--statsd-interval MILLISECONDS] [--statsd-debug BOOL]\n                    [--statsd-prefix TEXT] [--statsd-suffix TEXT]\n                    [--dump-genesis-data-to ARG] [--web] [--web-port PORT]\n                    [--tlscert FILEPATH] [--tlskey FILEPATH] [--tlsca FILEPATH]\n                    [--wallet-address IP:PORT] [--wallet-db-path ARG]\n                    [--wallet-rebuild-db]\n                    [--wallet-acid-cleanup-interval MINUTES] [--wallet-debug]\n                    [--flush-wallet-db]\n  Cardano SL main server node w/ wallet.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --db-path FILEPATH       Path to directory with all DBs used by the node. If\n                           specified path doesn’t exist, a directory will be\n                           created.\n  --rebuild-db             If node's database already exists, discard its\n                           contents and create a new one from scratch.\n  --genesis-secret INT     Used genesis secret key index.\n  --keyfile FILEPATH       Path to file with secret key (we use it for\n                           Daedalus).\n  --backup-phrase PHRASE   12-word phrase to recover the wallet. Words should be\n                           separated by spaces.\n  --topology FILEPATH      Path to a YAML file containing the network topology\n  --kademlia FILEPATH      Path to a YAML file containing the kademlia\n                           configuration\n  --node-id NODE_ID        Identifier for this node within the network\n  --default-port PORT      Port number for IP address to node ID translation\n  --policies FILEPATH      Path to a YAML file containing the network policies\n  --address IP:PORT        IP and port of external address. Please make sure\n                           these IP and port (on which node is running) are\n                           accessible otherwise proper work of CSL isn't\n                           guaranteed. 0.0.0.0 is not accepted as a valid host.\n  --listen IP:PORT         IP and port on which to bind and listen. Please make\n                           sure these IP and port are accessible, otherwise\n                           proper work of CSL isn't guaranteed.\n  --json-log FILEPATH      Path to JSON log file.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n  --update-latest-path FILEPATH\n                           Path to update installer file, which should be\n                           downloaded by Update System.\n  --update-with-package    Enable updating via installer.\n  --no-ntp                 Whether to use real NTP servers to synchronise time\n                           or rely on local time\n  --route53-health-check IP:PORT\n                           Host and port for the Route53 DNS health check.\n  --metrics                Enable metrics (EKG, statsd)\n  --ekg-server IP:PORT     Host and port for the EKG server\n  --statsd-server IP:PORT  Host and port for the statsd server\n  --statsd-interval MILLISECONDS\n                           Polling interval for statsd (milliseconds)\n  --statsd-debug BOOL      Enable statsd debug mode\n  --statsd-prefix TEXT     Prefix for statsd\n  --statsd-suffix TEXT     Suffix for statsd\n  --dump-genesis-data-to ARG\n                           Dump genesis data in canonical JSON format to this\n                           file.\n  --web                    Activate web API (it’s not linked with a wallet web\n                           API).\n  --web-port PORT          Port for web API. (default: 8080)\n  --tlscert FILEPATH       Path to file with TLS certificate\n  --tlskey FILEPATH        Path to file with TLS key\n  --tlsca FILEPATH         Path to file with TLS certificate authority\n  --wallet-address IP:PORT IP and port for backend wallet\n                           API. (default: (\"127.0.0.1\",8090))\n  --wallet-db-path ARG     Path to the wallet's database.\n  --wallet-rebuild-db      If wallet's database already exists, discard its\n                           contents and create a new one from scratch.\n  --wallet-acid-cleanup-interval MINUTES\n                           Interval on which to execute wallet cleanup action\n                           (create checkpoint and archive and cleanup archive\n                           partially)\n  --wallet-debug           Run wallet with debug params (e.g. include all the\n                           genesis keys in the set of secret keys).\n  --flush-wallet-db        Flushes all blockchain-recoverable data from DB\n                           (everything excluding wallets/accounts/addresses,\n                           metadata)\n\nCommand example:\n\n  stack exec -- cardano-node                                             \\\n    --db-path node-db0                                                   \\\n    --rebuild-db                                                         \\\n    --keyfile secrets/secret-1.key                                       \\\n    --kademlia-id a_P8zb6fNP7I2H54FtGuhqxaMDAwMDAwMDAwMDAwMDA=           \\\n    --address 127.0.0.1:3000                                             \\\n    --listen 127.0.0.1:3000                                              \\\n    --kademlia-address 127.0.0.1:3000                                    \\\n    --json-log=/tmp/logs/2017-05-22_181224/node0.json                    \\\n    --logs-prefix /tmp/logs/2017-05-22_181224                            \\\n    --log-config /tmp/logs/2017-05-22_181224/conf/node0.log.yaml         \\\n    --kademlia-dump-path /tmp/logs/2017-05-22_181224/dump/kademlia0.dump \\\n    --system-start 1495462345\n</code></pre>\n<h2>cardano-keygen</h2>\n<pre><code>Tool to generate keyfiles-related data\n\nUsage: cardano-keygen [--version] COMMAND [--configuration-file FILEPATH]\n                      [--configuration-key TEXT] [--system-start TIMESTAMP]\n                      [--configuration-seed INTEGER]\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n\nAvailable commands:\n  rearrange                Rearrange keyfiles.\n  generate-key             Generate keyfile.\n  generate-vss             Generate VSS certificate.\n  read-key                 Dump keyfile contents.\n  generate-avvm-seeds      Generate avvm seeds with public keys.\n  generate-keys-by-spec    Generate secret keys and avvm seed by\n                           genesis-spec.yaml\n  dump-genesis-data        Dump genesis data (as per configuration) in json\n                           format\n</code></pre>\n<h2>cardano-explorer-swagger</h2>\n<pre><code>Cardano SL Explorer web API docs generator.\n\nUsage: cardano-explorer-swagger [--version]\n  Generate Swagger specification for Explorer web API.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n\nThis program runs during 'cardano-sl' building on Travis CI. Generated file\n'explorer-web-api-swagger.json' will be used to produce HTML documentation. This\ndocumentation will be published at cardanodocs.com using\n'update-explorer-web-api-docs.sh'.\n</code></pre>\n<h2>cardano-node-simple</h2>\n<pre><code>Cardano SL node.\n\nUsage: cardano-node-simple [--version] [--db-path FILEPATH] [--rebuild-db]\n                           [--genesis-secret INT] [--keyfile FILEPATH]\n                           [--backup-phrase PHRASE] [--topology FILEPATH]\n                           [--kademlia FILEPATH] [--node-id NODE_ID]\n                           [--default-port PORT] [--policies FILEPATH]\n                           [--address IP:PORT] [--listen IP:PORT]\n                           [--json-log FILEPATH] [--log-config FILEPATH]\n                           [--logs-prefix FILEPATH] [--report-server URI]\n                           [--update-server URI] [--configuration-file FILEPATH]\n                           [--configuration-key TEXT] [--system-start TIMESTAMP]\n                           [--configuration-seed INTEGER]\n                           [--update-latest-path FILEPATH]\n                           [--update-with-package] [--no-ntp]\n                           [--route53-health-check IP:PORT] [--metrics]\n                           [--ekg-server IP:PORT] [--statsd-server IP:PORT]\n                           [--statsd-interval MILLISECONDS]\n                           [--statsd-debug BOOL] [--statsd-prefix TEXT]\n                           [--statsd-suffix TEXT] [--dump-genesis-data-to ARG]\n                           [--behavior FILE]\n  Cardano SL main server node.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --db-path FILEPATH       Path to directory with all DBs used by the node. If\n                           specified path doesn’t exist, a directory will be\n                           created.\n  --rebuild-db             If node's database already exists, discard its\n                           contents and create a new one from scratch.\n  --genesis-secret INT     Used genesis secret key index.\n  --keyfile FILEPATH       Path to file with secret key (we use it for\n                           Daedalus).\n  --backup-phrase PHRASE   12-word phrase to recover the wallet. Words should be\n                           separated by spaces.\n  --topology FILEPATH      Path to a YAML file containing the network topology\n  --kademlia FILEPATH      Path to a YAML file containing the kademlia\n                           configuration\n  --node-id NODE_ID        Identifier for this node within the network\n  --default-port PORT      Port number for IP address to node ID translation\n  --policies FILEPATH      Path to a YAML file containing the network policies\n  --address IP:PORT        IP and port of external address. Please make sure\n                           these IP and port (on which node is running) are\n                           accessible otherwise proper work of CSL isn't\n                           guaranteed. 0.0.0.0 is not accepted as a valid host.\n  --listen IP:PORT         IP and port on which to bind and listen. Please make\n                           sure these IP and port are accessible, otherwise\n                           proper work of CSL isn't guaranteed.\n  --json-log FILEPATH      Path to JSON log file.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n  --update-latest-path FILEPATH\n                           Path to update installer file, which should be\n                           downloaded by Update System.\n  --update-with-package    Enable updating via installer.\n  --no-ntp                 Whether to use real NTP servers to synchronise time\n                           or rely on local time\n  --route53-health-check IP:PORT\n                           Host and port for the Route53 DNS health check.\n  --metrics                Enable metrics (EKG, statsd)\n  --ekg-server IP:PORT     Host and port for the EKG server\n  --statsd-server IP:PORT  Host and port for the statsd server\n  --statsd-interval MILLISECONDS\n                           Polling interval for statsd (milliseconds)\n  --statsd-debug BOOL      Enable statsd debug mode\n  --statsd-prefix TEXT     Prefix for statsd\n  --statsd-suffix TEXT     Suffix for statsd\n  --dump-genesis-data-to ARG\n                           Dump genesis data in canonical JSON format to this\n                           file.\n  --behavior FILE          Path to the behavior config\n\nCommand example:\n\n  stack exec -- cardano-node                                             \\\n    --db-path node-db0                                                   \\\n    --rebuild-db                                                         \\\n    --keyfile secrets/secret-1.key                                       \\\n    --kademlia-id a_P8zb6fNP7I2H54FtGuhqxaMDAwMDAwMDAwMDAwMDA=           \\\n    --address 127.0.0.1:3000                                             \\\n    --listen 127.0.0.1:3000                                              \\\n    --kademlia-address 127.0.0.1:3000                                    \\\n    --json-log=/tmp/logs/2017-05-22_181224/node0.json                    \\\n    --logs-prefix /tmp/logs/2017-05-22_181224                            \\\n    --log-config /tmp/logs/2017-05-22_181224/conf/node0.log.yaml         \\\n    --kademlia-dump-path /tmp/logs/2017-05-22_181224/dump/kademlia0.dump \\\n    --system-start 1495462345\n</code></pre>\n<h2>cardano-launcher</h2>\n<pre><code>Tool to launch Cardano SL.\n\nUsage: cardano-launcher [--version] --node PATH [-n ARG]\n                        [--node-log-config PATH] [--node-log-path PATH]\n                        [--wallet PATH] [-w ARG] --updater PATH [-u ARG]\n                        [--update-archive PATH] [--updater-windows-runner PATH]\n                        --node-timeout SEC [--report-server URL]\n                        [--configuration-file FILEPATH]\n                        [--configuration-key TEXT] [--system-start TIMESTAMP]\n                        [--configuration-seed INTEGER]\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --node PATH              Path to the node executable.\n  -n ARG                   An argument to be passed to the node.\n  --node-log-config PATH   Path to log config that will be used by the node.\n  --node-log-path PATH     File where node stdout/err will be redirected (def:\n                           temp file).\n  --wallet PATH            Path to the wallet executable.\n  -w ARG                   An argument to be passed to the wallet.\n  --updater PATH           Path to the updater executable.\n  -u ARG                   An argument to be passed to the updater.\n  --update-archive PATH    Path to the update archive, it will be passed to the\n                           updater.\n  --updater-windows-runner PATH\n                           Path to write the Windows batch file executing\n                           updater\n  --node-timeout SEC       How much to wait for the node to exit before killing\n                           it.\n  --report-server URL      Where to send logs in case of failure.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n\nCommand example:\n\n  stack exec -- cardano-launcher                                   \\\n    --node binaries_v000/cardano-node                              \\\n    --node-log-config scripts/log-templates/update-log-config.yaml \\\n    -n \"--update-server\"                                           \\\n    -n \"http://localhost:3001\"                                     \\\n    -n \"--update-latest-path\"                                      \\\n    -n \"updateDownloaded.tar\"                                      \\\n    -n \"--listen\"                                                  \\\n    -n \"127.0.0.1:3004\"                                            \\\n    -n \"--kademlia-id\"                                             \\\n    -n \"a_P8zb6fNP7I2H54FtGuhqxaMDAwMDAwMDAwMDAwMDA=\"              \\\n    -n \"--flat-distr\"                                              \\\n    -n \"(3,100000)\"                                                \\\n    -n \"--rebuild-db\"                                              \\\n    -n \"--wallet\"                                                  \\\n    -n \"--web-port\"                                                \\\n    -n 8080                                                        \\\n    -n \"--wallet-rebuild-db\"                                       \\\n    --updater cardano-updater                                      \\\n    -u \"dir\"                                                       \\\n    -u \"binaries_v000\"                                             \\\n    --node-timeout 5                                               \\\n    --update-archive updateDownloaded.tar\n</code></pre>\n<h2>cardano-block-gen</h2>\n<pre><code>Cardano SL blockchain generator\n\nUsage: cardano-block-gen [--version] --blocks INT --nodes INT\n                         [--generated-db FILEPATH] [--append] [--seed INT]\n                         [--tx-count (INT,INT)] [--tx-max-outs INT]\n  It generates database of node, corresponding to some correct blockchain\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --blocks INT             Length of blockchain.\n  --nodes INT              Number of nodes.\n  --generated-db FILEPATH  Location of generated database.\n  --append                 If database already exists, append to it.\n  --seed INT               Custom seed to generate blocks.\n  --tx-count (INT,INT)     Tx count range.\n  --tx-max-outs INT        Max number of outputs in tx\n\nCommand example:\n\n  stack exec -- cardano-block-gen           \\\n    --blocks 5000                           \\\n    --nodes 3                               \\\n    --coins 100                             \\\n    --generated-db /path/to/existed/db      \\\n    --seed 123                              \\\n    --append\n</code></pre>\n<h2>cardano-report-server</h2>\n<pre><code>CardanoSL report server\n\nUsage: cardano-report-server [-p|--port INTEGER] [--logsdir FILEPATH]\n                             [--severity SEVERITY] [--size-limit BYTES]\n                             [--version]\n  CardanoSL reporting server daemon\n\nAvailable options:\n  -p,--port INTEGER        Port server is running on\n  --logsdir FILEPATH       Directory server will be saving logs in\n  --severity SEVERITY      Logging severity\n  --size-limit BYTES       Maximum body size allowed (will send 413 responses if\n                           bigger)\n  -h,--help                Show this help text\n  --version                Show version\n</code></pre>\n<h2>cardano-dht-keygen</h2>\n<pre><code>Generator of random key for Kademlia DHT.\n\nUsage: cardano-dht-keygen [--version] (-n|--nonce STRING)\n  Generated key will be print to stdout.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  -n,--nonce STRING        14-characters string.\n</code></pre>\n<h2>cardano-explorer-mock</h2>\n<pre><code>Cardano SL Explorer web mock.\n\nUsage: cardano-explorer-mock [--version]\n  Run mock for Explorer web API.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n\nThis program returns just the mocked data. It doesn't call any CSL functions and\ndoesn't interact with it. It just implements the API and returns simeple test\ndata.\n</code></pre>\n<h2>cardano-addr-convert</h2>\n<pre><code>Tool to convert vending addresses into testnet addresses.\n\nUsage: cardano-addr-convert [--version] [-a|--address STRING]\n  Produce public key and write it in stdout.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  -a,--address STRING      Address to convert. It must be in base64(url) format.\n\nCommand example:\n\n  stack exec -- cardano-addr-convert -a 2HF83bvYCTzoCbVta6t64W8rFEnvnkJbIUFoT5tOyoU=\n\nOutput example:\n\n  3mhNKjfhaCT13DjcQ9eMK4VHfZrFxmyXq8SjVPRtz7SWfP\n\nYou can also run it without arguments to switch to interactive mode.\nIn this case each entered vending address is echoed with a testnet address.\n</code></pre>\n<h2>cardano-blockchain-analyser</h2>\n<pre><code>Cardano SL blockchain generator\n\nUsage: cardano-blockchain-analyser --db FILEPATH ([-k] | [-m] | [-g] | [-a] |\n                                   [-b]) [--print-mode [human|csv|table]]\n                                   [-i|--incremental] [--log-config FILEPATH]\n                                   [--logs-prefix FILEPATH]\n                                   [--report-server URI] [--update-server URI]\n                                   [--configuration-file FILEPATH]\n                                   [--configuration-key TEXT]\n                                   [--system-start TIMESTAMP]\n                                   [--configuration-seed INTEGER]\n  Analyse a blockchain and spit out useful metrics.\n\nAvailable options:\n  -h,--help                Show this help text\n  --db FILEPATH            Location of the database where the blockchain is\n                           stored.\n  -k                       Display block counts in kilobytes (KB).\n  -m                       Display block counts in megabytes (MB).\n  -g                       Display block counts in gigabytes (GB).\n  -a                       Display block counts using an adaptive multiplier.\n  -b                       Display block counts in bytes (B).\n  --print-mode [human|csv|table]\n                           Select the desidered rendering mode, one between\n                           'human', 'csv' or 'table'.\n  -i,--incremental         Run in incremental mode. In this mode, table output\n                           will be disabled and rendered as a .csv, as is not\n                           possible to generate nice-looking tables whilst\n                           reading the blockchain one block at time. You almost\n                           always want to be using this mode for huge\n                           blockchains, as it's much more memory efficient.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n\nCommand example:\n\n  cardano-blockchain-analyser --db /path/to/existing/db\n</code></pre>\n<h2>cardano-auxx</h2>\n<pre><code>CLI-based utilities (auxx).\n\nUsage: cardano-auxx [--version] COMMAND [--db-path FILEPATH] [--rebuild-db]\n                    [--genesis-secret INT] [--keyfile FILEPATH]\n                    [--backup-phrase PHRASE] [--topology FILEPATH]\n                    [--kademlia FILEPATH] [--node-id NODE_ID]\n                    [--default-port PORT] [--policies FILEPATH]\n                    [--address IP:PORT] [--listen IP:PORT] [--json-log FILEPATH]\n                    [--log-config FILEPATH] [--logs-prefix FILEPATH]\n                    [--report-server URI] [--update-server URI]\n                    [--configuration-file FILEPATH] [--configuration-key TEXT]\n                    [--system-start TIMESTAMP] [--configuration-seed INTEGER]\n                    [--update-latest-path FILEPATH] [--update-with-package]\n                    [--no-ntp] [--route53-health-check IP:PORT] [--metrics]\n                    [--ekg-server IP:PORT] [--statsd-server IP:PORT]\n                    [--statsd-interval MILLISECONDS] [--statsd-debug BOOL]\n                    [--statsd-prefix TEXT] [--statsd-suffix TEXT]\n                    [--dump-genesis-data-to ARG] [--peer HOST:PORT]\n                    [--node-enabled]\n  Cardano SL CLI utilities.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --db-path FILEPATH       Path to directory with all DBs used by the node. If\n                           specified path doesn’t exist, a directory will be\n                           created.\n  --rebuild-db             If node's database already exists, discard its\n                           contents and create a new one from scratch.\n  --genesis-secret INT     Used genesis secret key index.\n  --keyfile FILEPATH       Path to file with secret key (we use it for\n                           Daedalus).\n  --backup-phrase PHRASE   12-word phrase to recover the wallet. Words should be\n                           separated by spaces.\n  --topology FILEPATH      Path to a YAML file containing the network topology\n  --kademlia FILEPATH      Path to a YAML file containing the kademlia\n                           configuration\n  --node-id NODE_ID        Identifier for this node within the network\n  --default-port PORT      Port number for IP address to node ID translation\n  --policies FILEPATH      Path to a YAML file containing the network policies\n  --address IP:PORT        IP and port of external address. Please make sure\n                           these IP and port (on which node is running) are\n                           accessible otherwise proper work of CSL isn't\n                           guaranteed. 0.0.0.0 is not accepted as a valid host.\n  --listen IP:PORT         IP and port on which to bind and listen. Please make\n                           sure these IP and port are accessible, otherwise\n                           proper work of CSL isn't guaranteed.\n  --json-log FILEPATH      Path to JSON log file.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n  --update-latest-path FILEPATH\n                           Path to update installer file, which should be\n                           downloaded by Update System.\n  --update-with-package    Enable updating via installer.\n  --no-ntp                 Whether to use real NTP servers to synchronise time\n                           or rely on local time\n  --route53-health-check IP:PORT\n                           Host and port for the Route53 DNS health check.\n  --metrics                Enable metrics (EKG, statsd)\n  --ekg-server IP:PORT     Host and port for the EKG server\n  --statsd-server IP:PORT  Host and port for the statsd server\n  --statsd-interval MILLISECONDS\n                           Polling interval for statsd (milliseconds)\n  --statsd-debug BOOL      Enable statsd debug mode\n  --statsd-prefix TEXT     Prefix for statsd\n  --statsd-suffix TEXT     Suffix for statsd\n  --dump-genesis-data-to ARG\n                           Dump genesis data in canonical JSON format to this\n                           file.\n  --peer HOST:PORT         Address of a peer.\n  --node-enabled           Run auxx as a plugin for the node, as opposed to\n                           running it standalone (default: standalone).\n\nAvailable commands:\n  repl                     Run REPL in console to evaluate the commands.\n  cmd                      Execute a list of predefined commands.\n\nCommand example:\n\n  stack exec -- cardano-auxx                                     \\\n    --db-path run/auxx-db                                        \\\n    --rebuild-db                                                 \\\n    --json-log=/tmp/logs/2017-05-22_181224/node0.json            \\\n    --logs-prefix /tmp/logs/2017-05-22_181224                    \\\n    --log-config /tmp/logs/2017-05-22_181224/conf/node0.log.yaml \\\n    --system-start 1495462345                                    \\\n    --peer 127.0.0.1:3001                                        \\\n    repl\n</code></pre>\n<h2>cardano-cli-docs</h2>\n<pre><code>Tool to generate CLI-docs for Cardano SL executable files.\n\nUsage: cardano-cli-docs [--version] --bin-dir PATH\n  Generate Markdown chapter for cardanodocs.com.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --bin-dir PATH           Path to the directory with Cardano SL executable\n                           files.\n\nAssumed that this program will run on Travis CI. Produced file\n'cardano-cli-docs.md' will be renamed in a chapter and pushed in cardanodocs.com\nrepository.\n</code></pre>\n<h2>cardano-genupdate</h2>\n<pre><code>Cardano SL updates generator.\n\nUsage: cardano-genupdate [--version] --old PATH --new PATH (-o|--output PATH)\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --old PATH               Path to directory with old program.\n  --new PATH               Path to directory with new program.\n  -o,--output PATH         Path to output .tar-file with diff.\n\nCommand example:\n\n  stack exec -- cardano-genupdate --old /tmp/app-v000 --new /tmp/app-v001 -o /tmp/app-update.tar\n\nBoth directories must have equal file structure (e.g. they must contain the same\nfiles in the same subdirectories correspondingly), otherwise 'cardano-genupdate' will fail.\n\nPlease note that 'cardano-genupdate' uses 'bsdiff' program, so make sure 'bsdiff' is available in the PATH.\n</code></pre>\n<h2>cardano-explorer</h2>\n<pre><code>Cardano SL explorer.\n\nUsage: cardano-explorer [--version] [--db-path FILEPATH] [--rebuild-db]\n                        [--genesis-secret INT] [--keyfile FILEPATH]\n                        [--backup-phrase PHRASE] [--topology FILEPATH]\n                        [--kademlia FILEPATH] [--node-id NODE_ID]\n                        [--default-port PORT] [--policies FILEPATH]\n                        [--address IP:PORT] [--listen IP:PORT]\n                        [--json-log FILEPATH] [--log-config FILEPATH]\n                        [--logs-prefix FILEPATH] [--report-server URI]\n                        [--update-server URI] [--configuration-file FILEPATH]\n                        [--configuration-key TEXT] [--system-start TIMESTAMP]\n                        [--configuration-seed INTEGER]\n                        [--update-latest-path FILEPATH] [--update-with-package]\n                        [--no-ntp] [--route53-health-check IP:PORT] [--metrics]\n                        [--ekg-server IP:PORT] [--statsd-server IP:PORT]\n                        [--statsd-interval MILLISECONDS] [--statsd-debug BOOL]\n                        [--statsd-prefix TEXT] [--statsd-suffix TEXT]\n                        [--dump-genesis-data-to ARG] [--web-port PORT]\n                        [--notifier-port PORT]\n  Cardano SL main server node w/ explorer.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n  --db-path FILEPATH       Path to directory with all DBs used by the node. If\n                           specified path doesn’t exist, a directory will be\n                           created.\n  --rebuild-db             If node's database already exists, discard its\n                           contents and create a new one from scratch.\n  --genesis-secret INT     Used genesis secret key index.\n  --keyfile FILEPATH       Path to file with secret key (we use it for\n                           Daedalus).\n  --backup-phrase PHRASE   12-word phrase to recover the wallet. Words should be\n                           separated by spaces.\n  --topology FILEPATH      Path to a YAML file containing the network topology\n  --kademlia FILEPATH      Path to a YAML file containing the kademlia\n                           configuration\n  --node-id NODE_ID        Identifier for this node within the network\n  --default-port PORT      Port number for IP address to node ID translation\n  --policies FILEPATH      Path to a YAML file containing the network policies\n  --address IP:PORT        IP and port of external address. Please make sure\n                           these IP and port (on which node is running) are\n                           accessible otherwise proper work of CSL isn't\n                           guaranteed. 0.0.0.0 is not accepted as a valid host.\n  --listen IP:PORT         IP and port on which to bind and listen. Please make\n                           sure these IP and port are accessible, otherwise\n                           proper work of CSL isn't guaranteed.\n  --json-log FILEPATH      Path to JSON log file.\n  --log-config FILEPATH    Path to logger configuration.\n  --logs-prefix FILEPATH   Prefix to logger output path.\n  --report-server URI      Reporting server to send crash/error logs on.\n  --update-server URI      Server to download updates from.\n  --configuration-file FILEPATH\n                           Path to a yaml configuration file\n  --configuration-key TEXT Key within the configuration file to use\n  --system-start TIMESTAMP System start time. Format - seconds since Unix Epoch.\n  --configuration-seed INTEGER\n                           Seed for genesis generation. Overrides one from\n                           configuration file.\n  --update-latest-path FILEPATH\n                           Path to update installer file, which should be\n                           downloaded by Update System.\n  --update-with-package    Enable updating via installer.\n  --no-ntp                 Whether to use real NTP servers to synchronise time\n                           or rely on local time\n  --route53-health-check IP:PORT\n                           Host and port for the Route53 DNS health check.\n  --metrics                Enable metrics (EKG, statsd)\n  --ekg-server IP:PORT     Host and port for the EKG server\n  --statsd-server IP:PORT  Host and port for the statsd server\n  --statsd-interval MILLISECONDS\n                           Polling interval for statsd (milliseconds)\n  --statsd-debug BOOL      Enable statsd debug mode\n  --statsd-prefix TEXT     Prefix for statsd\n  --statsd-suffix TEXT     Suffix for statsd\n  --dump-genesis-data-to ARG\n                           Dump genesis data in canonical JSON format to this\n                           file.\n  --web-port PORT          Port for web API. (default: 8100)\n  --notifier-port PORT     Port for update notifier, the socket.io\n                           backend. (default: 8110)\n</code></pre>\n<h2>cardano-swagger</h2>\n<pre><code>Cardano SL Wallet web API docs generator.\n\nUsage: cardano-swagger [--version]\n  Generate Swagger specification for Wallet web API.\n\nAvailable options:\n  -h,--help                Show this help text\n  --version                Show version.\n\nThis program runs during 'cardano-sl' building on Travis CI. Generated file\n'wallet-web-api-swagger.json' will be used to produce HTML documentation. This\ndocumentation will be published at cardanodocs.com using\n'update_wallet_web_api_docs.sh'.\n</code></pre>\n<h2>cardano-post-mortem</h2>\n<pre><code>cardano-post-mortem\n\nUsage: cardano-post-mortem COMMAND\n  analyzes the json logs from several directories or focusses on a single\n  transaction\n\nAvailable options:\n  -h,--help                Show this help text\n\nAvailable commands:\n  overview                 analyzes the json logs from LOGDIRS...\n  focus                    analyzes transaction FOCUS in log folder LOGDIR\n  txrelay                  analyzes transaction relays in the json logs from\n                           LOGDIRS...\n  throughput               analyzes transaction throughput and waiting time per\n                           time windows TXWINDOW and WAITWINDOW in the json logs\n                           from LOGDIRS...\n</code></pre>",
  frontmatter:{path:"/en/technical/cardano-sl-cli-options/",doc_title:"Cardano SL CLI Options",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/protocols/2017-01-10-network-transport.md absPath of file >>> MarkdownRemark",excerpt:"Network Transport Layer This guide is for developers who want to build their own client for Cardano SL.\nPlease read  Cardano SL…",html:'<!-- Reviewed at ef835a2334888eda7384da707c4077a8b576b192 -->\n<h1>Network Transport Layer</h1>\n<p>This guide is for developers who want to build their own client for Cardano SL.\nPlease read <a href="/technical/">Cardano SL Implementation Overview</a> for more info.\nThis guide covers the network transport layer used in Cardano SL nodes.</p>\n<p>The transport layer is a layer that sits between TCP and the application level\nprotocol. It is in principle independent of the application protocol (indeed the\nreference implementation is used in multiple different applications with\ndifferent application level protocols).</p>\n<p>The point of the transport layer is that it provides multiple lightweight\nlogical connections multiplexed on a single TCP connection. Each lightweight\nconnection is unidirectional and provides reliable ordered message transport\n(i.e. it provides framing on top of TCP).</p>\n<p>Properties of the transport protocol:</p>\n<ul>\n<li><strong>Single TCP connection</strong>. Only a single TCP connection at a time is used\nbetween any pair of peers. These connections are potentially long-lived.\nOnce a connection with a peer is established, it is used for\nsending/receiving messages until the TCP connection is <em>explicitly</em> closed\nor some unrecoverable error occurs.</li>\n</ul>\n<p>Properties of the implementation:</p>\n<ul>\n<li><strong>Reporting of network failures</strong>. Network failures are not hidden from the\napplication layer. If a TCP connection is dropped unexpectedly, the\ntransport layer should notify the application layer. In Cardano SL, the\npolicy is to try to reconnect and only declare a peer unreachable if\nreconnecting also fails.</li>\n</ul>\n<h2>Overview</h2>\n<p>Typical use of the transport involves:</p>\n<ol>\n<li>Listening for new TCP connections from peers.</li>\n<li>Establishing a TCP connection to other peer(s).</li>\n<li>Creating lightweight connections on an established TCP connection.</li>\n<li>Sending message(s) to peer(s) (on one or more lightweight connections).</li>\n<li>Receiving message(s) from peer(s) (on one or more lightweight connections).</li>\n<li>Closing lightweight connections.</li>\n<li>Closing TCP connections.</li>\n</ol>\n<p>In Cardano SL, multiple lightweight connections are used to support the\napplication level messaging protocol. Multiple application level messages can be\nsent concurrently, and multiple conversations can be in progress at once. Most\napplication messages are sent on a newly created lightweight connection, and, if\nneeded, larger application level message are broken into multiple transport\nlevel messages for transport. Other application level messages are sent as part\nof a conversation which is put together from a pair of unidirectional\nlightweight connections.</p>\n<h2>Terminology</h2>\n<p>Basic transport concepts are:</p>\n<ul>\n<li>Transport</li>\n<li>EndPoint</li>\n<li>Connection</li>\n<li>Event</li>\n<li>Errors</li>\n</ul>\n<p><strong>Transport</strong> refers to the whole layer and protocol described in this document.\nAn instance of the transport refers to the configuration and state of a running\nimplementation of the transport, which in particular includes a TCP listening\nsocket, bound to a particular port on a local network interface, for example\n<code>192.168.0.1:3010</code>.</p>\n<p><strong>EndPoint</strong> refers to a logical endpoint within a transport instance. This\nmeans it has an address and that connections are between endpoints. In practice\nit is just a thin abstraction over the TCP/IP notion of an endpoint, addressed\nvia a hostname and port.</p>\n<p>Endpoint addresses are binary strings with the structure <code>HOST:PORT:LOCAL_ID</code>,\nfor example, <code>192.168.0.1:3010:0</code>.</p>\n<p>Note that while a transport instance listens on a single port, in principle\nthere can be multiple addressable endpoints within a single transport instance,\nand this is what the <code>LOCAL_ID</code> refers to. Cardano SL, however, does not\ncurrently make use of this feature, so it always uses <code>LOCAL_ID</code> 0.</p>\n<p><strong>Heavyweight connection</strong> refers to a TCP connection between two endpoints. Two\nconnected endpoints use one and <em>only one</em> TCP-connection at once.</p>\n<p><strong>Connection</strong> (or more explicitly a <em>lightweight connection</em>) is a\nunidirectional connection between endpoints. All lightweight connections between\nendpoints are multiplexed on a single heavyweight connection (i.e. a single TCP\nconnection).</p>\n<p>The lightweight connections are a logical concept layered on top of TCP. Every\nconnection has an integer ID. It is in principle possible to have thousands of\nlightweight connections multiplexed on a single heavyweight TCP connection.</p>\n<p>The typical style of operation is that the application layer wishes to establish\na lightweight connection to an endpoint, and if no heavyweight connection yet\nexists, then one is created. Similarly, when the last lightweight connection is\nclosed, real TCP connection is shut down cleanly.</p>\n<p>Lightweight connections are unidirectional: messages on a lightweight connection\nflow in one direction only. However, lightweight connections can be established\nin either direction. The same heavyweight connection is used for lightweight\nconnections in either direction between peers; it does not matter which peer\nfirst established the heavyweight connection.</p>\n<p>A bidirectional conversation can be established by making use of a pair of\nunidirectional lightweight connections. Cardano SL follows this pattern. Refer\nto the <code>time-warp-nt</code> documentation for details. But note that this transport\nlayer has no special concept of a bidirectional conversation, there are only\ncollections of unidirectional connections.</p>\n<h2>Network Byte Order</h2>\n<p>In the following descriptions of control messages, all integers are encoded in\n<a href="https://en.wikipedia.org/wiki/Endianness#Networking">network byte order</a>.</p>\n<p>Thus <code>Int32</code> used below in message definitions refers to a 32-bit <em>signed</em>\ninteger value in network byte order.</p>\n<h2>Setting Up a Transport Instance</h2>\n<p>Each transport instance must set up a TCP listening socket. The local interface\nand port number to use are determined by the application using the transport.</p>\n<p>The implementation should be ready to accept new TCP connections at any time\n(perhaps limited by a resource policy), and then perform the initial steps for a\nnew heavyweight connection described below.</p>\n<h2>Establishing Heavyweight Connections (initiating)</h2>\n<p>Assume that a heavyweight connection is to be established between endpoints\nlabelled A and B, with endpoint A initiating the connection. Both endpoints have\nendpoint address, which, as previously described, are of the form\n<code>HOST:PORT:LOCAL_ID</code>.</p>\n<p>Establishing a heavyweight connection from A to B proceeds as follows. First A\nmust record in its local state that it is initializing a heavyweight connection\nto B. This is needed in case of crossed connection requests (see below). A TCP\nconnection is opened by endpoint A to the <code>HOST</code> and <code>PORT</code> of endpoint B.</p>\n<p>Endpoint A sends a <strong>connection request</strong> message with the following structure:</p>\n<pre><code>+-----------+-------------+--------------------+\n|   B-LID   |   A-EIDlen  |       A-EID        |\n+-----------+-------------+--------------------+\n|   Int32   |   Int32     |       bytes        |\n</code></pre>\n<p>Where</p>\n<ul>\n<li><code>B-LID</code> - <code>B</code>\'s endpoint local ID;</li>\n<li><code>A-EIDlen</code> - length of <code>A</code>\'s endpoint address;</li>\n<li><code>A-EID</code> - <code>A</code>\'s endpoint address.</li>\n</ul>\n<p>Thus A sends the local endpoint ID that it wishes to connect to, and its own\naddress to identify the initiating node. The address that A sends should be its\ncanonical public address. The host part may be an IP address or DNS name. It is\nused to avoid establishing multiple TCP connections between endpoints. Within\nthe Cardano SL protocol, the local endpoint ID is always 0.</p>\n<p>Endpoint A then expects a <strong>connection request response</strong> message which is a\nsingle <code>Int32</code> encoding one of the following responses:</p>\n<ul>\n<li><code>ConnectionRequestAccepted</code> (0)</li>\n<li><code>ConnectionRequestInvalid</code> (1)</li>\n<li><code>ConnectionRequestCrossed</code> (2)</li>\n</ul>\n<p>In the typical <code>ConnectionRequestAccepted</code> case, endpoint A must record in its\nlocal state that it now has an established (i.e. no longer initializing)\nheavyweight to B. It may then proceed to the main part of the protocol described\nbelow.</p>\n<p>A <code>ConnectionRequestInvalid</code> response occurs when the endpoint identified by the\nlocal endpoint ID does not exist. For example, it happens if A sends to B that\nit wishes to connect to local endpoint ID 1, when only ID 0 exists. In this case\nboth endpoints must close the TCP connection.</p>\n<p>A <code>ConnectionRequestCrossed</code> response occurs when endpoint B determined that a\nTCP connection already exists between A and B, or connections between A and B,\nand B and A were being established concurrently. In this case both endpoints\nmust close the TCP connection.</p>\n<h2>Establishing Heavyweight Connections (Receiving)</h2>\n<p>Assume, as before, that a heavyweight connection is to be established between\nendpoints labelled A and B, with endpoint A initiating the connection. We now\nconsider this from the point of view of endpoint B.</p>\n<p>Both endpoints have endpoint address of the form <code>HOST:PORT:LOCAL_ID</code>. To be\nconcrete, assume that B has only one endpoint, with <code>LOCAL_ID</code> of 0.</p>\n<p>The transport instance for B has a listening socket open on the host and port\ncorresponding to the endpoint IDs. It accepts a new TCP connection from some\npeer. It now expects to receive on that TCP connection a <strong>connection request</strong>\nmessage (in the format described above).</p>\n<p>Transport instance B must now respond with a <strong>connection request response</strong>\nmessage (in the format described above), based on the following rules.</p>\n<p>If the connection request asks for a local endpoint ID that does not exist (i.e.\nanything other than 0 in our example), it must respond with\n<code>ConnectionRequestInvalid</code> and close the TCP connection.</p>\n<p>The rules for <code>ConnectionRequestCrossed</code> are described below in more detail.</p>\n<p>Otherwise, when the endpoint ID is valid and there is no existing TCP\nconnection, it should reply with <code>ConnectionRequestAccepted</code> and record in its\nlocal state that it now has an established heavyweight with A. It may then\nproceed to the main part of the protocol.</p>\n<h2>Crossed Connection Request</h2>\n<p>As mentioned previously, the protocol tries to ensure that only one TCP\nconnection is used between any two endpoints at once. The typical case is that\nan endpoint can simply determine if it has an existing heavyweight connection to\na peer because it either initiated it or received it and it knows if any\nexisting TCP connection is still open. The hard case arises when two endpoints\ninitiate establishing heavyweight connections to each other <em>at the same time</em>\n(in the usual distributed systems sense of "same time").</p>\n<p>Each endpoint will have recorded in its local state that it is in the process of\ninitiating a heavyweight connection to the other endpoint. Each endpoint will\nsend the connection request message as usual. When each endpoint accepts an\nincoming TCP connection, it checks the peer endpoint ID from the connection\nrequest message.</p>\n<p>The additional rule is that it must lookup in its local state to see if a\nconnection to the peer endpoint was either 1. already <em>being</em> established\noutbound or 2. already fully established. In the first case then we are in the\ncrossed connection situation. The second case can also occur legitimately (i.e.\nnot a protocol violation) when one peer has discovered that the existing TCP\nconnection has failed (i.e. its end is closed) and is trying to establish a new\nTCP connection, while the other peer has not yet discovered that the existing\nTCP connection is dead.</p>\n<h3>Crossed Connection Situation</h3>\n<p>In the crossed connection situation, thus far this is completely symmetric\nbetween endpoints, but we must break the symmetry to resolve which of the two\nTCP connections to use, and which to close. The solution the protocol uses to\nbreak the symmetry is that the endpoint addresses can be ordered\n(lexicographically in their binary string form). Thus the rule each node must\nuse to decide whether to accept or reject the incoming connection request is:\nreply with <code>ConnectionRequestAccepted</code> if the peer\'s endpoint ID is less than\nthe local endpoint id, and otherwise reply with <code>ConnectionRequestCrossed</code> and\nclose the TCP connection.</p>\n<h3>Connection Dead / Re-establish Situation</h3>\n<p>In the second case, where the endpoint handling the incoming TCP connection has\ndetermined that an established connection already exists between the two\nendpoints, the protocol is as follows. A <code>ConnectionRequestCrossed</code> reply is\nsent and the TCP connection is closed. Additionally, the endpoint tries to\nvalidate the liveness of the existing connection, with the purpose of either\nvalidating that it is live or determining that it is not in order to close the\ndead connection (which will then allow opening a new one).</p>\n<p>To validate the liveness, the endpoint sends a <strong>ProbeSocket</strong> message. If a\n<strong>ProbeSocketAck</strong> message is not received within an implementation-defined time\nperiod then the endpoint should close the TCP connection and update its local\nstate accordingly to enable a new connection to be established by either\nendpoint.</p>\n<p>An endpoint that receives a ProbeSocket message should reply with a\nProbeSocketAck.</p>\n<p>The encoding for these messages is simple:</p>\n<pre><code>+-------------+\n| ProbeSocket |\n+-------------+\n|    Int32    |\n\n+----------------+\n| ProbeSocketAck |\n+----------------+\n|     Int32      |\n</code></pre>\n<p>where the value for the control message headers are 4 and 5 respectively.</p>\n<h2>Main Protocol</h2>\n<p>Once a heavyweight connection has been established between two endpoints then\nthe main part of the protocol begins.</p>\n<p>The main protocol between two endpoints consists of sending/receiving a series\nof messages: control messages and data messages. Each has a header to identify\nthe message and a body appropriate to the message type. The messages for the\nmain protocol are control messages to create and close lightweight connections,\nand data messages for sending data on a lightweight connection.</p>\n<p>Lightweight connections are unidirectional. There are independent sets of\nlightweight connections in each direction of the TCP connection. The lightweight\nconnections in each direction are managed by the <em>sending</em> side. The receiving\nside has no direct control over the allocation of lightweight connections.</p>\n<p>Lightweight connections are identified by a Lightweight connection ID, which is\na 32-bit signed integer. Lightweight connection IDs must be greater than 1024.\nLightweight connection ID numbers should be used sequentially.</p>\n<p>The control messages to create or close a lightweight connection simply identify\nthe lightweight connection ID that they act on. Similarly, data messages\nidentify the ID of the lightweight connection that the data is being sent on.</p>\n<p>Messages for different connection ID can be interleaved arbitrarily (enabling\nthe multiplexing of the different lightweight connections). The only constraints\nare the obvious ones: for any connection ID the sequence of messages must be a\ncreate connection message, any number of data messages and finally a close\nconnection message.</p>\n<p>The format of these messages is as follows:</p>\n<pre><code>+-----------+-----------+\n| CreateCon |   LWCId   |\n+-----------+-----------+\n|   Int32   |   Int32   |\n\n+-----------+-----------+\n|  CloseCon |   LWCId   |\n+-----------+-----------+\n|   Int32   |   Int32   |\n\n+-----------+-----------+-------------------+\n|   LWCId   |    Len    |       Data        |\n+-----------+-----------+-------------------+\n|   Int32   |   Int32   |     Len-bytes     |\n</code></pre>\n<p>where:</p>\n<ul>\n<li>CreateCon control header is 0;</li>\n<li>CloseCon control header is 1;</li>\n<li>LWCId is the lightweight connection id, which is >= 1024.</li>\n</ul>\n<p>The header Int32 is aliased between the control message headers and the\nlightweight connection IDs of the data messages, which is why connection ids\nmust be 1024 or greater.</p>\n<p>The data messages consist of the lightweight connection ID and a length-prefixed\nframe of data. Implementations of this protocol may wish to impose a maximum\nsize on these data frames, e.g. to ensure reasonable multiplexing between\nconnections or for resource considerations.</p>\n<p>Note that there need be no direct correspondence between these message\nboundaries and reads/writes on the TCP socket or packets. It may make sense for\nperformance or network efficiency to arrange for a connection open, small data\nmessage and connection close to be sent in a single write.</p>\n<h2>Closing Heavyweight Connections</h2>\n<p>Cleanly closing the heavyweight connection is not trivial. This is because the\nheavyweight connection should only be closed once lightweight connections in\nboth directions are closed. Given that the allocation of lightweight connections\nis controlled independently by each endpoint then some synchronization is\nrequired for both endpoints to agree that there are no more lightweight\nconnections in either direction.</p>\n<p>When one endpoint determines that it has no more outgoing lightweight\nconnections, and the set of incoming connections it knows of is empty, then it\nmay initiate the protocol to close the heavyweight connection. It does so by\nsending a <strong>CloseSocket</strong> message. The message carries the maximum incoming\nlightweight connection ID seen by the endpoint: i.e. the highest connection ID\nthat has been allocated by the remote endpoint that has so far been seen by the\nlocal endpoint. The local endpoint now updates the state it uses to track the\nremote endpoint to note that it is now in the process of closing. If the local\nendpoint now receives a create connection message from the remote endpoint,\nwhile it has the remote endpoint marked as being in the process of closing then\nit resets the state back to the normal connection established state. This\nhappens if the remote endpoint opened a new lightweight connection before it\nreceived the close socket message, and so the attempt to close the socket should\nbe abandoned.</p>\n<p>When an endpoint receives a <strong>CloseSocket</strong> message it checks its local state to\ncheck the number of outbound lightweight connections and the maximum lightweight\nconnection ID it has used for outgoing connections. If there are still outbound\nconnections then the close socket message is ignored. Additionally, if the\nmaximum outbound lightweight connection ID used thus far by the local node is\nhigher than the one received in the close socket message then the close socket\nmessage is ignored. This case can happen even if the number of outbound\nconnections is currently zero, if an outbound connection was created and then\nclosed prior to the close socket message arriving. In both cases what has\nhappened is that the heavyweight connection has become active again while one\nside was trying to close it due to inactivity, and so it is appropriate to\nabandon the attempt to close it.</p>\n<p>If on the other hand there are no outbound connections and the last new\nconnection ID seen by the remote endpoint is the same as that locally, then both\nsides agree and the TCP connection should be closed.</p>\n<p>The message structure is:</p>\n<pre><code>+-------------+-----------+\n| CloseSocket |   LWCId   |\n+-------------+-----------|\n|    Int32    |   Int32   |\n</code></pre>\n<p>where:</p>\n<ul>\n<li><code>CloseSocket</code> - close connection control message, value <code>2</code>;</li>\n<li><code>LWCId</code> - maximum lightweight connection ID used thus far.</li>\n</ul>\n<h2>Flow Control and Back-pressure</h2>\n<p>Lightweight connections do not provide any flow control over and above what is\nprovided by TCP. The protocol does not provide any facility to reject incoming\nlightweight connections. Any such facility must be layered on top, in the\napplication layer or another intermediate layer.</p>\n<p>Implementations should consider the problem of back-pressure and head of line\nblocking. Head of line blocking is a problem common to many protocols layered on\ntop of TCP, such as HTTP 1.x where one large response can "block" other smaller\nresponses for other URLs because the responses are sent in order. This problem\nis less severe in this transport protocol because connection are multiplexed, so\nsmall messages need not be blocked by large messages. Nevertheless, it is still\nthe case that the multiplexed stream of data for all connections must be\nreceived in order: it is not possible to push back on one lightweight connection\nvs another, only on the whole heavyweight connection.</p>',frontmatter:{path:"/en/technical/protocols/network-transport/",doc_title:"Network Transport Layer",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical-protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/technical/protocols/2017-01-13-binary.cn.md absPath of file >>> MarkdownRemark",excerpt:"二进制协议 重要提示：二进制协议即将更改。 所有字段的大小均以字节表示。总是使用大端序。符合类型按定义顺序进行序列化，不带分隔符。 例如， (Word32, Word8)  序列化为5个字节：4个  Word32 ，1个  Word8 。 对于依赖于类型 T…",html:'<!-- Reviewed at 721474b760466b888cf26545b52b35989b2162de -->\n<!-- Delegation : Updated at 15b8b777fde5a8ab4a85af71affeffdf31ad219c -->\n<h1>二进制协议</h1>\n<p><span style="color: red;"><strong>重要提示：二进制协议即将更改。</strong></span></p>\n<p>所有字段的大小均以字节表示。总是使用大端序。符合类型按定义顺序进行序列化，不带分隔符。</p>\n<p>例如，<code>(Word32, Word8)</code> 序列化为5个字节：4个 <code>Word32</code>，1个 <code>Word8</code>。</p>\n<p>对于依赖于类型 T 的对象的变长结构，我们使用 <code>size(T)</code> 符号。</p>\n<p><code>Word32</code> 是32位无符号整数(<code>uint32</code>)。</p>\n<p>为测试 <code>ghci</code> 中 <code>myObject</code> 对象的序列，应该在卡尔达诺结算层根目录中使用以下命令：</p>\n<pre><code>$ stack repl\n...\n&#x3C;Press Enter>\n...\nghci> import Data.ByteString.Builder\nghci> let hexEncode myObject = toLazyByteString $ lazyByteStringHex $ Pos.Binary.encode $ myObject\nghci> hexEncode (mkCoin 1000)\n"0064"\n</code></pre>\n<h2>常见的 HASKELL 数据类型</h2>\n<h3>Maybe</h3>\n<pre><code class="language-haskell">data Maybe a = Nothing | Just a\n</code></pre>\n<p><code>Maybe a</code> 是 <code>a</code> 类型或空类型（又名 <code>null</code>, <code>None</code>）。为了区分这两个值，我们在数据之前加了1个字节的标签。</p>\n<table>\n<thead>\n<tr>\n<th>标签大小</th>\n<th>标签类型</th>\n<th>标签值</th>\n<th>描述</th>\n<th>字段大小</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for Nothing</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for Just</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(a)</td>\n<td>Value of type \n<code>a</code></td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> hexEncode (Nothing :: Maybe Word32)\n"00"\nghci> hexEncode (Just 4  :: Maybe Word32)\n"0100000004"\n</code></pre>\n<h3>Either</h3>\n<pre><code class="language-haskell">data Either a b = Left a | Right b\n</code></pre>\n<p><code>Either a b</code> 表示类型 <code>a</code> 或 类型 <code>b</code>。为了区分这两个值，我们在数据之前添加了1个字节的标签。</p>\n<table>\n<thead>\n<tr>\n<th>标签大小</th>\n<th>标签类型</th>\n<th>标签值</th>\n<th>描述</th>\n<th>字段大小</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for Left</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(a)</td>\n<td>Value of type \n<code>a</code></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for Right</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(b)</td>\n<td>Value of type \n<code>b</code></td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> hexEncode (Left 3  :: Either Word16 Word32)\n"000003"\nghci> hexEncode (Right 4 :: Either Word16 Word32)\n"0100000004"\n</code></pre>\n<h3>大整数</h3>\n<pre><code class="language-haskell">-- Fixed-size type for a subset of Integer\ntype SmallInt = Int32\n</code></pre>\n<p>整数的编码有两种：如果它们适合 <code>SmallInt</code>，则它们被写为一个字节标记，并写入该值。如果该整数太大不能放入 SmallInt 中，将其与符号，长度字段写入字节数组。</p>\n<p>有关参考，请参考<a href="http://hackage.haskell.org/package/binary-0.8.4.1/docs/src/Data.Binary.Class.html#line-306">实现</a>。</p>\n<p>例子：</p>\n<pre><code>ghci> hexEncode $ (15 :: Integer)\n"000000000f"\nghci> hexEncode $ (  (2 :: Integer) ^ (128 :: Integer))\n"010100000000000000110000000000000000000000000000000001"\nghci> hexEncode $ (- (2 :: Integer) ^ (128 :: Integer))\n"01ff00000000000000110000000000000000000000000000000001"\n</code></pre>\n<h3>无符号变量长度整数</h3>\n<p>这种类型稍后将引用为 <code>UVarInt Word16</code> 或 <code>UVarInt Word64</code> 来描述最大可用值。</p>\n<pre><code class="language-haskell">newtype UnsignedVarInt a = UnsignedVarInt {getUnsignedVarInt :: a}\n    deriving (Eq, Ord, Show, Generic, NFData, Functor)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/core/Pos/Binary/Class.hs#L277">源代码链接</a>。</p>\n<p>值一次编码为7位，最重要的是是个连续位。因此，从0到127的数字只需要一个字节来编码，从128到16383的数字需要两个字节等等。</p>\n<p>这种<a href="https://developers.google.com/protocol-buffers/docs/encoding#varints">格式</a>取自 Google 的 Protocol Buffers，但它提供了更多的编码语言（TODO）</p>\n<p>例子:</p>\n<pre><code>ghci> hexEncode (UnsignedVarInt (3 :: Word32))\n"03"\nghci> hexEncode (UnsignedVarInt (126 :: Word32))\n"7e"\nghci> hexEncode (UnsignedVarInt (127 :: Word32))\n"7f"\nghci> hexEncode (UnsignedVarInt (128 :: Word32))\n"8001"\n</code></pre>\n<h3>微小的可变长度整数</h3>\n<pre><code class="language-haskell">-- | A newtype wrapper for non-negative integers less than @2^14@. Use it if\n-- you want to be extra careful. Compared to \'SignedVarInt\' and\n-- \'UnsignedVarInt\', it provides two benefits:\n--\n-- * It is guaranteed to take either 1 or 2 bytes (the standard decoder for\n--   variants can consume an unlimited amount of bytes).\n--\n-- * It is unambiguous (e.g. @0@ can be encoded in only one way instead of\n--   two).\nnewtype TinyVarInt = TinyVarInt {getTinyVarInt :: Word16}\n    deriving (Eq, Ord, Show, Generic, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/core/Pos/Binary/Class.hs#L295">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-2</td>\n<td>UVarInt Word16</td>\n<td>Variable length integer up to 2^14 - 1</td>\n</tr>\n</tbody>\n</table>\n<p>例子:</p>\n<pre><code>ghci> hexEncode $ TinyVarInt 0\n"00"\nghci> hexEncode $ TinyVarInt (2^14 -1)\n"ff7f"\n</code></pre>\n<p>在 <code>cardano</code> 中的 <code>ByteString</code> 被编码为以其长度开头的字节序列，其中长度被编码为可变长度整数。如果长度被编码为 <code>TinyVarInt</code>，那么这样的 <code>ByteString</code> 被表示为 <code>TinyBS</code>。</p>\n<h3>列表，非空值和向量空间</h3>\n<p>有时候我们在数据类型中存储一些对象的列表。你会看到他们被引用为 <code>Vector a</code>，<code>[a]</code>。您可以将其读作<em>类型对象的数组 <code>a</code></em>。这两种标准的 Haskell 数据类型都以相同的方式序列化。如果您看到 <code>NonEmpty a</code> 的类型的，您应该将它视作 <code>[a]</code>，但该列表的大小至少为 <code>1</code>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Size of array</td>\n</tr>\n<tr>\n<td>n \n*\n size(a)</td>\n<td>a\n[\nn\n]</td>\n<td></td>\n<td>Array with length \n<code>n</code>\n of objects of type \n<code>a</code></td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> hexEncode ([1, 31] :: [Word16])\n"020001001f"\nghci> hexEncode ([0..135] :: [Word8])  -- 136 bytes from 0 to 135 including\n"8801000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252\n62728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4\nf505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576777\n8797a7b7c7d7e7f8081828384858687"\n</code></pre>\n<h3>HashMap</h3>\n<p><code>HashMap key value</code> 是键到值的映射。在序列化中，HashMap 被表示为 <code>key</code> 与 <code>value</code> 对的列表，并且被序列化为 <code>[(key, value)]</code>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Size of HashMap</td>\n</tr>\n<tr>\n<td>n * (size(key) + size(value))</td>\n<td>&#x3C;key, value>\n[\nn\n]</td>\n<td></td>\n<td>Array with length \n<code>n</code>\n of objects of type \n<code>(key, value)</code></td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> hexEncode $ Data.HashMap.Strict.fromList [(1 :: Word8, 127 :: Word64), (2, 255)]\n"0201000000000000007f0200000000000000ff"\n</code></pre>\n<h2>网络</h2>\n<h3>MessageName</h3>\n<pre><code class="language-haskell">newtype MessageName = MessageName BS.ByteString\n</code></pre>\n<p><a href="https://github.com/serokell/time-warp-nt/blob/f5500cb587eb2fbb02954b8d945985dbd0d51c0d/src/Node/Message.hs#L44">源代码链接</a>。</p>\n<p>一般来说，我们用一个或两个编码的 <code>UnsignedVarInt</code> 来表示 <code>MessageName</code>。在序列化状态下，它被编码为二进制字符串，因此以字符串的长度为前缀。</p>\n<p>例子:</p>\n<pre><code>ghci> hexEncode $ messageName (Proxy :: Proxy SendProxySK)\n"0102"\nghci> hexEncode $ messageName (Proxy :: Proxy (DataMsg GtMsgContents))\n"020a03"\n</code></pre>\n<h2>卡尔达诺结算层基本数据类型</h2>\n<h3>币</h3>\n<pre><code class="language-haskell">-- | Coin is the least possible unit of currency.\nnewtype Coin = Coin\n    { getCoin :: Word64\n    } deriving (Show, Ord, Eq, Generic, Hashable, Data, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L391">源代码链接</a>。</p>\n<p>硬币总数量是 <a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L404">45 * 10^9 *\n10^6</a>。</p>\n<pre><code>45*10^15 needs 56 bits to represent\n45*10^9  (integral mega coins) needs 36 bits to represent\n999999   (floating mega coins) needs 20 bits to represent\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>Decimal</th>\n<th>Needed Bits</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0-9</td>\n<td>4 bits</td>\n</tr>\n<tr>\n<td>0-99</td>\n<td>7 bits</td>\n</tr>\n<tr>\n<td>0-999</td>\n<td>10 bits</td>\n</tr>\n<tr>\n<td>0-9999</td>\n<td>14 bits</td>\n</tr>\n<tr>\n<td>0-99999</td>\n<td>17 bits</td>\n</tr>\n<tr>\n<td>0-999999</td>\n<td>20 bits</td>\n</tr>\n</tbody>\n</table>\n<p>币被分成百万份，剩余的币用于序列化。</p>\n<pre><code>1000999 coin = 1.000999 mega coin\n</code></pre>\n<p>简单的变量以 <code>Word64</code> 限制。序列的总长度在第一个字节中用可变掩码进行编码。</p>\n<table>\n<thead>\n<tr>\n<th>header</th>\n<th>mask</th>\n<th>spare bits</th>\n<th>extra byte</th>\n<th>total bits as value</th>\n<th>serialized size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0 xxxxxxx</td>\n<td>0x7f</td>\n<td>7 bits</td>\n<td>0</td>\n<td>7 bits</td>\n<td>1 byte</td>\n</tr>\n<tr>\n<td>10 xxxxxx</td>\n<td>0x3f</td>\n<td>6 bits</td>\n<td>1</td>\n<td>14 bits</td>\n<td>2 bytes</td>\n</tr>\n<tr>\n<td>110 xxxxx</td>\n<td>0x1f</td>\n<td>5 bits</td>\n<td>2</td>\n<td>21 bits</td>\n<td>3 bytes</td>\n</tr>\n<tr>\n<td>1110 xxxx</td>\n<td>0x0f</td>\n<td>4 bits</td>\n<td>3</td>\n<td>27 bits</td>\n<td>4 bytes</td>\n</tr>\n<tr>\n<td>11110 xxx</td>\n<td>0x07</td>\n<td>3 bits</td>\n<td>4</td>\n<td>35 bits</td>\n<td>5 bytes</td>\n</tr>\n<tr>\n<td>111110 xx</td>\n<td>0x03</td>\n<td>2 bits</td>\n<td>5</td>\n<td>42 bits</td>\n<td>6 bytes</td>\n</tr>\n<tr>\n<td>1111110 x</td>\n<td>0x01</td>\n<td>1 bit</td>\n<td>6</td>\n<td>49 bits</td>\n<td>7 bytes</td>\n</tr>\n<tr>\n<td>11111110</td>\n<td>0x00</td>\n<td>0 bit</td>\n<td>7</td>\n<td>56 bits</td>\n<td>8 bytes</td>\n</tr>\n<tr>\n<td>11111111</td>\n<td>0x00</td>\n<td>0 bit</td>\n<td>8</td>\n<td>64 bits</td>\n<td>9 bytes</td>\n</tr>\n</tbody>\n</table>\n<p>专门用于最多只需要36位的组成部分。</p>\n<table>\n<thead>\n<tr>\n<th>header</th>\n<th>mask</th>\n<th>spare bits</th>\n<th>extra byte</th>\n<th>total bits as value</th>\n<th>serialized size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0 xxxxxxx</td>\n<td>0x7f</td>\n<td>7 bits</td>\n<td>0</td>\n<td>7 bits</td>\n<td>1 byte</td>\n</tr>\n<tr>\n<td>10 xxxxxx</td>\n<td>0x3f</td>\n<td>6 bits</td>\n<td>1</td>\n<td>14 bits</td>\n<td>2 bytes</td>\n</tr>\n<tr>\n<td>110 xxxxx</td>\n<td>0x1f</td>\n<td>5 bits</td>\n<td>2</td>\n<td>21 bits</td>\n<td>3 bytes</td>\n</tr>\n<tr>\n<td>1110 xxxx</td>\n<td>0x0f</td>\n<td>4 bits</td>\n<td>3</td>\n<td>27 bits</td>\n<td>4 bytes</td>\n</tr>\n<tr>\n<td>1111 xxxx</td>\n<td>0x0f</td>\n<td>4 bits</td>\n<td>4</td>\n<td>36 bits</td>\n<td>5 bytes</td>\n</tr>\n</tbody>\n</table>\n<p>而浮动部分则需要20位来表示，编码值从0到999999：</p>\n<table>\n<thead>\n<tr>\n<th>header</th>\n<th>mask</th>\n<th>spare bits</th>\n<th>extra byte</th>\n<th>total bits as value</th>\n<th>serialized size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0 xxxxxx</td>\n<td>0x7f</td>\n<td>7 bits</td>\n<td>0</td>\n<td>7 bits</td>\n<td>1 byte</td>\n</tr>\n<tr>\n<td>10 xxxxxx</td>\n<td>0x3f</td>\n<td>6 bits</td>\n<td>1</td>\n<td>14 bits</td>\n<td>2 bytes</td>\n</tr>\n<tr>\n<td>110 xxxxx</td>\n<td>0x3f</td>\n<td>5 bits</td>\n<td>2</td>\n<td>21 bits</td>\n<td>3 bytes</td>\n</tr>\n</tbody>\n</table>\n<p>注意：考虑的编码的结束，我们可以在3字节方案中保存一位，但我们不需要，不需要改变方案，我们可以重新使用以前的方案。</p>\n<p>有关实现的细节请看<a href="https://github.com/input-output-hk/cardano-sl/blob/1239a6a876fbbb970e836c8bc6bb72d781ba2fa9/core/Pos/Binary/Core/Coin.hs">这个模块</a>。</p>\n<p>例子:</p>\n<pre><code>ghci> hexEncode (mkCoin 0)\n"0000"\nghci> hexEncode (mkCoin 1)\n"00c186a0"\nghci> hexEncode (mkCoin 2)\n"00c30d40"\nghci> hexEncode (mkCoin 31)\n"00c1fbd0"\nghci> hexEncode (mkCoin 128)\n"00cc8708"\nghci> hexEncode (mkCoin 129)\n"00ce0da8"\nghci> hexEncode (mkCoin 1000)\n"0064"\nghci> hexEncode (mkCoin 10000)\n"000a"\nghci> hexEncode (mkCoin 1000000)\n"0100"\nghci> hexEncode (mkCoin 1000999)\n"01cf3e58"\n</code></pre>\n<h3>Hash</h3>\n<pre><code class="language-haskell">-- | Hash wrapper with phantom type for more type-safety.\n-- Made abstract in order to support different algorithms in\n-- different situations\nnewtype AbstractHash algo a = AbstractHash (Digest algo)\n    deriving (Show, Eq, Ord, ByteArray.ByteArrayAccess, Generic, NFData)\n\n-- | Type alias for commonly used hash\ntype Hash = AbstractHash Blake2b_256\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/652411b9b8777f08e948ee144a60779c55f363b3/core/Pos/Crypto/Hashing.hs#L118">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td>Word8\n[\n32\n]</td>\n<td>256 bits of hash digest</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：32。</p>\n<p>所以每当你看到 <code>Hash SomeType</code> 代码，这个字段将占用32个字节。<code>Hash</code> 只在类型安全的代码中使用附加的类型参数，并且对序列化没有影响。</p>\n<p>例子:</p>\n<pre><code>ghci> hash $ mkCoin 3\nAbstractHash 29bcdcff253cd2864a8b5e25992a6db86a7a41dc5e69c0599730f2c5716d9362\nghci> hexEncode $ hash $ mkCoin 3\n"29bcdcff253cd2864a8b5e25992a6db86a7a41dc5e69c0599730f2c5716d9362"\n</code></pre>\n<h3>公钥</h3>\n<pre><code class="language-haskell">-- | Wrapper around \'CC.XPub\'.\nnewtype PublicKey = PublicKey CC.XPub\n    deriving (Eq, Ord, Show, Generic, NFData, Hashable, Typeable)\n\ndata XPub = XPub !Edwards25519.PointCompressed !ChainCode\n    deriving (Eq, Ord, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L70">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td>ByteString</td>\n<td>32-byte PointCompressed</td>\n</tr>\n<tr>\n<td>32</td>\n<td>ByteString</td>\n<td>32-byte ChainCode</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：64。</p>\n<h3>签名</h3>\n<pre><code class="language-haskell">-- | Wrapper around \'CC.XSignature\'.\nnewtype Signature a = Signature CC.XSignature\n    deriving (Eq, Ord, Show, Generic, NFData, Hashable, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L149">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>64</td>\n<td>Word8\n[\n64\n]</td>\n<td>64 bytes of signature string</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：64。</p>\n<h3>Epoch 索引</h3>\n<pre><code class="language-haskell">-- | Index of epoch.\nnewtype EpochIndex = EpochIndex\n    { getEpochIndex :: Word64\n    } deriving (Show, Eq, Ord, Num, Enum, Ix, Integral, Real, Generic, Hashable, Bounded, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L342">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>epoch index</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：10。</p>\n<p>例子:</p>\n<pre><code>ghci> hexEncode (EpochIndex 128)\n"8001"\n</code></pre>\n<h3>本地 Slot 索引</h3>\n<pre><code class="language-haskell">-- | Index of slot inside a concrete epoch.\nnewtype LocalSlotIndex = LocalSlotIndex\n    { getSlotIndex :: Word16\n    } deriving (Show, Eq, Ord, Ix, Generic, Hashable, Buildable, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L353">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-3</td>\n<td>UVarInt Word16</td>\n<td>index of local slot</td>\n</tr>\n</tbody>\n</table>\n<p>例子:</p>\n<pre><code>ghci> hexEncode (LocalSlotIndex 15)\n"0f"\n</code></pre>\n<h3>SlotId</h3>\n<pre><code class="language-haskell">-- | Slot is identified by index of epoch and local index of slot in\n-- this epoch. This is a global index\ndata SlotId = SlotId\n    { siEpoch :: !EpochIndex\n    , siSlot  :: !LocalSlotIndex\n    } deriving (Show, Eq, Ord, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L377">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>Epoch index</td>\n</tr>\n<tr>\n<td>1-3</td>\n<td>UVarInt Word16</td>\n<td>Slot index inside a concrete epoch</td>\n</tr>\n</tbody>\n</table>\n<p>例子:</p>\n<pre><code>ghci> hexEncode (SlotId 128 15)\n"80010f"\n</code></pre>\n<h3>Attributes</h3>\n<pre><code class="language-haskell">-- | Convenient wrapper for the datatype to represent it (in binary\n-- format) as k-v map.\ndata Attributes h = Attributes\n    { -- | Data, containing known keys (deserialized)\n      attrData   :: h\n      -- | Remaining, unparsed fields\n    , attrRemain :: UnparsedFields\n    }\n  deriving (Eq, Ord, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Data/Attributes.hs#L60">源代码链接</a>。</p>\n<pre><code class="language-haskell">-- | Representation of unparsed fields in Attributes. Newtype wrapper is used\n-- for clear backward compatibility between previous representation (which was\n-- just a single ByteString) during transition from Store to CBOR.\nnewtype UnparsedFields = UnparsedFields (Map Word8 ByteString)\n    deriving (Eq, Ord, Show, Generic, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Data/Attributes.hs#L34">源代码链接</a>。</p>\n<p>消息大小限制：每个 <code>Attributes</code> 类型定义它们自己的限制。</p>\n<h4>一般情况序列化</h4>\n<p>存储为 <code>totalLen + (k, v) pairs + 一些剩余的部分</code>。<code>attrData</code> 存储为 <code>(Word8, v)</code> 对列表，其中 <code>key</code> 有 <code>Word8</code> 类型，你应该指定如何以这种方式编码 <code>h</code>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int64</td>\n<td>m + n</td>\n<td>Size of attributes in bytes</td>\n</tr>\n<tr>\n<td>m = t \n*\n (1 + size(v))</td>\n<td>&#x3C;Word8,v>\n[\nt\n]</td>\n<td></td>\n<td>Array of pairs. Given without length.</td>\n</tr>\n<tr>\n<td>n</td>\n<td>ByteString</td>\n<td></td>\n<td>Remaining byte array</td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> toLazyByteString\n      $ lazyByteStringHex\n      $ runPut\n      $ putAttributes (\\h -> [(1, put h), (0, put h)])\n      $ Attributes (9 :: Word32) "abc"\n"0d0000000009010000000961626"\n</code></pre>\n<p>其中 <code>h = 9 :: Word32</code>，我们将 <code>h</code> 编码为两个键值对：值为4字节<code>9</code>，键是<code>0</code>和<code>1</code>。</p>\n<h4>Attributes ()</h4>\n<p>在这种特殊情况下，没有 <code>(key, value)</code> 存储 - 只能是任意长度的字节数组。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-4</td>\n<td>UVarInt Int64</td>\n<td>n</td>\n<td>Size of attributes in bytes. Should be \n&#x3C;\n 2^28</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td><code>n</code>\n bytes of data</td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> hexEncode $ Attributes () (BSS.pack [])\n"00"\nghci> hexEncode $ Attributes () (BSS.pack [1,31])\n"02011f"\nghci> hexEncode $ Attributes () "abc"\n"03616263"\n</code></pre>\n<h3>脚本</h3>\n<pre><code class="language-haskell">-- | Version of script\ntype ScriptVersion = Word16\n\n-- | A script for inclusion into a transaction.\ndata Script = Script {\n    scrVersion :: ScriptVersion,    -- ^ Version\n    scrScript  :: LByteString}      -- ^ Serialized script\n  deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L424">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-3</td>\n<td>UVarInt Word16</td>\n<td></td>\n<td>Script version</td>\n</tr>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int64</td>\n<td>n</td>\n<td>Size of byte array</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td>n bytes of script</td>\n</tr>\n</tbody>\n</table>\n<p>例子:</p>\n<pre><code>ghci> hexEncode $ Script 0 "a"\n"000161"\n</code></pre>\n<h3>地址属性</h3>\n<pre><code class="language-haskell">-- | Additional information stored along with address. It\'s intended\n-- to be put into \'Attributes\' data type to make it extensible with\n-- softfork.\ndata AddrAttributes = AddrAttributes\n    { aaPkDerivationPath  :: !(Maybe HDAddressPayload)\n    , aaStakeDistribution :: !AddrStakeDistribution\n    } deriving (Eq, Ord, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L199">源代码链接</a>。</p>\n<p>地址属性包含关于地址的附加信息：</p>\n<ul>\n<li>HD钱包树根（<code>aaPkDerivationPath</code>）的加密导出路径。</li>\n<li>与此地址相关的股权分配（<code>aaStakeDistribution</code>）</li>\n</ul>\n<p>请注意，地址可能不包含加密派生路径。包含在属性中的不包含派生路径的地址通常从级别 0（钱包）公共密钥导出，并用做钱包的 ID。这样的地址并不意味着要包含任何资金。</p>\n<h4>地址有效载荷</h4>\n<pre><code class="language-haskell">data HDAddressPayload = HDAddressPayload !ByteString\n    deriving (Eq, Ord, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Crypto/HD.hs#L50">源代码链接</a>。</p>\n<p><code>HDAddressPayload</code> 数据类型表示派生路径(<code>[Word32]</code>)，通过 <code>ChaChaPoly1305</code> 算法对称算法加密。加密密钥可以是 <code>ByteString</code> 32个字节中的任何一个，只有该地址的所有者才知道。</p>\n<p>在目前的 Cardano 实现中，加密密钥是使用 PBKDF2 派生算法和 HMAC-SHA512 伪随机算法，进行500次迭代，将 <code>address-hashing</code> 字符串作为盐，从钱包的根公钥获得的32字节密钥。<a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Crypto/HD.hs#L58">源代码链接</a>。</p>\n<p>地址属性使用加密标签进行加密，从而可以检查属性是否被成功解密。因此，通过使用从钱包的根公共密钥导出的加密密钥来解密该地址的属性，可以确定给定的地址是否属于给定的钱包。这是实现属性解密和加密的<a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Crypto/HD.hs#L113">源代码链接</a>。</p>\n<h4>地址分配</h4>\n<pre><code class="language-haskell">-- | Stake distribution associated with an address.\ndata AddrStakeDistribution\n    = BootstrapEraDistr\n    -- ^ Stake distribution for bootstrap era.\n    | SingleKeyDistr !StakeholderId\n    -- ^ Stake distribution stating that all stake should go to the given stakeholder.\n    | UnsafeMultiKeyDistr !(Map StakeholderId CoinPortion)\n    -- ^ Stake distribution which gives stake to multiple\n    -- stakeholders. \'CoinPortion\' is a portion of an output (output\n    -- has a value, portion of this value is stake). The constructor\n    -- is unsafe because there are some predicates which must hold:\n    --\n    -- • the sum of portions must be @maxBound@ (basically 1);\n    -- • all portions must be positive;\n    -- • there must be at least 2 items, because if there is only one item,\n    -- \'SingleKeyDistr\' can be used instead (which is smaller).\n    deriving (Eq, Ord, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L137">源代码链接</a>。</p>\n<p>在 Byron 时代，所有的地址应该以 <code>BootstrapEraDistr</code> 作为股权分配 - 这意味着所有的股权都被自动委派给引导权益所有人。</p>\n<p>在 Shelley 时代，地址使用 <code>SingleKeyDistr</code> 或 <code>UnsafeMultiKeyDistr</code> 将股权委派给代表他们的权益所有人 ID。</p>\n<!-- | Size | Type                      | Value | Description                                             | -->\n<!-- |------|---------------------------|-------|---------------------------------------------------------| -->\n<!-- | 1-2  | TinyVarInt                | n + m | sise of `PubKeyAddress` content                         | -->\n<!-- | n    | Maybe (Word8, \\[Word32\\]) |       | Empty for nothing and list of Word32 preceded with zero | -->\n<!-- | m    | ByteString                |       | Remaining bytes                                         | -->\n<!-- See examples in the next section. -->\n<h3>地址</h3>\n<pre><code class="language-haskell">-- | Hash used to identify address.\ntype AddressHash = AbstractHash Blake2b_224\n\n-- | Stakeholder identifier (stakeholders are identified by their public keys)\ntype StakeholderId = AddressHash PublicKey\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L123">源代码链接</a>。</p>\n<p>卡尔达诺地址使用 <code>blake2b-224</code> 作为地址结构的散列。</p>\n<pre><code class="language-haskell">-- | Data which is bound to an address and must be revealed in order\n-- to spend coins belonging to this address.\ndata AddrSpendingData\n    = PubKeyASD !PublicKey\n    -- ^ Funds can be spent by revealing a \'PublicKey\' and providing a\n    -- valid signature.\n    | ScriptASD !Script\n    -- ^ Funds can be spent by revealing a \'Script\' and providing a\n    -- redeemer \'Script\'.\n    | RedeemASD !RedeemPublicKey\n    -- ^ Funds can be spent by revealing a \'RedeemScript\' and providing a\n    -- valid signature.\n    | UnknownASD !Word8 !ByteString\n    -- ^ Unknown type of spending data. It consists of a tag and\n    -- arbitrary \'ByteString\'. It allows us to introduce a new type of\n    -- spending data via softfork.\n    deriving (Eq, Generic, Typeable, Show)\n\n-- | Type of an address. It corresponds to constructors of\n-- \'AddrSpendingData\'. It\'s separated, because \'Address\' doesn\'t store\n-- \'AddrSpendingData\', but we want to know its type.\ndata AddrType\n    = ATPubKey\n    | ATScript\n    | ATRedeem\n    | ATUnknown !Word8\n    deriving (Eq, Ord, Generic, Typeable, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L137">源代码链接</a> </p>\n<p>卡尔达诺支持不同的地址类型。地址类型根据资金的可用性不同而有所不同。每个地址类型都有相应的支出数据类型。消费数据是为了生成地址的散列数据的一部分。要从地址中花费资金，应该为消费数据，同验证数据（例如签名）提供 <code>TxInWitness</code>。</p>\n<p>目前 Cardano 提供3种地址类型：</p>\n<ul>\n<li>公钥地址（<code>ATPublicKey</code>）：扩展了 Ed25519 公钥作为支出数据，对应的 Ed25519 签名作为验证数据。</li>\n<li>脚本地址（<code>ATScript</code>）：作为支出数据的 Plutus 验证脚本，Plutus 赎回脚本作为验证数据</li>\n<li>兑现地址（<code>ATRedeem</code>）：Ed25519 公钥作为支出数据，Ed25519 签名作为验证数据。仅用于为持有人预售 ADA。</li>\n</ul>\n<p>还有为向前兼容而添加的特殊地址类型 <code>ATUnknown</code>。</p>\n<pre><code class="language-haskell">-- | Hash of this data is stored in \'Address\'. This type exists mostly\n-- for internal usage.\nnewtype Address\' = Address\'\n    { unAddress\' :: (AddrType, AddrSpendingData, Attributes AddrAttributes)\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L206">源代码链接</a>。</p>\n<p>内部类型 <code>Address</code> 表示一个一个元组，作为 <code>Address</code> 的部分哈希存储。不仅 <code>AddrSpendingData</code> 会被哈希，<code>AddrType</code> 和 <code>AddrAttributes</code> 也会被哈希。</p>\n<pre><code class="language-haskell">-- | \'Address\' is where you can send coins.\ndata Address = Address\n    { addrRoot       :: !(AddressHash Address\')\n    -- ^ Root of imaginary pseudo Merkle tree stored in this address.\n    , addrAttributes :: !(Attributes AddrAttributes)\n    -- ^ Attributes associated with this address.\n    , addrType       :: !AddrType\n    -- ^ The type of this address. Should correspond to\n    -- \'AddrSpendingData\', but it can\'t be checked statically, because\n    -- spending data is hashed.\n    } deriving (Eq, Ord, Generic, Typeable, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L211">源代码链接</a>。</p>\n<p>一个 <code>Address</code> 数据类型由 <code>Address</code> 元组，类型标签，属性组成。</p>\n<h4>公钥地址</h4>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L107"><code>addrPkAttributes</code></a> 是 HD 钱包必须的字段。</p>\n<table>\n<thead>\n<tr>\n<th>大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td><code>PubKeyAddress</code>\n tag</td>\n</tr>\n<tr>\n<td>1-2</td>\n<td>TinyVarInt</td>\n<td>28 + m</td>\n<td>Size of \n<code>PubKeyAddress</code>\n content</td>\n</tr>\n<tr>\n<td>28</td>\n<td>Word8\n[\n28\n]</td>\n<td></td>\n<td><code>addKeyHash</code>\n: 28 bytes of Blake2b\n_\n224 hash</td>\n</tr>\n<tr>\n<td>m</td>\n<td>PubKeyAddressAttributes</td>\n<td></td>\n<td><code>addrPkAttributes</code></td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td></td>\n<td>CRC32 of all previous data</td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> abstractHash somPk :: AddressHash PublicKey\nAbstractHash 380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e0\nghci> hexEncode $ PubKeyAddress (abstractHash somePk) (Attributes (AddrPkAttrs Nothing) "a")\n"001e380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00161cf52c5ec"\nghci> hexEncode $ PubKeyAddress (abstractHash somePk) (Attributes (AddrPkAttrs $ Just [3,9]) "a")\n"0028380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00b0002000000030000000961f1d810f7"\n</code></pre>\n<p>你可以注意到第一个例子，<code>0xCF52C5EC</code> 是 <code>001e380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00161</code> 的 CRC32。</p>\n<h4>脚本地址</h4>\n<table>\n<thead>\n<tr>\n<th>大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x01</td>\n<td><code>ScriptAddress</code>\n tag</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x1C</td>\n<td>Size of \n<code>addrScriptHash</code>\n: always 28</td>\n</tr>\n<tr>\n<td>28</td>\n<td>Word8\n[\n28\n]</td>\n<td></td>\n<td>28 bytes of Blake2b\n_\n224 hash</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td></td>\n<td>CRC32 of all previous data</td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> hexEncode $ ScriptAddress (abstractHash $ Script 0 "a")\n"011c7ec20301993e369571c6225e1e563812198433801820a2d7328756dc61c5be8e"\n</code></pre>\n<p>您可以注意到，4字节的 <code>0x61c5be8e</code> 前缀是 <code>011c7ec20301993e369571c6225e1e563812198433801820a2d7328756dc</code> 的 CRC32 的前缀。</p>\n<h4>未知地址</h4>\n<table>\n<thead>\n<tr>\n<th>大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td></td>\n<td>t</td>\n<td><code>UnknownAddress</code>\n tag</td>\n</tr>\n<tr>\n<td>1-2</td>\n<td>TinyVarInt</td>\n<td>n</td>\n<td>Size of unknown address</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td>Unknown address itself</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td></td>\n<td>CRC32 of all previous data</td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<p>让我们对 <code>UnknownAddressType 3 "a"</code> 编码。没有 CRC32，它会被编码为 <code>0x030161</code>，<code>0x030161</code> 的 CRC32 是 <code>0xDEA907C4</code>。因此我们有：</p>\n<pre><code>ghci> hexEncode $ UnknownAddressType 3 "a"\n"030161dea907c4"\n</code></pre>\n<h3>MerkleRoot</h3>\n<pre><code class="language-haskell">-- | Data type for root of merkle tree.\nnewtype MerkleRoot a = MerkleRoot\n    { getMerkleRoot :: Hash Raw  -- ^ returns root \'Hash\' of Merkle Tree\n    } deriving (Show, Eq, Ord, Generic, ByteArrayAccess, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/214e7ac54fbb57007e18fdab4d274340371f2d19/core/Pos/Merkle.hs#L28">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Root hash of Merkle tree</td>\n</tr>\n</tbody>\n</table>\n<h3>链难度</h3>\n<pre><code class="language-haskell">-- | Chain difficulty represents necessary effort to generate a\n-- chain. In the simplest case it can be number of blocks in chain.\nnewtype ChainDifficulty = ChainDifficulty\n    { getChainDifficulty :: Word64\n    } deriving (Show, Eq, Ord, Num, Enum, Real, Integral, Generic, Buildable, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L135">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>Chain difficulty</td>\n</tr>\n</tbody>\n</table>\n<h3>SlotLeaders</h3>\n<pre><code>-- | \'NonEmpty\' list of slot leaders.\ntype SlotLeaders = NonEmpty StakeholderId\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L264">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Size of slot leaders list</td>\n</tr>\n<tr>\n<td>n \n*\n size(StakeholderId)</td>\n<td>StakeholderId\n[\nn\n]</td>\n<td></td>\n<td>List of slot leaders of size n</td>\n</tr>\n</tbody>\n</table>\n<h2>GodTossing</h2>\n<h3>Crypto.PVSS</h3>\n<p>Pvss 的类型前缀在 <a href="https://hackage.haskell.org/package/pvss-0.1/docs/Crypto-PVSS.html">Crypto.PVSS</a> 模块定义。本节介绍这些类型的二进制格式。</p>\n<h4>Point</h4>\n<pre><code class="language-haskell">newtype Point = Point { unPoint :: SSL.EcPoint }\n    deriving (Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/31bc53aa861bd4cae8f6741247e849299eae3983/src/Crypto/PVSS/ECC.hs#L92">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>33</td>\n<td>ByteString</td>\n<td>Binary represented elliptic curve point (see ecPointFromOct function)</td>\n</tr>\n</tbody>\n</table>\n<h4>Secret</h4>\n<pre><code class="language-haskell">-- | Secret\nnewtype Secret = Secret Point\n    deriving (Show,Eq,NFData,Binary)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/670ce35d0f4a11aeb9617de4df2992c23f30573d/src/Crypto/SCRAPE.hs#L78">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Secret</td>\n</tr>\n</tbody>\n</table>\n<h4>Proof</h4>\n<pre><code class="language-haskell">newtype Scalar = Scalar { unScalar :: Integer }\n    deriving (Show,Eq,Generic,NFData)\n\nnewtype Challenge = Challenge ByteString\n    deriving (Show,Eq,NFData)\n\n-- | The generated proof\ndata Proof = Proof\n    { proof_c :: !Challenge\n    , proof_z :: !Scalar\n    } deriving (Show,Eq,Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/31bc53aa861bd4cae8f6741247e849299eae3983/src/Crypto/PVSS/DLEQ.hs#L39">源代码链接</a>。</p>\n<p><code>Scalar</code> <a href="https://github.com/input-output-hk/pvss-haskell/blob/31bc53aa861bd4cae8f6741247e849299eae3983/src/Crypto/PVSS/ECC.hs#L110">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td>ByteString</td>\n<td>32-byte string challenge</td>\n</tr>\n<tr>\n<td>32</td>\n<td>Integer</td>\n<td>32-byte integer scalar</td>\n</tr>\n</tbody>\n</table>\n<h4>DecryptedShare</h4>\n<pre><code class="language-haskell">-- | An decrypted share decrypted by a party\'s key and\ndata DecryptedShare = DecryptedShare\n    { decryptedShareID    :: !ShareId\n    , shareDecryptedVal   :: !Point      -- ^ decrypted share\n    , decryptedValidProof :: !DLEQ.Proof -- ^ proof the decryption is valid\n    } deriving (Show,Eq,Generic)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td>Integer</td>\n<td>Share id</td>\n</tr>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Decrypted share</td>\n</tr>\n<tr>\n<td>size(Proof)</td>\n<td>Proof</td>\n<td>Proof the description is valid</td>\n</tr>\n</tbody>\n</table>\n<h4>ExtraGen</h4>\n<pre><code class="language-haskell">-- | Extra generator\nnewtype ExtraGen = ExtraGen Point\n    deriving (Show,Eq,NFData,Binary)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/670ce35d0f4a11aeb9617de4df2992c23f30573d/src/Crypto/PVSS.hs#L82">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Extra generator</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：33。</p>\n<h4>Commitment</h4>\n<pre><code class="language-haskell">newtype Commitment = Commitment { unCommitment :: Point }\n    deriving (Show,Eq,NFData,Binary)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/670ce35d0f4a11aeb9617de4df2992c23f30573d/src/Crypto/PVSS.hs#L69">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Commitment</td>\n</tr>\n</tbody>\n</table>\n<h4>PublicKey</h4>\n<pre><code class="language-haskell">-- | Public Key\nnewtype PublicKey = PublicKey Point\n    deriving (Show,Eq,NFData,Binary)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/31bc53aa861bd4cae8f6741247e849299eae3983/src/Crypto/PVSS/ECC.hs#L84">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Public key</td>\n</tr>\n</tbody>\n</table>\n<h3>密钥共享</h3>\n<p>一下大多数类型是 PVSS 类型的别名，所以它们以相同的方式被序列化。</p>\n<pre><code class="language-haskell">-- | Secret can be generated by `genSharedSecret` function along with shares.\nnewtype Secret = Secret\n    { getSecret :: Pvss.Secret\n    } deriving (Show, Eq)\n\n-- | Shares can be used to reconstruct Secret.\nnewtype Share = Share\n    { getShare :: Pvss.DecryptedShare\n    } deriving (Show, Eq)\n\n-- | Encrypted share which needs to be decrypted using VssKeyPair first.\nnewtype EncShare = EncShare\n    { getEncShare :: Pvss.EncryptedShare\n    } deriving (Show, Eq)\n\n-- | This extra data may be used to verify encrypted share.\ndata SecretSharingExtra =\n    SecretSharingExtra !Pvss.ExtraGen\n                       ![Pvss.Commitment]\n    deriving (Show, Eq, Generic)\n\n-- | SecretProof may be used to commit Secret without revealing it.\nnewtype SecretProof =\n    SecretProof Pvss.Proof\n    deriving (Show, Eq, Generic)\n\n-- | This key is used as public key in VSS.\nnewtype VssPublicKey = VssPublicKey\n    { getVssPublicKey :: Pvss.PublicKey\n    } deriving (Show, Eq)\n</code></pre>\n<p>SecretSharingExtra 的格式：</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(ExtraGen)</td>\n<td>Pvss.ExtraGen</td>\n<td></td>\n<td>Extra generator</td>\n</tr>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Length of commitments list</td>\n</tr>\n<tr>\n<td>n \n*\n size(Pvss.Commitment)</td>\n<td>[\nPvss.Commitment\n]</td>\n<td></td>\n<td>Commitments</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：32：</p>\n<ul>\n<li><code>Share</code> - 101.</li>\n<li><code>EncShare</code> - 101.</li>\n<li><code>SecretProof</code> - 64.</li>\n<li><code>VssPublicKey</code> - 33.</li>\n</ul>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/69dd4b2d0c56474db1059393336557fb649dba9a/core/Pos/Crypto/SecretSharing.hs">源代码链接</a>。</p>\n<h3>Commitments, Openings and Shares</h3>\n<h4>Commitment</h4>\n<pre><code class="language-haskell">-- | Commitment is a message generated during the first stage of\n-- GodTossing. It contains encrypted shares and proof of secret.\n-- Invariant which must be ensured: commShares is not empty.\ndata Commitment = Commitment\n    { commExtra  :: !(AsBinary SecretSharingExtra)\n    , commProof  :: !(AsBinary SecretProof)\n    , commShares :: !(HashMap (AsBinary VssPublicKey) (NonEmpty (AsBinary EncShare)))\n    } deriving (Show, Eq, Generic)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td></td>\n</tr>\n<tr>\n<td>n \n*\n (sizeof(VssPublicKey) + sizeof(EncShare))</td>\n<td>HashMapCommShares</td>\n<td></td>\n<td>commShares</td>\n</tr>\n<tr>\n<td>sizeof(SecretSharingExtra)</td>\n<td>AsBinary SecretSharingExtra</td>\n<td></td>\n<td>commExtra</td>\n</tr>\n<tr>\n<td>sizeof(SecretProof)</td>\n<td>AsBinary SecretProof</td>\n<td></td>\n<td>commProof</td>\n</tr>\n</tbody>\n</table>\n<p>其中 <code>HashMapCommShares</code> =\n<code>HashMap (AsBinary VssPublicKey) (NonEmpty (AsBinary EncShare))</code></p>\n<p>消息大小限制：33。</p>\n<h4>CommitmentSignature</h4>\n<pre><code class="language-haskell">-- | Signature which ensures that commitment was generated by node\n-- with given public key for given epoch.\ntype CommitmentSignature = Signature (EpochIndex, Commitment)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L73">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Signature)</td>\n<td>Signature (EpochIndex, Commitment)</td>\n<td>Signature which ensures that commitment was generated by node with given public key for given epoch</td>\n</tr>\n</tbody>\n</table>\n<h4>SignedCommitment</h4>\n<pre><code class="language-haskell">type SignedCommitment = (PublicKey, Commitment, CommitmentSignature)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L75">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>Public key of node that generated this commitment</td>\n</tr>\n<tr>\n<td>size(Commitment)</td>\n<td>Commitment</td>\n<td>Commitment</td>\n</tr>\n<tr>\n<td>size(CommitmentSignature)</td>\n<td>CommitmentSignature</td>\n<td>Commitment signature</td>\n</tr>\n</tbody>\n</table>\n<h4>CommitmentsMap</h4>\n<pre><code class="language-haskell">-- | \'CommitmentsMap\' is a wrapper for \'HashMap StakeholderId SignedCommitment\'\n-- which ensures that keys are consistent with values, i. e. \'PublicKey\'\n-- from \'SignedCommitment\' corresponds to key which is \'StakeholderId\'.\nnewtype CommitmentsMap = CommitmentsMap\n    { getCommitmentsMap :: HashMap StakeholderId SignedCommitment\n    } deriving (Semigroup, Monoid, Show, Eq, Container, NFData)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of commitments in map</td>\n</tr>\n<tr>\n<td>n * (size(StakeholderId) + size(SignedCommitment))</td>\n<td>HashMap StakeholderId SignedCommitment</td>\n<td></td>\n<td>Commitments map as list of pairs</td>\n</tr>\n</tbody>\n</table>\n<h4>Opening</h4>\n<pre><code class="language-haskell">-- | Opening reveals secret.\nnewtype Opening = Opening\n    { getOpening :: (AsBinary Secret)\n    } deriving (Show, Eq, Generic, Buildable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L102">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Secret)</td>\n<td>AsBinary Secret</td>\n<td>Revealed secret</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：33。</p>\n<h4>OpeningsMap</h4>\n<pre><code class="language-haskell">type OpeningsMap = HashMap StakeholderId Opening\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L106">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of openings in map</td>\n</tr>\n<tr>\n<td>n * (size(StakeholderId) + size(Opening))</td>\n<td>HashMap StakeholderId Opening</td>\n<td></td>\n<td>Openings map as list of pairs</td>\n</tr>\n</tbody>\n</table>\n<h4>VssCertificate</h4>\n<pre><code class="language-haskell">-- | VssCertificate allows VssPublicKey to participate in MPC.\n-- Each stakeholder should create a Vss keypair, sign VSS public key with signing\n-- key and send it into blockchain.\n--\n-- A public key of node is included in certificate in order to\n-- enable validation of it using only node\'s P2PKH address.\n-- Expiry epoch is last epoch when certificate is valid, expiry epoch is included\n-- in certificate and signature.\n--\n-- Other nodes accept this certificate if it is valid and if node has\n-- enough stake.\n--\n-- Invariant: \'checkSig vcSigningKey (vcVssKey, vcExpiryEpoch) vcSignature\'.\ndata VssCertificate = VssCertificate\n    { vcVssKey      :: !(AsBinary VssPublicKey)\n    , vcExpiryEpoch :: !EpochIndex\n    -- ^ Epoch up to which certificates is valid.\n    , vcSignature   :: !(Signature (AsBinary VssPublicKey, EpochIndex))\n    , vcSigningKey  :: !PublicKey\n    } deriving (Show, Eq, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/3a6ac3c5aa8d3ca87d8b409d5923e21b744b1e6b/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L149">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(VssPublicKey)</td>\n<td>AsBinary VssPublicKey</td>\n<td>Public key of stakeholder which is allowed to participate in MPC</td>\n</tr>\n<tr>\n<td>size(EpochIndex)</td>\n<td>EpochIndex</td>\n<td>Last epoch when certificate is valid</td>\n</tr>\n<tr>\n<td>size(Signature)</td>\n<td>Signature (AsBinary VssPublicKey, EpochIndex)</td>\n<td>Signature</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>Signing key</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：171。</p>\n<h4>VssCertificatesMap</h4>\n<pre><code class="language-haskell">-- | VssCertificatesMap contains all valid certificates collected\n-- during some period of time.\ntype VssCertificatesMap = HashMap StakeholderId VssCertificate\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/3a6ac3c5aa8d3ca87d8b409d5923e21b744b1e6b/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L211">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of certificates in map</td>\n</tr>\n<tr>\n<td>n * (size(StakeholderId) + size(VssCertificate))</td>\n<td>HashMap StakeholderId VssCertificate</td>\n<td></td>\n<td>Vss certificates map as list of pairs</td>\n</tr>\n</tbody>\n</table>\n<h3>TxProof</h3>\n<pre><code class="language-haskell">data TxProof = TxProof\n    { txpNumber            :: !Word32\n    , txpRoot              :: !(MerkleRoot Tx)\n    , txpWitnessesHash     :: !(Hash [TxWitness])\n    , txpDistributionsHash :: !(Hash [TxDistribution])\n    } deriving (Show, Eq, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/txp/Pos/Txp/Core/Types.hs#L262">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td>Tx proof number</td>\n</tr>\n<tr>\n<td>size(MerkleRoot)</td>\n<td>MerkleRoot Tx</td>\n<td>MerkleRoot</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Hash of the list of \n<code>TxWitness</code></td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Hash of the list of \n<code>TxDistribution</code></td>\n</tr>\n</tbody>\n</table>\n<h3>GtProof</h3>\n<pre><code class="language-haskell">-- | Proof of MpcData.\n-- We can use ADS for commitments, openings, shares as well,\n-- if we find it necessary.\ndata GtProof\n    = CommitmentsProof !(Hash CommitmentsMap) !(Hash VssCertificatesMap)\n    | OpeningsProof !(Hash OpeningsMap) !(Hash VssCertificatesMap)\n    | SharesProof !(Hash SharesMap) !(Hash VssCertificatesMap)\n    | CertificatesProof !(Hash VssCertificatesMap)\n    deriving (Show, Eq, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L232">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>标签大小</th>\n<th>标签类型</th>\n<th>标签值</th>\n<th>描述</th>\n<th>字段大小</th>\n<th>字段 类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for CommitmentsProof</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for OpeningsProof</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x02</td>\n<td>Tag for SharesProof</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x03</td>\n<td>Tag for CertificatesProof</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n</tbody>\n</table>\n<h2>区块头部</h2>\n<h3>区块版本</h3>\n<pre><code class="language-haskell">-- | Communication protocol version.\ndata BlockVersion = BlockVersion\n    { bvMajor :: !Word16\n    , bvMinor :: !Word16\n    , bvAlt   :: !Word8\n    } deriving (Eq, Generic, Ord, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L144">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>2</td>\n<td>Word16</td>\n<td>Major version</td>\n</tr>\n<tr>\n<td>2</td>\n<td>Word16</td>\n<td>Minor version</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>Alt version from initial US spec</td>\n</tr>\n</tbody>\n</table>\n<h3>软件版本</h3>\n<pre><code class="language-haskell">newtype ApplicationName = ApplicationName\n    { getApplicationName :: Text\n    } deriving (Eq, Ord, Show, Generic, Typeable, ToString, Hashable, Buildable, NFData)\n\n-- | Numeric software version associated with ApplicationName.\ntype NumSoftwareVersion = Word32\n\n-- | Software version.\ndata SoftwareVersion = SoftwareVersion\n    { svAppName :: !ApplicationName\n    , svNumber  :: !NumSoftwareVersion\n    } deriving (Eq, Generic, Ord, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L170">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Length of application name (should be \n&#x3C;\n= 10)</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td><code>svAppName</code>\n: UTF8 encoded application name</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td></td>\n<td><code>svNumber</code></td>\n</tr>\n</tbody>\n</table>\n<h3>主区块头部</h3>\n<!-- TODO: Replace all Main* and Genesis* by type (*Blockchain) -->\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td>Protocol magic</td>\n</tr>\n<tr>\n<td>size(HeaderHash)</td>\n<td>HeaderHash</td>\n<td>Previous block hash</td>\n</tr>\n<tr>\n<td>size(MainProof)</td>\n<td>MainProof</td>\n<td>Body proof</td>\n</tr>\n<tr>\n<td>size(MainConsensusData)</td>\n<td>MainConsensusData</td>\n<td>Consensus data</td>\n</tr>\n<tr>\n<td>size(MainExtraHeaderData)</td>\n<td>MainExtraHeaderData</td>\n<td>MainExtraHeaderData</td>\n</tr>\n</tbody>\n</table>\n<h4>MainProof</h4>\n<pre><code class="language-haskell">type SscProof SscGodTossing = GtProof\n\n-- | Proof that body of update message contains \'UpdatePayload\'.\ntype UpdateProof = Hash UpdatePayload\n\n-- | Proof of everything contained in the payload.\ndata BodyProof (MainBlockchain ssc) = MainProof\n    { mpTxProof       :: !TxProof\n    , mpMpcProof      :: !(SscProof ssc)\n    , mpProxySKsProof :: !(Hash DlgPayload)\n    , mpUpdateProof   :: !UpdateProof\n    } deriving (Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/2198551433ec666f2df400d49b87ced13f3bcbee/src/Pos/Block/Core/Main/Chain.hs#L42">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(TxProof)</td>\n<td>TxProof</td>\n<td>mpTxProof</td>\n</tr>\n<tr>\n<td>size(GtProof)</td>\n<td>SscProof ssc</td>\n<td>mpMpcProof</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>mpProxySKsProof</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>mpUpdateProof</td>\n</tr>\n</tbody>\n</table>\n<h4>MainConsensusData</h4>\n<pre><code class="language-haskell">data ConsensusData (MainBlockchain ssc) = MainConsensusData\n    { -- | Id of the slot for which this block was generated.\n      _mcdSlot       :: !SlotId\n    , -- | Public key of the slot leader. It\'s essential to have it here,\n      -- because FTS gives us only hash of public key (aka \'StakeholderId\').\n      _mcdLeaderKey  :: !PublicKey\n    , -- | Difficulty of chain ending in this block.\n      _mcdDifficulty :: !ChainDifficulty\n    , -- | Signature given by slot leader.\n      _mcdSignature  :: !(BlockSignature ssc)\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/2198551433ec666f2df400d49b87ced13f3bcbee/src/Pos/Block/Core/Main/Chain.hs#L48">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(SlotId)</td>\n<td>SlotId</td>\n<td>mcdSlot</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>mcdLeaderKey</td>\n</tr>\n<tr>\n<td>size(ChainDifficulty)</td>\n<td>ChainDifficulty</td>\n<td>mcdDifficulty</td>\n</tr>\n<tr>\n<td>64</td>\n<td>BlockSignature</td>\n<td>mcdSignature</td>\n</tr>\n</tbody>\n</table>\n<h4>MainExtraHeaderData</h4>\n<pre><code class="language-haskell">-- | Represents main block header attributes: map from 1-byte integer to\n-- arbitrary-type value. To be used for extending header with new\n-- fields via softfork.\ntype BlockHeaderAttributes = Attributes ()\n\n-- | Represents main block header extra data\ndata MainExtraHeaderData = MainExtraHeaderData\n    { -- | Version of block.\n      _mehBlockVersion    :: !BlockVersion\n    , -- | Software version.\n      _mehSoftwareVersion :: !SoftwareVersion\n    , -- | Header attributes\n      _mehAttributes      :: !BlockHeaderAttributes\n    } deriving (Eq, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/3a6ac3c5aa8d3ca87d8b409d5923e21b744b1e6b/src/Pos/Block/Core/Main/Types.hs#L73">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(BlockVersion)</td>\n<td>BlockVersion</td>\n<td>Version of block</td>\n</tr>\n<tr>\n<td>size(SoftwareVersion)</td>\n<td>SoftwareVersion</td>\n<td>Software version</td>\n</tr>\n<tr>\n<td>size(BlockHeaderAttributes)</td>\n<td>BlockHeaderAttributes</td>\n<td>Header attributes (used for extending header with new fields via softfork)</td>\n</tr>\n</tbody>\n</table>\n<h3>GenesisBlockHeader</h3>\n<pre><code class="language-haskell">-- | Header of block contains some kind of summary. There are various\n-- benefits which people get by separating header from other data.\n--\n-- The constructor has `Unsafe\' prefix in its name, because there in\n-- general there may be some invariants which must hold for the\n-- contents of header.\ndata GenericBlockHeader b = UnsafeGenericBlockHeader\n    { -- | Pointer to the header of the previous block.\n      _gbhPrevBlock :: !(BHeaderHash b)\n    , -- | Proof of body.\n      _gbhBodyProof :: !(BodyProof b)\n    , -- | Consensus data to verify consensus algorithm.\n      _gbhConsensus :: !(ConsensusData b)\n    , -- | Any extra data.\n      _gbhExtra     :: !(ExtraHeaderData b)\n    } deriving (Generic)\n\n-- | Header of Genesis block.\ntype GenesisBlockHeader ssc = GenericBlockHeader (GenesisBlockchain ssc)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/b4b2c282b0e2a2e4415163e70dcb559396a2237c/src/Pos/Block/Core/Genesis/Types.hs#L63">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>BHeaderHash b</td>\n<td>Pointer to the header of the previous block</td>\n</tr>\n<tr>\n<td>32</td>\n<td>BodyProof b</td>\n<td>Proof of body</td>\n</tr>\n<tr>\n<td>size(GenesisProof)</td>\n<td>ConsensusData b</td>\n<td>Consensus data to verify consensus algorithm</td>\n</tr>\n<tr>\n<td>size(GenesisConsensusData)</td>\n<td>ExtraHeaderData b</td>\n<td>Any extra data</td>\n</tr>\n</tbody>\n</table>\n<p>其中 <code>b</code> = <code>GenesisBlockchain ssc</code>。</p>\n<h4>GenesisProof</h4>\n<pre><code class="language-haskell">-- | Proof of GenesisBody is just a hash of slot leaders list.\ndata BodyProof (GenesisBlockchain ssc) = GenesisProof\n    !(Hash SlotLeaders)\n    deriving (Eq, Generic, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/b4b2c282b0e2a2e4415163e70dcb559396a2237c/src/Pos/Block/Core/Genesis/Chain.hs#L28">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Hash of slot leaders list</td>\n</tr>\n</tbody>\n</table>\n<h4>GenesisConsensusData</h4>\n<pre><code class="language-haskell">data ConsensusData (GenesisBlockchain ssc) = GenesisConsensusData\n    { -- | Index of the slot for which this genesis block is relevant.\n      _gcdEpoch :: !EpochIndex\n    , -- | Difficulty of the chain ending in this genesis block.\n      _gcdDifficulty :: !ChainDifficulty\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/b4b2c282b0e2a2e4415163e70dcb559396a2237c/src/Pos/Block/Core/Genesis/Chain.hs#L31">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(EpochIndex)</td>\n<td>EpochIndex</td>\n<td>Index of epoch for which this genesis block is relevant</td>\n</tr>\n<tr>\n<td>size(ChainDifficulty)</td>\n<td>ChainDifficulty</td>\n<td>Difficulty of the chain ending in this genesis block.</td>\n</tr>\n</tbody>\n</table>\n<h3>BlockHeader</h3>\n<pre><code class="language-haskell">-- | Either header of ordinary main block or genesis block.\ntype BlockHeader ssc = Either (GenesisBlockHeader ssc) (MainBlockHeader ssc)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/f571087e5b5af339767198141981c850227ca99c/src/Pos/Block/Core/Union/Types.hs#L39">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>标签大小</th>\n<th>标签类型</th>\n<th>标签值</th>\n<th>描述</th>\n<th>字段大小</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for \n<code>GenesisBlockHeader</code></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(GenesisBlockHeader)</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for \n<code>MainBlockHeader</code></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(MainBlockHeader)</td>\n</tr>\n</tbody>\n</table>\n<h3>区块</h3>\n<pre><code class="language-haskell">-- | Either genesis block or main block.\ntype Block ssc = Either (GenesisBlock ssc) (MainBlock ssc)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/f571087e5b5af339767198141981c850227ca99c/src/Pos/Block/Core/Union/Types.hs#L42">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>标签大小</th>\n<th>标签类型</th>\n<th>标签值</th>\n<th>描述</th>\n<th>字段大小</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for \n<code>GenesisBlock</code></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(GenesisBlock)</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for \n<code>MainBlock</code></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(MainBlock)</td>\n</tr>\n</tbody>\n</table>\n<h2>区块交换信息</h2>\n<h3>HeaderHash</h3>\n<pre><code class="language-haskell">-- | \'Hash\' of block header. This should be @Hash (BlockHeader ssc)@\n-- but we don\'t want to have @ssc@ in \'HeaderHash\' type.\ntype HeaderHash = Hash BlockHeaderStub\ndata BlockHeaderStub\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/2198551433ec666f2df400d49b87ced13f3bcbee/core/Pos/Core/Types.hs#L223">源代码链接</a>。</p>\n<h3>GetHeaders</h3>\n<pre><code class="language-haskell">-- | \'GetHeaders\' message. Behaviour of the response depends on\n-- particular combination of \'mghFrom\' and \'mghTo\'.\n--\n-- * \'mghTo\' resolves to some header (let\'s call it @top@ for\n-- convenience) -- node\'s tip if it\'s @Nothing@, header with hash in\n-- @Just@ if it\'s @Just@.\n--\n-- * If \'mghFrom\' is empty, then semantics is "request to return\n-- header of block @top@".\n--\n-- * Otherwise (if \'mghFrom\' isn\'t empty) it represents the set of\n-- checkpoints. Responding node will try to iterate headers from @top@\n-- to older until it reaches any checkpoint. If it finds checkpoint\n-- @c@, it returns all headers in range @[c.next..top]@. If it doesn\'t\n-- find any checkpoint or depth of searching exceeds\n-- \'recoveryHeadersMessage\', it will try to find the newest checkpoint\n-- @cc@ from \'mghFrom\' that\'s in main chain of responding node and\n-- then return at most \'recoveryHeadersMessage\' headers starting with\n-- @cc@ as the oldest one, returning headers in range @l2 =\n-- [cc.next..x]@ where @x@ is either @top@ (in case @length l2 &#x3C;\n-- recoveryHeadersMessage@) or some arbitrary header (and length is\n-- precisely \'recoveryHeadersMessage\').\ndata MsgGetHeaders = MsgGetHeaders\n    { -- not guaranteed to be in any particular order\n      mghFrom :: ![HeaderHash]\n    , mghTo   :: !(Maybe HeaderHash)\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L42">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of checkpoints</td>\n</tr>\n<tr>\n<td>n \n*\n size(Hash)</td>\n<td>Hash\n[\nn\n]</td>\n<td></td>\n<td>List of length \n<code>n</code>\n with hashes</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>tag = 0x00 or 0x01</td>\n<td>Tag for optional \n<code>to</code>\n hash</td>\n</tr>\n<tr>\n<td>tag \n*\n size(Hash)</td>\n<td>Hash</td>\n<td></td>\n<td>If tag is not \n<code>0x00</code>\n then hash of \n<code>to</code>\n block</td>\n</tr>\n</tbody>\n</table>\n<h3>GetBlocks</h3>\n<pre><code class="language-haskell">-- | \'GetBlocks\' message (see protocol specification).\ndata MsgGetBlocks = MsgGetBlocks\n    { mgbFrom :: !HeaderHash\n    , mgbTo   :: !HeaderHash\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L54">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>字段</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td><code>mgbFrom</code></td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td><code>mgbTo</code></td>\n</tr>\n</tbody>\n</table>\n<h3>Headers</h3>\n<pre><code class="language-haskell">-- | \'Headers\' message (see protocol specification).\nnewtype MsgHeaders ssc =\n    MsgHeaders (NewestFirst NE (BlockHeader ssc))\n    deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L65">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of block headers</td>\n</tr>\n<tr>\n<td>n \n*\n size(BlockHeader)</td>\n<td>BlockHeader\n[\nn\n]</td>\n<td></td>\n<td><code>n</code>\n block headers</td>\n</tr>\n</tbody>\n</table>\n<h3>Block</h3>\n<pre><code class="language-haskell">-- | \'Block\' message (see protocol specification).\nnewtype MsgBlock ssc =\n    MsgBlock (Block ssc)\n    deriving (Generic, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L70">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int64</td>\n<td>n</td>\n<td>Size of \n<code>Block</code>\n in bytes</td>\n</tr>\n<tr>\n<td>size(Block)</td>\n<td>Block</td>\n<td></td>\n<td><code>Block</code>\n with size of \n<code>n</code>\n bytes</td>\n</tr>\n</tbody>\n</table>\n<p>包含一个 <code>Block</code>。我们对区块大小进行编码，然后对区块进行编码，以便在不消耗整个区块的情况下，如果大小错误，我们可以拒绝区块。</p>\n<h2>Transaction sending</h2>\n<p>要发送转账，您需要创建 <code>TxAux</code> 数据类型并将其发送到节点。本节介绍了成功执行发送所需的所有数据类型。</p>\n<h3>Transaction input</h3>\n<pre><code class="language-haskell">-- | Represents transaction identifier as \'Hash\' of \'Tx\'.\ntype TxId = Hash Tx\n\n-- | Transaction input.\ndata TxIn = TxIn\n    { -- | Which transaction\'s output is used\n      txInHash  :: !TxId\n      -- | Index of the output in transaction\'s outputs\n    , txInIndex :: !Word32\n    } deriving (Eq, Ord, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/txp/Pos/Txp/Core/Types.hs#L147">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>字段 name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>txInHash</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td>txInIndex</td>\n</tr>\n</tbody>\n</table>\n<h3>转账输出</h3>\n<pre><code class="language-haskell">-- | Transaction output.\ndata TxOut = TxOut\n    { txOutAddress :: !Address\n    , txOutValue   :: !Coin\n    } deriving (Eq, Ord, Generic, Show, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/txp/Pos/Txp/Core/Types.hs#L160">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>字段 name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Address)</td>\n<td>Address</td>\n<td>txOutAddress</td>\n</tr>\n<tr>\n<td>size(Coin)</td>\n<td>Coin</td>\n<td>txOutValue</td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> let addr = PubKeyAddress (abstractHash somePk) (Attributes (AddrPkAttrs Nothing) "a")\nghci> hexEncode addr\n"001e380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00161cf52c5ec"\nghci> hexEncode $ TxOut addr (mkCoin 1000)\n"001e380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00161cf52c5ec0064"\n</code></pre>\n<h3>转账输出分配</h3>\n<pre><code class="language-haskell">type TxOutDistribution = [(StakeholderId, Coin)]\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L129">源代码链接</a>。</p>\n<p>定义 <code>distr_size(n) = n * (size(Hash) + size(Coin))</code>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>distr\n_\nsize(n)</td>\n<td>&#x3C;Hash,Coin>\n[\nn\n]</td>\n<td>Array of pairs for StakeholderId and Coin</td>\n</tr>\n</tbody>\n</table>\n<h3>转账输出辅助词</h3>\n<pre><code class="language-haskell">-- | Transaction output and auxilary data corresponding to it.\ndata TxOutAux = TxOutAux\n    { toaOut   :: !TxOut             -- ^ Tx output\n    , toaDistr :: !TxOutDistribution -- ^ Stake distribution\n                                     -- associated with output\n    } deriving (Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L173">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>字段 name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(TxOut)</td>\n<td>TxOut</td>\n<td>toaOut</td>\n</tr>\n<tr>\n<td>size(TxOutDistribution)</td>\n<td>TxOutDistribution</td>\n<td>toaDistr</td>\n</tr>\n</tbody>\n</table>\n<h3>转账签名数据</h3>\n<pre><code class="language-haskell">-- | Data that is being signed when creating a TxSig.\ndata TxSigData = TxSigData\n    { -- | Input that we\'re signing (i.e. our signature certifies that we own\n      -- funds referenced by this input)\n      txSigInput     :: !TxIn\n      -- | Outputs of the transaction (i.e. our signature certifies that we\n      -- actually want the funds to go to these particular outputs)\n    , txSigOutsHash  :: !(Hash (NonEmpty TxOut))\n      -- | Distribution of the transaction\n    , txSigDistrHash :: !(Hash TxDistribution)\n    }\n    deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L80">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(TxIn)</td>\n<td>TxIn</td>\n<td>txSigInput</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>txSigOutsHash</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>txSigDistrHash</td>\n</tr>\n</tbody>\n</table>\n<h3>转账见证</h3>\n<pre><code class="language-haskell">-- | \'Signature\' of addrId.\ntype TxSig = Signature TxSigData\n\n-- | A witness for a single input.\ndata TxInWitness\n    = PkWitness { twKey :: !PublicKey\n                , twSig :: !TxSig }\n    | ScriptWitness { twValidator :: !Script\n                    , twRedeemer  :: !Script }\n    | RedeemWitness { twRedeemKey :: !RedeemPublicKey\n                    , twRedeemSig :: !(RedeemSignature TxSigData) }\n    | UnknownWitnessType !Word8 !ByteString\n    deriving (Eq, Show, Generic, Typeable)\n\n-- | A witness is a proof that a transaction is allowed to spend the funds it\n-- spends (by providing signatures, redeeming scripts, etc). A separate proof\n-- is provided for each input.\ntype TxWitness = Vector TxInWitness\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L96">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>标签大小</th>\n<th>标签类型</th>\n<th>标签值</th>\n<th>描述</th>\n<th>字段大小</th>\n<th>字段 类型</th>\n<th>字段 name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for PkWitness</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>twKey</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>64</td>\n<td>TxSig</td>\n<td>twSig</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for ScriptWitness</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Script)</td>\n<td>Script</td>\n<td>twValidator</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Script)</td>\n<td>Script</td>\n<td>twRedeemer</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x02</td>\n<td>Tag for RedeemWitness</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(RedeemPublicKey)</td>\n<td>RedeemPublicKey</td>\n<td>twRedeemKey</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(RedeemSignature)</td>\n<td>RedeemSignature TxSigData</td>\n<td>twRedeemSig</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x03</td>\n<td>Tag for UnknownWitnessType</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>1</td>\n<td>Word8</td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>ByteString</td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<h3>转账</h3>\n<pre><code class="language-haskell">-- | Transaction.\ndata Tx = UnsafeTx\n    { _txInputs     :: !(NonEmpty TxIn)  -- ^ Inputs of transaction.\n    , _txOutputs    :: !(NonEmpty TxOut) -- ^ Outputs of transaction.\n    , _txAttributes :: !TxAttributes     -- ^ Attributes of transaction\n    } deriving (Eq, Ord, Generic, Show, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L196">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of transaction inputs</td>\n</tr>\n<tr>\n<td>n \n*\n size(TxIn)</td>\n<td>TxIn\n[\nn\n]</td>\n<td></td>\n<td>Array of transaction inputs</td>\n</tr>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>m</td>\n<td>Number of transaction outputs</td>\n</tr>\n<tr>\n<td>m \n*\n size(TxOut)</td>\n<td>TxOut\n[\nm\n]</td>\n<td></td>\n<td>Array of transaction outputs</td>\n</tr>\n<tr>\n<td>size(TxAttributes)</td>\n<td>TxAttributes</td>\n<td></td>\n<td>Attributes of transaction</td>\n</tr>\n</tbody>\n</table>\n<h3>转账分发</h3>\n<pre><code class="language-haskell">-- | Distribution of “fake” stake that follow-the-satoshi would use\n-- for a particular transaction.  Length of stored list must be same\n-- as length of \'_txOutputs\' of corresponding transaction.\nnewtype TxDistribution = TxDistribution\n    { getTxDistribution :: NonEmpty TxOutDistribution\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L134">源代码链接</a>。</p>\n<p>虽然转账分发可以使用前面的序列化策略来作为列表的列表存储，但经常发生我们通过了空列表的列表的情况。在这种情况下，我们应该更有效地存储这些列表。</p>\n<table>\n<thead>\n<tr>\n<th>标签大小</th>\n<th>标签类型</th>\n<th>标签值</th>\n<th>描述</th>\n<th>字段大小</th>\n<th>字段 类型</th>\n<th>值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>List of empty lists</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Some lists are not empty</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>distr\n_\nsize(n)</td>\n<td>&#x3C;Hash,Coin>\n[\nn\n]</td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<h3>转账分配</h3>\n<pre><code class="language-haskell">-- | Transaction + auxiliary data\ndata TxAux = TxAux\n    { taTx           :: !Tx\n    , taWitness      :: !TxWitness\n    , taDistribution :: !TxDistribution\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/ab543154d3ff34d3432620ac2557187d124b7d4f/txp/Pos/Txp/Core/Types.hs#L205">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Tx)</td>\n<td>Tx</td>\n<td>Transaction itself</td>\n</tr>\n<tr>\n<td>size(TxWitness)</td>\n<td>TxWitness</td>\n<td>Witness for transaction</td>\n</tr>\n<tr>\n<td>size(TxDistribution)</td>\n<td>TxDistribution</td>\n<td>Transaction distribution</td>\n</tr>\n</tbody>\n</table>\n<!-- TODO: describe full creation of transaction by bytes -->\n<h2>委派</h2>\n<p>请阅读<a href="/technical/protocols/csl-application-level/#delegation-messages">委派信息</a>机制的解释，在这里你只能找到消息格式的描述。</p>\n<h3>代理证书</h3>\n<p>类似于 <code>Signature</code></p>\n<pre><code class="language-haskell">-- | Proxy certificate, made of ω + public key of delegate.\nnewtype ProxyCert w = ProxyCert { unProxyCert :: CC.XSignature }\n    deriving (Eq, Ord, Show, Generic, NFData, Hashable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L209">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>64</td>\n<td>Word8\n[\n64\n]</td>\n<td><code>unProxyCert</code>\n: 64 bytes of signature string</td>\n</tr>\n</tbody>\n</table>\n<p>消息大小限制：64。</p>\n<p>例子：</p>\n<pre><code>ghci> (issuerPk, issuerSk) &#x3C;- keyGen\nghci> hexEncode issuerPk\n"0659c8e27599dc4709dab3bb58ce50d0729150fc238010fd3a68dcf07c621bdc"\nghci> (delegatePk, delegateSk) &#x3C;- keyGen\nghci> hexEncode delegatePk\n"5eaf0944733da8386c427656a876b20ae411fa686ea4bb165b53a311c868c287"\nghci> let cert = createProxyCert issuerSk delegatePk (0, 10) :: ProxyCert (EpochIndex, EpochIndex)\nghci> hexEncode cert\n"8db543c5fff7dd5dab609d04a834cda77958faf48cabee351def8985a2ec7dae71c7b2f0390caa54c61c9d41f5228e1a0b5da1c08638b99d03a1c02c81cb1607"\nghci> verifyProxyCert issuerPk delegatePk (0, 10) cert\nTrue\n</code></pre>\n<h3>代理密钥</h3>\n<pre><code class="language-haskell">-- | Convenient wrapper for secret key, that\'s basically ω + certificate.\ndata ProxySecretKey w = ProxySecretKey\n    { pskOmega      :: w\n    , pskIssuerPk   :: PublicKey\n    , pskDelegatePk :: PublicKey\n    , pskCert       :: ProxyCert w\n    } deriving (Eq, Ord, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L224">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(w)</td>\n<td>w</td>\n<td>pskOmega</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskIssuerPk</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskDelegatePk</td>\n</tr>\n<tr>\n<td>size(ProxyCert)</td>\n<td>ProxyCert w</td>\n<td>pskCert</td>\n</tr>\n</tbody>\n</table>\n<h3>代理签名</h3>\n<pre><code class="language-haskell">-- | Delegate signature made with certificate-based permission. @w@\n-- stays for message type used in proxy (ω in the implementation\n-- notes), @a@ for type of message signed.\ndata ProxySignature w a = ProxySignature\n    { psigPsk :: ProxySecretKey w\n    , psigSig :: CC.XSignature\n    } deriving (Eq, Ord, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L256">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(PproxySK)</td>\n<td>ProxySecretKey</td>\n<td>psigPsk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>XSignature</td>\n<td>psigSig</td>\n</tr>\n</tbody>\n</table>\n<h3>代理密钥和轻量级委派的签名</h3>\n<p><strong>警告：目前，轻量级委派被禁用，并在 <a href="https://cardanoroadmap.com/">Shelley 版本</a>进行了重新编写，因此一下信息可能已过时。</strong></p>\n<h4>密钥</h4>\n<pre><code class="language-haskell">-- | Same alias for the proxy secret key (see \'ProxySigLight\').\ntype ProxySKLight = ProxySecretKey (EpochIndex, EpochIndex)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L238">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>from epoch</td>\n</tr>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>to epoch</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskIssuerPk</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskDelegatePk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>ProxyCert (EpochIndex, EpochIndex)</td>\n<td>pskCert</td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> let proxySk = createProxySecretKey issuerSk delegatePk (0, 10) :: ProxySKLight\nghci> hexEncode proxySk\n"000a0659c8e27599dc4709dab3bb58ce50d0729150fc238010fd3a68dcf07c621bdc5eaf0944733da8386\nc427656a876b20ae411fa686ea4bb165b53a311c868c2878db543c5fff7dd5dab609d04a834cda77958faf\n48cabee351def8985a2ec7dae71c7b2f0390caa54c61c9d41f5228e1a0b5da1c08638b99d03a1c02c81cb1607"\nghci> verifyProxySecretKey proxySk\nTrue\n</code></pre>\n<h4>签名</h4>\n<pre><code class="language-haskell">-- | Proxy signature used in csl -- holds a pair of epoch\n-- indices. Block is valid if it\'s epoch index is inside this range.\ntype ProxySigLight a = ProxySignature (EpochIndex, EpochIndex) a\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L235">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>from epoch</td>\n</tr>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>to epoch</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pdDelegatePk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>ProxyCert (EpochIndex, EpochIndex)</td>\n<td>pdCert</td>\n</tr>\n<tr>\n<td>64</td>\n<td>Signature</td>\n<td>pdSig</td>\n</tr>\n</tbody>\n</table>\n<p>例子</p>\n<pre><code>ghci> let proxyLightSig = proxySign delegateSk proxySk proxySk :: ProxySigLight ProxySKLight\nghci> hexEncode proxyLightSig\n"000a5eaf0944733da8386c427656a876b20ae411fa686ea4bb165b53a311c868c2878db543c5fff7dd5dab609d04a\n834cda77958faf48cabee351def8985a2ec7dae71c7b2f0390caa54c61c9d41f5228e1a0b5da1c08638b99d03a1c02\nc81cb1607e764468529599312ebe4dd5587383e5ccd3c2755401b22c8ff08827ecabd1afc8c634e17085ec83179193\nafad2868e6aabce3e3e46e3170d077ee4e8613aa700"\nghci> proxyVerify issuerPk proxyLightSig (== (0, 10)) proxySk\nTrue\n</code></pre>\n<h3>代理密钥和重量级代理签名</h3>\n<h4>密钥</h4>\n<pre><code class="language-haskell">-- | Correspondent SK for no-ttl proxy signature scheme.\ntype ProxySKHeavy = ProxySecretKey EpochIndex\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L247">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>epoch</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskIssuerPk</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskDelegatePk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>ProxyCert EpochIndex</td>\n<td>pskCert</td>\n</tr>\n</tbody>\n</table>\n<h4>签名</h4>\n<pre><code class="language-haskell">-- | Simple proxy signature without ttl/epoch index\n-- constraints. \'EpochIndex\' inside is needed for replay attack\n-- prevention.\ntype ProxySigHeavy a = ProxySignature EpochIndex a\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L244">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>epoch</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pdDelegatePk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>ProxyCert EpochIndex</td>\n<td>pdCert</td>\n</tr>\n<tr>\n<td>64</td>\n<td>Signature</td>\n<td>pdSig</td>\n</tr>\n</tbody>\n</table>\n<h3>轻量级委派确认</h3>\n<p><strong>警告：目前，轻量级委派被禁用，并在 <a href="https://cardanoroadmap.com/">Shelley 版本</a>进行了重新编写，因此一下信息可能已过时。</strong></p>\n<h4>ProxySKLightConfirmation</h4>\n<pre><code class="language-haskell">-- | Confirmation of light cert type.\ntype ProxySKLightConfirmation = (ProxySKLight, ProxySigLight ProxySKLight)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(ProxySKLight)</td>\n<td>Certificate</td>\n</tr>\n<tr>\n<td>size(ProxySigLight)</td>\n<td>Proof for certificate</td>\n</tr>\n</tbody>\n</table>\n<h2>更新系统</h2>\n<h3>更新投票</h3>\n<pre><code class="language-haskell">-- | ID of software update proposal\ntype UpId = Hash UpdateProposal\n\n-- | Vote for update proposal\ndata UpdateVote = UpdateVote\n    { -- | Public key of stakeholder, who votes\n      uvKey        :: !PublicKey\n    , -- | Proposal to which this vote applies\n      uvProposalId :: !UpId\n    , -- | Approval/rejection bit\n      uvDecision   :: !Bool\n    , -- | Signature of (Update proposal, Approval/rejection bit)\n      --   by stakeholder\n      uvSignature  :: !(Signature (UpId, Bool))\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/fbe9760bd50ea136203e54d578d62ed3070b5513/update/Pos/Update/Core/Types.hs#L255">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>字段</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>uvKey</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>uvProposalId</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Bool</td>\n<td>uvDecision</td>\n</tr>\n<tr>\n<td>64</td>\n<td>Signature</td>\n<td>uvSignature</td>\n</tr>\n</tbody>\n</table>\n<h3>投票标识符</h3>\n<pre><code class="language-haskell">type VoteId = (UpId, PublicKey, Bool)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/fbe9760bd50ea136203e54d578d62ed3070b5513/update/Pos/Update/Core/Types.hs#L252">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Hash of update proposal</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>Public key</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Bool</td>\n<td>Vote result</td>\n</tr>\n</tbody>\n</table>\n<p>有关字段的更多描述，请参阅 <em>UpdateVote</em> 消息描述。<code>VoteId</code> 是 <code>(uvProposalId, uvKey, uvDecision)</code>。</p>\n<h3>区块版本数据</h3>\n<pre><code class="language-haskell">-- | Data which is associated with \'BlockVersion\'.\ndata BlockVersionData = BlockVersionData\n    { bvdScriptVersion     :: !ScriptVersion\n    , bvdSlotDuration      :: !Millisecond\n    , bvdMaxBlockSize      :: !Byte\n    , bvdMaxHeaderSize     :: !Byte\n    , bvdMaxTxSize         :: !Byte\n    , bvdMaxProposalSize   :: !Byte\n    , bvdMpcThd            :: !CoinPortion\n    , bvdHeavyDelThd       :: !CoinPortion\n    , bvdUpdateVoteThd     :: !CoinPortion\n    , bvdUpdateProposalThd :: !CoinPortion\n    , bvdUpdateImplicit    :: !FlatSlotId\n    , bvdUpdateSoftforkThd :: !CoinPortion\n    } deriving (Show, Eq, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L201">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>字段</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-3</td>\n<td>UVarInt Word16</td>\n<td>bvdScriptVersion</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdSlotDuration</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdMaxBlockSize</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdMaxHeaderSize</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdMaxTxSize</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdMaxProposalSize</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdMpcThd</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdHeavyDelThd</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdUpdateVoteThd</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdUpdateProposalThd</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdUpdateImplicit</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdUpdateSoftforkThd</td>\n</tr>\n</tbody>\n</table>\n<h3>更新数据</h3>\n<pre><code class="language-haskell">-- | Data which describes update. It is specific for each system.\ndata UpdateData = UpdateData\n    { udAppDiffHash  :: !(Hash Raw)\n    -- ^ Hash of binary diff between two applications. This diff can\n    -- be passed to updater to create new application.\n    , udPkgHash      :: !(Hash Raw)\n    -- ^ Hash of package to install new application. This package can\n    -- be used to install new application from scratch instead of\n    -- updating existing application.\n    , udUpdaterHash  :: !(Hash Raw)\n    -- ^ Hash if update application which can be used to install this\n    -- update (relevant only when updater is used, not package).\n    , udMetadataHash :: !(Hash Raw)\n    -- ^ Hash of metadata relevant to this update.  It is raw hash,\n    -- because metadata can include image or something\n    -- (maybe). Anyway, we can always use `unsafeHash`.\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/update/Pos/Update/Core/Types.hs#L224">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>字段</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>udAppDiffHash</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>udPkgHash</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>udUpdaterHash</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>udMetadataHash</td>\n</tr>\n</tbody>\n</table>\n<h3>系统标签</h3>\n<pre><code class="language-haskell">-- | Tag of system for which update data is purposed, e.g. win64, mac32\nnewtype SystemTag = SystemTag { getSystemTag :: Text }\n  deriving (Eq, Ord, Show, Generic, Buildable, Hashable, Lift, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/update/Pos/Update/Core/Types.hs#L81">源代码链接</a>。</p>\n<p><code>SystemTag</code> 按 UTF-8 编码为 <code>ByteString</code>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>字段</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int64</td>\n<td>n</td>\n<td>Size of text in bytes</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td><code>n</code>\n bytes of UTF-8 encoded text</td>\n</tr>\n</tbody>\n</table>\n<h3>更新协议</h3>\n<pre><code class="language-haskell">type UpAttributes = Attributes ()\n\n-- | Proposal for software update\ndata UpdateProposal = UnsafeUpdateProposal\n    { upBlockVersion     :: !BlockVersion\n    , upBlockVersionData :: !BlockVersionData\n    , upSoftwareVersion  :: !SoftwareVersion\n    , upData             :: !(HM.HashMap SystemTag UpdateData)\n    -- ^ UpdateData for each system which this update affects.\n    -- It must be non-empty.\n    , upAttributes       :: !UpAttributes\n    -- ^ Attributes which are currently empty, but provide\n    -- extensibility.\n    , upFrom             :: !PublicKey\n    -- ^ Who proposed this UP.\n    , upSignature        :: !(Signature UpdateProposalToSign)\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>值</th>\n<th>字段</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>5</td>\n<td>BlockVersion</td>\n<td></td>\n<td>upBlockVersion</td>\n</tr>\n<tr>\n<td>size(BlockVersionData)</td>\n<td>BlockVersionData</td>\n<td></td>\n<td>upBlockVersionData</td>\n</tr>\n<tr>\n<td>size(SoftwareVersion)</td>\n<td>SoftwareVersion</td>\n<td></td>\n<td>upSoftwareVersion</td>\n</tr>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td></td>\n</tr>\n<tr>\n<td>n \n*\n (size(SystemTag) + size(UpdateData))</td>\n<td>&#x3C;SystemTag, UpdateData>\n[\nn\n]</td>\n<td></td>\n<td>upData</td>\n</tr>\n<tr>\n<td>size(Attributes ())</td>\n<td>Attributes ()</td>\n<td></td>\n<td>upAttributes</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td></td>\n<td>upFrom</td>\n</tr>\n<tr>\n<td>size(Signature)</td>\n<td>Signature UpdateProposalToSign</td>\n<td></td>\n<td>upSignature</td>\n</tr>\n</tbody>\n</table>\n<h2>对等点数据</h2>\n<h3>HandlerSpec</h3>\n<pre><code class="language-haskell">data HandlerSpec\n    = ConvHandler { hsReplyType :: MessageName}\n    | UnknownHandler Word8 ByteString\n    deriving (Show, Generic, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/414817a6f8c8de405553c8ba1325e1366dc7b60e/infra/Pos/Communication/Types/Protocol.hs#L80">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>类型</th>\n<th>大小</th>\n<th>值</th>\n<th>Following data</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>ConvHandler m where m : UnsignedVarInt \n&#x3C;\n 64</td>\n<td>Word8</td>\n<td>01xx xxxx</td>\n<td>none</td>\n</tr>\n<tr>\n<td>ConvHandler m where m : Unknown</td>\n<td>Word8 + TinyBS</td>\n<td>0000 0001</td>\n<td>ByteString</td>\n</tr>\n<tr>\n<td>UnknownHandler w8 bs</td>\n<td>Word8 + TinyBS</td>\n<td>w8</td>\n<td>bs</td>\n</tr>\n</tbody>\n</table>\n<p>例子：</p>\n<pre><code>ghci> hexEncode (ConvHandler (messageName (Proxy :: Proxy MsgGetHeaders)))\n"44"\nghci> hexEncode (UnknownHandler 10 "aba")\n"0a03616261"\n</code></pre>\n<h3>VerInfo</h3>\n<pre><code class="language-haskell">type HandlerSpecs = HashMap MessageName HandlerSpec\n\nnewtype InSpecs = InSpecs HandlerSpecs\n    deriving (Eq, Show, Generic)\n\nnewtype OutSpecs = OutSpecs HandlerSpecs\n    deriving (Eq, Show, Generic)\n\ndata VerInfo = VerInfo\n    { vIMagic        :: Int32\n    , vIBlockVersion :: BlockVersion\n    , vIInHandlers   :: HandlerSpecs\n    , vIOutHandlers  :: HandlerSpecs\n    } deriving (Eq, Generic, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/414817a6f8c8de405553c8ba1325e1366dc7b60e/infra/Pos/Communication/Types/Protocol.hs#L102">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>字段</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>Int32</td>\n<td><code>vIMagic</code></td>\n</tr>\n<tr>\n<td>5</td>\n<td>BlockVersion</td>\n<td><code>vIBlockVersion</code></td>\n</tr>\n<tr>\n<td>size(HandlerSpecs)</td>\n<td>HandlerSpecs</td>\n<td><code>vIInHandlers</code></td>\n</tr>\n<tr>\n<td>size(HandlerSpecs)</td>\n<td>HandlerSpecs</td>\n<td><code>vIOutHandlers</code></td>\n</tr>\n</tbody>\n</table>\n<p><code>HandlerSpec</code> 只是在消息名称和这些消息的处理方式之间进行映射：通过单消息风格或对话风格+消息标签。这个映射被编码为其他 <code>Map</code> - 列表对。</p>\n<p><code>InSpecs</code> 和 <code>OutSpecs</code> 只是 <code>HandlerSpecs</code> 的封装。这些封装只用于保证类型安全，以区分传入和传出消息的规范。</p>\n<!-- TODO: didn\'t find examples of inSpecs :( -->\n<h3>PeerData</h3>\n<pre><code class="language-haskell">type PeerData = VerInfo\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/414817a6f8c8de405553c8ba1325e1366dc7b60e/infra/Pos/Communication/Types/Protocol.hs#L47">源代码链接</a>。</p>\n<table>\n<thead>\n<tr>\n<th>字段大小</th>\n<th>类型</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(VerInfo)</td>\n<td>VerInfo</td>\n<td>MessageName table</td>\n</tr>\n</tbody>\n</table>\n<p>我们发送的 <code>VerInfo</code> 在<a href="https://github.com/input-output-hk/cardano-sl/blob/81b40e54bb5dda2e94850ccc9a835b46e5c445b5/src/Pos/Launcher/Runner.hs#L286">这里</a>创建。</p>\n<p>例子：</p>\n<pre><code class="language-haskell">ghci> let ourVerInfo = VerInfo protocolMagic lastKnownBlockVersion mempty outSpecs\nghci> let peerIdExample = PeerId "0123456789ABCD"\nghci> hexEncode ourVerInfo\n"0000000000000000000004030800000103020900030801010103020901030802\n020103020902030803030103020903"\nghci> hexEncode ((peerIdExample, ourVerInfo) :: PeerData)\n"3031323334353637383941424344000000000000000000000403080000010302\n0900030801010103020901030802020103020902030803030103020903"\n</code></pre>',
  frontmatter:{path:"/cn/technical/protocols/binary-protocols/",doc_title:"二进制协议",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/technical/protocols/2017-01-13-binary.md absPath of file >>> MarkdownRemark",excerpt:"Binary Protocols IMPORTANT: BINARY PROTOCOLS WILL BE CHANGED SOON. Sizes of all fields are represented in bytes. Big-Endian is used…",html:'<!-- Reviewed at 721474b760466b888cf26545b52b35989b2162de -->\n<!-- Delegation : Updated at 15b8b777fde5a8ab4a85af71affeffdf31ad219c -->\n<h1>Binary Protocols</h1>\n<p><span style="color: red;"><strong>IMPORTANT: BINARY PROTOCOLS WILL BE CHANGED SOON.</strong></span></p>\n<p>Sizes of all fields are represented in bytes. Big-Endian is used everywhere.\nComposite types are serialized in the order of definition with no delimiters.</p>\n<p>For example, <code>(Word32, Word8)</code> is serialized with 5 bytes: 4 for <code>Word32</code>, and 1\nfor <code>Word8</code>.</p>\n<p>For variable-length structures, dependent on object of type T, we use <code>size(T)</code>\nnotation.</p>\n<p><code>Word32</code> is <em>unsigned integer of 32 bits</em> (<code>uint32</code>).</p>\n<p>To test serialization of object <code>myObject</code> in <code>ghci</code>, one should use the\nfollowing commands in <code>cardano-sl</code> root project directory:</p>\n<pre><code>$ stack repl\n...\n&#x3C;Press Enter>\n...\nghci> import Data.ByteString.Builder\nghci> let hexEncode myObject = toLazyByteString $ lazyByteStringHex $ Pos.Binary.encode $ myObject\nghci> hexEncode (mkCoin 1000)\n"0064"\n</code></pre>\n<h2>Common Haskell Data Types</h2>\n<h3>Maybe</h3>\n<pre><code class="language-haskell">data Maybe a = Nothing | Just a\n</code></pre>\n<p><code>Maybe a</code> is either value of type <code>a</code> or empty (aka <code>null</code>, <code>None</code>). To\ndistinguish between two values we add 1 byte tag before data.</p>\n<table>\n<thead>\n<tr>\n<th>Tag size</th>\n<th>Tag Type</th>\n<th>Tag Value</th>\n<th>Description</th>\n<th>Field size</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for Nothing</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for Just</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(a)</td>\n<td>Value of type \n<code>a</code></td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode (Nothing :: Maybe Word32)\n"00"\nghci> hexEncode (Just 4  :: Maybe Word32)\n"0100000004"\n</code></pre>\n<h3>Either</h3>\n<pre><code class="language-haskell">data Either a b = Left a | Right b\n</code></pre>\n<p><code>Either a b</code> is either value of type <code>a</code> or value of type <code>b</code>. To distinguish\nbetween two values we add 1 byte tag before data.</p>\n<table>\n<thead>\n<tr>\n<th>Tag size</th>\n<th>Tag Type</th>\n<th>Tag Value</th>\n<th>Description</th>\n<th>Field size</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for Left</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(a)</td>\n<td>Value of type \n<code>a</code></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for Right</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(b)</td>\n<td>Value of type \n<code>b</code></td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode (Left 3  :: Either Word16 Word32)\n"000003"\nghci> hexEncode (Right 4 :: Either Word16 Word32)\n"0100000004"\n</code></pre>\n<h3>Big Integer</h3>\n<pre><code class="language-haskell">-- Fixed-size type for a subset of Integer\ntype SmallInt = Int32\n</code></pre>\n<p>Integers are encoded in two ways: if they fit inside a <code>SmallInt</code>, they\'re\nwritten as a byte tag, and that value. If the <code>Integer</code> value is too large to\nfit in a SmallInt, it is written as a byte array, along with a sign and length\nfield.</p>\n<p>For reference, see\n<a href="http://hackage.haskell.org/package/binary-0.8.4.1/docs/src/Data.Binary.Class.html#line-306">implementation</a>.</p>\n<p>Example:</p>\n<pre><code>ghci> hexEncode $ (15 :: Integer)\n"000000000f"\nghci> hexEncode $ (  (2 :: Integer) ^ (128 :: Integer))\n"010100000000000000110000000000000000000000000000000001"\nghci> hexEncode $ (- (2 :: Integer) ^ (128 :: Integer))\n"01ff00000000000000110000000000000000000000000000000001"\n</code></pre>\n<h3>Unsigned Variable Length Integer</h3>\n<p>This type will be referenced to later as <code>UVarInt Word16</code> or <code>UVarInt Word64</code> to\ndescribe maximum available value.</p>\n<pre><code class="language-haskell">newtype UnsignedVarInt a = UnsignedVarInt {getUnsignedVarInt :: a}\n    deriving (Eq, Ord, Show, Generic, NFData, Functor)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/core/Pos/Binary/Class.hs#L277">Source code\nlink</a>.</p>\n<p>Values are encoded 7 bits at a time, with the most significant one being a\ncontinuation bit. Thus, the numbers from 0 to 127 require only a single byte to\nencode, those from 128 to 16383 require two bytes, etc.</p>\n<p>This\n<a href="https://developers.google.com/protocol-buffers/docs/encoding#varints">format</a>\nis taken from Google\'s Protocol Buffers, which provides a bit more verbiage on\nthe encoding.</p>\n<p>Example:</p>\n<pre><code>ghci> hexEncode (UnsignedVarInt (3 :: Word32))\n"03"\nghci> hexEncode (UnsignedVarInt (126 :: Word32))\n"7e"\nghci> hexEncode (UnsignedVarInt (127 :: Word32))\n"7f"\nghci> hexEncode (UnsignedVarInt (128 :: Word32))\n"8001"\n</code></pre>\n<h3>Tiny Variable Length Integer</h3>\n<pre><code class="language-haskell">-- | A newtype wrapper for non-negative integers less than @2^14@. Use it if\n-- you want to be extra careful. Compared to \'SignedVarInt\' and\n-- \'UnsignedVarInt\', it provides two benefits:\n--\n-- * It is guaranteed to take either 1 or 2 bytes (the standard decoder for\n--   variants can consume an unlimited amount of bytes).\n--\n-- * It is unambiguous (e.g. @0@ can be encoded in only one way instead of\n--   two).\nnewtype TinyVarInt = TinyVarInt {getTinyVarInt :: Word16}\n    deriving (Eq, Ord, Show, Generic, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/core/Pos/Binary/Class.hs#L295">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-2</td>\n<td>UVarInt Word16</td>\n<td>Variable length integer up to 2^14 - 1</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode $ TinyVarInt 0\n"00"\nghci> hexEncode $ TinyVarInt (2^14 -1)\n"ff7f"\n</code></pre>\n<p><code>ByteString</code>s in <code>cardano</code> are encoded as a sequence of bytes preceded by its\nlength, where the length is encoded as a variable-length integer. If length is\nencoded as <code>TinyVarInt</code> then such <code>ByteString</code> is denoted as <code>TinyBS</code>.</p>\n<h3>Lists, NonEmpty and Vectors</h3>\n<p>Sometimes we store a list of some objects inside our datatypes. You will see\nreferences to them as <code>Vector a</code> or <code>[a]</code>. You should read this as <em>array of\nobjects of types <code>a</code></em>. Both of these standard Haskell data types are serialized\nin the same way. If you see <code>NonEmpty a</code> in type you should read it as <code>[a]</code> but\nthe size of that list is guaranteed to be at least <code>1</code>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Size of array</td>\n</tr>\n<tr>\n<td>n \n*\n size(a)</td>\n<td>a\n[\nn\n]</td>\n<td></td>\n<td>Array with length \n<code>n</code>\n of objects of type \n<code>a</code></td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode ([1, 31] :: [Word16])\n"020001001f"\nghci> hexEncode ([0..135] :: [Word8])  -- 136 bytes from 0 to 135 including\n"8801000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252\n62728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4\nf505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576777\n8797a7b7c7d7e7f8081828384858687"\n</code></pre>\n<h3>HashMap</h3>\n<p><code>HashMap key value</code> is mapping from keys to values. In serialization, HashMap is\nrepresented as list of pairs from <code>key</code> and <code>value</code> and thus is serialized as\n<code>[(key, value)]</code>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Size of HashMap</td>\n</tr>\n<tr>\n<td>n * (size(key) + size(value))</td>\n<td>&#x3C;key, value>\n[\nn\n]</td>\n<td></td>\n<td>Array with length \n<code>n</code>\n of objects of type \n<code>(key, value)</code></td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode $ Data.HashMap.Strict.fromList [(1 :: Word8, 127 :: Word64), (2, 255)]\n"0201000000000000007f0200000000000000ff"\n</code></pre>\n<h2>Networking</h2>\n<h3>MessageName</h3>\n<pre><code class="language-haskell">newtype MessageName = MessageName BS.ByteString\n</code></pre>\n<p><a href="https://github.com/serokell/time-warp-nt/blob/f5500cb587eb2fbb02954b8d945985dbd0d51c0d/src/Node/Message.hs#L44">Source code\nlink</a>.</p>\n<p>Generally, we use <code>MessageName</code> represented by one or two encoded\n<code>UnsignedVarInt</code>s. At serialization state it is encoded as binary string, thus\ngets prefixed by length of the string.</p>\n<p>Example:</p>\n<pre><code>ghci> hexEncode $ messageName (Proxy :: Proxy SendProxySK)\n"0102"\nghci> hexEncode $ messageName (Proxy :: Proxy (DataMsg GtMsgContents))\n"020a03"\n</code></pre>\n<h2>Basic Cardano SL Data Types</h2>\n<h3>Coin</h3>\n<pre><code class="language-haskell">-- | Coin is the least possible unit of currency.\nnewtype Coin = Coin\n    { getCoin :: Word64\n    } deriving (Show, Ord, Eq, Generic, Hashable, Data, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L391">Source code\nlink</a>.</p>\n<p>Number of total coins is <a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L404">45 * 10^9 *\n10^6</a>.</p>\n<pre><code>45*10^15 needs 56 bits to represent\n45*10^9  (integral mega coins) needs 36 bits to represent\n999999   (floating mega coins) needs 20 bits to represent\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>Decimal</th>\n<th>Needed Bits</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0-9</td>\n<td>4 bits</td>\n</tr>\n<tr>\n<td>0-99</td>\n<td>7 bits</td>\n</tr>\n<tr>\n<td>0-999</td>\n<td>10 bits</td>\n</tr>\n<tr>\n<td>0-9999</td>\n<td>14 bits</td>\n</tr>\n<tr>\n<td>0-99999</td>\n<td>17 bits</td>\n</tr>\n<tr>\n<td>0-999999</td>\n<td>20 bits</td>\n</tr>\n</tbody>\n</table>\n<p>Coin is splitted in mega coin (10^6) and the remaining coin for serialization.</p>\n<pre><code>1000999 coin = 1.000999 mega coin\n</code></pre>\n<p>Simple variant encoding with <code>Word64</code> limit. The total length of the sequence is\nencoded in the first byte with a variable mask.</p>\n<table>\n<thead>\n<tr>\n<th>header</th>\n<th>mask</th>\n<th>spare bits</th>\n<th>extra byte</th>\n<th>total bits as value</th>\n<th>serialized size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0 xxxxxxx</td>\n<td>0x7f</td>\n<td>7 bits</td>\n<td>0</td>\n<td>7 bits</td>\n<td>1 byte</td>\n</tr>\n<tr>\n<td>10 xxxxxx</td>\n<td>0x3f</td>\n<td>6 bits</td>\n<td>1</td>\n<td>14 bits</td>\n<td>2 bytes</td>\n</tr>\n<tr>\n<td>110 xxxxx</td>\n<td>0x1f</td>\n<td>5 bits</td>\n<td>2</td>\n<td>21 bits</td>\n<td>3 bytes</td>\n</tr>\n<tr>\n<td>1110 xxxx</td>\n<td>0x0f</td>\n<td>4 bits</td>\n<td>3</td>\n<td>27 bits</td>\n<td>4 bytes</td>\n</tr>\n<tr>\n<td>11110 xxx</td>\n<td>0x07</td>\n<td>3 bits</td>\n<td>4</td>\n<td>35 bits</td>\n<td>5 bytes</td>\n</tr>\n<tr>\n<td>111110 xx</td>\n<td>0x03</td>\n<td>2 bits</td>\n<td>5</td>\n<td>42 bits</td>\n<td>6 bytes</td>\n</tr>\n<tr>\n<td>1111110 x</td>\n<td>0x01</td>\n<td>1 bit</td>\n<td>6</td>\n<td>49 bits</td>\n<td>7 bytes</td>\n</tr>\n<tr>\n<td>11111110</td>\n<td>0x00</td>\n<td>0 bit</td>\n<td>7</td>\n<td>56 bits</td>\n<td>8 bytes</td>\n</tr>\n<tr>\n<td>11111111</td>\n<td>0x00</td>\n<td>0 bit</td>\n<td>8</td>\n<td>64 bits</td>\n<td>9 bytes</td>\n</tr>\n</tbody>\n</table>\n<p>Specialized to the integral part which only needs 36 bits maximum:</p>\n<table>\n<thead>\n<tr>\n<th>header</th>\n<th>mask</th>\n<th>spare bits</th>\n<th>extra byte</th>\n<th>total bits as value</th>\n<th>serialized size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0 xxxxxxx</td>\n<td>0x7f</td>\n<td>7 bits</td>\n<td>0</td>\n<td>7 bits</td>\n<td>1 byte</td>\n</tr>\n<tr>\n<td>10 xxxxxx</td>\n<td>0x3f</td>\n<td>6 bits</td>\n<td>1</td>\n<td>14 bits</td>\n<td>2 bytes</td>\n</tr>\n<tr>\n<td>110 xxxxx</td>\n<td>0x1f</td>\n<td>5 bits</td>\n<td>2</td>\n<td>21 bits</td>\n<td>3 bytes</td>\n</tr>\n<tr>\n<td>1110 xxxx</td>\n<td>0x0f</td>\n<td>4 bits</td>\n<td>3</td>\n<td>27 bits</td>\n<td>4 bytes</td>\n</tr>\n<tr>\n<td>1111 xxxx</td>\n<td>0x0f</td>\n<td>4 bits</td>\n<td>4</td>\n<td>36 bits</td>\n<td>5 bytes</td>\n</tr>\n</tbody>\n</table>\n<p>And the floating part, needs 20 bits to represent, encoding value from 0 to\n999999:</p>\n<table>\n<thead>\n<tr>\n<th>header</th>\n<th>mask</th>\n<th>spare bits</th>\n<th>extra byte</th>\n<th>total bits as value</th>\n<th>serialized size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0 xxxxxx</td>\n<td>0x7f</td>\n<td>7 bits</td>\n<td>0</td>\n<td>7 bits</td>\n<td>1 byte</td>\n</tr>\n<tr>\n<td>10 xxxxxx</td>\n<td>0x3f</td>\n<td>6 bits</td>\n<td>1</td>\n<td>14 bits</td>\n<td>2 bytes</td>\n</tr>\n<tr>\n<td>110 xxxxx</td>\n<td>0x3f</td>\n<td>5 bits</td>\n<td>2</td>\n<td>21 bits</td>\n<td>3 bytes</td>\n</tr>\n</tbody>\n</table>\n<p>Note: we could save one bit in the 3 bytes scheme here by considering the end of\nencoding but we don\'t need it, so by not changing the scheme we can re-use the\nprevious scheme for integral as is.</p>\n<p>For details of implementations look at <a href="https://github.com/input-output-hk/cardano-sl/blob/1239a6a876fbbb970e836c8bc6bb72d781ba2fa9/core/Pos/Binary/Core/Coin.hs">this\nmodule</a>.</p>\n<p>Examples:</p>\n<pre><code>ghci> hexEncode (mkCoin 0)\n"0000"\nghci> hexEncode (mkCoin 1)\n"00c186a0"\nghci> hexEncode (mkCoin 2)\n"00c30d40"\nghci> hexEncode (mkCoin 31)\n"00c1fbd0"\nghci> hexEncode (mkCoin 128)\n"00cc8708"\nghci> hexEncode (mkCoin 129)\n"00ce0da8"\nghci> hexEncode (mkCoin 1000)\n"0064"\nghci> hexEncode (mkCoin 10000)\n"000a"\nghci> hexEncode (mkCoin 1000000)\n"0100"\nghci> hexEncode (mkCoin 1000999)\n"01cf3e58"\n</code></pre>\n<h3>Hash</h3>\n<pre><code class="language-haskell">-- | Hash wrapper with phantom type for more type-safety.\n-- Made abstract in order to support different algorithms in\n-- different situations\nnewtype AbstractHash algo a = AbstractHash (Digest algo)\n    deriving (Show, Eq, Ord, ByteArray.ByteArrayAccess, Generic, NFData)\n\n-- | Type alias for commonly used hash\ntype Hash = AbstractHash Blake2b_256\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/652411b9b8777f08e948ee144a60779c55f363b3/core/Pos/Crypto/Hashing.hs#L118">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td>Word8\n[\n32\n]</td>\n<td>256 bits of hash digest</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limit: 32.</p>\n<p>So whenever you see <code>Hash SomeType</code> in the code, this field will occupy 32\nbytes. An additional type parameter after <code>Hash</code> is used only in code for\ntype-safety and has no impact on serialization.</p>\n<p>Example:</p>\n<pre><code>ghci> hash $ mkCoin 3\nAbstractHash 29bcdcff253cd2864a8b5e25992a6db86a7a41dc5e69c0599730f2c5716d9362\nghci> hexEncode $ hash $ mkCoin 3\n"29bcdcff253cd2864a8b5e25992a6db86a7a41dc5e69c0599730f2c5716d9362"\n</code></pre>\n<h3>Public Key</h3>\n<pre><code class="language-haskell">-- | Wrapper around \'CC.XPub\'.\nnewtype PublicKey = PublicKey CC.XPub\n    deriving (Eq, Ord, Show, Generic, NFData, Hashable, Typeable)\n\ndata XPub = XPub !Edwards25519.PointCompressed !ChainCode\n    deriving (Eq, Ord, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L70">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td>ByteString</td>\n<td>32-byte PointCompressed</td>\n</tr>\n<tr>\n<td>32</td>\n<td>ByteString</td>\n<td>32-byte ChainCode</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limit: 64.</p>\n<h3>Signature</h3>\n<pre><code class="language-haskell">-- | Wrapper around \'CC.XSignature\'.\nnewtype Signature a = Signature CC.XSignature\n    deriving (Eq, Ord, Show, Generic, NFData, Hashable, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L149">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>64</td>\n<td>Word8\n[\n64\n]</td>\n<td>64 bytes of signature string</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limit: 64.</p>\n<h3>Epoch Index</h3>\n<pre><code class="language-haskell">-- | Index of epoch.\nnewtype EpochIndex = EpochIndex\n    { getEpochIndex :: Word64\n    } deriving (Show, Eq, Ord, Num, Enum, Ix, Integral, Real, Generic, Hashable, Bounded, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L342">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>epoch index</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limit: 10.</p>\n<p>Example:</p>\n<pre><code>ghci> hexEncode (EpochIndex 128)\n"8001"\n</code></pre>\n<h3>Local Slot Index</h3>\n<pre><code class="language-haskell">-- | Index of slot inside a concrete epoch.\nnewtype LocalSlotIndex = LocalSlotIndex\n    { getSlotIndex :: Word16\n    } deriving (Show, Eq, Ord, Ix, Generic, Hashable, Buildable, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L353">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-3</td>\n<td>UVarInt Word16</td>\n<td>index of local slot</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode (LocalSlotIndex 15)\n"0f"\n</code></pre>\n<h3>SlotId</h3>\n<pre><code class="language-haskell">-- | Slot is identified by index of epoch and local index of slot in\n-- this epoch. This is a global index\ndata SlotId = SlotId\n    { siEpoch :: !EpochIndex\n    , siSlot  :: !LocalSlotIndex\n    } deriving (Show, Eq, Ord, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L377">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>Epoch index</td>\n</tr>\n<tr>\n<td>1-3</td>\n<td>UVarInt Word16</td>\n<td>Slot index inside a concrete epoch</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode (SlotId 128 15)\n"80010f"\n</code></pre>\n<h3>Attributes</h3>\n<pre><code class="language-haskell">-- | Convenient wrapper for the datatype to represent it (in binary\n-- format) as k-v map.\ndata Attributes h = Attributes\n    { -- | Data, containing known keys (deserialized)\n      attrData   :: h\n      -- | Remaining, unparsed fields\n    , attrRemain :: UnparsedFields\n    }\n  deriving (Eq, Ord, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Data/Attributes.hs#L60">Source code\nlink</a></p>\n<pre><code class="language-haskell">-- | Representation of unparsed fields in Attributes. Newtype wrapper is used\n-- for clear backward compatibility between previous representation (which was\n-- just a single ByteString) during transition from Store to CBOR.\nnewtype UnparsedFields = UnparsedFields (Map Word8 ByteString)\n    deriving (Eq, Ord, Show, Generic, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Data/Attributes.hs#L34">Source code\nlink</a></p>\n<p>Message size limit: each type with <code>Attributes</code> defines its own limit for them.</p>\n<h4>General Case Serialization</h4>\n<p>Stored as <code>totalLen + (k, v) pairs + some remaining part</code>. <code>attrData</code> is stored\nas list of pairs <code>(Word8, v)</code> where <code>key</code> has type <code>Word8</code> and you should\nspecify how to encode <code>h</code> in that way.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int64</td>\n<td>m + n</td>\n<td>Size of attributes in bytes</td>\n</tr>\n<tr>\n<td>m = t \n*\n (1 + size(v))</td>\n<td>&#x3C;Word8,v>\n[\nt\n]</td>\n<td></td>\n<td>Array of pairs. Given without length.</td>\n</tr>\n<tr>\n<td>n</td>\n<td>ByteString</td>\n<td></td>\n<td>Remaining byte array</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> toLazyByteString\n      $ lazyByteStringHex\n      $ runPut\n      $ putAttributes (\\h -> [(1, put h), (0, put h)])\n      $ Attributes (9 :: Word32) "abc"\n"0d0000000009010000000961626"\n</code></pre>\n<p>Here <code>h = 9 :: Word32</code> and we encode <code>h</code> as two <em>key-value</em> pairs: value is\n4-byte <code>9</code> and keys are <code>0</code> and <code>1</code>.</p>\n<h4>Attributes ()</h4>\n<p>In this special case no <code>(key, value)</code> pairs are stored — only arbitrary length\nbyte array.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-4</td>\n<td>UVarInt Int64</td>\n<td>n</td>\n<td>Size of attributes in bytes. Should be \n&#x3C;\n 2^28</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td><code>n</code>\n bytes of data</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode $ Attributes () (BSS.pack [])\n"00"\nghci> hexEncode $ Attributes () (BSS.pack [1,31])\n"02011f"\nghci> hexEncode $ Attributes () "abc"\n"03616263"\n</code></pre>\n<h3>Script</h3>\n<pre><code class="language-haskell">-- | Version of script\ntype ScriptVersion = Word16\n\n-- | A script for inclusion into a transaction.\ndata Script = Script {\n    scrVersion :: ScriptVersion,    -- ^ Version\n    scrScript  :: LByteString}      -- ^ Serialized script\n  deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L424">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-3</td>\n<td>UVarInt Word16</td>\n<td></td>\n<td>Script version</td>\n</tr>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int64</td>\n<td>n</td>\n<td>Size of byte array</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td>n bytes of script</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode $ Script 0 "a"\n"000161"\n</code></pre>\n<h3>Address Attributes</h3>\n<pre><code class="language-haskell">-- | Additional information stored along with address. It\'s intended\n-- to be put into \'Attributes\' data type to make it extensible with\n-- softfork.\ndata AddrAttributes = AddrAttributes\n    { aaPkDerivationPath  :: !(Maybe HDAddressPayload)\n    , aaStakeDistribution :: !AddrStakeDistribution\n    } deriving (Eq, Ord, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L199">Source code\nlink</a></p>\n<p>Address attributes hold additional information about address:</p>\n<ul>\n<li>encrypted derivation path from the root of HD wallet tree (<code>aaPkDerivationPath</code>)</li>\n<li>stake distribution associated with this address (<code>aaStakeDistribution</code>)</li>\n</ul>\n<p>Note that address may not contain an encrypted derivation path. Addresses\nwithout derivation path included in the attributes are usually derived from\nlevel 0 (wallet) public keys and used as IDs for wallets. Such addresses are not\nmeant to contain any money.</p>\n<h4>Address Payload</h4>\n<pre><code class="language-haskell">data HDAddressPayload = HDAddressPayload !ByteString\n    deriving (Eq, Ord, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Crypto/HD.hs#L50">Source code\nlink</a></p>\n<p><code>HDAddressPayload</code> datatype represents a derivation path (<code>[Word32]</code>),\nsymmetrically encrypted via <code>ChaChaPoly1305</code> algorithm. An encryption key may be\nany <code>ByteString</code> of 32 bytes, known only to owner of the address.</p>\n<p>In current Cardano implementation, encryption key is a 32-byte key derived from\nroot public key of wallet using PBKDF2 derivation algorithm with HMAC-SHA512 as\npseudorandom function, 500 iterations and string <code>address-hashing</code> as a salt.\n<a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Crypto/HD.hs#L58">Source code link</a></p>\n<p>Address attributes are encrypted with crypto tag, thus allowing to check whether\nor not attributes are decrypted successfully. Consequently, one can determine\nwhether or not given address belongs to a given wallet by trying to decrypt this\naddress\' attributes using encryption key derived from wallet\'s root public key.\n<a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Crypto/HD.hs#L113">Source code link</a>\nto helper functions which implement attributes decryption and encryption.</p>\n<h4>Address Stake Distribution</h4>\n<pre><code class="language-haskell">-- | Stake distribution associated with an address.\ndata AddrStakeDistribution\n    = BootstrapEraDistr\n    -- ^ Stake distribution for bootstrap era.\n    | SingleKeyDistr !StakeholderId\n    -- ^ Stake distribution stating that all stake should go to the given stakeholder.\n    | UnsafeMultiKeyDistr !(Map StakeholderId CoinPortion)\n    -- ^ Stake distribution which gives stake to multiple\n    -- stakeholders. \'CoinPortion\' is a portion of an output (output\n    -- has a value, portion of this value is stake). The constructor\n    -- is unsafe because there are some predicates which must hold:\n    --\n    -- • the sum of portions must be @maxBound@ (basically 1);\n    -- • all portions must be positive;\n    -- • there must be at least 2 items, because if there is only one item,\n    -- \'SingleKeyDistr\' can be used instead (which is smaller).\n    deriving (Eq, Ord, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L137">Source code\nlink</a></p>\n<p>In Byron era, all addresses should use <code>BootstrapEraDistr</code> as stake\ndistribution -- which means, all the stake is automatically delegated to\nbootstrap stakeholders.</p>\n<p>In Shelley era, addresses will use <code>SingleKeyDistr</code> or <code>UnsafeMultiKeyDistr</code> to\ndelegate stake associated with address\' balance to their own stakeholder IDs.</p>\n<!-- | Size | Type                      | Value | Description                                             | -->\n<!-- |------|---------------------------|-------|---------------------------------------------------------| -->\n<!-- | 1-2  | TinyVarInt                | n + m | sise of `PubKeyAddress` content                         | -->\n<!-- | n    | Maybe (Word8, \\[Word32\\]) |       | Empty for nothing and list of Word32 preceded with zero | -->\n<!-- | m    | ByteString                |       | Remaining bytes                                         | -->\n<!-- See examples in the next section. -->\n<h3>Address</h3>\n<pre><code class="language-haskell">-- | Hash used to identify address.\ntype AddressHash = AbstractHash Blake2b_224\n\n-- | Stakeholder identifier (stakeholders are identified by their public keys)\ntype StakeholderId = AddressHash PublicKey\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L123">Source code\nlink</a></p>\n<p>Cardano addresses use <code>blake2b-224</code> for hashes included in address structure.</p>\n<pre><code class="language-haskell">-- | Data which is bound to an address and must be revealed in order\n-- to spend coins belonging to this address.\ndata AddrSpendingData\n    = PubKeyASD !PublicKey\n    -- ^ Funds can be spent by revealing a \'PublicKey\' and providing a\n    -- valid signature.\n    | ScriptASD !Script\n    -- ^ Funds can be spent by revealing a \'Script\' and providing a\n    -- redeemer \'Script\'.\n    | RedeemASD !RedeemPublicKey\n    -- ^ Funds can be spent by revealing a \'RedeemScript\' and providing a\n    -- valid signature.\n    | UnknownASD !Word8 !ByteString\n    -- ^ Unknown type of spending data. It consists of a tag and\n    -- arbitrary \'ByteString\'. It allows us to introduce a new type of\n    -- spending data via softfork.\n    deriving (Eq, Generic, Typeable, Show)\n\n-- | Type of an address. It corresponds to constructors of\n-- \'AddrSpendingData\'. It\'s separated, because \'Address\' doesn\'t store\n-- \'AddrSpendingData\', but we want to know its type.\ndata AddrType\n    = ATPubKey\n    | ATScript\n    | ATRedeem\n    | ATUnknown !Word8\n    deriving (Eq, Ord, Generic, Typeable, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L137">Source code\nlink</a> </p>\n<p>Cardano supports different address types. Address types differ in how funds\nbelonging to the address can be spent. Each address type have corresponding type\nof spending data. Spending data is a part of data which is hashed in order to\nmake the address. Spending data, together with verification data (e.g. a\nsignature) should be provided in <code>TxInWitness</code> in order to spend funds from address.</p>\n<p>Currently Cardano supports 3 address types:</p>\n<ul>\n<li>Public key address (<code>ATPublicKey</code>): extended Ed25519 public key as spending\ndata, corresponding Ed25519 signature as verification data. </li>\n<li>Script address (<code>ATScript</code>): Plutus validator script as spending data, Plutus\nredeemer script as verification data.</li>\n<li>Redeem address (<code>ATRedeem</code>): plain Ed25519 public key as spending data,\nEd25519 signature as verification data. Used only in genesis to provide\npre-sold ADA to holders.</li>\n</ul>\n<p>Also there is special <code>ATUnknown</code> address type added for forward compatibility.</p>\n<pre><code class="language-haskell">-- | Hash of this data is stored in \'Address\'. This type exists mostly\n-- for internal usage.\nnewtype Address\' = Address\'\n    { unAddress\' :: (AddrType, AddrSpendingData, Attributes AddrAttributes)\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L206">Source code\nlink</a></p>\n<p>Internal type <code>Address\'</code> denotes a tuple, hash of which is stored as a part of\nthe <code>Address</code>. Not only <code>AddrSpendingData</code> is hashed, but also <code>AddrType</code> and\n<code>AddrAttributes</code>.</p>\n<pre><code class="language-haskell">-- | \'Address\' is where you can send coins.\ndata Address = Address\n    { addrRoot       :: !(AddressHash Address\')\n    -- ^ Root of imaginary pseudo Merkle tree stored in this address.\n    , addrAttributes :: !(Attributes AddrAttributes)\n    -- ^ Attributes associated with this address.\n    , addrType       :: !AddrType\n    -- ^ The type of this address. Should correspond to\n    -- \'AddrSpendingData\', but it can\'t be checked statically, because\n    -- spending data is hashed.\n    } deriving (Eq, Ord, Generic, Typeable, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/524bb4d6d6620bec7e269e33de1154d2b1be5183/core/Pos/Core/Types.hs#L211">Source code link</a></p>\n<p>An <code>Address</code> datatype consists of blake2b-224 hash of <code>Address\'</code> tuple, type tag\nand attributes.</p>\n<h4>Public Key Address</h4>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L107"><code>addrPkAttributes</code></a>\nfield is required for HD-wallets.</p>\n<table>\n<thead>\n<tr>\n<th>Size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td><code>PubKeyAddress</code>\n tag</td>\n</tr>\n<tr>\n<td>1-2</td>\n<td>TinyVarInt</td>\n<td>28 + m</td>\n<td>Size of \n<code>PubKeyAddress</code>\n content</td>\n</tr>\n<tr>\n<td>28</td>\n<td>Word8\n[\n28\n]</td>\n<td></td>\n<td><code>addKeyHash</code>\n: 28 bytes of Blake2b\n_\n224 hash</td>\n</tr>\n<tr>\n<td>m</td>\n<td>PubKeyAddressAttributes</td>\n<td></td>\n<td><code>addrPkAttributes</code></td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td></td>\n<td>CRC32 of all previous data</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> abstractHash somPk :: AddressHash PublicKey\nAbstractHash 380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e0\nghci> hexEncode $ PubKeyAddress (abstractHash somePk) (Attributes (AddrPkAttrs Nothing) "a")\n"001e380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00161cf52c5ec"\nghci> hexEncode $ PubKeyAddress (abstractHash somePk) (Attributes (AddrPkAttrs $ Just [3,9]) "a")\n"0028380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00b0002000000030000000961f1d810f7"\n</code></pre>\n<p>You can notice in first example, that <code>0xCF52C5EC</code> is CRC32 of\n<code>001e380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00161</code>.</p>\n<h4>Script Address</h4>\n<table>\n<thead>\n<tr>\n<th>Size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x01</td>\n<td><code>ScriptAddress</code>\n tag</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x1C</td>\n<td>Size of \n<code>addrScriptHash</code>\n: always 28</td>\n</tr>\n<tr>\n<td>28</td>\n<td>Word8\n[\n28\n]</td>\n<td></td>\n<td>28 bytes of Blake2b\n_\n224 hash</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td></td>\n<td>CRC32 of all previous data</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> hexEncode $ ScriptAddress (abstractHash $ Script 0 "a")\n"011c7ec20301993e369571c6225e1e563812198433801820a2d7328756dc61c5be8e"\n</code></pre>\n<p>As you can notice, 4-byte suffix <code>0x61c5be8e</code> is CRC32 of prefix:\n<code>011c7ec20301993e369571c6225e1e563812198433801820a2d7328756dc</code>.</p>\n<h4>Unknown Address</h4>\n<table>\n<thead>\n<tr>\n<th>Size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td></td>\n<td>t</td>\n<td><code>UnknownAddress</code>\n tag</td>\n</tr>\n<tr>\n<td>1-2</td>\n<td>TinyVarInt</td>\n<td>n</td>\n<td>Size of unknown address</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td>Unknown address itself</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td></td>\n<td>CRC32 of all previous data</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<p>Let\'s encode <code>UnknownAddressType 3 "a"</code>. Without CRC32 this will be encoded as\n<code>0x030161</code>. CRC32 of <code>0x030161</code> is <code>0xDEA907C4</code>. Thus we have:</p>\n<pre><code>ghci> hexEncode $ UnknownAddressType 3 "a"\n"030161dea907c4"\n</code></pre>\n<h3>MerkleRoot</h3>\n<pre><code class="language-haskell">-- | Data type for root of merkle tree.\nnewtype MerkleRoot a = MerkleRoot\n    { getMerkleRoot :: Hash Raw  -- ^ returns root \'Hash\' of Merkle Tree\n    } deriving (Show, Eq, Ord, Generic, ByteArrayAccess, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/214e7ac54fbb57007e18fdab4d274340371f2d19/core/Pos/Merkle.hs#L28">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Root hash of Merkle tree</td>\n</tr>\n</tbody>\n</table>\n<h3>Chain Difficulty</h3>\n<pre><code class="language-haskell">-- | Chain difficulty represents necessary effort to generate a\n-- chain. In the simplest case it can be number of blocks in chain.\nnewtype ChainDifficulty = ChainDifficulty\n    { getChainDifficulty :: Word64\n    } deriving (Show, Eq, Ord, Num, Enum, Real, Integral, Generic, Buildable, Typeable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L135">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>Chain difficulty</td>\n</tr>\n</tbody>\n</table>\n<h3>SlotLeaders</h3>\n<pre><code>-- | \'NonEmpty\' list of slot leaders.\ntype SlotLeaders = NonEmpty StakeholderId\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L264">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Size of slot leaders list</td>\n</tr>\n<tr>\n<td>n \n*\n size(StakeholderId)</td>\n<td>StakeholderId\n[\nn\n]</td>\n<td></td>\n<td>List of slot leaders of size n</td>\n</tr>\n</tbody>\n</table>\n<h2>GodTossing</h2>\n<h3>Crypto.PVSS</h3>\n<p>Types prefixed with Pvss are defined in\n<a href="https://hackage.haskell.org/package/pvss-0.1/docs/Crypto-PVSS.html">Crypto.PVSS</a>\nmodule. This section describes binary format of these types.</p>\n<h4>Point</h4>\n<pre><code class="language-haskell">newtype Point = Point { unPoint :: SSL.EcPoint }\n    deriving (Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/31bc53aa861bd4cae8f6741247e849299eae3983/src/Crypto/PVSS/ECC.hs#L92">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>33</td>\n<td>ByteString</td>\n<td>Binary represented elliptic curve point (see ecPointFromOct function)</td>\n</tr>\n</tbody>\n</table>\n<h4>Secret</h4>\n<pre><code class="language-haskell">-- | Secret\nnewtype Secret = Secret Point\n    deriving (Show,Eq,NFData,Binary)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/670ce35d0f4a11aeb9617de4df2992c23f30573d/src/Crypto/SCRAPE.hs#L78">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Secret</td>\n</tr>\n</tbody>\n</table>\n<h4>Proof</h4>\n<pre><code class="language-haskell">newtype Scalar = Scalar { unScalar :: Integer }\n    deriving (Show,Eq,Generic,NFData)\n\nnewtype Challenge = Challenge ByteString\n    deriving (Show,Eq,NFData)\n\n-- | The generated proof\ndata Proof = Proof\n    { proof_c :: !Challenge\n    , proof_z :: !Scalar\n    } deriving (Show,Eq,Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/31bc53aa861bd4cae8f6741247e849299eae3983/src/Crypto/PVSS/DLEQ.hs#L39">Source code\nlink</a>.\n<code>Scalar</code> <a href="https://github.com/input-output-hk/pvss-haskell/blob/31bc53aa861bd4cae8f6741247e849299eae3983/src/Crypto/PVSS/ECC.hs#L110">source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td>ByteString</td>\n<td>32-byte string challenge</td>\n</tr>\n<tr>\n<td>32</td>\n<td>Integer</td>\n<td>32-byte integer scalar</td>\n</tr>\n</tbody>\n</table>\n<h4>DecryptedShare</h4>\n<pre><code class="language-haskell">-- | An decrypted share decrypted by a party\'s key and\ndata DecryptedShare = DecryptedShare\n    { decryptedShareID    :: !ShareId\n    , shareDecryptedVal   :: !Point      -- ^ decrypted share\n    , decryptedValidProof :: !DLEQ.Proof -- ^ proof the decryption is valid\n    } deriving (Show,Eq,Generic)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>32</td>\n<td>Integer</td>\n<td>Share id</td>\n</tr>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Decrypted share</td>\n</tr>\n<tr>\n<td>size(Proof)</td>\n<td>Proof</td>\n<td>Proof the description is valid</td>\n</tr>\n</tbody>\n</table>\n<h4>ExtraGen</h4>\n<pre><code class="language-haskell">-- | Extra generator\nnewtype ExtraGen = ExtraGen Point\n    deriving (Show,Eq,NFData,Binary)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/670ce35d0f4a11aeb9617de4df2992c23f30573d/src/Crypto/PVSS.hs#L82">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Extra generator</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limit: 33.</p>\n<h4>Commitment</h4>\n<pre><code class="language-haskell">newtype Commitment = Commitment { unCommitment :: Point }\n    deriving (Show,Eq,NFData,Binary)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/670ce35d0f4a11aeb9617de4df2992c23f30573d/src/Crypto/PVSS.hs#L69">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Commitment</td>\n</tr>\n</tbody>\n</table>\n<h4>PublicKey</h4>\n<pre><code class="language-haskell">-- | Public Key\nnewtype PublicKey = PublicKey Point\n    deriving (Show,Eq,NFData,Binary)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/pvss-haskell/blob/31bc53aa861bd4cae8f6741247e849299eae3983/src/Crypto/PVSS/ECC.hs#L84">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Point)</td>\n<td>Point</td>\n<td>Public key</td>\n</tr>\n</tbody>\n</table>\n<h3>Secret Sharing</h3>\n<p>Most of following types are just aliases for PVSS types, so they are serialized\nin the same way.</p>\n<pre><code class="language-haskell">-- | Secret can be generated by `genSharedSecret` function along with shares.\nnewtype Secret = Secret\n    { getSecret :: Pvss.Secret\n    } deriving (Show, Eq)\n\n-- | Shares can be used to reconstruct Secret.\nnewtype Share = Share\n    { getShare :: Pvss.DecryptedShare\n    } deriving (Show, Eq)\n\n-- | Encrypted share which needs to be decrypted using VssKeyPair first.\nnewtype EncShare = EncShare\n    { getEncShare :: Pvss.EncryptedShare\n    } deriving (Show, Eq)\n\n-- | This extra data may be used to verify encrypted share.\ndata SecretSharingExtra =\n    SecretSharingExtra !Pvss.ExtraGen\n                       ![Pvss.Commitment]\n    deriving (Show, Eq, Generic)\n\n-- | SecretProof may be used to commit Secret without revealing it.\nnewtype SecretProof =\n    SecretProof Pvss.Proof\n    deriving (Show, Eq, Generic)\n\n-- | This key is used as public key in VSS.\nnewtype VssPublicKey = VssPublicKey\n    { getVssPublicKey :: Pvss.PublicKey\n    } deriving (Show, Eq)\n</code></pre>\n<p>Format of SecretSharingExtra:</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(ExtraGen)</td>\n<td>Pvss.ExtraGen</td>\n<td></td>\n<td>Extra generator</td>\n</tr>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Length of commitments list</td>\n</tr>\n<tr>\n<td>n \n*\n size(Pvss.Commitment)</td>\n<td>[\nPvss.Commitment\n]</td>\n<td></td>\n<td>Commitments</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limits: </p>\n<ul>\n<li><code>Share</code> - 101.</li>\n<li><code>EncShare</code> - 101.</li>\n<li><code>SecretProof</code> - 64.</li>\n<li><code>VssPublicKey</code> - 33.</li>\n</ul>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/69dd4b2d0c56474db1059393336557fb649dba9a/core/Pos/Crypto/SecretSharing.hs">Source code\nlink</a>.</p>\n<h3>Commitments, Openings and Shares</h3>\n<h4>Commitment</h4>\n<pre><code class="language-haskell">-- | Commitment is a message generated during the first stage of\n-- GodTossing. It contains encrypted shares and proof of secret.\n-- Invariant which must be ensured: commShares is not empty.\ndata Commitment = Commitment\n    { commExtra  :: !(AsBinary SecretSharingExtra)\n    , commProof  :: !(AsBinary SecretProof)\n    , commShares :: !(HashMap (AsBinary VssPublicKey) (NonEmpty (AsBinary EncShare)))\n    } deriving (Show, Eq, Generic)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td></td>\n</tr>\n<tr>\n<td>n \n*\n (sizeof(VssPublicKey) + sizeof(EncShare))</td>\n<td>HashMapCommShares</td>\n<td></td>\n<td>commShares</td>\n</tr>\n<tr>\n<td>sizeof(SecretSharingExtra)</td>\n<td>AsBinary SecretSharingExtra</td>\n<td></td>\n<td>commExtra</td>\n</tr>\n<tr>\n<td>sizeof(SecretProof)</td>\n<td>AsBinary SecretProof</td>\n<td></td>\n<td>commProof</td>\n</tr>\n</tbody>\n</table>\n<p>where <code>HashMapCommShares</code> =\n<code>HashMap (AsBinary VssPublicKey) (NonEmpty (AsBinary EncShare))</code></p>\n<p>Message size limit: 33.</p>\n<h4>CommitmentSignature</h4>\n<pre><code class="language-haskell">-- | Signature which ensures that commitment was generated by node\n-- with given public key for given epoch.\ntype CommitmentSignature = Signature (EpochIndex, Commitment)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L73">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Signature)</td>\n<td>Signature (EpochIndex, Commitment)</td>\n<td>Signature which ensures that commitment was generated by node with given public key for given epoch</td>\n</tr>\n</tbody>\n</table>\n<h4>SignedCommitment</h4>\n<pre><code class="language-haskell">type SignedCommitment = (PublicKey, Commitment, CommitmentSignature)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L75">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>Public key of node that generated this commitment</td>\n</tr>\n<tr>\n<td>size(Commitment)</td>\n<td>Commitment</td>\n<td>Commitment</td>\n</tr>\n<tr>\n<td>size(CommitmentSignature)</td>\n<td>CommitmentSignature</td>\n<td>Commitment signature</td>\n</tr>\n</tbody>\n</table>\n<h4>CommitmentsMap</h4>\n<pre><code class="language-haskell">-- | \'CommitmentsMap\' is a wrapper for \'HashMap StakeholderId SignedCommitment\'\n-- which ensures that keys are consistent with values, i. e. \'PublicKey\'\n-- from \'SignedCommitment\' corresponds to key which is \'StakeholderId\'.\nnewtype CommitmentsMap = CommitmentsMap\n    { getCommitmentsMap :: HashMap StakeholderId SignedCommitment\n    } deriving (Semigroup, Monoid, Show, Eq, Container, NFData)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of commitments in map</td>\n</tr>\n<tr>\n<td>n * (size(StakeholderId) + size(SignedCommitment))</td>\n<td>HashMap StakeholderId SignedCommitment</td>\n<td></td>\n<td>Commitments map as list of pairs</td>\n</tr>\n</tbody>\n</table>\n<h4>Opening</h4>\n<pre><code class="language-haskell">-- | Opening reveals secret.\nnewtype Opening = Opening\n    { getOpening :: (AsBinary Secret)\n    } deriving (Show, Eq, Generic, Buildable, NFData)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L102">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Secret)</td>\n<td>AsBinary Secret</td>\n<td>Revealed secret</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limit: 33.</p>\n<h4>OpeningsMap</h4>\n<pre><code class="language-haskell">type OpeningsMap = HashMap StakeholderId Opening\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L106">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of openings in map</td>\n</tr>\n<tr>\n<td>n * (size(StakeholderId) + size(Opening))</td>\n<td>HashMap StakeholderId Opening</td>\n<td></td>\n<td>Openings map as list of pairs</td>\n</tr>\n</tbody>\n</table>\n<h4>VssCertificate</h4>\n<pre><code class="language-haskell">-- | VssCertificate allows VssPublicKey to participate in MPC.\n-- Each stakeholder should create a Vss keypair, sign VSS public key with signing\n-- key and send it into blockchain.\n--\n-- A public key of node is included in certificate in order to\n-- enable validation of it using only node\'s P2PKH address.\n-- Expiry epoch is last epoch when certificate is valid, expiry epoch is included\n-- in certificate and signature.\n--\n-- Other nodes accept this certificate if it is valid and if node has\n-- enough stake.\n--\n-- Invariant: \'checkSig vcSigningKey (vcVssKey, vcExpiryEpoch) vcSignature\'.\ndata VssCertificate = VssCertificate\n    { vcVssKey      :: !(AsBinary VssPublicKey)\n    , vcExpiryEpoch :: !EpochIndex\n    -- ^ Epoch up to which certificates is valid.\n    , vcSignature   :: !(Signature (AsBinary VssPublicKey, EpochIndex))\n    , vcSigningKey  :: !PublicKey\n    } deriving (Show, Eq, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/3a6ac3c5aa8d3ca87d8b409d5923e21b744b1e6b/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L149">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(VssPublicKey)</td>\n<td>AsBinary VssPublicKey</td>\n<td>Public key of stakeholder which is allowed to participate in MPC</td>\n</tr>\n<tr>\n<td>size(EpochIndex)</td>\n<td>EpochIndex</td>\n<td>Last epoch when certificate is valid</td>\n</tr>\n<tr>\n<td>size(Signature)</td>\n<td>Signature (AsBinary VssPublicKey, EpochIndex)</td>\n<td>Signature</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>Signing key</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limit: 171.</p>\n<h4>VssCertificatesMap</h4>\n<pre><code class="language-haskell">-- | VssCertificatesMap contains all valid certificates collected\n-- during some period of time.\ntype VssCertificatesMap = HashMap StakeholderId VssCertificate\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/3a6ac3c5aa8d3ca87d8b409d5923e21b744b1e6b/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L211">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of certificates in map</td>\n</tr>\n<tr>\n<td>n * (size(StakeholderId) + size(VssCertificate))</td>\n<td>HashMap StakeholderId VssCertificate</td>\n<td></td>\n<td>Vss certificates map as list of pairs</td>\n</tr>\n</tbody>\n</table>\n<h3>TxProof</h3>\n<pre><code class="language-haskell">data TxProof = TxProof\n    { txpNumber            :: !Word32\n    , txpRoot              :: !(MerkleRoot Tx)\n    , txpWitnessesHash     :: !(Hash [TxWitness])\n    , txpDistributionsHash :: !(Hash [TxDistribution])\n    } deriving (Show, Eq, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/txp/Pos/Txp/Core/Types.hs#L262">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td>Tx proof number</td>\n</tr>\n<tr>\n<td>size(MerkleRoot)</td>\n<td>MerkleRoot Tx</td>\n<td>MerkleRoot</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Hash of the list of \n<code>TxWitness</code></td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Hash of the list of \n<code>TxDistribution</code></td>\n</tr>\n</tbody>\n</table>\n<h3>GtProof</h3>\n<pre><code class="language-haskell">-- | Proof of MpcData.\n-- We can use ADS for commitments, openings, shares as well,\n-- if we find it necessary.\ndata GtProof\n    = CommitmentsProof !(Hash CommitmentsMap) !(Hash VssCertificatesMap)\n    | OpeningsProof !(Hash OpeningsMap) !(Hash VssCertificatesMap)\n    | SharesProof !(Hash SharesMap) !(Hash VssCertificatesMap)\n    | CertificatesProof !(Hash VssCertificatesMap)\n    deriving (Show, Eq, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/1bab05d8a199ed6e9af066d4994ef13abdb95da7/godtossing/Pos/Ssc/GodTossing/Core/Types.hs#L232">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Tag size</th>\n<th>Tag Type</th>\n<th>Tag Value</th>\n<th>Description</th>\n<th>Field size</th>\n<th>Field Type</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for CommitmentsProof</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for OpeningsProof</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x02</td>\n<td>Tag for SharesProof</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x03</td>\n<td>Tag for CertificatesProof</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Hash)</td>\n<td>Hash</td>\n</tr>\n</tbody>\n</table>\n<h2>Block Headers</h2>\n<h3>BlockVersion</h3>\n<pre><code class="language-haskell">-- | Communication protocol version.\ndata BlockVersion = BlockVersion\n    { bvMajor :: !Word16\n    , bvMinor :: !Word16\n    , bvAlt   :: !Word8\n    } deriving (Eq, Generic, Ord, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L144">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>2</td>\n<td>Word16</td>\n<td>Major version</td>\n</tr>\n<tr>\n<td>2</td>\n<td>Word16</td>\n<td>Minor version</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>Alt version from initial US spec</td>\n</tr>\n</tbody>\n</table>\n<h3>SoftwareVersion</h3>\n<pre><code class="language-haskell">newtype ApplicationName = ApplicationName\n    { getApplicationName :: Text\n    } deriving (Eq, Ord, Show, Generic, Typeable, ToString, Hashable, Buildable, NFData)\n\n-- | Numeric software version associated with ApplicationName.\ntype NumSoftwareVersion = Word32\n\n-- | Software version.\ndata SoftwareVersion = SoftwareVersion\n    { svAppName :: !ApplicationName\n    , svNumber  :: !NumSoftwareVersion\n    } deriving (Eq, Generic, Ord, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L170">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Length of application name (should be \n&#x3C;\n= 10)</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td><code>svAppName</code>\n: UTF8 encoded application name</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td></td>\n<td><code>svNumber</code></td>\n</tr>\n</tbody>\n</table>\n<h3>MainBlockHeader</h3>\n<!-- TODO: Replace all Main* and Genesis* by type (*Blockchain) -->\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td>Protocol magic</td>\n</tr>\n<tr>\n<td>size(HeaderHash)</td>\n<td>HeaderHash</td>\n<td>Previous block hash</td>\n</tr>\n<tr>\n<td>size(MainProof)</td>\n<td>MainProof</td>\n<td>Body proof</td>\n</tr>\n<tr>\n<td>size(MainConsensusData)</td>\n<td>MainConsensusData</td>\n<td>Consensus data</td>\n</tr>\n<tr>\n<td>size(MainExtraHeaderData)</td>\n<td>MainExtraHeaderData</td>\n<td>MainExtraHeaderData</td>\n</tr>\n</tbody>\n</table>\n<h4>MainProof</h4>\n<pre><code class="language-haskell">type SscProof SscGodTossing = GtProof\n\n-- | Proof that body of update message contains \'UpdatePayload\'.\ntype UpdateProof = Hash UpdatePayload\n\n-- | Proof of everything contained in the payload.\ndata BodyProof (MainBlockchain ssc) = MainProof\n    { mpTxProof       :: !TxProof\n    , mpMpcProof      :: !(SscProof ssc)\n    , mpProxySKsProof :: !(Hash DlgPayload)\n    , mpUpdateProof   :: !UpdateProof\n    } deriving (Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/2198551433ec666f2df400d49b87ced13f3bcbee/src/Pos/Block/Core/Main/Chain.hs#L42">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(TxProof)</td>\n<td>TxProof</td>\n<td>mpTxProof</td>\n</tr>\n<tr>\n<td>size(GtProof)</td>\n<td>SscProof ssc</td>\n<td>mpMpcProof</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>mpProxySKsProof</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>mpUpdateProof</td>\n</tr>\n</tbody>\n</table>\n<h4>MainConsensusData</h4>\n<pre><code class="language-haskell">data ConsensusData (MainBlockchain ssc) = MainConsensusData\n    { -- | Id of the slot for which this block was generated.\n      _mcdSlot       :: !SlotId\n    , -- | Public key of the slot leader. It\'s essential to have it here,\n      -- because FTS gives us only hash of public key (aka \'StakeholderId\').\n      _mcdLeaderKey  :: !PublicKey\n    , -- | Difficulty of chain ending in this block.\n      _mcdDifficulty :: !ChainDifficulty\n    , -- | Signature given by slot leader.\n      _mcdSignature  :: !(BlockSignature ssc)\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/2198551433ec666f2df400d49b87ced13f3bcbee/src/Pos/Block/Core/Main/Chain.hs#L48">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(SlotId)</td>\n<td>SlotId</td>\n<td>mcdSlot</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>mcdLeaderKey</td>\n</tr>\n<tr>\n<td>size(ChainDifficulty)</td>\n<td>ChainDifficulty</td>\n<td>mcdDifficulty</td>\n</tr>\n<tr>\n<td>64</td>\n<td>BlockSignature</td>\n<td>mcdSignature</td>\n</tr>\n</tbody>\n</table>\n<h4>MainExtraHeaderData</h4>\n<pre><code class="language-haskell">-- | Represents main block header attributes: map from 1-byte integer to\n-- arbitrary-type value. To be used for extending header with new\n-- fields via softfork.\ntype BlockHeaderAttributes = Attributes ()\n\n-- | Represents main block header extra data\ndata MainExtraHeaderData = MainExtraHeaderData\n    { -- | Version of block.\n      _mehBlockVersion    :: !BlockVersion\n    , -- | Software version.\n      _mehSoftwareVersion :: !SoftwareVersion\n    , -- | Header attributes\n      _mehAttributes      :: !BlockHeaderAttributes\n    } deriving (Eq, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/3a6ac3c5aa8d3ca87d8b409d5923e21b744b1e6b/src/Pos/Block/Core/Main/Types.hs#L73">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(BlockVersion)</td>\n<td>BlockVersion</td>\n<td>Version of block</td>\n</tr>\n<tr>\n<td>size(SoftwareVersion)</td>\n<td>SoftwareVersion</td>\n<td>Software version</td>\n</tr>\n<tr>\n<td>size(BlockHeaderAttributes)</td>\n<td>BlockHeaderAttributes</td>\n<td>Header attributes (used for extending header with new fields via softfork)</td>\n</tr>\n</tbody>\n</table>\n<h3>GenesisBlockHeader</h3>\n<pre><code class="language-haskell">-- | Header of block contains some kind of summary. There are various\n-- benefits which people get by separating header from other data.\n--\n-- The constructor has `Unsafe\' prefix in its name, because there in\n-- general there may be some invariants which must hold for the\n-- contents of header.\ndata GenericBlockHeader b = UnsafeGenericBlockHeader\n    { -- | Pointer to the header of the previous block.\n      _gbhPrevBlock :: !(BHeaderHash b)\n    , -- | Proof of body.\n      _gbhBodyProof :: !(BodyProof b)\n    , -- | Consensus data to verify consensus algorithm.\n      _gbhConsensus :: !(ConsensusData b)\n    , -- | Any extra data.\n      _gbhExtra     :: !(ExtraHeaderData b)\n    } deriving (Generic)\n\n-- | Header of Genesis block.\ntype GenesisBlockHeader ssc = GenericBlockHeader (GenesisBlockchain ssc)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/b4b2c282b0e2a2e4415163e70dcb559396a2237c/src/Pos/Block/Core/Genesis/Types.hs#L63">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>BHeaderHash b</td>\n<td>Pointer to the header of the previous block</td>\n</tr>\n<tr>\n<td>32</td>\n<td>BodyProof b</td>\n<td>Proof of body</td>\n</tr>\n<tr>\n<td>size(GenesisProof)</td>\n<td>ConsensusData b</td>\n<td>Consensus data to verify consensus algorithm</td>\n</tr>\n<tr>\n<td>size(GenesisConsensusData)</td>\n<td>ExtraHeaderData b</td>\n<td>Any extra data</td>\n</tr>\n</tbody>\n</table>\n<p>where <code>b</code> = <code>GenesisBlockchain ssc</code>.</p>\n<h4>GenesisProof</h4>\n<pre><code class="language-haskell">-- | Proof of GenesisBody is just a hash of slot leaders list.\ndata BodyProof (GenesisBlockchain ssc) = GenesisProof\n    !(Hash SlotLeaders)\n    deriving (Eq, Generic, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/b4b2c282b0e2a2e4415163e70dcb559396a2237c/src/Pos/Block/Core/Genesis/Chain.hs#L28">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Hash of slot leaders list</td>\n</tr>\n</tbody>\n</table>\n<h4>GenesisConsensusData</h4>\n<pre><code class="language-haskell">data ConsensusData (GenesisBlockchain ssc) = GenesisConsensusData\n    { -- | Index of the slot for which this genesis block is relevant.\n      _gcdEpoch :: !EpochIndex\n    , -- | Difficulty of the chain ending in this genesis block.\n      _gcdDifficulty :: !ChainDifficulty\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/b4b2c282b0e2a2e4415163e70dcb559396a2237c/src/Pos/Block/Core/Genesis/Chain.hs#L31">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(EpochIndex)</td>\n<td>EpochIndex</td>\n<td>Index of epoch for which this genesis block is relevant</td>\n</tr>\n<tr>\n<td>size(ChainDifficulty)</td>\n<td>ChainDifficulty</td>\n<td>Difficulty of the chain ending in this genesis block.</td>\n</tr>\n</tbody>\n</table>\n<h3>BlockHeader</h3>\n<pre><code class="language-haskell">-- | Either header of ordinary main block or genesis block.\ntype BlockHeader ssc = Either (GenesisBlockHeader ssc) (MainBlockHeader ssc)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/f571087e5b5af339767198141981c850227ca99c/src/Pos/Block/Core/Union/Types.hs#L39">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Tag size</th>\n<th>Tag Type</th>\n<th>Tag Value</th>\n<th>Description</th>\n<th>Field size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for \n<code>GenesisBlockHeader</code></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(GenesisBlockHeader)</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for \n<code>MainBlockHeader</code></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(MainBlockHeader)</td>\n</tr>\n</tbody>\n</table>\n<h3>Block</h3>\n<pre><code class="language-haskell">-- | Either genesis block or main block.\ntype Block ssc = Either (GenesisBlock ssc) (MainBlock ssc)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/f571087e5b5af339767198141981c850227ca99c/src/Pos/Block/Core/Union/Types.hs#L42">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Tag size</th>\n<th>Tag Type</th>\n<th>Tag Value</th>\n<th>Description</th>\n<th>Field size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for \n<code>GenesisBlock</code></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(GenesisBlock)</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for \n<code>MainBlock</code></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(MainBlock)</td>\n</tr>\n</tbody>\n</table>\n<h2>Block Exchange Messages</h2>\n<h3>HeaderHash</h3>\n<pre><code class="language-haskell">-- | \'Hash\' of block header. This should be @Hash (BlockHeader ssc)@\n-- but we don\'t want to have @ssc@ in \'HeaderHash\' type.\ntype HeaderHash = Hash BlockHeaderStub\ndata BlockHeaderStub\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/2198551433ec666f2df400d49b87ced13f3bcbee/core/Pos/Core/Types.hs#L223">Source code\nlink</a>.</p>\n<h3>GetHeaders</h3>\n<pre><code class="language-haskell">-- | \'GetHeaders\' message. Behaviour of the response depends on\n-- particular combination of \'mghFrom\' and \'mghTo\'.\n--\n-- * \'mghTo\' resolves to some header (let\'s call it @top@ for\n-- convenience) -- node\'s tip if it\'s @Nothing@, header with hash in\n-- @Just@ if it\'s @Just@.\n--\n-- * If \'mghFrom\' is empty, then semantics is "request to return\n-- header of block @top@".\n--\n-- * Otherwise (if \'mghFrom\' isn\'t empty) it represents the set of\n-- checkpoints. Responding node will try to iterate headers from @top@\n-- to older until it reaches any checkpoint. If it finds checkpoint\n-- @c@, it returns all headers in range @[c.next..top]@. If it doesn\'t\n-- find any checkpoint or depth of searching exceeds\n-- \'recoveryHeadersMessage\', it will try to find the newest checkpoint\n-- @cc@ from \'mghFrom\' that\'s in main chain of responding node and\n-- then return at most \'recoveryHeadersMessage\' headers starting with\n-- @cc@ as the oldest one, returning headers in range @l2 =\n-- [cc.next..x]@ where @x@ is either @top@ (in case @length l2 &#x3C;\n-- recoveryHeadersMessage@) or some arbitrary header (and length is\n-- precisely \'recoveryHeadersMessage\').\ndata MsgGetHeaders = MsgGetHeaders\n    { -- not guaranteed to be in any particular order\n      mghFrom :: ![HeaderHash]\n    , mghTo   :: !(Maybe HeaderHash)\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L42">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of checkpoints</td>\n</tr>\n<tr>\n<td>n \n*\n size(Hash)</td>\n<td>Hash\n[\nn\n]</td>\n<td></td>\n<td>List of length \n<code>n</code>\n with hashes</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>tag = 0x00 or 0x01</td>\n<td>Tag for optional \n<code>to</code>\n hash</td>\n</tr>\n<tr>\n<td>tag \n*\n size(Hash)</td>\n<td>Hash</td>\n<td></td>\n<td>If tag is not \n<code>0x00</code>\n then hash of \n<code>to</code>\n block</td>\n</tr>\n</tbody>\n</table>\n<h3>GetBlocks</h3>\n<pre><code class="language-haskell">-- | \'GetBlocks\' message (see protocol specification).\ndata MsgGetBlocks = MsgGetBlocks\n    { mgbFrom :: !HeaderHash\n    , mgbTo   :: !HeaderHash\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L54">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Field</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td><code>mgbFrom</code></td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td><code>mgbTo</code></td>\n</tr>\n</tbody>\n</table>\n<h3>Headers</h3>\n<pre><code class="language-haskell">-- | \'Headers\' message (see protocol specification).\nnewtype MsgHeaders ssc =\n    MsgHeaders (NewestFirst NE (BlockHeader ssc))\n    deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L65">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of block headers</td>\n</tr>\n<tr>\n<td>n \n*\n size(BlockHeader)</td>\n<td>BlockHeader\n[\nn\n]</td>\n<td></td>\n<td><code>n</code>\n block headers</td>\n</tr>\n</tbody>\n</table>\n<h3>Block</h3>\n<pre><code class="language-haskell">-- | \'Block\' message (see protocol specification).\nnewtype MsgBlock ssc =\n    MsgBlock (Block ssc)\n    deriving (Generic, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/c8620af754252ebb71b1f5bc369b4f672f46d537/src/Pos/Block/Network/Types.hs#L70">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int64</td>\n<td>n</td>\n<td>Size of \n<code>Block</code>\n in bytes</td>\n</tr>\n<tr>\n<td>size(Block)</td>\n<td>Block</td>\n<td></td>\n<td><code>Block</code>\n with size of \n<code>n</code>\n bytes</td>\n</tr>\n</tbody>\n</table>\n<p>Contains one <code>Block</code>. We encode block size and then the block itself so that\nwe\'d be able to reject the block if it\'s of the wrong size without consuming the\nwhole block.</p>\n<h2>Transaction sending</h2>\n<p>To send transaction you need to create and send <code>TxAux</code> data type to node. All\ndata types required to successfully perform sending are described in this\nsection.</p>\n<h3>Transaction input</h3>\n<pre><code class="language-haskell">-- | Represents transaction identifier as \'Hash\' of \'Tx\'.\ntype TxId = Hash Tx\n\n-- | Transaction input.\ndata TxIn = TxIn\n    { -- | Which transaction\'s output is used\n      txInHash  :: !TxId\n      -- | Index of the output in transaction\'s outputs\n    , txInIndex :: !Word32\n    } deriving (Eq, Ord, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/txp/Pos/Txp/Core/Types.hs#L147">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Field name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>txInHash</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Word32</td>\n<td>txInIndex</td>\n</tr>\n</tbody>\n</table>\n<h3>Transaction output</h3>\n<pre><code class="language-haskell">-- | Transaction output.\ndata TxOut = TxOut\n    { txOutAddress :: !Address\n    , txOutValue   :: !Coin\n    } deriving (Eq, Ord, Generic, Show, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/895619d7056fe397e9c2a56d88994f167263c397/txp/Pos/Txp/Core/Types.hs#L160">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Field name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Address)</td>\n<td>Address</td>\n<td>txOutAddress</td>\n</tr>\n<tr>\n<td>size(Coin)</td>\n<td>Coin</td>\n<td>txOutValue</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> let addr = PubKeyAddress (abstractHash somePk) (Attributes (AddrPkAttrs Nothing) "a")\nghci> hexEncode addr\n"001e380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00161cf52c5ec"\nghci> hexEncode $ TxOut addr (mkCoin 1000)\n"001e380dea393a631ad563154a13bc5ee49fa4b62a60218358b5dcb875e00161cf52c5ec0064"\n</code></pre>\n<h3>Transaction output distribution</h3>\n<pre><code class="language-haskell">type TxOutDistribution = [(StakeholderId, Coin)]\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L129">Source code\nlink</a>.</p>\n<p>Lets define <code>distr_size(n) = n * (size(Hash) + size(Coin))</code>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>distr\n_\nsize(n)</td>\n<td>&#x3C;Hash,Coin>\n[\nn\n]</td>\n<td>Array of pairs for StakeholderId and Coin</td>\n</tr>\n</tbody>\n</table>\n<h3>Transaction output auxilary</h3>\n<pre><code class="language-haskell">-- | Transaction output and auxilary data corresponding to it.\ndata TxOutAux = TxOutAux\n    { toaOut   :: !TxOut             -- ^ Tx output\n    , toaDistr :: !TxOutDistribution -- ^ Stake distribution\n                                     -- associated with output\n    } deriving (Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L173">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Field name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(TxOut)</td>\n<td>TxOut</td>\n<td>toaOut</td>\n</tr>\n<tr>\n<td>size(TxOutDistribution)</td>\n<td>TxOutDistribution</td>\n<td>toaDistr</td>\n</tr>\n</tbody>\n</table>\n<h3>Transaction signature data</h3>\n<pre><code class="language-haskell">-- | Data that is being signed when creating a TxSig.\ndata TxSigData = TxSigData\n    { -- | Input that we\'re signing (i.e. our signature certifies that we own\n      -- funds referenced by this input)\n      txSigInput     :: !TxIn\n      -- | Outputs of the transaction (i.e. our signature certifies that we\n      -- actually want the funds to go to these particular outputs)\n    , txSigOutsHash  :: !(Hash (NonEmpty TxOut))\n      -- | Distribution of the transaction\n    , txSigDistrHash :: !(Hash TxDistribution)\n    }\n    deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L80">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(TxIn)</td>\n<td>TxIn</td>\n<td>txSigInput</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>txSigOutsHash</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>txSigDistrHash</td>\n</tr>\n</tbody>\n</table>\n<h3>Transaction witness</h3>\n<pre><code class="language-haskell">-- | \'Signature\' of addrId.\ntype TxSig = Signature TxSigData\n\n-- | A witness for a single input.\ndata TxInWitness\n    = PkWitness { twKey :: !PublicKey\n                , twSig :: !TxSig }\n    | ScriptWitness { twValidator :: !Script\n                    , twRedeemer  :: !Script }\n    | RedeemWitness { twRedeemKey :: !RedeemPublicKey\n                    , twRedeemSig :: !(RedeemSignature TxSigData) }\n    | UnknownWitnessType !Word8 !ByteString\n    deriving (Eq, Show, Generic, Typeable)\n\n-- | A witness is a proof that a transaction is allowed to spend the funds it\n-- spends (by providing signatures, redeeming scripts, etc). A separate proof\n-- is provided for each input.\ntype TxWitness = Vector TxInWitness\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L96">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Tag size</th>\n<th>Tag Type</th>\n<th>Tag Value</th>\n<th>Description</th>\n<th>Field size</th>\n<th>Field Type</th>\n<th>Field name</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>Tag for PkWitness</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>twKey</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>64</td>\n<td>TxSig</td>\n<td>twSig</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Tag for ScriptWitness</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Script)</td>\n<td>Script</td>\n<td>twValidator</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(Script)</td>\n<td>Script</td>\n<td>twRedeemer</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x02</td>\n<td>Tag for RedeemWitness</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(RedeemPublicKey)</td>\n<td>RedeemPublicKey</td>\n<td>twRedeemKey</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>size(RedeemSignature)</td>\n<td>RedeemSignature TxSigData</td>\n<td>twRedeemSig</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x03</td>\n<td>Tag for UnknownWitnessType</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>1</td>\n<td>Word8</td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>ByteString</td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<h3>Transaction</h3>\n<pre><code class="language-haskell">-- | Transaction.\ndata Tx = UnsafeTx\n    { _txInputs     :: !(NonEmpty TxIn)  -- ^ Inputs of transaction.\n    , _txOutputs    :: !(NonEmpty TxOut) -- ^ Outputs of transaction.\n    , _txAttributes :: !TxAttributes     -- ^ Attributes of transaction\n    } deriving (Eq, Ord, Generic, Show, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L196">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td>Number of transaction inputs</td>\n</tr>\n<tr>\n<td>n \n*\n size(TxIn)</td>\n<td>TxIn\n[\nn\n]</td>\n<td></td>\n<td>Array of transaction inputs</td>\n</tr>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>m</td>\n<td>Number of transaction outputs</td>\n</tr>\n<tr>\n<td>m \n*\n size(TxOut)</td>\n<td>TxOut\n[\nm\n]</td>\n<td></td>\n<td>Array of transaction outputs</td>\n</tr>\n<tr>\n<td>size(TxAttributes)</td>\n<td>TxAttributes</td>\n<td></td>\n<td>Attributes of transaction</td>\n</tr>\n</tbody>\n</table>\n<h3>Transaction distribution</h3>\n<pre><code class="language-haskell">-- | Distribution of “fake” stake that follow-the-satoshi would use\n-- for a particular transaction.  Length of stored list must be same\n-- as length of \'_txOutputs\' of corresponding transaction.\nnewtype TxDistribution = TxDistribution\n    { getTxDistribution :: NonEmpty TxOutDistribution\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/src/Pos/Txp/Core/Types.hs#L134">Source code\nlink</a>.</p>\n<p>Though transaction distribution can be stored as list of list using previous\nserialization strategy it is often happens that we pass list of empty lists. In\nthat case we store such lists more efficiently.</p>\n<table>\n<thead>\n<tr>\n<th>Tag size</th>\n<th>Tag Type</th>\n<th>Tag Value</th>\n<th>Description</th>\n<th>Field size</th>\n<th>Field Type</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>Word8</td>\n<td>0x00</td>\n<td>List of empty lists</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td>0x01</td>\n<td>Some lists are not empty</td>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>distr\n_\nsize(n)</td>\n<td>&#x3C;Hash,Coin>\n[\nn\n]</td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<h3>Transaction auxilary</h3>\n<pre><code class="language-haskell">-- | Transaction + auxiliary data\ndata TxAux = TxAux\n    { taTx           :: !Tx\n    , taWitness      :: !TxWitness\n    , taDistribution :: !TxDistribution\n    } deriving (Generic, Show, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/ab543154d3ff34d3432620ac2557187d124b7d4f/txp/Pos/Txp/Core/Types.hs#L205">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Tx)</td>\n<td>Tx</td>\n<td>Transaction itself</td>\n</tr>\n<tr>\n<td>size(TxWitness)</td>\n<td>TxWitness</td>\n<td>Witness for transaction</td>\n</tr>\n<tr>\n<td>size(TxDistribution)</td>\n<td>TxDistribution</td>\n<td>Transaction distribution</td>\n</tr>\n</tbody>\n</table>\n<!-- TODO: describe full creation of transaction by bytes -->\n<h2>Delegation</h2>\n<p>Please read about <a href="/technical/protocols/csl-application-level/#delegation-messages">Delegation\nMessages</a> for\nmechanism explanation. Here you can find description of messages format only.</p>\n<h3>Proxy Certificate</h3>\n<p>Similar to <code>Signature</code>.</p>\n<pre><code class="language-haskell">-- | Proxy certificate, made of ω + public key of delegate.\nnewtype ProxyCert w = ProxyCert { unProxyCert :: CC.XSignature }\n    deriving (Eq, Ord, Show, Generic, NFData, Hashable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L209">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>64</td>\n<td>Word8\n[\n64\n]</td>\n<td><code>unProxyCert</code>\n: 64 bytes of signature string</td>\n</tr>\n</tbody>\n</table>\n<p>Message size limit: 64.</p>\n<p>Example:</p>\n<pre><code>ghci> (issuerPk, issuerSk) &#x3C;- keyGen\nghci> hexEncode issuerPk\n"0659c8e27599dc4709dab3bb58ce50d0729150fc238010fd3a68dcf07c621bdc"\nghci> (delegatePk, delegateSk) &#x3C;- keyGen\nghci> hexEncode delegatePk\n"5eaf0944733da8386c427656a876b20ae411fa686ea4bb165b53a311c868c287"\nghci> let cert = createProxyCert issuerSk delegatePk (0, 10) :: ProxyCert (EpochIndex, EpochIndex)\nghci> hexEncode cert\n"8db543c5fff7dd5dab609d04a834cda77958faf48cabee351def8985a2ec7dae71c7b2f0390caa54c61c9d41f5228e1a0b5da1c08638b99d03a1c02c81cb1607"\nghci> verifyProxyCert issuerPk delegatePk (0, 10) cert\nTrue\n</code></pre>\n<h3>Proxy Secret Key</h3>\n<pre><code class="language-haskell">-- | Convenient wrapper for secret key, that\'s basically ω + certificate.\ndata ProxySecretKey w = ProxySecretKey\n    { pskOmega      :: w\n    , pskIssuerPk   :: PublicKey\n    , pskDelegatePk :: PublicKey\n    , pskCert       :: ProxyCert w\n    } deriving (Eq, Ord, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L224">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(w)</td>\n<td>w</td>\n<td>pskOmega</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskIssuerPk</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskDelegatePk</td>\n</tr>\n<tr>\n<td>size(ProxyCert)</td>\n<td>ProxyCert w</td>\n<td>pskCert</td>\n</tr>\n</tbody>\n</table>\n<h3>Proxy signature</h3>\n<pre><code class="language-haskell">-- | Delegate signature made with certificate-based permission. @w@\n-- stays for message type used in proxy (ω in the implementation\n-- notes), @a@ for type of message signed.\ndata ProxySignature w a = ProxySignature\n    { psigPsk :: ProxySecretKey w\n    , psigSig :: CC.XSignature\n    } deriving (Eq, Ord, Show, Generic)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Crypto/Signing.hs#L256">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(PproxySK)</td>\n<td>ProxySecretKey</td>\n<td>psigPsk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>XSignature</td>\n<td>psigSig</td>\n</tr>\n</tbody>\n</table>\n<h3>Proxy Secret Key and Signature for Lightweight Delegation</h3>\n<p><strong>WARNING: Currently, lightweight delegation is disabled and will be reworked in\n<a href="https://cardanoroadmap.com/">Shelley release</a>, so information below can be outdated.</strong></p>\n<h4>Secret Key</h4>\n<pre><code class="language-haskell">-- | Same alias for the proxy secret key (see \'ProxySigLight\').\ntype ProxySKLight = ProxySecretKey (EpochIndex, EpochIndex)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L238">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>from epoch</td>\n</tr>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>to epoch</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskIssuerPk</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskDelegatePk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>ProxyCert (EpochIndex, EpochIndex)</td>\n<td>pskCert</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> let proxySk = createProxySecretKey issuerSk delegatePk (0, 10) :: ProxySKLight\nghci> hexEncode proxySk\n"000a0659c8e27599dc4709dab3bb58ce50d0729150fc238010fd3a68dcf07c621bdc5eaf0944733da8386\nc427656a876b20ae411fa686ea4bb165b53a311c868c2878db543c5fff7dd5dab609d04a834cda77958faf\n48cabee351def8985a2ec7dae71c7b2f0390caa54c61c9d41f5228e1a0b5da1c08638b99d03a1c02c81cb1607"\nghci> verifyProxySecretKey proxySk\nTrue\n</code></pre>\n<h4>Signature</h4>\n<pre><code class="language-haskell">-- | Proxy signature used in csl -- holds a pair of epoch\n-- indices. Block is valid if its epoch index is inside this range.\ntype ProxySigLight a = ProxySignature (EpochIndex, EpochIndex) a\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L235">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>from epoch</td>\n</tr>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>to epoch</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pdDelegatePk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>ProxyCert (EpochIndex, EpochIndex)</td>\n<td>pdCert</td>\n</tr>\n<tr>\n<td>64</td>\n<td>Signature</td>\n<td>pdSig</td>\n</tr>\n</tbody>\n</table>\n<p>Example:</p>\n<pre><code>ghci> let proxyLightSig = proxySign delegateSk proxySk proxySk :: ProxySigLight ProxySKLight\nghci> hexEncode proxyLightSig\n"000a5eaf0944733da8386c427656a876b20ae411fa686ea4bb165b53a311c868c2878db543c5fff7dd5dab609d04a\n834cda77958faf48cabee351def8985a2ec7dae71c7b2f0390caa54c61c9d41f5228e1a0b5da1c08638b99d03a1c02\nc81cb1607e764468529599312ebe4dd5587383e5ccd3c2755401b22c8ff08827ecabd1afc8c634e17085ec83179193\nafad2868e6aabce3e3e46e3170d077ee4e8613aa700"\nghci> proxyVerify issuerPk proxyLightSig (== (0, 10)) proxySk\nTrue\n</code></pre>\n<h3>Proxy Secret Key and Signature for Heavyweight Delegation</h3>\n<h4>Secret Key</h4>\n<pre><code class="language-haskell">-- | Correspondent SK for no-ttl proxy signature scheme.\ntype ProxySKHeavy = ProxySecretKey EpochIndex\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L247">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>epoch</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskIssuerPk</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pskDelegatePk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>ProxyCert EpochIndex</td>\n<td>pskCert</td>\n</tr>\n</tbody>\n</table>\n<h4>Signature</h4>\n<pre><code class="language-haskell">-- | Simple proxy signature without ttl/epoch index\n-- constraints. \'EpochIndex\' inside is needed for replay attack\n-- prevention.\ntype ProxySigHeavy a = ProxySignature EpochIndex a\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L244">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-10</td>\n<td>UVarInt Word64</td>\n<td>epoch</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>pdDelegatePk</td>\n</tr>\n<tr>\n<td>64</td>\n<td>ProxyCert EpochIndex</td>\n<td>pdCert</td>\n</tr>\n<tr>\n<td>64</td>\n<td>Signature</td>\n<td>pdSig</td>\n</tr>\n</tbody>\n</table>\n<h3>Lightweight Delegation Confirmation</h3>\n<p><strong>WARNING: Currently, lightweight delegation is disabled and will be reworked in\n<a href="https://cardanoroadmap.com/">Shelley release</a>, so information below can be outdated.</strong></p>\n<h4>ProxySKLightConfirmation</h4>\n<pre><code class="language-haskell">-- | Confirmation of light cert type.\ntype ProxySKLightConfirmation = (ProxySKLight, ProxySigLight ProxySKLight)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(ProxySKLight)</td>\n<td>Certificate</td>\n</tr>\n<tr>\n<td>size(ProxySigLight)</td>\n<td>Proof for certificate</td>\n</tr>\n</tbody>\n</table>\n<h2>Update System</h2>\n<h3>Update Vote</h3>\n<pre><code class="language-haskell">-- | ID of software update proposal\ntype UpId = Hash UpdateProposal\n\n-- | Vote for update proposal\ndata UpdateVote = UpdateVote\n    { -- | Public key of stakeholder, who votes\n      uvKey        :: !PublicKey\n    , -- | Proposal to which this vote applies\n      uvProposalId :: !UpId\n    , -- | Approval/rejection bit\n      uvDecision   :: !Bool\n    , -- | Signature of (Update proposal, Approval/rejection bit)\n      --   by stakeholder\n      uvSignature  :: !(Signature (UpId, Bool))\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/fbe9760bd50ea136203e54d578d62ed3070b5513/update/Pos/Update/Core/Types.hs#L255">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Field</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>uvKey</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>uvProposalId</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Bool</td>\n<td>uvDecision</td>\n</tr>\n<tr>\n<td>64</td>\n<td>Signature</td>\n<td>uvSignature</td>\n</tr>\n</tbody>\n</table>\n<h3>Vote Identifier</h3>\n<pre><code class="language-haskell">type VoteId = (UpId, PublicKey, Bool)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/fbe9760bd50ea136203e54d578d62ed3070b5513/update/Pos/Update/Core/Types.hs#L252">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>Hash of update proposal</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td>Public key</td>\n</tr>\n<tr>\n<td>1</td>\n<td>Bool</td>\n<td>Vote result</td>\n</tr>\n</tbody>\n</table>\n<p>For more description of fields, see <em>UpdateVote</em> message description. <code>VoteId</code>\nis just <code>(uvProposalId, uvKey, uvDecision)</code>.</p>\n<h3>Block Version Data</h3>\n<pre><code class="language-haskell">-- | Data which is associated with \'BlockVersion\'.\ndata BlockVersionData = BlockVersionData\n    { bvdScriptVersion     :: !ScriptVersion\n    , bvdSlotDuration      :: !Millisecond\n    , bvdMaxBlockSize      :: !Byte\n    , bvdMaxHeaderSize     :: !Byte\n    , bvdMaxTxSize         :: !Byte\n    , bvdMaxProposalSize   :: !Byte\n    , bvdMpcThd            :: !CoinPortion\n    , bvdHeavyDelThd       :: !CoinPortion\n    , bvdUpdateVoteThd     :: !CoinPortion\n    , bvdUpdateProposalThd :: !CoinPortion\n    , bvdUpdateImplicit    :: !FlatSlotId\n    , bvdUpdateSoftforkThd :: !CoinPortion\n    } deriving (Show, Eq, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/64bc3ade3555dd4035da3f4bcb15223c9c22f518/core/Pos/Core/Types.hs#L201">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Field</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-3</td>\n<td>UVarInt Word16</td>\n<td>bvdScriptVersion</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdSlotDuration</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdMaxBlockSize</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdMaxHeaderSize</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdMaxTxSize</td>\n</tr>\n<tr>\n<td>size(Integer)</td>\n<td>Integer</td>\n<td>bvdMaxProposalSize</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdMpcThd</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdHeavyDelThd</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdUpdateVoteThd</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdUpdateProposalThd</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdUpdateImplicit</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Word64</td>\n<td>bvdUpdateSoftforkThd</td>\n</tr>\n</tbody>\n</table>\n<h3>Update Data</h3>\n<pre><code class="language-haskell">-- | Data which describes update. It is specific for each system.\ndata UpdateData = UpdateData\n    { udAppDiffHash  :: !(Hash Raw)\n    -- ^ Hash of binary diff between two applications. This diff can\n    -- be passed to updater to create new application.\n    , udPkgHash      :: !(Hash Raw)\n    -- ^ Hash of package to install new application. This package can\n    -- be used to install new application from scratch instead of\n    -- updating existing application.\n    , udUpdaterHash  :: !(Hash Raw)\n    -- ^ Hash if update application which can be used to install this\n    -- update (relevant only when updater is used, not package).\n    , udMetadataHash :: !(Hash Raw)\n    -- ^ Hash of metadata relevant to this update.  It is raw hash,\n    -- because metadata can include image or something\n    -- (maybe). Anyway, we can always use `unsafeHash`.\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/update/Pos/Update/Core/Types.hs#L224">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Field</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>udAppDiffHash</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>udPkgHash</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>udUpdaterHash</td>\n</tr>\n<tr>\n<td>size(Hash)</td>\n<td>Hash</td>\n<td>udMetadataHash</td>\n</tr>\n</tbody>\n</table>\n<h3>System Tag</h3>\n<pre><code class="language-haskell">-- | Tag of system for which update data is purposed, e.g. win64, mac32\nnewtype SystemTag = SystemTag { getSystemTag :: Text }\n  deriving (Eq, Ord, Show, Generic, Buildable, Hashable, Lift, Typeable)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/732a2c765a417ba0a5010df81061c4473f80a0dc/update/Pos/Update/Core/Types.hs#L81">Source code\nlink</a>.</p>\n<p><code>SystemTag</code> is encoded as <code>ByteString</code> in UTF-8 encoding.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Field</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int64</td>\n<td>n</td>\n<td>Size of text in bytes</td>\n</tr>\n<tr>\n<td>n</td>\n<td>Word8\n[\nn\n]</td>\n<td></td>\n<td><code>n</code>\n bytes of UTF-8 encoded text</td>\n</tr>\n</tbody>\n</table>\n<h3>Update Proposal</h3>\n<pre><code class="language-haskell">type UpAttributes = Attributes ()\n\n-- | Proposal for software update\ndata UpdateProposal = UnsafeUpdateProposal\n    { upBlockVersion     :: !BlockVersion\n    , upBlockVersionData :: !BlockVersionData\n    , upSoftwareVersion  :: !SoftwareVersion\n    , upData             :: !(HM.HashMap SystemTag UpdateData)\n    -- ^ UpdateData for each system which this update affects.\n    -- It must be non-empty.\n    , upAttributes       :: !UpAttributes\n    -- ^ Attributes which are currently empty, but provide\n    -- extensibility.\n    , upFrom             :: !PublicKey\n    -- ^ Who proposed this UP.\n    , upSignature        :: !(Signature UpdateProposalToSign)\n    } deriving (Eq, Show, Generic, Typeable)\n</code></pre>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Value</th>\n<th>Field</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>5</td>\n<td>BlockVersion</td>\n<td></td>\n<td>upBlockVersion</td>\n</tr>\n<tr>\n<td>size(BlockVersionData)</td>\n<td>BlockVersionData</td>\n<td></td>\n<td>upBlockVersionData</td>\n</tr>\n<tr>\n<td>size(SoftwareVersion)</td>\n<td>SoftwareVersion</td>\n<td></td>\n<td>upSoftwareVersion</td>\n</tr>\n<tr>\n<td>1-9</td>\n<td>UVarInt Int</td>\n<td>n</td>\n<td></td>\n</tr>\n<tr>\n<td>n \n*\n (size(SystemTag) + size(UpdateData))</td>\n<td>&#x3C;SystemTag, UpdateData>\n[\nn\n]</td>\n<td></td>\n<td>upData</td>\n</tr>\n<tr>\n<td>size(Attributes ())</td>\n<td>Attributes ()</td>\n<td></td>\n<td>upAttributes</td>\n</tr>\n<tr>\n<td>size(PublicKey)</td>\n<td>PublicKey</td>\n<td></td>\n<td>upFrom</td>\n</tr>\n<tr>\n<td>size(Signature)</td>\n<td>Signature UpdateProposalToSign</td>\n<td></td>\n<td>upSignature</td>\n</tr>\n</tbody>\n</table>\n<h2>Peer Data</h2>\n<h3>HandlerSpec</h3>\n<pre><code class="language-haskell">data HandlerSpec\n    = ConvHandler { hsReplyType :: MessageName}\n    | UnknownHandler Word8 ByteString\n    deriving (Show, Generic, Eq)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/414817a6f8c8de405553c8ba1325e1366dc7b60e/infra/Pos/Communication/Types/Protocol.hs#L80">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Type</th>\n<th>Size</th>\n<th>Value</th>\n<th>Following data</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>ConvHandler m where m : UnsignedVarInt \n&#x3C;\n 64</td>\n<td>Word8</td>\n<td>01xx xxxx</td>\n<td>none</td>\n</tr>\n<tr>\n<td>ConvHandler m where m : Unknown</td>\n<td>Word8 + TinyBS</td>\n<td>0000 0001</td>\n<td>ByteString</td>\n</tr>\n<tr>\n<td>UnknownHandler w8 bs</td>\n<td>Word8 + TinyBS</td>\n<td>w8</td>\n<td>bs</td>\n</tr>\n</tbody>\n</table>\n<p>Examples:</p>\n<pre><code>ghci> hexEncode (ConvHandler (messageName (Proxy :: Proxy MsgGetHeaders)))\n"44"\nghci> hexEncode (UnknownHandler 10 "aba")\n"0a03616261"\n</code></pre>\n<h3>VerInfo</h3>\n<pre><code class="language-haskell">type HandlerSpecs = HashMap MessageName HandlerSpec\n\nnewtype InSpecs = InSpecs HandlerSpecs\n    deriving (Eq, Show, Generic)\n\nnewtype OutSpecs = OutSpecs HandlerSpecs\n    deriving (Eq, Show, Generic)\n\ndata VerInfo = VerInfo\n    { vIMagic        :: Int32\n    , vIBlockVersion :: BlockVersion\n    , vIInHandlers   :: HandlerSpecs\n    , vIOutHandlers  :: HandlerSpecs\n    } deriving (Eq, Generic, Show)\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/414817a6f8c8de405553c8ba1325e1366dc7b60e/infra/Pos/Communication/Types/Protocol.hs#L102">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Field</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>Int32</td>\n<td><code>vIMagic</code></td>\n</tr>\n<tr>\n<td>5</td>\n<td>BlockVersion</td>\n<td><code>vIBlockVersion</code></td>\n</tr>\n<tr>\n<td>size(HandlerSpecs)</td>\n<td>HandlerSpecs</td>\n<td><code>vIInHandlers</code></td>\n</tr>\n<tr>\n<td>size(HandlerSpecs)</td>\n<td>HandlerSpecs</td>\n<td><code>vIOutHandlers</code></td>\n</tr>\n</tbody>\n</table>\n<p><code>HandlerSpec</code> is just mapping between message names and how those messages\nhandled: via single-message style or conversation style + message tag. This\nmapping is encoded as every other <code>Map</code> — list of pairs.</p>\n<p><code>InSpecs</code> and <code>OutSpecs</code> are just wrappers around <code>HandlerSpecs</code>. These wrappers\nare used only for type-safety to distinguish spec for incoming and outgoing\nmessages.</p>\n<!-- TODO: didn\'t find examples of inSpecs :( -->\n<h3>PeerData</h3>\n<pre><code class="language-haskell">type PeerData = VerInfo\n</code></pre>\n<p><a href="https://github.com/input-output-hk/cardano-sl/blob/414817a6f8c8de405553c8ba1325e1366dc7b60e/infra/Pos/Communication/Types/Protocol.hs#L47">Source code\nlink</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Field size</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size(VerInfo)</td>\n<td>VerInfo</td>\n<td>MessageName table</td>\n</tr>\n</tbody>\n</table>\n<p><code>VerInfo</code> we sending is created\n<a href="https://github.com/input-output-hk/cardano-sl/blob/81b40e54bb5dda2e94850ccc9a835b46e5c445b5/src/Pos/Launcher/Runner.hs#L286">here</a>.</p>\n<p>Examples:</p>\n<pre><code class="language-haskell">ghci> let ourVerInfo = VerInfo protocolMagic lastKnownBlockVersion mempty outSpecs\nghci> let peerIdExample = PeerId "0123456789ABCD"\nghci> hexEncode ourVerInfo\n"0000000000000000000004030800000103020900030801010103020901030802\n020103020902030803030103020903"\nghci> hexEncode ((peerIdExample, ourVerInfo) :: PeerData)\n"3031323334353637383941424344000000000000000000000403080000010302\n0900030801010103020901030802020103020902030803030103020903"\n</code></pre>',
  frontmatter:{path:"/en/technical/protocols/binary-protocols/",doc_title:"Binary protocols",author:null,date:"2017-01-01",language:"en",label:"docs",keywords:null,group:"technical-protocols"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/docs/2017-01-10-technical.cn.md absPath of file >>> MarkdownRemark",excerpt:"…",html:'<!-- Reviewed at d0868afac50ba6ffcbd95054e65cbf77fa513082 -->\n<h1>卡尔达诺结算层技术细节</h1>\n<p>对于想要贡献原始客户端，以及想基于卡尔达诺结算层创建自己的客户端的开发人员来说，这一章节是一个起点。尽管如此，这一节将主要覆盖原始客户端，并有所扩展，在一段时间内可以把它当做最初的参考文档</p>\n<h2>高层次概述</h2>\n<p>一个卡尔达诺结算层节点是一个区块链节点。运行时，他会找到其他节点(通过 <a href="http://ast-deim.urv.cat/cpairot/dhts.html">DHT</a>)，然后开始执行区块链的相关任务。</p>\n<p>卡尔达诺结算层中的时间会以 epochs 划分。epochs 又会以 slots 划分。 Epochs 和 slots 会被编号。 因此，slot <code>(3,5)</code> 被读作『第3个 epochs 的第5个 slot』 (第0个 slot 以及第0个 epoch 也是可以的).</p>\n<p>卡尔达诺结算层会使用一些常量集, 特殊值定义在\n<a href="https://github.com/input-output-hk/cardano-sl/blob/bf5dd592b7bf77a68bf71314718dc7a8d5cc8877/core/constants.yaml"><code>constants.yaml</code> 配置文件中</a>。\n主要有两种：生产模式和开发模式。 在本指南中，我们将参考生产常量。</p>\n<p>假设卡尔达诺结算层的值是：:</p>\n<ul>\n<li>slot 持续时间: 120秒,</li>\n<li>安全参数 <em>k</em>: 60.</li>\n</ul>\n<p>换句话说，<strong>一个 slot 可以持续120秒</strong>, 而一个 epochs有 <a href="https://github.com/input-output-hk/cardano-sl/blob/9ee12d3cc9ca0c8ad95f3031518a4a7acdcffc56/core/Pos/Core/Constants/Raw.hs#L161"><code>10×k</code></a>\n个 slot, 所以它可以持续<strong>1200分钟</strong>或<strong>20个小时</strong>.</p>\n<p>每个 slot 上有一个节点被称作 slot 领导者。只有这个 slot 有权在这些 slot 中生成一个新区块；这个区块会被加入到区块链中。然而我们并不能确保这个区块一定会被生成(比如 slot 领导者在响应的过程中可能会离线)。</p>\n<p>此外，slot 领导者可以将其权利委托给另一个节点 <code>N</code>；在这种情况下，节点 <code>N</code> 而非 slot 领导者将有权生成一个新的块。请注意，<code>N</code> 具有委托权的节点不能被称为 slot 领导者，它只是一个委托。</p>\n<p>理论上可以将 slot 领导者的权力委托给多个节点，但是不推荐，之后会解释原因。此外，使用相同的密钥（即一台计算机上）我们可以运行中多个节点，假设有节点 <code>A</code>, <code>B</code>, <code>C</code>，如果节点 <code>A</code> 被选为 slot 领导者，不仅 <code>A</code> 本身，节点 <code>B</code> 和 <code>C</code> 都能够生成一个新区块。在这种情况下，每一个节点都将发出一个不同的块，网络将分叉 - 每个其他节点将只接受这些并发区块块中的一个。之后，这个分叉将被淘汰。</p>\n<p>在 epoch 中，节点之间相互发送 MPC 消息，以达成共识，谁将被允许在下一个时期生成区块。Data 消息中的有效载荷 （以及事务）会被包含在块中。</p>\n<p>一个地址持有的货币（或『股份』）越多，被选择生成一个区块的可能性就越大。请阅读<a href="/cardano/proof-of-stake/">乌洛波罗斯权益证明算法</a>获取更多细节。</p>\n<p>简而言之:</p>\n<ol>\n<li>发送信息，</li>\n<li>接收信息/交易/等等，</li>\n<li>形成一个区块 (如果你是 slot 领导者的话)，</li>\n<li>重复。</li>\n</ol>\n<h2>商业逻辑</h2>\n<h3>接收者</h3>\n<p>接收者处理传入的消息并对其作出响应。各种补充的听众不会被覆盖，而是集中在一个接收者上。</p>\n<p>接收者大多使用<a href="/technical/protocols/csl-application-level/#invreqdata-and-messagepart">中继框架</a>，其中包括三种类型的消息：</p>\n<ul>\n<li><code>Inventory</code> 消息：节点在获取新数据时向网络发布消息。  </li>\n<li><code>Request</code> 消息：如果某个新数据没有被这个节点获取的话，节点会向其他节点获取在 <code>Inventory</code> 消息中的新数据。  </li>\n<li><code>Data</code> 消息：节点对 <code>Request</code> 消息回复的数据。<code>Data</code>消息包含具体的数据。</li>\n</ul>\n<p>例如，当用户创建新的交易时，钱包将具有交易 ID 的 <code>Inventory</code> 消息发送到网络。如果收到 <code>Inventory</code> 的节点没有该 ID 相关的交易记录，那么它会回复 <code>Request</code> 消息，然后钱包会在 <code>Data</code> 消息中发送该交易信息。节点收到 <code>Data</code> 消息后，将 <code>Inventory</code> 消息发送给 DHT 网络中的邻居，并重复之前的操作。</p>\n<p>另一个例子 - 区块接收者：<a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/src/Pos/Block/Network/Listeners.hs#L30"><code>handleGetHeaders</code></a>，\n<a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/src/Pos/Block/Network/Listeners.hs#L50"><code>handleGetBlocks</code></a>，\n<a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/src/Pos/Block/Network/Listeners.hs#L77"><code>handleBlockHeaders</code></a>。</p>\n<h3>Worker</h3>\n<p>一个 Worker 会在一个时间区间内进行重复性的工作. 比如：</p>\n<ul>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/infra/Pos/Communication/Protocol.hs#L218"><code>onNewSlotWorker</code></a>：在每个插槽的开始时运行。做一些清理，然后运行其他功能。这个 Worker 在这个 epoch 的开始时也会创造了一个 『起始块』。有两种类型的块：『生成块』和『主块』。主块储存在区块链中; 在 epoch 之间，每个节点都会间断性地生成块。主块不会被告知其他节点。但是，如果节点离线一段时间，并且需要同步区块链，节点可以请求其他人的创世区块。</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/d01d392d49db8a25e17749173ec9bce057911191/src/Pos/Block/Worker.hs#L69"><code>blkOnNewSlot</code></a>: 创建一个新块（当轮到节点创建一个新块时），并将其发给其他节点。</li>\n</ul>\n<h2>权益证明</h2>\n<p>卡尔达诺结算层的核心基于 乌洛波罗斯 权益证明算法。正如同名的<a href="https://eprint.iacr.org/2016/889">白皮书</a>所描述的那样。</p>\n<h2>分叉</h2>\n<p>通常，一个链（主链）由一个节点维护，但最终可能会出现分叉链。回想一下，只有区块 <code>k</code> 和更多 slot 被认为是稳定的。这样一来，如果接收一个区块，它既不是区块链的一部分也不是 blockchain 的延续，我们首先检查其复杂程度（复杂性是链的长度）是否比我们的大，TODO</p>\n<p>然后我们开始随后请求来自先前块提供替代链头的节点。如果我们来得深入k插槽前，替代链被拒绝。否则，一旦我们到达我们连锁店中​​存在的区块，替代链就会被添加到存储区。从国家的角度来看，我们存储和维护所有可行的替代链。如果看起来一个替代链比主链更长，那么它们被替换，使替代链成为新的主链。</p>\n<h2>补充部分</h2>\n<h3>Slotting</h3>\n<p>我们使用的共识方案依赖于正确的 slot。更具体地说，它依赖于系统中的节点可以访问的当前时间（小的偏差是可接受的），然后用于确定何时开始和结束任何特定的 slot，并且在该 slot 执行特定的动作。</p>\n<p>系统开始时间是 <code>(0,0)</code> slot 的时间戳（即，第0 epoch 的第0slot）。</p>\n<h2>P2P 网络</h2>\n<h3>Peer 发现</h3>\n<p>我们使用 Kademlia DHT 进行对等节点的发现。这是基于 <a href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf">Kademlia: 基于 XOR 度量的 P2P 信息系统</a> 的哈希表的通用解决方案。</p>\n<p>简言之，在 Kademlia 网络的每个节点都被提供一个 <code>160</code> 字节的随机生成的 id。节点之间的距离由 <code>XOR</code> 确定。网络以这样的方式组织：节点对于每个相对距离：<code>2^i &#x3C; d &#x3C;= 2^(i+1)</code> 只知道 <code>K</code> (在最初的客户端实现中 <code>K=7</code>)。</p>\n<p>初始对等节点通过<a href="https://github.com/serokell/kademlia/blob/bbdca50c263c6dae251e67eb36a7d4e1ba7c1cb6/src/Network/Kademlia/Implementation.hs#L194">发送</a> Kademlia 的 <code>FIND_NODE</code> 信息完成，它带有以自己节点 ID 作为<a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/src/Pos/Constants.hs#L89">预先配置的一组节点</a>以及通过用户命令行输入的节点的参数。我们的实现中会一次<a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/infra/Pos/DHT/Real/Real.hs#L228">发送</a>这个请求给所有已知的对等节点，然后等待第一个回复。</p>\n<p>客户端运行时，每个 Kademlia 协议收集对等节点。已知对等节点在后续启动之间保存，<a href="https://github.com/serokell/kademlia/blob/bbdca50c263c6dae251e67eb36a7d4e1ba7c1cb6/src/Network/Kademlia.hs#L197">恢复</a>。对于每个对等体，我们保存其<a href="https://github.com/serokell/kademlia/blob/bbdca50c263c6dae251e67eb36a7d4e1ba7c1cb6/src/Network/Kademlia/Types.hs#L42">主机和端口号</a>，以及它们的<a href="https://github.com/serokell/kademlia/blob/bbdca50c263c6dae251e67eb36a7d4e1ba7c1cb6/src/Network/Kademlia/Types.hs#L70">节点 id</a>。</p>\n<h3>Messaging</h3>\n<p>Kademlia 已经提供了已知节点的概念。这样的节点可以被称为<em>邻居</em>。要将消息发送到网络上的所有节点，你可以发送给邻居，它们会将其发送给它们的邻居，依次类推。但有时候我们可能不需要在整个网络上传播消息，而是只将消息发送给邻居。因此我们有三种类型的发送消息：</p>\n<ul>\n<li>发送给一个节点，</li>\n<li>发送给邻居，</li>\n<li>发送给网络。</li>\n</ul>\n<h4>消息类型</h4>\n<p>为了处理这个，使用三种消息头，并且有两种消息：</p>\n<ul>\n<li>简单：发送给一个同伴。</li>\n<li>广播：试图发送到整个网络，迭代地发送消息到邻居。</li>\n</ul>\n<p>广播消息在检索（在处理之前）重新发送给邻居。而且，它们会通过 LRU 缓存检查，已经收到的消息会被忽略。</p>\n<h3>领导者和富人计算（LRC）</h3>\n<p>『Slot 领导者』和『富人』是乌洛波罗斯权益证明算法的重要概念。</p>\n<ul>\n<li>\n<p>Slot 领导者：当前 epoch（当前 epoch 的每个 slot） 的 slot 领导者是在而当前 epoch 开始时通过<a href="/cardano/proof-of-stake/#%E8%BF%BD%E9%9A%8F%E4%B8%AD%E6%9C%AC%E8%81%AA">追随中本聪</a>（FTS）计算的。FTS 使用 <code>shared seed</code>，它是前一个 epoch <a href="/cardano/proof-of-stake/#%E5%A4%9A%E6%96%B9%E8%AE%A1%E7%AE%97">多方计算</a>（MPC）算法的结果：MPC 结果中，一些节点揭露它们的 种子，这些种子的 <code>xor</code> 称为 <code>shared seed</code>。</p>\n</li>\n<li>\n<p>富人：只有已经发送 VSS 证书并且有足够权益的节点才能参与 MPC 算法。在 epoch 的开始，节点必须知道所有潜在的参与者以在这个 epoch 中验证 MPC 消息。富人也是在当前 epoch 的开始计算的。</p>\n</li>\n</ul>\n<p>富人对于其他组件也很重要；例如，更新系统使用富人判断节点是否可以发布更新协议和投票。</p>\n<p>有两种计算富人的方法：</p>\n<ul>\n<li>考虑共同权益 </li>\n<li>考虑委派权益（乌洛波洛斯提供委派自己权益给其他节点的机会，更多信息请参阅<a href="/cardano/differences/#%E6%9D%83%E7%9B%8A%E5%A7%94%E6%B4%BE">委派章节</a>。</li>\n</ul>\n<p>MPC 和更新系统组件需要具有委派权益的富人，但不需要拥有共同权益的委派组成。</p>\n<h2>常量</h2>\n<p>卡尔达诺结算层使用一些基础常量。他们的值经过了协议原作者和独立安全评论员的讨论，因此强烈推荐可选客户端使用这些常量。 </p>\n<p>这些常量在\n<a href="https://github.com/input-output-hk/cardano-sl/blob/bf5dd592b7bf77a68bf71314718dc7a8d5cc8877/core/constants.yaml"><code>constants.yaml</code> 配置文件</a>\n中定义，分为生产环境和开发环境。</p>',frontmatter:{path:"/cn/technical-details",doc_title:"技术细节",author:null,date:"2017-01-01",language:"cn",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/2017-01-10-technical.en.md absPath of file >>> MarkdownRemark",excerpt:"\n<!-- Reviewed at d0868afac50ba6ffcbd95054e65cbf77fa513082 -->\n\n# Cardano SL Technical Details\n\nThis section is a starting point for developers who wish to contribute to the\noriginal client, as well as those who wish to undertake making their own client\nfor Cardano SL. Nonetheless, this section covers the original client to great\nextent, assuming that it will be the initial reference client for some time.\n",html:'<!-- Reviewed at d0868afac50ba6ffcbd95054e65cbf77fa513082 -->\n<h1>Cardano SL Technical Details</h1>\n<p>This section is a starting point for developers who wish to contribute to the\noriginal client, as well as those who wish to undertake making their own client\nfor Cardano SL. Nonetheless, this section covers the original client to great\nextent, assuming that it will be the initial reference client for some time.</p>\n<!-- end -->\n<h2>High-level overview</h2>\n<p>A Cardano SL node is a blockchain node. When ran, it finds other nodes (via\n<a href="http://ast-deim.urv.cat/cpairot/dhts.html">DHT</a>) and then starts performing\nblockchain-related procedures.</p>\n<p>Time in Cardano SL is divided into <em>epochs</em>. Every epoch is divided into\n<em>slots</em>. Epochs and slots are numbered. Therefore, the slot <code>(3,5)</code> is read as\n"the fifth slot of the third epoch" (the 0-th slot and the 0-th epoch are also\npossible).</p>\n<p>Cardano SL uses sets of constants, special values defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/bf5dd592b7bf77a68bf71314718dc7a8d5cc8877/core/constants.yaml">the <code>constants.yaml</code> configuration file</a>.\nThere are two main sets: for production mode and development mode. In this guide\nwe\'ll refer to productions constants.</p>\n<p>Suppose the values for Cardano SL are:</p>\n<ul>\n<li>slot duration: 120 seconds,</li>\n<li>security parameter <em>k</em>: 60.</li>\n</ul>\n<p>In other words, <strong>a slot lasts 120 seconds</strong>, and an epoch has <a href="https://github.com/input-output-hk/cardano-sl/blob/9ee12d3cc9ca0c8ad95f3031518a4a7acdcffc56/core/Pos/Core/Constants/Raw.hs#L161"><code>10×k</code></a>\nslots in it, so it lasts <strong>1200 minutes</strong> or <strong>20 hours</strong>.</p>\n<p>There is one node called the slot leader on each slot. Only this node has right\nto generate a new block during this slot; this block will be added to the\nblockchain. However, there\'s no guarantee that new block will be actually\ngenerated (e.g. slot leader can be offline during a corresponding slot).</p>\n<p>Furthermore, slot leader may delegate its right to another node <code>N</code>; in this\ncase node <code>N</code> will have a right to generate a new block instead of slot leader.\nPlease note that node <code>N</code> with delegated right is not called a slot leader\nthough, it is just a delegate.</p>\n<p>It\'s theoretically possible to delegate the slot leader\'s right to multiple\nnodes, but it is <strong>not</strong> recommended by reasons explained later. Moreover, we can\nrun multiple nodes with the same key (i.e. on one computer), let\'s say nodes\n<code>A</code>, <code>B</code> and <code>C</code>, and if node <code>A</code> is elected as the slot leader, not only <code>A</code>\nitself, but nodes <code>B</code> and <code>C</code> will be able to generate a new block as well. In\nthis case, every one of these nodes will issue a most probably different block,\nand the network will fork — each other node will accept <strong>only one</strong> of these\nconcurrent blocks. Later, this fork will be eliminated.</p>\n<p>During the epoch, nodes send each other MPC messages to come to the consensus as\nto who would be allowed to generate blocks in the next epoch. Payloads from\n<code>Data</code> messages (along with transactions) are included into blocks.</p>\n<p>The more currency (or "stake") an address holds, the more likely it is to be\nchosen to generate a block. Please read about <a href="/cardano/proof-of-stake/">Ouroboros Proof of Stake Algorithm</a>\nfor more details.</p>\n<p>In short:</p>\n<ol>\n<li>send messages,</li>\n<li>receive messages/transactions/etc,</li>\n<li>form a block (if you are the slot leader),</li>\n<li>repeat.</li>\n</ol>\n<h2>Business logic</h2>\n<h3>Listeners</h3>\n<p>Listeners handle incoming messages and respond to them. Various supplemental\nlisteners will not be covered, focusing on the main ones instead.</p>\n<p>Listeners mostly use the <a href="/en/technical/protocols/csl-application-level/#invreqdata-and-messagepart">Relay\nframework</a>,\nwhich includes three type of messages:</p>\n<ul>\n<li><code>Inventory</code> message: node publishes message to network when gets a new data.</li>\n<li><code>Request</code> message: node requests a new data which was published in\n<code>Inventory</code> message, from other node, if this data is not known yet by\nthis node.</li>\n<li><code>Data</code> message: node replies with this message on <code>Request</code> message. <code>Data</code>\nmessage contains concrete data.</li>\n</ul>\n<p>For instance, when a user creates a new transaction, the wallet sends\n<code>Inventory</code> message with transaction id to the network. If the node that has\nreceived <code>Inventory</code> doesn\'t know any transaction with such id, then it replies\nwith <code>Request</code> message, after that the wallet sends this transaction in <code>Data</code>\nmessage. After the node has received the <code>Data</code> message, it can send the\n<code>Inventory</code> message to its neighbors in DHT network and repeat previous\niterations again.</p>\n<p>Another example - block listeners <a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/src/Pos/Block/Network/Listeners.hs#L30"><code>handleGetHeaders</code></a>,\n<a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/src/Pos/Block/Network/Listeners.hs#L50"><code>handleGetBlocks</code></a>,\n<a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/src/Pos/Block/Network/Listeners.hs#L77"><code>handleBlockHeaders</code></a>.</p>\n<h3>Workers</h3>\n<p>A Worker is an action repeated with some interval. For example:</p>\n<ul>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/69e896143cb02612514352e286403852264f0ba3/infra/Pos/Communication/Protocol.hs#L218"><code>onNewSlotWorker</code></a>: Runs at the beginning of each slot. Does some cleanup and\nthen runs additional functions. This worker also creates a\n<em>genesis block</em> at the beginning of the epoch. There are two kinds of\nblocks: "genesis blocks" and "main blocks". Main blocks are stored in the\nblockchain; genesis blocks are generated by each node internally between\nepochs. Genesis blocks aren\'t announced to other nodes. However, a node may\nrequest a genesis block from someone else for convenience, if this node was\noffline for some time and needs to catch up with the blockchain.</li>\n<li><a href="https://github.com/input-output-hk/cardano-sl/blob/d01d392d49db8a25e17749173ec9bce057911191/src/Pos/Block/Worker.hs#L69"><code>blkOnNewSlot</code></a>: Creates\na new block (when it is the node\'s turn to create a new block) and announces it\nto other nodes.</li>\n</ul>\n<h2>Proof of Stake</h2>\n<p>At the heart of Cardano SL sits the Ouroboros Proof of Stake protocol, as\ndescribed in <a href="https://eprint.iacr.org/2016/889">the whitepaper</a> of the same\nname.</p>\n<h2>Forks</h2>\n<p>Generally, one chain (the <em>main chain</em>) is maintained by a node, but eventually\nalternative chains may arise. Recall that only blocks <code>k</code> and more slots deep are\nconsidered stable. This way, if a block which is neither a part nor a\ncontinuation of our blockchain is received, we first check if its complexity is\nbigger than ours (the complexity is the length of the chain), and then we start\nsubsequently requesting previous blocks from the node that provided an\nalternative chain header. If we come deeper than <code>k</code> slots ago, the alternative\nchain gets rejected. Otherwise, once we get to the block existing in our chain,\nthe alternative chain is added to storage. From the standpoint of state, we\nstore and maintain all the alternative chains that are viable. If it appears\nthat an alternative chain is longer than the main chain, they are swapped,\nmaking the alternative chain the new main chain.</p>\n<h2>Supplemental parts</h2>\n<h3>Slotting</h3>\n<p>The consensus scheme we use relies on correct slotting. More specifically, it\nrelies on the assumption that nodes in the system have access to the current\ntime (small deviations are acceptable), which is then used to figure out when\nany particular slot begins and ends, and perform particular actions in this\nslot.</p>\n<p>System start time is a timestamp of the <code>(0,0)</code> slot (i.e. the 0-th slot of the 0-th\nepoch).</p>\n<h2>P2P Network</h2>\n<h3>Peer discovery</h3>\n<p>We use Kademlia DHT for peer discovery. It is a general solution for distributed\nhash tables, based on <a href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf">a whitepaper by Petar Maymounkov and David Mazières,\n2002</a>.</p>\n<p>However, we only take advantage of its peer discovery mechanism, and use none of\nits hash table capabilities.</p>\n<p>In short, each node in the Kademlia network is provided a <code>160</code>-bit id generated\nrandomly. The distance between the nodes is defined by <code>XOR</code> metric. The network\nis organized in such a way that node knows no more than <code>K</code> (<code>K=7</code> in the\noriginal client implementation) nodes for each relative distance range:\n<code>2^i &#x3C; d &#x3C;= 2^(i+1)</code>.</p>\n<p>Initial peer discovery is done by\n<a href="https://github.com/serokell/kademlia/blob/bbdca50c263c6dae251e67eb36a7d4e1ba7c1cb6/src/Network/Kademlia/Implementation.hs#L194">sending</a>\na Kademlia <code>FIND_NODE</code> message with our own node id as a parameter to <a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/src/Pos/Constants.hs#L89">a\npre-configured set of\nnodes</a>\nand the nodes passed by the user on the command line. Our implementation\n<a href="https://github.com/input-output-hk/cardano-sl/blob/43a2d079a026b90ba860e79b5be52d1337e26c6f/infra/Pos/DHT/Real/Real.hs#L228">sends</a>\nthis request to all known peers at once and then waits for the first reply.</p>\n<p>While the client runs, it collects peers per Kademlia protocol. The list of\nknown peers is preserved and\n<a href="https://github.com/serokell/kademlia/blob/bbdca50c263c6dae251e67eb36a7d4e1ba7c1cb6/src/Network/Kademlia.hs#L197">restored</a>\nbetween subsequent launches. For each peer, we keep their <a href="https://github.com/serokell/kademlia/blob/bbdca50c263c6dae251e67eb36a7d4e1ba7c1cb6/src/Network/Kademlia/Types.hs#L42">host and port\nnumber</a>,\nas well as their <a href="https://github.com/serokell/kademlia/blob/bbdca50c263c6dae251e67eb36a7d4e1ba7c1cb6/src/Network/Kademlia/Types.hs#L70">node\nid</a>.</p>\n<h3>Messaging</h3>\n<p>Kademlia already provides the notion of nodes that are known. Such nodes can be\ncalled <em>neighbors</em>. To send message to all nodes in a network, you can send it\nto neighbors, they will resend it to their neighbors, and so on. But sometimes\nwe may need to not propagate messages across all network, but send it to\nneighbors only. Hence we have three types of sending messages:</p>\n<ul>\n<li>send to a node,</li>\n<li>send to neighbors,</li>\n<li>send to network.</li>\n</ul>\n<h4>Message types</h4>\n<p>To handle this, three kind of message headers are used, and there are two\nmessage types:</p>\n<ul>\n<li>Simple: sending to a single peer.</li>\n<li>Broadcast: attempting to send to the entire network, iteratively sending\nmessages to neighbors.</li>\n</ul>\n<p>Broadcast messages are resent to neighbors right after retrieval (before\nhandling). Also, they are being checked against LRU cache, and messages that\nhave been already received once get ignored.</p>\n<h3>Leaders and rich men computation (LRC)</h3>\n<p>"Slot leaders" and "rich men" are two important notions of Ouroboros Proof of\nStake Algorithm.</p>\n<ul>\n<li>\n<p>Slot leaders: Slot leaders for the current epoch (for each slot of the\ncurrent epoch) are computed by <a href="/en/cardano/proof-of-stake/#follow-the-satoshi">Follow the\nSatoshi</a> (FTS) algorithm in the\nbeginning of current epoch. FTS uses a <code>shared seed</code> which is result of\n<a href="/en/cardano/proof-of-stake/#multi-party-computation">Multi Party Computation</a>\n(MPC) algorithm for previous epoch: in the result of MPC some nodes reveal\ntheir seeds, <code>xor</code> of these seeds is called <code>shared seed</code>.</p>\n</li>\n<li>\n<p>Rich men: Only nodes that have sent their VSS certificates and also have\nenough stake can participate in the MPC algorithm. So in the beginning of\nepoch node must know all potential participants for validation of MPC\nmessages during this epoch. Rich men are also computed in the beginning of\ncurrent epoch.</p>\n</li>\n</ul>\n<p>Rich men are important for other components as well; for instance, Update system\nuses rich men for checking that node can publish update proposal and vote.</p>\n<p>There are two ways of computing who the rich men will be: - considering common\nstake - considering delegated stake (Ouroboros provides opportunity to delegate\nown stake to other node, see more in <a href="/en/cardano/differences/#stake-delegation">Delegation\nsection</a>)</p>\n<p>MPC and Update System components need rich men with delegated stake, but\nDelegation component with common stake.</p>\n<h2>Constants</h2>\n<p>Cardano SL uses a list of the fundamental constants. Their values have been\ndiscussed with the original authors of the protocol as well as independent\nsecurity auditors, so reusing these constants is strongly recommended for\nalternative clients.</p>\n<p>Values of these constants are defined in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/bf5dd592b7bf77a68bf71314718dc7a8d5cc8877/core/constants.yaml">the <code>constants.yaml</code> configuration file</a>,\nfor production and development environments separately.</p>',frontmatter:{path:"/en/technical-details/",doc_title:"Technical details",author:null,date:"2017-01-02",language:"en",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/2017-01-04-installation.en.md absPath of file >>> MarkdownRemark",excerpt:"\n# Installation\n\n## Supported Platforms\n\nSupported platforms are Windows, macOS and Linux. There are\n[installers for Windows and macOS](https://daedaluswallet.io/#download),\nwhich include a main node and [Daedalus wallet](https://github.com/input-output-hk/daedalus).\n\nLinux installer is going to be released soon. Currently, there are two options to\nget Cardano SL on Linux:\n",html:'<h1>Installation</h1>\n<h2>Supported Platforms</h2>\n<p>Supported platforms are Windows, macOS and Linux. There are\n<a href="https://daedaluswallet.io/#download">installers for Windows and macOS</a>,\nwhich include a main node and <a href="https://github.com/input-output-hk/daedalus">Daedalus wallet</a>.</p>\n<p>Linux installer is going to be released soon. Currently, there are two options to\nget Cardano SL on Linux:</p>\n<!-- end -->\n<ol>\n<li>Build from the source code (recommended). Please refer to <a href="https://github.com/input-output-hk/cardano-sl/blob/develop/docs/how-to/build-cardano-sl-and-daedalus-from-source-code.md">How to Build Cardano SL and Daedalus from\nSource Code</a> manual.</li>\n<li>\n<p>Use <strong>unofficial</strong> packages for Arch Linux:</p>\n<ul>\n<li><a href="https://aur.archlinux.org/packages/cardano-sl/">cardano-sl</a></li>\n<li><a href="https://aur.archlinux.org/packages/daedalus-bridge/">daedalus-bridge</a></li>\n<li><a href="https://aur.archlinux.org/packages/daedalus/">daedalus</a></li>\n</ul>\n</li>\n</ol>',frontmatter:{path:"/en/installation/",doc_title:"Installation",author:null,date:"2017-01-03",language:"en",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/2017-01-13-for-contributors.en.md absPath of file >>> MarkdownRemark",excerpt:"Cardano contributing guide: Can be found here  https://github.com/input-output-hk/cardano-sl/blob/develop/CONTRIBUTING.md",html:'<h2>Cardano contributing guide:</h2>\n<p>Can be found here <a href="https://github.com/input-output-hk/cardano-sl/blob/develop/CONTRIBUTING.md">https://github.com/input-output-hk/cardano-sl/blob/develop/CONTRIBUTING.md</a></p>',frontmatter:{path:"/en/for-contributors/",doc_title:"For Contributors",author:null,date:"2017-01-04",language:"en",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/2017-01-19-glossary.en.md absPath of file >>> MarkdownRemark",excerpt:"\n<!-- Reviewed at d0d6c2fedefb642744a24b4b0a6d8d7ad11532f6 -->\n\n# Glossary\n\n## Ada\n\nThe name of our currency, named in honor of [Ada\nLovelace](https://en.wikipedia.org/wiki/Ada_Lovelace).\n\n## Address\n\nThe unique identifier of a [node](#node). Please read about [Addresses in\nCardano SL](/en/cardano/addresses/) for more details.\n\n## Balance\n\nPlease read about [Balance and Stake in Cardano SL](/en/cardano/balance-and-stake/)\nfor explanation.\n\n## Block\n\nA fundamental part of a [Ledger](#ledger). Please read about [Blocks in Cardano\nSL](/en/technical/blocks/) for technical details.\n\n## Blockchain\n\nPlease see [Ledger](#ledger).\n\n## Cardano SL\n\nCardano SL (or Cardano Settlement Layer) is a decentralized cryptographic\ncurrency designed and developed by [IOHK](https://iohk.io/team). Named in honor\nof [Gerolamo Cardano](https://en.wikipedia.org/wiki/Gerolamo_Cardano).\n\n## Coin Tossing\n\nA Coin Tossing is a protocol that allows two or more parties to obtain\na uniformly random value. We use Coin Tossing protocol as a base of [SSC](#ssc).\nPlease read [paper](#paper) (page 36) for more details about Coin Tossing.\n\n## Consensus Algorithm\n\nA way for a decentralized system to reach a consistent view on shared\ncollections of data. Cardano SL uses the [Ouroboros Consensus\nAlgorithm](/en/cardano/proof-of-stake/), which is an algorithm based on\n[Proof of Stake](#proof-of-stake).\n\n## Cryptocurrency\n\nA computer system which uses cryptographic protocols to generate a ledger.\nPlease read about [Cryptocurrency Basics](/introduction/#cryptocurrency-basics)\nfor more details.\n\n## Daedalus\n\nCardano SL wallet application. It provides a GUI for users, so they can access\ntheir funds, send and receive transactions, etc. Please read about [Cardano SL\nWallet Frontend](/en/technical/wallet-frontend/) for more details.\n\n## Decentralization\n\nA notion of a computer system operating through interaction of independent\nnodes. In case of maintaining a shared data collection such as a ledger, a\nconsensus is required for consistency and reliability of data.\n\n## Epoch\n\nA bigger period of time for which we know in advance who will have the right to\ngenerate a block in each slot. Please read [paper](#paper) (page 3) for\ntechnical details.\n\n## Follow The Satoshi\n\nA mechanism whereby stakeholders are selected at random to forge a new block in\nthe blockchain, with a proportional chance to get elected depending on their\namount of stake in the protocol.\n\n## Guaranteed Output Delivery\n\nGuaranteed output delivery is a mechanism that proves that the honest parties\nare guaranteed to successfully complete the multiparty computation (MPC). We\nuse G.O.D. in [SSC](#ssc).\n\n## Honest Majority\n\nHonest majority is a situation when the number of honest participants is strictly\ngreater than the number of adversaries, i.e. at least 50% + 1. Honest majority \nis assumed by default.\n\n## Kademlia\n\nPlease see [Peer Discovery](#peer-discovery).\n\n## Leader Election\n\nA process of picking who will generate blocks during the next epoch. Leaders are\nelected with a probability proportional to their stake (see [Proof of\nStake](#proof-of-stake), [Follow the Satoshi](#follow-the-satoshi)).\n\n## Ledger\n\nA collection of data that keeps track of value assigned to individuals. Please\nread [paper](#paper) (page 32) for technical details.\n\n## Lovelace\n\nName of a smallest unit of our currency. Named in honor of [Ada\nLovelace](https://en.wikipedia.org/wiki/Ada_Lovelace).\n\n## Minting\n\nA process of a new block creation in [Proof of\nStake](/introduction/#proof-of-stake-and-minting) systems.\n\n## Node\n\nA computer program that participates in a decentralized protocol system. Please\nread [High-level technical overview](/en/technical/#high-level-overview) for more\ndetails.\n\n## Paper\n\nOfficial protocol report [Ouroboros: A Provably Secure Proof-of-Stake Blockchain\nProtocol](https://eprint.iacr.org/2016/889). Please notice that Cardano SL\nimplementation differs from the paper, [read about\ndifferences](/en/cardano/differences/) for more details.\n\n## Peer Discovery\n\nA way how a node can find other nodes after running. Peer discovery we use is\nbased on Kademlia DHT. Please read [a Kademlia\npaper](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf)\nfor technical details.\n\n## Plutus\n\nStrictly typed pure functional programming language used for defining smart\ncontracts in Cardano. Please read about\n[Plutus](/en/en/technical/plutus/introduction/) for more details.\n\n## Proof of Stake\n\nOuroboros Proof of Stake algorithm is the most important part of the [protocol](#paper).\nIt defines the way [nodes](#node) reach consensus about the state of [ledger](#ledger).\nPlease read about [Ouroboros Proof of Stake Algorithm](/en/cardano/proof-of-stake/)\nfor more details.\n\n## PVSS\n\nPVSS (Publicly Verifiable Secret Sharing) is a cryptographic scheme we use in [SSC](#ssc).\nPlease read about [PVSS implementation in Cardano SL](/en/technical/pvss/) for more details.\n\n## Richman\n\nStakeholder with stake enough for participation in some action. Particularly,\nthere are three kinds of such actions: randomness generation (for [slot leaders\nelections process](/en/technical/leader-selection/)),\n[heavyweight stake delegation](/en/technical/delegation/#heavyweight-delegation)\nand voting for [update proposals](/en/cardano/update-mechanism/#application-update-sign-and-announce).\n\n## Signing\n\nA way to generate a proof of genuine authenticity of any kind of information we\nuse in [cryptocurrency](#cryptocurrency).\n\n## Slot\n\nA small period of physical time that is significantly larger than the expected\ndifference in clocks on different nodes. Please read [paper](#paper) (page 4) for\ntechnical details.\n\n## Slot Leader\n\nA slot leader is a node which was elected to have a right to create a block in\nthe current slot. Please read [paper](#paper) (page 7) for technical details.\n\n## SSC\n\nSSC (Shared Seed Computation) is a part of [slot leader election](#leader-election)\nprocess. This part is implemented as a [Coin Tossing](#coin-tossing) protocol with\n[Guaranteed Output Delivery](#guaranteed-output-delivery). As a result of SSC we get\na randomness which will be used in [Follow The Satoshi](#follow-the-satoshi) mechanism.\n\n## Stake\n\nPlease read about [Balance and Stake in Cardano SL](/en/cardano/balance-and-stake/)\nfor explanation.\n\n## Stakeholder\n\nA node with a positive stake.\n\n## Transaction\n\nThe data that represents the act of transferring value. Please read about\n[Transactions in Cardano SL](/en/cardano/transactions/) for more details.\n\n## Transaction Fees\n\nPlease read about [Transaction Fees in Cardano SL](/en/cardano/transaction-fees/)\nfor explanation.\n",
  html:'<!-- Reviewed at d0d6c2fedefb642744a24b4b0a6d8d7ad11532f6 -->\n<h1>Glossary</h1>\n<h2>Ada</h2>\n<p>The name of our currency, named in honor of <a href="https://en.wikipedia.org/wiki/Ada_Lovelace">Ada\nLovelace</a>.</p>\n<h2>Address</h2>\n<p>The unique identifier of a <a href="#node">node</a>. Please read about <a href="/en/cardano/addresses/">Addresses in\nCardano SL</a> for more details.</p>\n<h2>Balance</h2>\n<p>Please read about <a href="/en/cardano/balance-and-stake/">Balance and Stake in Cardano SL</a>\nfor explanation.</p>\n<h2>Block</h2>\n<p>A fundamental part of a <a href="#ledger">Ledger</a>. Please read about <a href="/en/technical/blocks/">Blocks in Cardano\nSL</a> for technical details.</p>\n<h2>Blockchain</h2>\n<p>Please see <a href="#ledger">Ledger</a>.</p>\n<h2>Cardano SL</h2>\n<p>Cardano SL (or Cardano Settlement Layer) is a decentralized cryptographic\ncurrency designed and developed by <a href="https://iohk.io/team">IOHK</a>. Named in honor\nof <a href="https://en.wikipedia.org/wiki/Gerolamo_Cardano">Gerolamo Cardano</a>.</p>\n<h2>Coin Tossing</h2>\n<p>A Coin Tossing is a protocol that allows two or more parties to obtain\na uniformly random value. We use Coin Tossing protocol as a base of <a href="#ssc">SSC</a>.\nPlease read <a href="#paper">paper</a> (page 36) for more details about Coin Tossing.</p>\n<h2>Consensus Algorithm</h2>\n<p>A way for a decentralized system to reach a consistent view on shared\ncollections of data. Cardano SL uses the <a href="/en/cardano/proof-of-stake/">Ouroboros Consensus\nAlgorithm</a>, which is an algorithm based on\n<a href="#proof-of-stake">Proof of Stake</a>.</p>\n<h2>Cryptocurrency</h2>\n<p>A computer system which uses cryptographic protocols to generate a ledger.\nPlease read about <a href="/introduction/#cryptocurrency-basics">Cryptocurrency Basics</a>\nfor more details.</p>\n<h2>Daedalus</h2>\n<p>Cardano SL wallet application. It provides a GUI for users, so they can access\ntheir funds, send and receive transactions, etc. Please read about <a href="/en/technical/wallet-frontend/">Cardano SL\nWallet Frontend</a> for more details.</p>\n<h2>Decentralization</h2>\n<p>A notion of a computer system operating through interaction of independent\nnodes. In case of maintaining a shared data collection such as a ledger, a\nconsensus is required for consistency and reliability of data.</p>\n<h2>Epoch</h2>\n<p>A bigger period of time for which we know in advance who will have the right to\ngenerate a block in each slot. Please read <a href="#paper">paper</a> (page 3) for\ntechnical details.</p>\n<h2>Follow The Satoshi</h2>\n<p>A mechanism whereby stakeholders are selected at random to forge a new block in\nthe blockchain, with a proportional chance to get elected depending on their\namount of stake in the protocol.</p>\n<h2>Guaranteed Output Delivery</h2>\n<p>Guaranteed output delivery is a mechanism that proves that the honest parties\nare guaranteed to successfully complete the multiparty computation (MPC). We\nuse G.O.D. in <a href="#ssc">SSC</a>.</p>\n<h2>Honest Majority</h2>\n<p>Honest majority is a situation when the number of honest participants is strictly\ngreater than the number of adversaries, i.e. at least 50% + 1. Honest majority\nis assumed by default.</p>\n<h2>Kademlia</h2>\n<p>Please see <a href="#peer-discovery">Peer Discovery</a>.</p>\n<h2>Leader Election</h2>\n<p>A process of picking who will generate blocks during the next epoch. Leaders are\nelected with a probability proportional to their stake (see <a href="#proof-of-stake">Proof of\nStake</a>, <a href="#follow-the-satoshi">Follow the Satoshi</a>).</p>\n<h2>Ledger</h2>\n<p>A collection of data that keeps track of value assigned to individuals. Please\nread <a href="#paper">paper</a> (page 32) for technical details.</p>\n<h2>Lovelace</h2>\n<p>Name of a smallest unit of our currency. Named in honor of <a href="https://en.wikipedia.org/wiki/Ada_Lovelace">Ada\nLovelace</a>.</p>\n<h2>Minting</h2>\n<p>A process of a new block creation in <a href="/introduction/#proof-of-stake-and-minting">Proof of\nStake</a> systems.</p>\n<h2>Node</h2>\n<p>A computer program that participates in a decentralized protocol system. Please\nread <a href="/en/technical/#high-level-overview">High-level technical overview</a> for more\ndetails.</p>\n<h2>Paper</h2>\n<p>Official protocol report <a href="https://eprint.iacr.org/2016/889">Ouroboros: A Provably Secure Proof-of-Stake Blockchain\nProtocol</a>. Please notice that Cardano SL\nimplementation differs from the paper, <a href="/en/cardano/differences/">read about\ndifferences</a> for more details.</p>\n<h2>Peer Discovery</h2>\n<p>A way how a node can find other nodes after running. Peer discovery we use is\nbased on Kademlia DHT. Please read <a href="https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf">a Kademlia\npaper</a>\nfor technical details.</p>\n<h2>Plutus</h2>\n<p>Strictly typed pure functional programming language used for defining smart\ncontracts in Cardano. Please read about\n<a href="/en/en/technical/plutus/introduction/">Plutus</a> for more details.</p>\n<h2>Proof of Stake</h2>\n<p>Ouroboros Proof of Stake algorithm is the most important part of the <a href="#paper">protocol</a>.\nIt defines the way <a href="#node">nodes</a> reach consensus about the state of <a href="#ledger">ledger</a>.\nPlease read about <a href="/en/cardano/proof-of-stake/">Ouroboros Proof of Stake Algorithm</a>\nfor more details.</p>\n<h2>PVSS</h2>\n<p>PVSS (Publicly Verifiable Secret Sharing) is a cryptographic scheme we use in <a href="#ssc">SSC</a>.\nPlease read about <a href="/en/technical/pvss/">PVSS implementation in Cardano SL</a> for more details.</p>\n<h2>Richman</h2>\n<p>Stakeholder with stake enough for participation in some action. Particularly,\nthere are three kinds of such actions: randomness generation (for <a href="/en/technical/leader-selection/">slot leaders\nelections process</a>),\n<a href="/en/technical/delegation/#heavyweight-delegation">heavyweight stake delegation</a>\nand voting for <a href="/en/cardano/update-mechanism/#application-update-sign-and-announce">update proposals</a>.</p>\n<h2>Signing</h2>\n<p>A way to generate a proof of genuine authenticity of any kind of information we\nuse in <a href="#cryptocurrency">cryptocurrency</a>.</p>\n<h2>Slot</h2>\n<p>A small period of physical time that is significantly larger than the expected\ndifference in clocks on different nodes. Please read <a href="#paper">paper</a> (page 4) for\ntechnical details.</p>\n<h2>Slot Leader</h2>\n<p>A slot leader is a node which was elected to have a right to create a block in\nthe current slot. Please read <a href="#paper">paper</a> (page 7) for technical details.</p>\n<h2>SSC</h2>\n<p>SSC (Shared Seed Computation) is a part of <a href="#leader-election">slot leader election</a>\nprocess. This part is implemented as a <a href="#coin-tossing">Coin Tossing</a> protocol with\n<a href="#guaranteed-output-delivery">Guaranteed Output Delivery</a>. As a result of SSC we get\na randomness which will be used in <a href="#follow-the-satoshi">Follow The Satoshi</a> mechanism.</p>\n<h2>Stake</h2>\n<p>Please read about <a href="/en/cardano/balance-and-stake/">Balance and Stake in Cardano SL</a>\nfor explanation.</p>\n<h2>Stakeholder</h2>\n<p>A node with a positive stake.</p>\n<h2>Transaction</h2>\n<p>The data that represents the act of transferring value. Please read about\n<a href="/en/cardano/transactions/">Transactions in Cardano SL</a> for more details.</p>\n<h2>Transaction Fees</h2>\n<p>Please read about <a href="/en/cardano/transaction-fees/">Transaction Fees in Cardano SL</a>\nfor explanation.</p>\n<!-- end -->',frontmatter:{path:"/en/glossary/",doc_title:"Glossary",author:null,date:"2017-01-05",language:"en",label:"docs",keywords:null,group:"base"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/content/welcome-text.en.md absPath of file >>> MarkdownRemark",excerpt:"亲爱的读者，本文档的目的是让您对于 Cardano 平台技术栈第一层即结算层有所了解。如果您理解了结算层是什么，我们建议您先阅读论文和实现的差异，然后再阅读协议和实现的文档。 本文档目标读者是 IOHK…",html:"<p>亲爱的读者，本文档的目的是让您对于 Cardano 平台技术栈第一层即结算层有所了解。如果您理解了结算层是什么，我们建议您先阅读论文和实现的差异，然后再阅读协议和实现的文档。</p>\n<p>本文档目标读者是 IOHK 的开发人员，第三方软件开发人员，审计和致力于实现卡尔达诺结算层或使用卡尔达诺结算层参考实现的咨询人员。</p>",frontmatter:{path:"/cn/welcome-text/",doc_title:null,author:null,date:null,language:"cn",label:"content",keywords:"welcome",group:null}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/cn/content/intro.cn.md absPath of file >>> MarkdownRemark",excerpt:"WHAT IS CARDANO SL? Cardano SL (or Cardano Settlement Layer) is a cryptographic currency designed and developed by IOHK in conjunction with…",html:"<h3>WHAT IS CARDANO SL?</h3>\n<p>Cardano SL (or Cardano Settlement Layer) is a cryptographic currency designed and developed by IOHK in conjunction with the University of Edinburgh, the University of Athens and the University of Connecticut. Cardano SL is based on the Haskell implementation of the white paper “Ouroboros: A Provably Secure Proof of Stake Blockchain Protocol” by Aggelos Kiayias, Alexander Russell, Bernardo David and Roman Oliynykov.</p>\n<p>You can think of Cardano SL as Bitcoin reimagined with a freedom to fix Bitcoin’s design flaws. Please read “What Makes Cardano SL Special?” for more information about similarities and differences between Cardano SL and Bitcoin.\nCRYPTOCURRENCY BASICS\nBefore giving a definition of a cryptocurrency, let’s talk about why we care about digital currencies in general and cryptographic currencies in particular.</p>\n<h3>WHY DO WE CARE?</h3>\n<ul>\n<li>\n<h5>SPEED</h5>\n<p>As opposed to conventional (also known as fiat), centrally banked currencies, such as the Yen or the American Dollar, digital currencies do not require a banking system to move value. With this restriction lifted, working with digital currencies is much faster than working with banking, especially on a global scale. Transferring 10 USD from Osaka to Denver no longer takes days when a digital currency is used. All transactions are made rapidly regardless of the distance.</p>\n</li>\n<li>\n<h5>YOU OWN YOUR MONEY</h5>\n<p>All that a commercial bank account owner is given is a promise of being paid a certain amount of money within a reasonable amount of time after receiving a payout request. Banking systems also have limits to any volume of value being moved, rendering an individual unable to withdraw or transfer large amounts quickly. In case of cryptocurrencies, the person who holds a special kind of information called a secret key can spend the money at will. No other entity has a power to manipulate the value that a user owns.</p>\n</li>\n<li>\n<h5>PSEUDONYMITY</h5>\n<p>One can have as many cryptocurrency addresses as they wish, receiving and spending money from different addresses as per their purpose. A merchant running an E-Commerce shop can have a set of addresses for receiving money and issuing refunds, and a separate personal “wallet” for their own needs. A single interface is used to control all of these wallets, and there is no need to log in to several payment platforms, which makes the process very time-efficient.</p>\n</li>\n<li>\n<h5>SECURITY</h5>\n<p>Your money is as secure as the secret key that allows spending it. This means that storing your secret key on a USB flash drive in a safe is equivalent to having banknotes in a safe. Absolutely nobody can steal this money even by carrying out a successful cyberattack.</p>\n</li>\n</ul>\n<h3>EXTENSIBILITY</h3>\n<p>Using an approach known as side chains, general purpose cryptocurrencies such as Cardano SL or Bitcoin can enable domain specific cryptocurrencies, such as Ethereum Classic. This way, any innovation developed via domain specific cryptocurrency can have participants who hold value in a general purpose cryptocurrency. Examples of such applications are identity management, gaming and gambling, and verifiable computations.</p>\n<h3>WHAT IS A CRYPTOCURRENCY?</h3>\n<p>Cryptocurrency is a form of digital currency that uses cryptography to manipulate value. Cryptography provides a way to generate proof of genuine authenticity of any kind of information. This is called digital signing. In cryptocurrencies we generate a ledger (a database which provides information on how much money each address has) by signing and sending transactions to the network and receiving blocks of confirmed transactions. Cryptocurrencies are normally decentralized, meaning that many people from all over the globe participate in ledger generation by running cryptocurrency nodes. Thus, a consensus about the state of the ledger has to be achieved. Two most significant approaches for achieving such consensus are discussed in the next section.</p>\n<h3>WHAT MAKES CARDANO SL SPECIAL?</h3>\n<p>While there are similarities between Bitcoin and Cardano SL, there are also many differences between these two cryptocurrencies. The most significant difference is that Bitcoin is a proof of work type cryptocurrency, while Cardano SL makes use of a proof of stake approach to reach consensus. This encourages honesty and long term participation.</p>\n<h3>PURPOSE OF A CONSENSUS ALGORITHM</h3>\n<p>Consensus algorithms are used to produce new transaction blocks, resulting in an updated state of the ledger. Whenever someone publishes a block of transactions, they — or rather, their node that runs the cryptocurrency protocol — have to attach a proof that they have merited it. Below two types of such proofs are discussed.</p>\n<h3>PROOF OF WORK AND MINING</h3>\n<p>Proof of work is the most common consensus algorithm type for cryptocurrencies. It originated in Bitcoin, and this is how this cryptocurrency works. To generate proof of work, a computer has to solve a challenge. The challenge is a computationally heavy problem which is hard to solve, but the solution is easy to verify. When a computer on a proof of work based network finds a solution, it publishes it along with the transactions that the computer has been observing while cracking the problem. The owner of this computer collects the transaction fees and a reward for generating a block. The entire process is called mining. Mining is very energy consuming, and the amount of energy needed is constantly increasing, which can lead to unsound competition.</p>\n<h3>PROOF OF STAKE AND MINTING</h3>\n<p>Proof of stake is a novel approach to block generation. IOHK scientists led by Prof. Aggelos Kiayias have designed the first provably secure proof of stake algorithm called Ouroboros. Ouroboros lies at the heart of Cardano SL. Research team has published a white paper that is a worthy read for anyone with a background in cryptocurrency theory. The core idea of proof of stake is that instead of wasting electricity on cracking computationally heavy problems, a node is selected to mint a new block, with a probability proportional to the amount of coins this node has. If a node has positive (> 0) stake, it is called a stakeholder. If a node eventually becomes chosen to mint a block, it is called a slot leader. You can read more about this process in Proof of Stake in Cardano SL.</p>\n<h3>BEYOND SETTLEMENT LAYER</h3>\n<p>Cardano SL is called “Layer” for a reason. It is the first component of the Cardano Platform. Eventually, it will be expanded with a Control Layer, serving as a trusted computation framework to evaluate a special kind of proofs to ensure that a certain computation was carried out correctly. In gaming and gambling, such systems are used for verifying honesty of random number generation and game outcomes. Accompanied with side chains, it will make possible to accomplish such tasks as provably fair distribution of winnings in games. But the application of Control Layer lies well beyond gaming and gambling. Identity management, credit system and more will be a part of Cardano Platform. We are also aiming to evolve Daedalus, the Cardano SL wallet application, into a universal cryptocurrency wallet featuring automated cryptocurrency trading and cryptocurrency-to-fiat transactions.</p>",frontmatter:{path:"/en/intro-text/",doc_title:null,author:null,date:null,language:"en",label:"content",keywords:"intro",group:null}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/content/welcome-text.cn.md absPath of file >>> MarkdownRemark",excerpt:"Dear reader, the purpose of this documentation is to provide you with understanding of the first layer of Cardano Platform stack, the…",html:'<p>Dear reader, the purpose of this documentation is to provide you with understanding of the first layer of Cardano Platform stack, the Settlement Layer. If you have an understanding of what Settlement Layer is, we suggest you first read <a href="/cardano/differences/">Differences Between the Paper and the Implementation</a>, and then move on to documentation on <a href="/technical/protocols/csl-application-level/">protocols and implementation</a>.</p>\n<p>This documentation targets IOHK developers, third party software developers, auditors, and consultants who collaborate on implementing Cardano Settlement Layer or use Cardano Settlement Layer reference implementation.</p>',frontmatter:{path:"/en/welcome-text/",doc_title:null,author:null,date:null,language:"en",label:"content",keywords:"welcome",group:null}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/content/intro.en.md absPath of file >>> MarkdownRemark",excerpt:"Cardano SL (或卡尔达诺运算层）是由 IOHK 联合爱丁堡大学，雅典大学和康涅狄格大学共同设计开发的一种加密货币。卡尔达诺运算层是基于 Aggelos Kiayias，Alexander Russell，Bernardo David 和 Roman Oliynykov…",html:"<h3>Cardano SL</h3>\n<p>(或卡尔达诺运算层）是由 IOHK 联合爱丁堡大学，雅典大学和康涅狄格大学共同设计开发的一种加密货币。卡尔达诺运算层是基于 Aggelos Kiayias，Alexander Russell，Bernardo David 和 Roman Oliynykov 的白皮书 『乌洛波罗斯：可证明安全的权益证明协议』的 Haskell 实现。</p>\n<p>您可以将卡尔达诺结算层视为基于比特币重新设计的针对比特币缺陷的自由修复。 有关卡尔达诺结算层和比特币之间的相似之处和差异的更多信息，请阅读『卡尔达诺结算层为什么特别?』。</p>\n<h3>加密货币基础</h3>\n<p>在给出加密货币的定义之前，我们先来谈谈为什么我们在意数字货币，特别是加密货币。</p>\n<h3>我们为什么在意?</h3>\n<ul>\n<li>\n<h4>速度</h4>\n<p>与传统（也称为法定）中心银行货币，与日元或美元相反，电子货币不需要一个银行系统来转移价值。这一限制的解除，使用数字货币的速度要快于银行业务，尤其是在全球范围内。使用数字货币从大阪转移10美元到丹佛不再需要数天的时间。无论距离如何，所有交易都能迅速完成。</p>\n</li>\n<li>\n<h4>你掌控你自己的钱</h4>\n<p>所有的商业银行账户所有者在收到支付请求后在合理的时间内只能支付一定的金额。银行体系对任何价值量都有限制，使个人无法迅速撤出或转移大量资金。有加密货币的情况下，持有一种称为密钥这一特殊信息的人就可以随意花钱。没有其他实体有权操纵用户拥有的价值。</p>\n</li>\n<li>\n<h4>匿名</h4>\n<p>人们可以根据需要，拥有任意多的加密货币地址，从不同的地址接收，消费资产。经营电子商务商店的商家可以拥有一组收款和退款的地址，以及一个用于他们自身需要的单独的个人『钱包』。通过统一的接口控制所有这些钱包，并且不需要登录到多个支付平台，这使得该过程非常节省时间。</p>\n</li>\n<li>\n<h4>安全</h4>\n<p>你的钱就像可用于消费的密钥一样安全。这意味着将密钥存储在保险箱中的 USB 闪存上相当于让纸币处于安全状态。即使进行了成功的网络攻击，也绝对没有人能够窃取这笔钱。</p>\n</li>\n<li>\n<h4>扩展性</h4>\n<p>使用一种称为侧链的方法，以及通用加密货币，如卡尔达诺结算层和比特币，就可以启用特定领域的加密货币，例如以太经典。这样一来，通过特定领域的加密货币开发的任何创新产品都可以让参与者在通用的加密货币中保持价值。这样的应用程序的例子有身份管理，游戏和赌博，以及可验证计算。</p>\n</li>\n</ul>\n<h3>什么是加密货币?</h3>\n<p>加密货币是一种数字货币形式，使用密码来控制价值。密码学提供了一种生成任何类型信息的真实真实性证据的方法。这就是所谓的数字签名。在加密货币中，我们通过签署和发送交易到网络并接收已确认的交易块，生成一个总账（一个提供每个地址有多少钱的信息的数据库）。加密货币通常是分散的，这意味着来自全球各地的许多人通过运行加密货币节点参与总账的生成。因此，必须达成关于总账状况的共识。下一节讨论实现这种共识的两个最重要的方法。</p>\n<h3>卡尔达诺结算层为什么特别</h3>\n<p>虽然比特币和卡尔达诺结算层之间有相似之处，但这两个加密货币之间也有很多不同之处。最显着的区别是，比特币是工作量证明类型的加密货币，而卡尔达诺结算层使用权益证明的方法达成共识。这鼓励诚信和长期的参与。</p>\n<h3>共识算法的目的</h3>\n<p>共识算法被用来产生新的交易区块，使账本更新状态。每当有人发布一个交易区块时，他们（或者说他们的运行加密货币协议的节点）就必须附上他们已经证明的证据。下面讨论两种类型的证明。</p>\n<h3>工作量证明和挖矿</h3>\n<p>工作量证明是加密货币最普遍的共识算法类型。它起源于比特币，加密货币就是这么工作的。为了生成工作证明，计算机必须解决一个挑战。这是难以解决的计算繁重的问题，但解决方案很容易验证。当一台基于网络的工作量证明的计算机找到一个解决方案时，它会将交易发布于同它一起计算的其他计算机。这台计算机会因为产生区块得到交易费和奖励。整个过程被称为挖矿。挖矿是非常耗能的，所需的能源数量在不断增加，这可能导致不健康的竞争。</p>\n<h3>权益证明和铸币</h3>\n<p>权益证明是一种生成区块的新方法。由 Aggelos Kiayias 教授领导的 IOHK 科学家们设计了第一个可证明的，称为乌洛波罗斯的权益证明算法。乌洛波罗斯是卡尔达诺结算层的核心。研究小组已经发表了一篇白皮书 ，这封白皮书对于那些拥有加密货币理论背景的人来说是值得一读的。权益证明的核心思想是，不要浪费电力来解决计算繁重的问题，而是选择一个节点来铸造一个新的区块，其概率与这个节点的硬币数量成正相关。如果一个节点有整数个(> 0)的 slot，它被称为 slot 所有人。如果一个节点最终被选中来铸造一个区块，那么这个节点被称为 slot 领导者。您可以在卡尔达诺结算层的股权证明中了解更多关于该流程的信息。</p>\n<h3>卡尔达诺结算层之上</h3>\n<p>卡尔达诺结算层被称为『层』是有原因的。这是卡尔达诺平台的第一个组件。最终，它将被扩展到一个控制层，作为一个可信的计算框架来评估一种特殊的证明，以确保一定的计算正确执行。在游戏和赌博中，这样的系统被用于验证随机数生成和游戏结果的真实性。伴随着侧链，它将有可能完成诸如在游戏中公平分配奖金的任务。但是控制层的应用远远超出了游戏和赌博。身份管理，信用系统等将成为卡尔达诺平台的一部分。我们将迭代卡尔达诺钱包应用程序 Daedalus，使其变成一个具有自动加密货币交易功能和合法加密货币交易功能的通用加密货币钱包。</p>",frontmatter:{path:"/cn/intro-text/",doc_title:null,author:null,date:null,language:"cn",label:"content",keywords:"intro",group:null}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-01-13-balance-and-stake.en.md absPath of file >>> MarkdownRemark",excerpt:"<!-- Reviewed at e070e675764738b5190b2f93424de403f1937216 -->\n\n# How Balance and Stake work within the Cardano SL\n\nThere are two important concepts within the Cardano SL: these are **balance** and **stake**. This chapter\nexplains the difference between these two concepts and how they both function.\n\n### Balance\n\nBalance is the real amount of coins that each user has. When you install a Daedalus wallet on your computer\nand perform the [Ada redemption](/timeline/bootstrap/) process, you receive an amount of Ada. This amount of\nAda is called your balance. You can send an amount of Ada (within this balance), to other users, as well as\nreceive any amount of Ada from other users.\n",html:'<!-- Reviewed at e070e675764738b5190b2f93424de403f1937216 -->\n<h1>How Balance and Stake work within the Cardano SL</h1>\n<p>There are two important concepts within the Cardano SL: these are <strong>balance</strong> and <strong>stake</strong>. This chapter\nexplains the difference between these two concepts and how they both function.</p>\n<h3>Balance</h3>\n<p>Balance is the real amount of coins that each user has. When you install a Daedalus wallet on your computer\nand perform the <a href="/timeline/bootstrap/">Ada redemption</a> process, you receive an amount of Ada. This amount of\nAda is called your balance. You can send an amount of Ada (within this balance), to other users, as well as\nreceive any amount of Ada from other users.</p>\n<!-- end -->\n<p>Thus, when we refer to the balance, we are talking about the user\'s actual money.</p>\n<h3>Stake</h3>\n<p>Unlike balance (the real amount of money you have),\nstake is a key element of the entire financial power of Cardano SL. Stake gives a user the\npower to control various Cardano SL algorithm parts, for example: being the <a href="/glossary/#slot-leader">slot leader</a>,\nvoting in the <a href="/cardano/update-mechanism/">Update system</a>, taking part in <a href="/technical/leader-selection/#follow-the-satoshi">MPC/SSC</a>. This is why all thresholds in the Cardano SL protocol are expressed in terms of stake, rather than balance.</p>\n<p>Thus, when we refer to the stake, we are talking about the user\'s ability to control the actual Cardano SL. For more information about stake, please refer to the following <a href="/glossary/#paper">paper</a>. </p>\n<h3>The Relationship Between Balance and Stake</h3>\n<p>Every coin in Cardano SL is associated with a balance and with a stake. We use <a href="/cardano/transactions/#design">transaction output</a>\nto associate coin <code>C</code> with a user\'s balance, and we use <a href="/cardano/transactions/#stake-distribution">stake distribution</a>\nto associate coin <code>C</code> with a user\'s stake.</p>\n<p>Note: It is possible to change the association between coin and stake using what is known as <a href="/technical/delegation/">stake delegation</a>.</p>',frontmatter:{path:"/en/cardano/balance-and-stake/",doc_title:"Balance and Stake",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-01-19-topology.en.md absPath of file >>> MarkdownRemark",excerpt:"<!-- Reviewed at ba744590c89d8ffa6d6f0919ec11f52202a6d8f2 -->\n\n# Cardano SL Network Topology\n\nThis is an overview of Cardano SL network topology.\n\n## Nodes Groups\n\nThough Cardano SL is designed and implemented as a distributed network, for purpose of DDoS protection\nadditional facilities were added to Cardano SL implementation and topology. Currently all nodes are\ndivided into 3 groups:\n\n1. Core\n2. Relay\n3. Edge\n\nLet's describe each of these groups.\n",html:'<!-- Reviewed at ba744590c89d8ffa6d6f0919ec11f52202a6d8f2 -->\n<h1>Cardano SL Network Topology</h1>\n<p>This is an overview of Cardano SL network topology.</p>\n<h2>Nodes Groups</h2>\n<p>Though Cardano SL is designed and implemented as a distributed network, for purpose of DDoS protection\nadditional facilities were added to Cardano SL implementation and topology. Currently all nodes are\ndivided into 3 groups:</p>\n<ol>\n<li>Core</li>\n<li>Relay</li>\n<li>Edge</li>\n</ol>\n<p>Let\'s describe each of these groups.</p>\n<!-- end -->\n<h3>Core Node</h3>\n<p>Core nodes are the most important ones.</p>\n<p>As described <a href="/timeline/bootstrap/#stake-locking">here</a>, for Byron release we will have stake effectively\nlocked on federation of core nodes. Only these few nodes can be <a href="/glossary/#slot-leader">slot leaders</a>, so\nonly these nodes will be able to create new blocks over this period. This is essential for network core nodes to\noperate well and continue maintaining the blockchain. We also bring additional security level around this set\nof core nodes: we put them inside a perimeter of relay nodes, so core nodes are isolated from the public\ninternet and only relay nodes are allowed to communicate with core nodes. This is how we reduce probability\nfor them being attacked.</p>\n<p>Please note that core nodes never create currency transactions (only edge nodes can do it, see below).</p>\n<h3>Relay Node</h3>\n<p>You can think of relay nodes as of proxy between core nodes and public internet.</p>\n<p>Since relay nodes are not isolated, they can be attacked, but they are in principle stateless and do not have\nany stake, so they can be moved, or their number can be increased. If relays are taken down, this does deny\nservice, but the integrity of the core nodes (and the blockchain) should not be compromised.</p>\n<p>Since relay nodes do not have any stake, they cannot be slot leaders. Moreover, they cannot create currency\ntransactions as well.</p>\n<p>Relay nodes are fully under the control of the federated committee of initial stakeholders.</p>\n<h3>Edge Node</h3>\n<p>Edge node is a simple node that anyone can run on their computer. Only these nodes can create currency\ntransactions.</p>\n<p>Since edge nodes do not have any stake, they cannot be slot leaders as well as relay nodes. Furthermore,\nedge nodes cannot directly communicate with core nodes, only with relay nodes and with other edge nodes.</p>',frontmatter:{path:"/en/cardano/topology/",doc_title:"Topology",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-01-07-addresses.en.md absPath of file >>> MarkdownRemark",excerpt:'<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n\n# Addresses in Cardano SL\n\nTo send and receive value, addresses are used in virtually all cryptocurrencies.\nCardano SL supports 3 main types of addresses:\n\n1.  public key address,\n2.  script address,\n3.  redeem address.\n\nPublic key address is a normal address like in any other cryptocurrency. It is\na hashed public key. Read more about public key addresses [below](#public-key-addresses).\n\nScript address is used in so-called "Pay to Script Hash" (P2SH) transactions.\nIt operates autonomously and acts somewhat like a bank deposit: you can send\nmoney to it, but in order to redeem it you have to satisfy certain conditions,\ndetermined by a script associated with the address. The address itself contains\nthe hash of the serialized script. Read more about P2SH [below](#pay-to-script-hash).\n',html:'<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<h1>Addresses in Cardano SL</h1>\n<p>To send and receive value, addresses are used in virtually all cryptocurrencies.\nCardano SL supports 3 main types of addresses:</p>\n<ol>\n<li>public key address,</li>\n<li>script address,</li>\n<li>redeem address.</li>\n</ol>\n<p>Public key address is a normal address like in any other cryptocurrency. It is\na hashed public key. Read more about public key addresses <a href="#public-key-addresses">below</a>.</p>\n<p>Script address is used in so-called "Pay to Script Hash" (P2SH) transactions.\nIt operates autonomously and acts somewhat like a bank deposit: you can send\nmoney to it, but in order to redeem it you have to satisfy certain conditions,\ndetermined by a script associated with the address. The address itself contains\nthe hash of the serialized script. Read more about P2SH <a href="#pay-to-script-hash">below</a>.</p>\n<!-- end -->\n<p>Redeem address is a special type of address for ADA redemption. Read more about redeem\naddresses <a href="#redeem-addresses">below</a>.</p>\n<p>Moreover, Cardano SL support <code>Unknown</code> address type as well. This type will allow us to use\ncustom types of addresses in the future.</p>\n<h2>What Does an Address Look Like?</h2>\n<p>Addresses are <code>base58</code>-encoded bytestrings, for example:</p>\n<pre><code>Ae2tdPwUPEZKmwoy3AU3cXb5Chnasj6mvVNxV1H11997q3VW5ihbSfQwGpm\n</code></pre>\n<h3>Encoding</h3>\n<p><code>base58</code> encoding is the same one as used in Bitcoin. It uses a 58-symbol alphabet\nto encode data, hence the name. Here is the alphabet we are using:</p>\n<pre><code>123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\n</code></pre>\n<p>It avoids both non-alphanumeric characters and letters which might look\nambiguous when printed (<code>0</code>, <code>O</code>, <code>I</code>, <code>l</code>); therefore it is suitable for human\nusers who enter the data manually, copying it from some visual source, and also\nallows easy copy and paste by double-clicking which usually selects the whole\nstring.</p>\n<h2>Public Key Addresses</h2>\n<p>As mentioned in the <a href="/introduction/#you-own-your-money">Introduction</a>, the wallets\nyou can see in the user interface are a convenient representation of the fact that\nyou own a secret key to spend money in this particular wallet. But how is such\nspending verified by the network and how can you receive money from others? The\nanswer is that along with the secret key which is used to control the value in\nyour wallets, a public key is generated. This public component can be known by\nanybody, hence the name.</p>\n<p>A public key address contains the hash of this public key.</p>\n<p>Public keys are also used for verifying your identity when you create a\ntransaction and other auxiliary purposes.</p>\n<h2>Pay to Script Hash</h2>\n<p>The idea of Pay to Script Hash (P2SH) is to provide a lot of flexibility for\nformulating complex rules for spending money. Instead of sending a transaction\nto a public key address, we create a validator script that can take a so-called\nredemption script as a parameter. To redeem funds, we pass the redemption script\nto the validator and evaluate it. If it evaluates to <code>success</code>, money is sent as\nspecified by the redeemer. Otherwise nothing happens.</p>\n<p>To quote Bitcoin Wiki,</p>\n<blockquote>\n<p>Using P2SH, you can send bitcoins to an address that is secured in various\nunusual ways without knowing anything about the details of how the security is\nset up. The recipient might need the signatures of several people to spend\nthese bitcoins, or a password might be required, or the requirements could be\ncompletely unique.</p>\n</blockquote>\n<h2>Redeem Addresses</h2>\n<p>Redeem addresses are Pay To PubKey Hash (P2PKH). Such an address contains the hash\nof redeem public key, and this key is actually <a href="http://ed25519.cr.yp.to/">Ed25519</a>\npublic key.</p>\n<h2>Other Address Types</h2>\n<p>In the future, we may use the update system to introduce other address types. Please\n<a href="/cardano/update-mechanism/#soft-fork-updates">see more</a> on extending the system in\nnon-breaking fashion.</p>\n<h2>Address Structure</h2>\n<p>Address consists of 3 parts:</p>\n<ul>\n<li>address root,</li>\n<li>address attributes,</li>\n<li>address type.</li>\n</ul>\n<p>We can imagine an address as a JSON-like structure, for example:</p>\n<pre><code>Address {\n    addrRoot = AbstractHash e63175c654dfd93a9290342a067158dc0f57a1108ddbd8cace3839bd,\n    addrAttributes = Attributes {\n        data: AddrAttributes {\n            aaPkDerivationPath = Nothing,\n            aaStakeDistribution = BootstrapEraDistr\n        } \n    },\n    addrType = ATPubKey\n}\n</code></pre>\n<p><code>addrRoot</code> is the BLAKE2b-224 hash of the tuple made from <code>addrType</code>, <code>addrSpendingData</code> and <code>addrAttributes</code>.</p>\n<p><code>addrSpendingData</code> is a special value which is bound to an address and must be revealed in order to spend coins belonging to\nthis address. For example, for public key address this value contains the public key. In this case, it is impossible to change\naddress attributes without knowing of the public key because if the attributes have been changed the whole address becomes\ninvalid.</p>\n<p><code>addrAttributes</code> include important attributes of each address: derivation path and stake distribution.</p>\n<p>For more info about derivation path please read <a href="https://cardanodocs.com/technical/hd-wallets/">HD Wallets in Cardano SL</a> chapter.</p>\n<p>For more info about stake distribution please read <a href="https://cardanodocs.com/cardano/transactions/#stake-distribution">Transactions in Cardano SL</a>\nchapter.</p>\n<p>Value of <code>addrType</code> corresponds to address type as was mentioned above, in this example it is a public key address.</p>\n<h3>Length</h3>\n<p>Addresses may have different lengths depending on address type and additional data in it.</p>\n<p>For example, this address</p>\n<pre><code>Ae2tdPwUPEZKmwoy3AU3cXb5Chnasj6mvVNxV1H11997q3VW5ihbSfQwGpm\n</code></pre>\n<p>and this one</p>\n<pre><code>4swhHtxKapQbj3TZEipgtp7NQzcRWDYqCxXYoPQWjGyHmhxS1w1TjUEszCQT1sQucGwmPQMYdv1FYs3d51KgoubviPBf\n</code></pre>\n<p>are both public key addresses.</p>',
  frontmatter:{path:"/en/cardano/addresses/",doc_title:"Addresses",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-02-01-monetary-policy.en.md absPath of file >>> MarkdownRemark",excerpt:'<!-- Reviewed at 1bd2a2f5979233f4f50a7e66ab4e1819ac486400 -->\n\n# Cardano Monetary Policy\n\n<div  markdown="1">\nThis section defines the Cardano monetary policy.\n\n### THE LAUNCH OF CARDANO AND AVAILABILITY OF ADA\n\nDuring the sale that occurred at the launch, 25,927,070,538 Ada were sold. An amount equal to 20% of the total Ada vouchers were sold during the sale period, equating to 5,185,414,108 units. These Ada vouchers were generated and distributed to three entities of the Cardano community, each members of the Technical and Business Development Pool, namely: [IOHK](https://iohk.io), [Emurgo](http://emurgo.io/) and the [Cardano Foundation](https://cardanofoundation.org/). The total amount of Ada that was made available at the launch is equal to 31,112,484,646 ADA.\n',html:'<!-- Reviewed at 1bd2a2f5979233f4f50a7e66ab4e1819ac486400 -->\n<h1>Cardano Monetary Policy</h1>\n<div  markdown="1">\nThis section defines the Cardano monetary policy.\n<h3>THE LAUNCH OF CARDANO AND AVAILABILITY OF ADA</h3>\n<p>During the sale that occurred at the launch, 25,927,070,538 Ada were sold. An amount equal to 20% of the total Ada vouchers were sold during the sale period, equating to 5,185,414,108 units. These Ada vouchers were generated and distributed to three entities of the Cardano community, each members of the Technical and Business Development Pool, namely: <a href="https://iohk.io">IOHK</a>, <a href="http://emurgo.io/">Emurgo</a> and the <a href="https://cardanofoundation.org/">Cardano Foundation</a>. The total amount of Ada that was made available at the launch is equal to 31,112,484,646 ADA.</p>\n<!-- end -->\n<h3>ADA SUPPLY CAP</h3>\n<p>Ada is capped at an arbitrary 45,000,000,000, or forty-five billion Ada.</p>\n<h3>ADA TO BE ISSUED DURING THE OPERATION OF THE CARDANO PROTOCOL</h3>\n<p>The remaining Ada, 13,887,515,354, will be issued after the launch through minting.</p>\n<p>Note: There will never be more than 45,000,000,000 Ada in circulation.</p>\n</div>\n<h2>TREASURY AND FEES</h2>\n<div  markdown="1">\nThis section outlines treasury plans and associated fees.\n<h3>BOOTSTRAP ERA (LAUNCH)</h3>\n<p>Cardano is currently in its bootstrapping phase. During this phase, fees are not being collected and no Ada is being minted. Fees from this phase will be collected in the future and they will be destroyed.</p>\n<h3>TREASURY</h3>\n<p>Cardano will have a treasury going forward. This treasury will be endowed via some portion (yet to be defined), of newly-minted Ada and transaction fees. The treasury will be governed by Ada holders.</p>\n<h3>MINIMAL FEE (Current Calculation)</h3>\n<p>The minimal fee = 0.155381 ADA + 0.000043946 (ADA/Byte) x size-of-transaction.</p>\n<p>Note: Fee calculations and incentives are areas that are currently being researched and their development is in progress.</p>\n<h3>DENOMINATIONS</h3>\n<ul>\n<li>1 ADA = 1,000,000 Lovelaces</li>\n<li>1 Lovelace = 1/1,000,000 Ada</li>\n<li>Ada has six decimal places.</li>\n<li>1.000000 = 1 ADA</li>\n<li>0.000001 = 1 Lovelace</li>\n</ul>\n<p>In terms of money units, there are two points of consideration. Firstly in Japan, yen amounts are much larger, where 10,000 yen is similar to a 100 dollar bill. Factoring this into unit calculations, the amount changes from 25 billion Ada to 250 million. Remember that a unit of Ada is equal to a million Lovelaces (the smallest unit), and after factoring in this adjustment, equates to a total of 2.5 million. Secondly, Ada has six digits from the decimal point, rather than eight digits for Bitcoin. </p>\n</div>',frontmatter:{path:"/en/cardano/monetary-policy/",doc_title:"Monetary Policy",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-02-02-transaction-fees.en.md absPath of file >>> MarkdownRemark",excerpt:"\n# Transaction Fees in Cardano SL\n\n## Motivation\n\nThere are two main reasons why transaction fees are needed for Cardano SL:\n\n1.  People who run full Cardano SL nodes spend time, money and effort to run the protocol, for which they should\n    be compensated and rewarded. In contrast to Bitcoin, where new currency is created with each mined block,\n    in Cardano SL, transaction fees are the only source of income for participants in the protocol.\n2.  The second reason is the prevention of DDoS (Distributed Denial of Service) attacks. In a DDoS attack, an attacker\n    tries to flood the network with dummy transactions, and if he has to pay a sufficiently high fee for each of those\n    dummy transactions, this form of attack will become prohibitively expensive for him.\n",html:'<h1>Transaction Fees in Cardano SL</h1>\n<h2>Motivation</h2>\n<p>There are two main reasons why transaction fees are needed for Cardano SL:</p>\n<ol>\n<li>People who run full Cardano SL nodes spend time, money and effort to run the protocol, for which they should\nbe compensated and rewarded. In contrast to Bitcoin, where new currency is created with each mined block,\nin Cardano SL, transaction fees are the only source of income for participants in the protocol.</li>\n<li>\n<p>The second reason is the prevention of DDoS (Distributed Denial of Service) attacks. In a DDoS attack, an attacker\ntries to flood the network with dummy transactions, and if he has to pay a sufficiently high fee for each of those\ndummy transactions, this form of attack will become prohibitively expensive for him.</p>\n<!-- end -->\n<h2>How transaction fees work</h2>\n</li>\n</ol>\n<p>Whenever somebody wants to transfer an amount of Ada, some minimal fees are computed for that transaction. In order for\nthe transaction to be valid, these minimal fees have to be included, although the sender is free to pay higher fees if\nhe so wishes.</p>\n<p>Please also read about transaction distribution <a href="#transaction-fees-distribution">below</a>.</p>\n<h2>Minimal transaction fees</h2>\n<p>The minimal fees for a transaction are calculated according to the formula:</p>\n<pre><code>a + b × size\n</code></pre>\n<p>where:</p>\n<ul>\n<li><code>a</code> is a special constant, at the moment it is 0.155381 ADA;</li>\n<li><code>b</code> is a special constant, at the moment it is 0.000043946 ADA/byte;</li>\n<li><code>size</code> is the size of the transaction in bytes.</li>\n</ul>\n<p>This means that each transaction costs at least 0.155381 ADA, with an additional cost of 0.000043946 ADA per byte of\ntransaction size. For example, a transaction of size 200 bytes (a fairly typical size) costs:</p>\n<pre><code>0.155381 ADA + 0.000043946 ADA/byte × 200 byte = 0.1641702 ADA.\n</code></pre>\n<p>The reason for having parameter <code>a</code> is the prevention of DDoS attacks mentioned above: even a very small dummy\ntransaction should cost enough to hurt an attacker who tries to generate many thousands of them.</p>\n<p>Parameter <code>b</code> has been introduced to reflect actual costs: storing larger transactions needs more computer memory\nthan storing smaller transactions, so larger transactions should be more expensive than smaller ones.</p>\n<p>Although particular values for parameters <code>a</code> and <code>b</code> were calculated, these values will probably be adjusted in\nfuture to better reflect actual costs.</p>\n<h2>Transaction fees distribution</h2>\n<p>All transaction fees of a given <a href="https://cardanodocs.com/glossary/#epoch">epoch</a> are collected in a virtual pool,\nand the idea is to then redistribute the money from that pool amongst people who were elected <a href="https://cardanodocs.com/glossary/#slot-leader">slot leaders</a>\nby the PoS-algorithm during that epoch and who created blocks.</p>\n<p>At this stage of Cardano SL, where all blocks are created by nodes operated by IOHK and our partners, fees are\nalready collected (to prevent DDoS attacks), but they will not be distributed and instead will be burnt.</p>\n<p>As soon as Cardano SL enters its next, <a href="https://cardanoroadmap.com/">fully decentralized stage</a>, fees will be\ndistributed as described above.</p>',frontmatter:{path:"/en/cardano/transaction-fees/",doc_title:"Transaction Fees",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-01-04-differences.en.md absPath of file >>> MarkdownRemark",excerpt:"<!-- Reviewed at c4c45ce9a7a8f4aa6d88a32829755196a017f6a1 -->\n\n# Differences Between the Ouroborous Protocol Paper and the Implementation\n\nThe goal of this document is to outline the ways in which the Cardano SL\nimplementation differs from the specifications presented in the *Ouroboros*\nprotocol [paper](/glossary/#paper) and to clarify any outstanding questions \nafter reading the paper.\n\nThis document is divided into four parts:\n\n1.  *Clarifications* - clarifies any details that are not specified in the\n    paper, but are important for practical implementations.\n2.  *Modifications* - outlines elements that are specified in the paper, but are\n    implemented differently in Cardano SL.\n3.  *Added features* - briefly outlines new features which are not described\n    in the paper, but have been implemented in Cardano SL.\n4.  *Omissions* - lists topics described in the paper but are not yet implemented into\n    Cardano SL.\n",html:'<!-- Reviewed at c4c45ce9a7a8f4aa6d88a32829755196a017f6a1 -->\n<h1>Differences Between the Ouroborous Protocol Paper and the Implementation</h1>\n<p>The goal of this document is to outline the ways in which the Cardano SL\nimplementation differs from the specifications presented in the <em>Ouroboros</em>\nprotocol <a href="/glossary/#paper">paper</a> and to clarify any outstanding questions\nafter reading the paper.</p>\n<p>This document is divided into four parts:</p>\n<ol>\n<li><em>Clarifications</em> - clarifies any details that are not specified in the\npaper, but are important for practical implementations.</li>\n<li><em>Modifications</em> - outlines elements that are specified in the paper, but are\nimplemented differently in Cardano SL.</li>\n<li><em>Added features</em> - briefly outlines new features which are not described\nin the paper, but have been implemented in Cardano SL.</li>\n<li>\n<p><em>Omissions</em> - lists topics described in the paper but are not yet implemented into\nCardano SL.</p>\n<!-- end -->\n<h1>Clarifications</h1>\n<p>This section outlines any topics that require clarifications. </p>\n</li>\n</ol>\n<h2>Time, Slots, and Synchrony</h2>\n<p>In a basic model of the protocol time is divided into discrete units called\n<em>slots</em>. However, there are no details on how to obtain the current time value securely\nand with enough precision.</p>\n<p>In Cardano SL, the current time value is obtained from a user\'s computer system time value.</p>\n<p>We also have a feature to notify users if their system time is incorrect\n(we compare it with the time value that is obtained from NTP servers). This feature is planned for a future release.</p>\n<h2>Coin Tossing and Verifiable Secret Sharing</h2>\n<p>The paper suggests PVSS (Publicly Verifiable Secret Sharing) scheme by Schoenmakers for Cardano SL. However,\ncurrently Cardano SL uses <a href="https://eprint.iacr.org/2017/216.pdf">"SCRAPE: Scalable Randomness Attested by\nPublic Entities"</a> PVSS scheme.</p>\n<p>One of the challenges while using a VSS (Verifiable Secret Sharing) scheme is associating the\npublic key used for signing with the public key used for the VSS scheme\n(<code>VssPublicKey</code>). This is solved by introducing <code>VssCertificate</code>s. This\ncertificate is a signature given by a signing key for a pair consisting of\n<code>VssPublicKey</code> and the epoch until which this certificate is valid. Initially,\nall stakeholders with stake enough for participation in randomness generation\nhold certificates. When a new stakeholder with enough stake appears, or when an\nexisting certificate expires, a new certificate should be generated and\nsubmitted to the network. <code>VssCertificate</code>s are stored in blocks.</p>\n<p>PVSS scheme uses share verification information which also\nincludes a commitment to the secret. It is also used as a commitment in\nthe protocol. The PVSS scheme has been implemented over the elliptic curve\nsecp256r1. Please refer to <a href="/technical/pvss/">PVSS implementation in Cardano\nSL</a> for more details.</p>\n<h2>Block Generation Time</h2>\n<p>In the paper, they do not state explicitly when a slot leader should\ngenerate a new block and send it to the network: it can be done at the beginning\nof a slot, at the end of a slot, in the middle of a slot, etc. In Cardano SL\nthere is a special constant called "network diameter" which approximates maximal time\nnecessary to broadcast a block to all nodes in the network. For example, if network\ndiameter is 3, then block is generated and announced 3 seconds before the end of a slot.</p>\n<h2>Stake Delegation</h2>\n<p>Delegation scheme, as described in the paper, does not explicitly state whether proxy\nsigning certificates should be stored within the blockchain (though there is a\nsuggestion to store the revocation list in the blockchain). Without storing\nproxy signing certificates in the blockchain it is barely possible to consider\ndelegated stake in checking eligibility threshold. On the other hand, if all\ncertificates are stored in the blockchain, it may lead to a blockchain bloat\nwhen a big portion of blocks will be occupied by proxy certificates. Submitting\na certificate is free, so adversaries can generate as many certificates as they\nwant.</p>\n<p>There are two types of delegation in Cardano SL: heavyweight and lightweight.\nThere is a threshold on stake that one has to posses in order to participate in\nheavyweight delegation. Proxy signing certificates from heavyweight delegation\nare stored within the blockchain. On the contrary, lightweight delegation is\navailable for everybody, but certificates are not stored within the blockchain\nand are not considered when checking eligibility threshold. As the paper suggests,\n<em>delegation-by-proxy</em> scheme is used.</p>\n<p>Please read about <a href="/technical/delegation/">Stake Delegation in Cardano SL</a> for\nimplementation details.</p>\n<h1>Modifications</h1>\n<h2>Leader Selection Process</h2>\n<p>In the paper, Leader Selection Process is described as flipping a\n<code>(1 - p₁) … (1 - pⱼ₋₁) pⱼ</code>-biased coin to see whether the <code>j</code>-th stakeholder is\nselected as the leader of the given slot. Here <code>pⱼ</code> is probability of selecting the <code>j</code>-th\nstakeholder.</p>\n<p>In Cardano SL, it is implemented in a slightly different way. <code>R</code> random\nnumbers in a range <code>[0 .. totalCoins]</code> are generated, where <code>R</code> is a number of\nslots in an epoch. Stakeholders occupy different subsegments on this range,\nproportional to their stakes. This way, each random number maps into stakeholder.\nAlso, as the paper suggests, a short (32-bits) seed is used for initializing PRG\ninstead of using <code>n ⌈log λ⌉</code> random bits.</p>\n<p>Please read about <a href="/technical/leader-selection/">Leader Selection in Cardano SL</a>\nfor implementation details.</p>\n<h2>Commitments, openings, shares sending</h2>\n<p>Time of sending is randomized within a small interval. It is done to avoid network\noverload when all coin-tossing participants send their data at the same time.\nThis interval is chosen to be small enough for protocol to remain secure. If\nthis data is sent too late and there are many adversaries leading last few slots\nof a certain phase, it can happen that data will not be included into the block.</p>\n<h2>Multishares</h2>\n<p>In the paper, each stakeholder is presented as exactly one participant of the\nunderlying VSS scheme. However, it is natural that a stakeholder with more stake\nis more important than a stakeholder with less stake with regards to secret\nsharing. For instance, if three honest stakeholders control 60% of stake in\ntotal (each of them controls 20%) and there are 40 adversary stakeholders each\nhaving 1% of stake, then the adversary has full control over secret sharing.</p>\n<p>To overcome this problem, a number of shares for each stakeholder proportional\nto their stake is generated in Cardano SL.</p>\n<h2>Randomness Generation Failure</h2>\n<p>The paper does not cover the situation when commitments cannot be recovered.\nHowever, a practical implementation should account for such scenarios.\nCardano SL implementation uses a seed consisting of all zeroes if there are no\ncommitments that could be recovered.</p>\n<h1>Added Features</h1>\n<h2>Update System</h2>\n<p>See the article on <a href="/cardano/update-mechanism/">update system</a>.</p>\n<h2>Security of P2P</h2>\n<p>See the article on <a href="/technical/protocols/p2p/">P2P implementation and\nhardening</a>.</p>\n<h1>Omissions</h1>\n<p>The sections on <em>Input Endorsers</em> and <em>Incentive Structure</em> are not implemented\nyet. Those sections are to be implemented together with the pending research on\nSide-chains and released within the Side-chains release.</p>',frontmatter:{path:"/en/cardano/differences-between-paper-and-the-implementation/",doc_title:"Differences Between Paper and the Implementation",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-02-05-explorer.en.md absPath of file >>> MarkdownRemark",excerpt:"<!-- Reviewed at dec0d911d6c4beb8e708ed4076f832ff871f6125 -->\n\n# Cardano SL Explorer\n\nThis is an overview of Cardano SL Explorer service (hereafter referred to as\n\"Explorer\").\n\nExplorer is an [online service](https://cardanoexplorer.com/) for searching\naddresses, transactions, epochs and slots on the Cardano network.\n\n## Address\n\nIt is possible to find information about users' addresses. After inserting the\naddress' hash we'll see:\n\n1.  The number of transactions related to this address.\n2.  The final balance on this address.\n3.  The QR-code associated with this address.\n\nExample of an address' hash: `1fhXcTriF8i8FFSdCTaU9d3yp3oCLFQhon5KBkevT8rQDPP`.\n",html:"<!-- Reviewed at dec0d911d6c4beb8e708ed4076f832ff871f6125 -->\n<h1>Cardano SL Explorer</h1>\n<p>This is an overview of Cardano SL Explorer service (hereafter referred to as\n\"Explorer\").</p>\n<p>Explorer is an <a href=\"https://cardanoexplorer.com/\">online service</a> for searching\naddresses, transactions, epochs and slots on the Cardano network.</p>\n<h2>Address</h2>\n<p>It is possible to find information about users' addresses. After inserting the\naddress' hash we'll see:</p>\n<ol>\n<li>The number of transactions related to this address.</li>\n<li>The final balance on this address.</li>\n<li>The QR-code associated with this address.</li>\n</ol>\n<p>Example of an address' hash: <code>1fhXcTriF8i8FFSdCTaU9d3yp3oCLFQhon5KBkevT8rQDPP</code>.</p>\n<!-- end -->\n<h2>Transaction</h2>\n<p>We can find information about a transaction. After inserting the transaction's\nID we'll see:</p>\n<ol>\n<li>Transaction date and time.</li>\n<li>This transaction's source address.</li>\n<li>This transaction's address destination.</li>\n<li>The amount of ADA transferred within this transaction.</li>\n<li>Transaction fee.</li>\n</ol>\n<p>The example of a transaction's ID:\n<code>fe0681c7fe20c27071befc329caac059bb183afaf68b9595744c52125c61cf68</code>.</p>\n<h2>Time</h2>\n<p>We can find information about transactions by the time as well. Now it's\npossible to specify <a href=\"/glossary/#epoch\">epoch</a> and <a href=\"/glossary/#slot\">slot</a> only.\nAfter inserting the epoch's index and the slot's index, we'll see:</p>\n<ol>\n<li>The number of transactions for this slot.</li>\n<li>The total amount of ADA transferred during this slot.</li>\n<li>The size of the block generated within this slot.</li>\n</ol>\n<h3>Slot</h3>\n<p>It's possible to get the information about a particular slot. After inserting\nthe slot's hash we'll see:</p>\n<ol>\n<li>The number of transaction for this slot.</li>\n<li>The total output value.</li>\n<li>Estimated volume of ADA for this slot.</li>\n<li>Fees.</li>\n<li>The slot's ID.</li>\n</ol>\n<p>Furthermore, we'll see information about hashes:</p>\n<ol>\n<li>This slot's hash.</li>\n<li>The previous slot's hash (if exists).</li>\n<li>The next slot's hash (if exists).</li>\n<li>The Merkle root.</li>\n</ol>",frontmatter:{path:"/en/cardano/explorer/",doc_title:"Explorer",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-01-01-proof-of-stake.en.md absPath of file >>> MarkdownRemark",excerpt:"<!-- Reviewed at c4c45ce9a7a8f4aa6d88a32829755196a017f6a1 -->\n\n# Ouroboros Proof of Stake Algorithm\n\nThe Ouroboros Proof of Stake (PoS) Algorithm is the most important part of the protocol.\nIt defines the way in which nodes reach consensus about the state of [ledger](/glossary/#ledger).\n\nOuroboros is unique as it is the first blockchain protocol that is based on proof of\nstake and has been scientifically proven as secure.\n\n## Why Proof of Stake?\n\nThe most important thing about picking a Proof of Stake (PoS) algorithm over a Proof\nof Work (PoW) algorithm (as adopted by Bitcoin), is the energy consumption\nconsiderations. Running the bitcoin protocol is a very expensive endeavor which uses\nlarge amounts of energy. It is estimated that 3.8 American households can be powered\nfor a day by the energy that is spent to generate one bitcoin transaction. These energy\nrequirements for running the bitcoin protocol continue to grow as more and more bitcoin\nminers sink money into mining. In addition, more energy is needed as the difficulty\nof the problems that their computers or mining rigs, encounter increases. This is why\nresearchers have investigated alternative ways to reach consensus — such as using the\nso-called BFT (Byzantine Fault Tolerant), consensus algorithms and PoS algorithms.\n\n## What is Proof of Stake?\n\nProof of Stake is a novel approach to block generation. The core idea of Proof of Stake\nis that instead of wasting electricity on cracking computationally heavy problems, a node\nis selected to generate (or “mint”) a new block with a probability proportional to the\namount of coins this node has. If a node has positive (> 0) stake, it is called a “stakeholder”.\nIf a node eventually becomes chosen to mint a new block, it is called a “slot leader”.\n",html:'<!-- Reviewed at c4c45ce9a7a8f4aa6d88a32829755196a017f6a1 -->\n<h1>Ouroboros Proof of Stake Algorithm</h1>\n<p>The Ouroboros Proof of Stake (PoS) Algorithm is the most important part of the protocol.\nIt defines the way in which nodes reach consensus about the state of <a href="/glossary/#ledger">ledger</a>.</p>\n<p>Ouroboros is unique as it is the first blockchain protocol that is based on proof of\nstake and has been scientifically proven as secure.</p>\n<h2>Why Proof of Stake?</h2>\n<p>The most important thing about picking a Proof of Stake (PoS) algorithm over a Proof\nof Work (PoW) algorithm (as adopted by Bitcoin), is the energy consumption\nconsiderations. Running the bitcoin protocol is a very expensive endeavor which uses\nlarge amounts of energy. It is estimated that 3.8 American households can be powered\nfor a day by the energy that is spent to generate one bitcoin transaction. These energy\nrequirements for running the bitcoin protocol continue to grow as more and more bitcoin\nminers sink money into mining. In addition, more energy is needed as the difficulty\nof the problems that their computers or mining rigs, encounter increases. This is why\nresearchers have investigated alternative ways to reach consensus — such as using the\nso-called BFT (Byzantine Fault Tolerant), consensus algorithms and PoS algorithms.</p>\n<h2>What is Proof of Stake?</h2>\n<p>Proof of Stake is a novel approach to block generation. The core idea of Proof of Stake\nis that instead of wasting electricity on cracking computationally heavy problems, a node\nis selected to generate (or “mint”) a new block with a probability proportional to the\namount of coins this node has. If a node has positive (> 0) stake, it is called a “stakeholder”.\nIf a node eventually becomes chosen to mint a new block, it is called a “slot leader”.</p>\n<!-- end -->\n<h3>Proof</h3>\n<p>The “proof” part of “proof of stake” refers to evidence that blocks of\ntransactions are legitimate.</p>\n<h3>Stake</h3>\n<p>While “stake” means “the relative value held by addresses on the node”. By “relative\nvalue” we mean “all the total value held by wallets on a particular node divided by\nthe total value in the Cardano SL system”. For more information, please see:\n<a href="/cardano/balance-and-stake/">Balance and Stake in Cardano SL</a></p>\n<h2>About Slot Leaders</h2>\n<p>Nodes with a positive stake are called stakeholders, and only stakeholders may\nparticipate in running the protocol. Moreover, to be able to generate new blocks\nfor the blockchain, a stakeholder must be elected as a slot leader. The slot leader can\nlisten to transactions announced by other nodes, make a block of those transactions,\nsign this block with its secret key and publish it to the network.</p>\n<p>You can think of a slot leader as a miner in bitcoin, but the above-mentioned consensus\ndefines who will be able to mine, when and how much.</p>\n<h2>Epochs and Slots</h2>\n<p>The Ouroboros protocol divides the physical time into <strong>epochs</strong>, and each epoch is\ndivided into <strong>slots</strong>. For example:</p>\n<pre><code>+----------+----------+-------+----------+--------------------> t\n|  slot 0  |  slot 1  |  ...  |  slot N  |\n\n \\                                      / \\\n  -------------- epoch M ---------------   -- epoch M+1 -- ...\n</code></pre>\n<p><strong>Note:</strong> a slot is a relatively short period of time (for example, 20 seconds).</p>\n<p>Each slot has one and only one leader (slot leader, SL):</p>\n<pre><code>+----------+----------+-------+----------+----> t\n|  slot 0  |  slot 1  |  ...  |  slot N  |\n\n    SL 0       SL 1               SL N\n</code></pre>\n<p>The slot leader has a (sole) right to produce one and only one block during his slot:</p>\n<pre><code>  +------+   +------+           +------+\n  | Bl 0 |&#x3C;--| Bl 1 |&#x3C;-- ... &#x3C;--| Bl N |\n  +------+   +------+           +------+\n+----------+----------+-------+----------+----> t\n|  slot 0  |  slot 1  |  ...  |  slot N  |\n\n    SL 0       SL 1               SL N\n</code></pre>\n<p>It means that the number of slot leaders is strictly equal to the number of slots\nin epoch (let\'s call this number <code>N</code>), so it is impossible to produce more than <code>N</code>\nblocks during an epoch.</p>\n<p>If slot leader missed their slot (for example, when offline), the right to produce\na block is lost until they are elected again.</p>\n<p><strong>Note:</strong> One or more slots can remain empty (without generated blocks), but the\nmajority of blocks (at least 50% + 1) <strong>must</strong> be generated during an epoch.</p>\n<h2>How Slot Leaders Elections Work</h2>\n<p>Slot leaders are elected from the group of all stakeholders. Please note that not all\nstakeholders participate in this election, but only ones who have enough stake (for example, 2% of\nthe total stake). This group of stakeholders are known as “electors”.</p>\n<p>Electors elect slot leaders for the next epoch during the current epoch. Thus, at the end of epoch\n<code>N</code> it is already known who are slot leaders for the epoch <code>N+1</code>, and it cannot be\nchanged.</p>\n<p>You can think of this election as a “fair lottery”; anyone from the group of stakeholders can\nbecome a slot leader. However, an important idea of PoS is that the more stake stakeholder has,\nthe more chances one has to be elected as a slot leader. </p>\n<p><strong>Note:</strong> One stakeholder can be elected as a slot leader for more than one slot\nduring the same epoch.</p>\n<h3>Multiparty Computation</h3>\n<p>One of the fundamental problems of the slot leader election process is its unbiasedness.\nA certain degree of randomness is needed as a base for election, in this case, results of\nthis election are random and fair. So the question is where can this randomness be obtained\nfrom?</p>\n<p>A multiparty computation (MPC) approach is used to achieve this randomness where each elector\nindependently performs an action which is called “coin tossing” and after that shares results\nwith other electors. The idea is that results are randomly generated by each elector, but eventually\nthey agree on the same final value.</p>\n<h4>Commitment Phase</h4>\n<p>First of all, an elector generates a secret (or special random value). Next, an elector forms a\n“commitment” which is a message that contains encrypted shares (see an explanation below) and\nproof of secret.</p>\n<p>The next step is when an elector signs this commitment with its secret key, specifies the epoch\'s\nnumber and attaches its public key. In this case, everybody can check who created this commitment\nand which epoch this commitment relates to.</p>\n<p>Subsequently, an elector sends its commitment to other electors, so eventually each elector collects\ncommitments from all other electors.</p>\n<p><strong>Note:</strong> these commitments are put into the block, that is, they become a part of the blockchain.</p>\n<h4>Reveal Phase</h4>\n<p>The reveal phase is where an elector sends an “opening”, or special value for opening a commitment.\nA commitment is like a locked box (with a secret in it), and the act of opening involves a key that\nopens the box retrieves the secret.</p>\n<p><strong>Note:</strong> all openings are put into the block, that is, they become a part of the blockchain.</p>\n<h4>Recovery Phase</h4>\n<p>The final phase in the process is called the recovery phase.</p>\n<p>Eventually, an elector has both commitments and openings. Theoretically some electors can be an\nadversary and can publish its commitment but <strong>not</strong> publish its opening.</p>\n<p>In this case, the honest electors can post all shares (mentioned above) to reconstruct the\nsecret. The idea is simple: an election finishes successfully even if some electors are adversaries.</p>\n<p>Subsequently, an elector verifies that commitments and openings match, and if so, extracts the\nsecrets from the commitments and forms a seed (randomly generated byte string) from these secrets.\nSo all electors get the same seed, and it will be used for Follow the Satoshi (FTS) algorithm.</p>\n<h3>Follow the Satoshi</h3>\n<p>At this moment, electors have the seed (randomness we need). Now they have to select a particular slot\nleaders for the next epoch. This is where the Follow the Satoshi (FTS) algorithm comes into effect:</p>\n<pre><code>         +-----+\nSEED --->| FTS |---> ELECTED_SLOT_LEADERS\n         +-----+\n</code></pre>\n<p>To explain how a slot leader gets selected, think of the smallest, atomic piece\nof value as a coin called “<a href="/glossary/#lovelace">Lovelace</a>”. Fundamentally, the ledger produces the\ndistribution of coins, and since slot leaders can only be selected from stakeholders distribution of\nstake. FTS is an algorithm that verifiably picks a coin, and when coin owned by stakeholder <code>S</code> selected,\n<code>S</code> become a slot leader. It is clear that the more coins <code>S</code> has, the higher the probability that one\nof his coins will be picked.</p>\n<p>The reason why it is called “Follow the Satoshi” is that in bitcoin, an atomic piece of currency\nis called “Satoshi”, honoring Satoshi Nakamoto, the creator of bitcoin. </p>\n<h2>Honest Majority</h2>\n<p>The fundamental assumption of a protocol is known as <strong>honest majority</strong>. This means that\nparticipants owning at least 50% + 1 of the total stake are honest ones. In this\ncase we can <strong>prove</strong> that adversaries cannot break <em>persistence</em> and <em>liveness</em>\nof the blockchain. For more information see the <a href="/glossary/#paper">paper</a> (pages 2 and 3).</p>',
  frontmatter:{path:"/en/cardano/ouroboros-proof-of-stake-algorithm/",doc_title:"Ouroboros Proof of Stake Algorithm",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-01-10-transactions.en.md absPath of file >>> MarkdownRemark",excerpt:"<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n\n# Transactions in Cardano SL\n\n## Overview\n\nA transaction (*tx*) is a special data which represents the *act* of the value\ntransferring between nodes (from the user's point of view, transferring between\nwallets). Thus, when the user *Alice* sends money to the user *Bob*, the new\ntransaction emerges. Let's call this transaction `Tx1`, the node under *Alice*'\nwallet `N1`, and the node under *Bob*'s wallet `N2`.\n\nThus, the node `N1` does the following steps:\n\n1.  Creating transaction `Tx1` and signs it with its private key.\n2.  Sending it to all known nodes (i.e. neighbors).\n3.  Saving it in its local data.\n\nEach of `N1`'s neighbors sends `Tx1` transaction to its neighbors and so on, and\nsome slot leader will store this transaction in some block in the ledger. Please\nnote that if the network is under high load, it may take a lot of time for\ntransaction to be actually added to the block.\n",html:"<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<h1>Transactions in Cardano SL</h1>\n<h2>Overview</h2>\n<p>A transaction (<em>tx</em>) is a special data which represents the <em>act</em> of the value\ntransferring between nodes (from the user's point of view, transferring between\nwallets). Thus, when the user <em>Alice</em> sends money to the user <em>Bob</em>, the new\ntransaction emerges. Let's call this transaction <code>Tx1</code>, the node under <em>Alice</em>'\nwallet <code>N1</code>, and the node under <em>Bob</em>'s wallet <code>N2</code>.</p>\n<p>Thus, the node <code>N1</code> does the following steps:</p>\n<ol>\n<li>Creating transaction <code>Tx1</code> and signs it with its private key.</li>\n<li>Sending it to all known nodes (i.e. neighbors).</li>\n<li>Saving it in its local data.</li>\n</ol>\n<p>Each of <code>N1</code>'s neighbors sends <code>Tx1</code> transaction to its neighbors and so on, and\nsome slot leader will store this transaction in some block in the ledger. Please\nnote that if the network is under high load, it may take a lot of time for\ntransaction to be actually added to the block.</p>\n<!-- end -->\n<h2>Design</h2>\n<p>Each transaction contains a list of <em>inputs</em> and a list of <em>outputs</em>; outputs of\nthe transaction <code>Tx0</code> can be used as inputs of the other transaction <code>Tx1</code>, and\nso on:</p>\n<pre><code>            Tx0                           Tx1\n  +----------------------+      +----------------------+\n  |                      |      |                      |\n  |  Inputs     Outputs  |      |  Inputs     Outputs  |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  | | In0  |   | Out0  + |      | | In0  |   | Out0  | |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  | | In1  |   | Out1  | |      | | In1  |   | Out1  | |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  | | ...  |   | ...   | |      | | ..   |   | ...   | |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  | | InN  |   | OutM  | |      | | InN  |   | OutM  | |\n  | +------+   +-------+ |      | +------+   +-------+ |\n  |                      |      |                      |\n  +----------------------+      +----------------------+     ...\n</code></pre>\n<p>Inputs and outputs carry information about <em>money flow</em>: inputs inform where the\nmoney came from, and outputs inform where the money comes to. Please notice that\nthere's <code>N</code> and <code>M</code>, because the actual number of inputs and outputs can be\ndifferent.</p>\n<p>Thus, each input contains:</p>\n<ol>\n<li>An ID of transaction <code>TxN</code>, whose output is used for this input. Transaction\nID is a BLAKE2b-256 hash of the transaction, something like\n<code>f9bcbe752aee4512457f1fd350200cf870906b7e6e836688c9a3779645c86c01</code>.</li>\n<li>An index of the using output in <code>TxN</code>'s outputs.</li>\n</ol>\n<p>Each output contains:</p>\n<ol>\n<li>An address of the node <code>N</code> we want to send a value to. An address is a\nBLAKE2b-224 hash of the hash of the public key of the <code>N</code> node, something\nlike <code>1fsAhhf4E1LQDB8agSds8teuD4E7U8JsRESngEX52kinBhi</code>. Please read about\n<a href=\"/cardano/addresses/\">Addresses in Cardano SL</a> for more info.</li>\n<li>Amount of money we want to send. This value is 64-bit unsigned integer with\nmaximum value <code>45000000000000000</code>.</li>\n</ol>\n<p>For example:</p>\n<pre><code>  Tx 891971a4cc31e32..                           Tx f9bcbe752aee4512..\n------------------------+           +----------------------------------------------+\n\\                       |           |                                              |\n/        Outputs        |           |       Inputs                  Outputs        |\n\\  +------------------+ |           | +-----------------+     +------------------+ |\n/  | Out0             | |           | | In0             |     | Out0             | |\n\\  | +--------------+ | |           | | +-------------+ |     | +--------------+ | |\n/  | | Value        | | |           | | | Tx id       | |     | | Value        | | |\n\\  | | 100 ADA      | | |           | | | 891971a4c.. | |     | | 100 ADA      | | |\n/  | +--------------+------->>  ------>>+-------------+ |     | +--------------+------->>\n\\  | | Node address | | |           | | | Out index   | |     | | Node address | | |\n/  | | a00e4bb2..   | | |           | | | 0           | |     | | 88ca7f79..   | | |\n\\  | +--------------+ | |           | | +-------------+ |     | +--------------+ | |\n/  | ...              | |           | | ...             |     | ...              | |\n\\  +------------------+ |           | +-----------------+     +------------------+ |\n/                       |           |                                              |\n------------------------+           +----------------------------------------------+\n</code></pre>\n<p>Node <code>a00e4bb2..</code> generates transaction <code>f9bcbe752aee4512..</code>, and this\ntransaction informs us that:</p>\n<ol>\n<li>We want to send 100 ADA from the current node with address <code>a00e4bb2..</code> to\nthe node with address <code>88ca7f79..</code>.</li>\n<li>This money corresponds to <code>0</code>th output of the previous transaction with an\nID <code>891971a4c..</code>.</li>\n</ol>\n<h2>Verification</h2>\n<p>As mentioned above, the transaction's output becomes the input of the other\ntransaction. In this case, we treat such output as <em>spent transaction output</em>.\nThus, an output <code>Out0</code> of the transaction <code>891971a4cc31e32..</code> is a spent output,\nbecause it already is an input of the <code>f9bcbe752aee4512..</code> transaction.</p>\n<p>But such spendings do not occur immediately, so an output that <em>isn't yet</em> an\ninput of another transaction is called an <em>unspent transaction output</em>. Only\nunspent outputs can be used as inputs for other transactions, to prevent\n<a href=\"https://en.bitcoin.it/wiki/Double-spending\">double-spending</a>.</p>\n<p>So every node in the network not only accepts transactions, but also\nverifies them. To do it, every node has to keep track of unspent outputs, it\nallows to validate that inputs in a published transaction are indeed the unspent\noutputs. Actually, all unspent outputs called <em>utxo</em>, and this is a part of the\nspecial key-value database called <em>Global State</em>.</p>\n<h2>Proofs of Transaction Legitimacy</h2>\n<p>Each transaction in Cardano SL is accompanied by a proof (also called a <strong>witness</strong>)\nthat this transaction is legitimate. Even if the output is an unspent one, we\nhave to prove that we have <em>a right</em> to spend it. Since a <code>TxN</code> transaction can\nhave many inputs, the witness for it consists of the witnesses of all <code>TxN</code>'s\ninputs, and only if all the inputs are legitimate, <code>TxN</code> is legitimate too. If a\nparticular transaction isn't legitimate, it will be rejected by the network.</p>\n<p>Because of <a href=\"/cardano/addresses/#what-does-an-address-look-like\">two available types of node\naddress</a> we use two\ncorresponding versions of the witness: based on <em>public key</em> and based on\n<em>script</em>.</p>\n<p>For example, the first option works with a public key <code>PK</code> and a transaction\nsignature: legitimate input must be signed with a private key corresponding to <code>PK</code>.\nSo it's possible to check this signature and either accept that input or reject it.</p>\n<p>Witnesses are stored in the blockchain and anybody can see, inspect and\nindependently verify them. But after some time a node may delete old proofs in\norder to save space. The technique of storing transactions separately from their\nproofs is called \"segregated witness\" (you may have heard of it being recently\n<a href=\"https://bitcoincore.org/en/2016/01/26/segwit-benefits/\">implemented in\nBitcoin</a>). Under this\nscheme, transactions and proofs are stored in two separate places in a block,\nand can be processed independently.</p>\n<h2>Stake Distribution</h2>\n<p>Stake distribution is another part of Cardano SL, not directly related to delegation,\nbut one we can exploit for its benefit.</p>\n<p>Some addresses have multiple owners, which poses a problem of stake computation as per\nFollow-the-Satoshi each coin should only be counted once towards each stakeholder's stake total.\nUnlike balance (real amount of coins on the balance), stake gives user power to control different\nalgorithm parts: being the slot leader, voting in Update system, taking part in MPC/SSC.</p>\n<p>Stake distribution is a value associated with each address. Technically stake distribution is a value\nwhich is a part of address' attributes. This value corresponds to one of three different cases:</p>\n<ol>\n<li>Bootstrap era distribution. This is a special value which is mandatory in Bootstrap era, but it can be used\nafter Bootstrap era as well.</li>\n<li>Single key distribution, which means that all stake will go to the given stakeholder.\nIn this case distribution contains stakeholder's identifier.</li>\n<li>Multiple key distribution, which means that stake will go to the multiple stakeholders (at least two).\nIn this case distribution contains pairs \"stakeholder's identifier - portion of an output\".\nTransaction's output has a value, portion of this value is a stake.</li>\n</ol>\n<p>Stake distributions are considered by both <a href=\"https://cardanodocs.com/technical/leader-selection/\">slot-leader election process</a>\nand Richmen Computations.</p>\n<p>This feature can be used in similar way to <a href=\"https://cardanodocs.com/technical/delegation/\">delegation</a>, but there\nare differences:</p>\n<ol>\n<li>There is no certificate(s): to revoke stake delegation <code>A</code> has to move funds, providing\ndifferent stake distribution.</li>\n<li>The portion of <code>A</code>'s stake can be delegated via distribution. On the contrary, delegation\nrequires you to delegate all funds of whole address at once.</li>\n</ol>",frontmatter:{path:"/en/cardano/transactions/",doc_title:"Transactions",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-01-16-updating.en.md absPath of file >>> MarkdownRemark",excerpt:"<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<!-- Updated at 6b5eda44e5942599a9781e5ad3f51eb820665b83 -->\n\n# Update Research Overview\n\nIn the Update Mechanism research, we have managed to propose an update system\nthat is capable of producing painless and almost seamless software updates as\nwell as providing stakeholders with an option to vote for hard forks\n(backwards-incompatible protocol updates) without the necessity to introduce any\nnon-protocol-level tools.\n\nWe propose to use stake for voting for soft and hard forks.\n",html:'<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<!-- Updated at 6b5eda44e5942599a9781e5ad3f51eb820665b83 -->\n<h1>Update Research Overview</h1>\n<p>In the Update Mechanism research, we have managed to propose an update system\nthat is capable of producing painless and almost seamless software updates as\nwell as providing stakeholders with an option to vote for hard forks\n(backwards-incompatible protocol updates) without the necessity to introduce any\nnon-protocol-level tools.</p>\n<p>We propose to use stake for voting for soft and hard forks.</p>\n<!-- end -->\n<h2>Update System Model</h2>\n<p>For CSL, we decided to add some support for protocol updates at the protocol\nlayer itself. It introduces some overhead to blockchain processing, but has\nseveral important benefits:</p>\n<ol>\n<li>For each client implementing the protocol, its latest version from\nblockchain is known.</li>\n<li>There is no central entity responsible for maintaining or distributing\nupdates, any such update is proposed under implicit or explicit agreement of\nthe majority of stake and then distributed in a decentralized way.</li>\n<li>We do not rely upon clients updating the software on their PCs in time; this\nis done automatically, and updates are announced directly via the\nblockchain.</li>\n<li>If any security flaws are detected in some version of the CSL protocol or in\nsome particular implementation, there would be a mechanism to distribute an\nupdate rapidly (and still under agreement of the majority of stake).</li>\n</ol>\n<h2>Application Update: Sign and Announce</h2>\n<p>Here we consider ways to update the application securely. Protocol updates are a\nseparate issue which is covered in the relevant section of this document.</p>\n<p>For an update to be applied, its proposal needs be approved first. Update\nproposal can be approved if at least one of two agreements is reached:</p>\n<ol>\n<li><strong>Explicit agreement</strong>: it has positive votes from majority of total stake\n(i. e. strictly greater than <code>50%</code>).</li>\n<li><strong>Implicit agreement</strong>: it has positive votes from more stake than negative\nvotes \ufeff⁠⁠⁠and\ufeff⁠⁠⁠ it has been in blockchain for at least <code>U</code> slots.</li>\n</ol>\n<p>This approach seems to fit naturally into the CSL model, as in a PoS\ncryptocurrency every stakeholder is responsible for maintaining the system\nproportionally to the relative size of their stake, and the blockchain is\nmaintained via consensus among stakeholders.</p>\n<p>Software updates are a part of this maintenance process too, so the stakeholders\nshould agree on whether to consider this update trusted.</p>\n<h3>Implicit Agreement</h3>\n<p>The fact that stakeholders are responsible for system updates does not restrict\nus to a system where every single update requires a signature from the majority\nof stake. We can introduce the concept of an <strong>implicit agreement</strong>.</p>\n<p>An update has to have at least minimal bound (<code>updateProposalThd</code> in\n<a href="https://github.com/input-output-hk/cardano-sl/blob/e26ad11397c87ce8b00f2a26d5e237f54d6ea90a/lib/configuration.yaml">configuration.yaml</a>.)\nof the stake signatures to be published on\nthe blockchain. It is not enough for stakeholders to sign the update — they\nshould vote either for or against it.</p>\n<h3>Incorporation of Alternative Clients</h3>\n<p>IOHK will maintain a single official client. But there is also room for\nthird-party alternative clients maintained by the community. One requires enough\ncollected signatures from stakeholders to publish their system update, which may\nbe not an «update», but a different client developed from scratch, or a fork of\nthe official client. As long as this update has enough signatures from\nstakeholders, the network considers it trusted, and it is updated via the same\nmechanisms as the official client.</p>\n<h2>Application Update: Deliver and Apply</h2>\n<p>А list of HTTP mirrors ran by IOHK shall be sufficient for a start.</p>\n<p>In process of time, we plan to maintain a Bittorrent-based or Bittorrent-like\nsolution to distribute updates. In general, P2P update distribution is a crucial\nbusiness requirement due to legal concerns. It is to be decided which\nBittorrent-like solution particular we will use.</p>\n<p>Also, it’s interesting to note that the update itself does not require a secure\nand trusted channel to be used for delivery, as it is signed with some known in\nadvance and trusted key (or set of keys).</p>\n<p>Application updates are prepared with\n<a href="https://github.com/mendsley/bsdiff">bsdiff</a> and applied either directly or via\nan installer. We\'re considering migrating to\n<a href="http://dev.chromium.org/developers/design-documents/software-updates-courgette">courgette</a>\nin the future.</p>\n<h2>Protocol Update</h2>\n<p>First, we need to distinguish hard and soft protocol updates.</p>\n<p>A soft fork proposes modifying blockchain consensus rules so that the new\nversion blocks are still compatible with old version clients. A hard fork is one\nthat doesn’t maintain backward compatibility with the previous version.</p>\n<p><a href="https://github.com/bitcoin/bips/blob/ed283b05b332b85b6fd683be3a5d73fab6c15554/bip-0099.mediawiki">BIP-99</a>\nprovides excellent criteria to distinguish between these two fork types:</p>\n<ul>\n<li>A <strong>soft fork</strong> introduces new rules, or restrictions, on blocks. That way,\neverything that was previously invalid remains invalid, while some blocks\nthat would have been previously considered valid become invalid.</li>\n<li>A <strong>hard fork</strong> is a fork that makes previously invalid blocks valid.</li>\n</ul>\n<p>Soft forks have some deployment advantages like backward compatibility, and they\ndon\'t require everyone\'s consensus, as the stake majority of users can impose\nthe new rules. By contrast, hard forks require all users to upgrade.</p>\n<p>In theory, a hard fork may lead to a situation when a network splits into two\nparts, each maintaining a separate chain: one from the nodes that adopted the\nlatest system update, and another from the nodes that rejected to do that. This\nmeans some blocks from the first part are considered invalid by the other part,\nand vice versa.</p>\n<p>We define <strong>protocol version</strong> as a tuple <code>(Maj, Min, Alt)</code>:</p>\n<ul>\n<li>Major version (2 bytes): to be changed rarely, changes are not\nbackward-compatible and would produce a hard fork.</li>\n<li>\n<p>Minor version (2 bytes): integer to be adjusted for each update.</p>\n<ul>\n<li>Changes should be backward-compatible in a sense that a block generated\nby the new version shall be somehow accepted by old version.</li>\n<li>A particular block may contain addresses of unknown type. For each case\nlike this, a concise workaround should be found in order not to affect\nstability and correctness of the system.</li>\n</ul>\n</li>\n<li>Alt version (1 byte): integer to manage several simultaneous protocol update\nproposals.</li>\n</ul>\n<p>The protocol version is to be announced in the application update, and is to be\nput later into each block created by updated software.</p>\n<p>A major version change triggers a hard fork in the future.</p>\n<p>A minor version change notifies the network that the subsequent application\nupdate modifies the protocol managed by a soft fork.</p>\n<p>Alt version is a marker of new features. It allows independent developers to\nintroduce multiple changes to the protocol simultaneously. For example, if one\nvendor decides to introduce feature X via a soft fork, and another proposes\nfeature Y (also via a soft fork), their software will be issuing blocks with\nversions <code>a.b.X</code> and <code>a.b.Y</code>, which can coexist in the blockchain. However, only\none will eventually be adopted.</p>\n<h2>Soft Fork Updates</h2>\n<p>There is a thin line between what we can do within a soft fork and what we\ncannot:</p>\n<ol>\n<li>An old version of the client should always find recent blocks valid. (This\nis what\n<a href="https://github.com/bitcoin/bips/blob/ed283b05b332b85b6fd683be3a5d73fab6c15554/bip-0099.mediawiki">BIP-99</a>\ncalls "everything invalid remains invalid").</li>\n<li>Some blocks issued by an old version of the client may be considered invalid\nby a newer version.</li>\n</ol>\n<p>Obviously, imposing rule 2 as it is may cause the network to be split into two\nparts: a stakeholder with a stake large enough could update and maintain their\nown chain, rejecting blocks from others, but others would be still able to\nmaintain their chain, rejecting blocks from this stakeholder (since he does not\nhave a majority of stake, and therefore cannot catch up with the rest of the\ncrowd, so his chain is shorter). A simple resolution rule could go like this: if\n95% of the latest 2016 blocks have a newer block version, the blocks with the\nolder version are rejected.</p>\n<p><strong>NOTE</strong>: <strong>block version</strong> here and later has the same meaning as the\n<strong>protocol version</strong>.</p>\n<p>It may seem unclear why we would like to make some block version invalid at some\nmoment. The key insight here is that a new feature is actually a restriction on\nwhat we had had previously. For example, currently we have plain old\ntransactions which may contain either PublicKey-based addresses or Script-based\nones. Then at some point we decide to include a third address type (no matter\nwhat its purpose is). Which strategy do we need for verifying a block with a\ntransaction with an address of unknown type? Obviously the only option is not\nverifying this address.</p>\n<p>Then imagine somebody proposing a transaction to this address, possibly doing\nthat with an intention to secure funds from being spent until some conditions\nare met — and then watching them being spent in some other transaction in a\nblock with version 1. This is the point. We cannot make use of a restriction\nwithout waiting for the network to start assuming the old version to be\ndeprecated (since we can only start rejecting blocks when their version is\ndeprecated).</p>\n<p>We also cannot bluntly accept all blocks with a version that is higher than the\none currently adopted, since in our implementation every block has a special field\nwhich is used for storing auxiliary information. An attacker can claim she uses a\nhigher version of the protocol and generate a block whose <code>attributes</code> are polluted\nwith meaningless keys. If we accept it, it will bloat the blockchain.</p>\n<p>This is the motivation for the logic described below.</p>\n<p>In our implementation, a block version can exist in the following states:</p>\n<ul>\n<li><strong>Adopted</strong>, when the soft fork resolution rule (see below) for a confirmed\nblock version is triggered.</li>\n<li><strong>Confirmed</strong>, when there is an update proposal that contains a confirmed\nversion of the software and this block version. Note that "confirmed version\nof the software" is a technical term defined\n<a href="/cardano/update-mechanism/#soft-fork-updates">elsewhere</a>. If there are\nmultiple block versions where corresponding software is confirmed, but these\nversions aren\'t adopted, we call them <strong>competing</strong>. For instance, there\nmight be versions <code>2.0.0</code>, <code>2.0.1</code>, <code>1.2.0</code>, <code>1.2.1</code>, <code>1.1.1</code> and <code>1.1.2</code>,\nwith the last adopted version being <code>1.1.3</code>. In this case the versions that\nare competing are <code>2.0.0</code>, <code>2.0.1</code>, <code>1.2.0</code> and <code>1.2.1</code>. The older versions\n<code>1.1.1</code> and <code>1.1.2</code> aren\'t competing, because <code>1.1.3</code> is already adopted.</li>\n<li>Everything else. For example, a new block version is proposed, but the\nsoftware version isn\'t confirmed yet. There is no special name for this\nstate.</li>\n</ul>\n<p>The soft fork resolution rule works as follows:</p>\n<ul>\n<li>Informally, a block version becomes <em>adopted</em> when a certain percentage of\nstake (75% in the current implementation, but this may be different in the\nmainnet) creates a block with version <code>X</code>.</li>\n<li>Formally, we do the following. First, recall that by design, our system does\nnot allow rollbacks of blockchain deeper than a certain fixed global\nthreshold <code>k</code>, which allows to define <em>stable</em> stake for each stakeholder as\ntheir stake <code>k</code> blocks ago. When we process genesis block for epoch <code>e</code>, we\ncompute the stable stake of all leaders of all slots from the very beginning\nof the network\'s existence. For each block with version <code>X</code> that is\ncurrently <em>competing</em>, we take all created <em>stable</em> blocks with version <code>X</code>,\ntake set of all leaders of these blocks and accumulate their stakes. If one\nof versions has ≥ 75%, it gets <em>adopted</em>. If more than one version has ≥\n75%, we take one of them deterministically.</li>\n</ul>\n<p>Note that adopted block version can\'t be changed during epoch (only between\nepochs), so all blocks in an epoch are verified according to the same rules\n(because rules are defined by adopted block version). But it\'s wrong to assume\nthat <em>all</em> blocks in an epoch have the same block version. After block version\nis adopted, another block version can become competing and some nodes may create\nblocks with this new version.</p>\n<p>So, gathering everything up:</p>\n<ol>\n<li>Once the update is confirmed, the protocol version (say <code>0.5.0</code>) can be\nused.</li>\n<li>\n<p>Behavior of nodes that <em>have</em> been updated (i.e. can issue and validate\nblocks with the newer version):</p>\n<ol>\n<li>Before the soft fork is resolved (i.e. before the resolution rule is\ntriggered), issue blocks with the new version <code>0.5.0</code>, but do not\ninclude any new <code>attributes</code> (if there are any). Treat and validate\nblocks of version <code>0.5.0</code> as blocks of version <code>0.4.0</code>.</li>\n<li>Once the soft fork is resolved, issue and validate blocks per version\n<code>0.5.0</code>, including the new <code>attributes</code>.</li>\n</ol>\n</li>\n<li>\n<p>Behavior of nodes that <em>have not</em> been updated (i.e. cannot issue and\nvalidate blocks with the newer version):</p>\n<ol>\n<li>Before the soft fork is resolved, issue and validate blocks per version\n<code>0.4.0</code>. Among other things, a block is not accepted if it contains\nunknown <code>attributes</code>.</li>\n<li>Once the soft fork is resolved, start accepting all blocks with version\n<code>0.5.0</code>, including the ones with unknown <code>attributes</code>. Keep validating\nthem as version <code>0.4.0</code>.</li>\n</ol>\n</li>\n</ol>\n<h2>Hard Fork Updates</h2>\n<p>Hard forks are resolved using modified proof of burn. As it is not implemented\nyet, we omit this section from this document and will publish it as a separate\ndocument.</p>',frontmatter:{path:"/en/cardano/update-mechanism/",doc_title:"Update Mechanism",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}},{node:{id:"/Users/robinclark/iohk-sites/cardanodocs.com/src/pages/en/docs/cardano/2017-02-03-transaction-assurance.en.md absPath of file >>> MarkdownRemark",excerpt:"<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n\n<style>\n.full-width {\n    width: 100%;\n}\n\n.r {\n    color: white;\n    background-color: #ef4e4e;\n    text-align: right;\n    font-weight: 400;\n}\n\n.y {\n    color: white;\n    background-color: #c09e0f;\n    text-align: right;\n    font-weight: 400;\n}\n\n.g {\n    color: white;\n    background-color: green;\n    text-align: right;\n    font-weight: 400;\n}\n\n.gr {\n    color: white;\n    background-color: #aaa;\n    font-weight: 700;\n}\n\n.rd {\n    background-color: #fca8a8;\n    text-align: right;\n    font-weight: 700;\n}\n\n.yd {\n    background-color: #eccd4a;\n    text-align: right;\n    font-weight: 700;\n}\n\n.gd {\n    background-color: #53d153;\n    text-align: right;\n    font-weight: 700;\n}\n\n.center {\n    text-align: center;\n}\n\n.pct25 {\n    width: 25%;\n}\n</style>\n# Transaction Assurance Level\n\nTables below show color-coded levels of assurance that a transaction won’t be\ncanceled by some fork.\n\nFor example, at normal security level, if the attacker’s stake is **10%** (or $6\nmillions for Cardano market capitalization of $60 millions), the levels of\nassurance for a user’s transaction are:\n\n1.  Lowest assurance (color-coded with red) — when the user’s block with coin\n    transfer transaction has depth less than **3** blocks.\n2.  Medium assurance (color-coded with yellow) — when the user’s block has depth\n    from **3** to **7** blocks.\n3.  High assurance (color-coded with green) — when the user’s block has depth\n    **9** or more blocks.\n",html:'<!-- Reviewed at a6a1cdf72c7e167a13f500c0679c01fe4cfa0ca8 -->\n<style>\n.full-width {\n    width: 100%;\n}\n\n.r {\n    color: white;\n    background-color: #ef4e4e;\n    text-align: right;\n    font-weight: 400;\n}\n\n.y {\n    color: white;\n    background-color: #c09e0f;\n    text-align: right;\n    font-weight: 400;\n}\n\n.g {\n    color: white;\n    background-color: green;\n    text-align: right;\n    font-weight: 400;\n}\n\n.gr {\n    color: white;\n    background-color: #aaa;\n    font-weight: 700;\n}\n\n.rd {\n    background-color: #fca8a8;\n    text-align: right;\n    font-weight: 700;\n}\n\n.yd {\n    background-color: #eccd4a;\n    text-align: right;\n    font-weight: 700;\n}\n\n.gd {\n    background-color: #53d153;\n    text-align: right;\n    font-weight: 700;\n}\n\n.center {\n    text-align: center;\n}\n\n.pct25 {\n    width: 25%;\n}\n</style>\n<h1>Transaction Assurance Level</h1>\n<p>Tables below show color-coded levels of assurance that a transaction won’t be\ncanceled by some fork.</p>\n<p>For example, at normal security level, if the attacker’s stake is <strong>10%</strong> (or $6\nmillions for Cardano market capitalization of $60 millions), the levels of\nassurance for a user’s transaction are:</p>\n<ol>\n<li>Lowest assurance (color-coded with red) — when the user’s block with coin\ntransfer transaction has depth less than <strong>3</strong> blocks.</li>\n<li>Medium assurance (color-coded with yellow) — when the user’s block has depth\nfrom <strong>3</strong> to <strong>7</strong> blocks.</li>\n<li>\n<p>High assurance (color-coded with green) — when the user’s block has depth\n<strong>9</strong> or more blocks.</p>\n<!-- end -->\n<h2>Normal Security Level</h2>\n</li>\n</ol>\n<p>Normal level is for covert adversaries (the model is described in the latest\nversion of Ouroboros being prepared now to be shared). Values in the table\ncorrespond to Cardano market capitalization of $60 millions.</p>\n<table class="full-width">\n<tr>\n    <th class="center">             Attackers\' stake, %</th>\n    <th class="center pct25">       Attackers’ stake, $ mln </th> \n    <th colspan="6" class="center"> Assurance level         </th>\n</tr>\n<tr class="center">\n    <td></td>\n    <td></td>\n    <td> Low    </td>\n    <td> 0.950  </td>\n    <td> 0.990  </td>\n    <td> 0.995  </td>\n    <td> 0.999  </td>\n    <td> High   </td>\n</tr>\n<tr>\n    <td class="gr"> 10          </td>\n    <td class="gr"> 6           </td>\n    <td class="rd"> &lt; 3      </td>\n    <td class="yd"> 3           </td>\n    <td class="yd"> 5           </td>\n    <td class="yd"> 7           </td>\n    <td class="gd"> 9           </td>\n    <td class="gd"> 9 &lt;      </td>\n</tr>\n<tr>\n    <td>            15          </td>\n    <td>            9           </td>\n    <td class="r">  &lt; 5      </td>\n    <td class="y">  5           </td>\n    <td class="y">  9           </td>\n    <td class="y">  11          </td>\n    <td class="g">  15          </td>\n    <td class="g">  15 &lt;     </td>\n</tr>\n<tr>\n    <td>            20          </td>\n    <td>            12          </td>\n    <td class="r">  &lt; 7      </td>\n    <td class="y">  7           </td>\n    <td class="y">  13          </td>\n    <td class="y">  15          </td>\n    <td class="g">  21          </td>\n    <td class="g">  21 &lt;     </td>\n</tr>\n<tr>\n    <td>            25          </td>\n    <td>            15          </td>\n    <td class="r">  &lt; 9      </td>\n    <td class="y">  9           </td>\n    <td class="y">  19          </td>\n    <td class="y">  23          </td>\n    <td class="g">  33          </td>\n    <td class="g">  33 &lt;     </td>\n</tr>\n<tr>\n    <td>            30          </td>\n    <td>            18          </td>\n    <td class="r">  &lt; 17     </td>\n    <td class="y">  17          </td>\n    <td class="y">  31          </td>\n    <td class="y">  39          </td>\n    <td class="g">  55          </td>\n    <td class="g">  55 &lt;     </td>\n</tr>\n<tr>\n    <td>            35          </td>\n    <td>            21          </td>\n    <td class="r">  &lt; 29     </td>\n    <td class="y">  29          </td>\n    <td class="y">  57          </td>\n    <td class="y">  71          </td>\n    <td class="g">  101         </td>\n    <td class="g">  101 &lt;    </td>\n</tr>\n<tr>\n    <td>            40          </td>\n    <td>            24          </td>\n    <td class="r">  &lt; 67     </td>\n    <td class="y">  67          </td>\n    <td class="y">  133         </td>\n    <td class="y">  163         </td>\n    <td class="g">  235         </td>\n    <td class="g">  235 &lt;    </td>\n</tr>\n<tr>\n    <td>            45          </td>\n    <td>            27          </td>\n    <td class="r">  &lt; 269    </td>\n    <td class="y">  269         </td>\n    <td class="y">  539         </td>\n    <td class="y">  661         </td>\n    <td class="g">  951         </td>\n    <td class="g">  951 &lt;    </td>\n</tr>\n<tr>\n    <td>            46          </td>\n    <td>            27.6        </td>\n    <td class="r">  &lt; 421    </td>\n    <td class="y">  421         </td>\n    <td class="y">  843         </td>\n    <td class="y">  1033        </td>\n    <td class="g">  1487        </td>\n    <td class="g">  1487 &lt;   </td>\n</tr>\n<tr>\n    <td>            47          </td>\n    <td>            28.2        </td>\n    <td class="r">  &lt; 751    </td>\n    <td class="y">  751         </td>\n    <td class="y">  1501        </td>\n    <td class="y">  1841        </td>\n    <td class="g">  2649        </td>\n    <td class="g">  2649 &lt;   </td>\n</tr>\n<tr>\n    <td>            48          </td>\n    <td>            28.8        </td>\n    <td class="r">  &lt; 1691   </td>\n    <td class="y">  1691        </td>\n    <td class="y">  3381        </td>\n    <td class="y">  4143        </td>\n    <td class="g">  5965        </td>\n    <td class="g">  5965 &lt;   </td>\n</tr>\n<tr>\n    <td>            49          </td>\n    <td>            29.4        </td>\n    <td class="r">  &lt; 6763   </td>\n    <td class="y">  6763        </td>\n    <td class="y">  13527       </td>\n    <td class="y">  16585       </td>\n    <td class="g">  23869       </td>\n    <td class="g">  23869 &lt;  </td>\n</tr>\n</table>\n## Strict Security Level\n<p>Strict security level protects against all types of adversaries (it requires\nmore block confirmations). Values in the table correspond to Cardano market\ncapitalization of $60 millions.</p>\n<table class="full-width">\n<tr>\n    <th class="center">             Attackers\' stake, %</th>\n    <th class="center pct25">       Attackers’ stake, $ mln </th> \n    <th colspan="6" class="center"> Assurance level         </th>\n</tr>\n<tr class="center">\n    <td></td>\n    <td></td>\n    <td> Low    </td>\n    <td> 0.950  </td>\n    <td> 0.990  </td>\n    <td> 0.995  </td>\n    <td> 0.999  </td>\n    <td> High   </td>\n</tr>\n<tr>\n    <td class="gr"> 10          </td>\n    <td class="gr"> 6           </td>\n    <td class="rd"> &lt; 5      </td>\n    <td class="yd"> 5           </td>\n    <td class="yd"> 9           </td>\n    <td class="yd"> 11          </td>\n    <td class="gd"> 15          </td>\n    <td class="gd"> 15 &lt;     </td>\n</tr>\n<tr>\n    <td>            15          </td>\n    <td>            9           </td>\n    <td class="r">  &lt; 7      </td>\n    <td class="y">  7           </td>\n    <td class="y">  14          </td>\n    <td class="y">  16          </td>\n    <td class="g">  23          </td>\n    <td class="g">  23 &lt;     </td>\n</tr>\n<tr>\n    <td>            20          </td>\n    <td>            12          </td>\n    <td class="r">  &lt; 12     </td>\n    <td class="y">  12          </td>\n    <td class="y">  21          </td>\n    <td class="y">  25          </td>\n    <td class="g">  35          </td>\n    <td class="g">  35 &lt;     </td>\n</tr>\n<tr>\n    <td>            25          </td>\n    <td>            15          </td>\n    <td class="r">  &lt; 19     </td>\n    <td class="y">  19          </td>\n    <td class="y">  34          </td>\n    <td class="y">  40          </td>\n    <td class="g">  55          </td>\n    <td class="g">  55 &lt;     </td>\n</tr>\n<tr>\n    <td>            30          </td>\n    <td>            18          </td>\n    <td class="r">  &lt; 32     </td>\n    <td class="y">  32          </td>\n    <td class="y">  57          </td>\n    <td class="y">  68          </td>\n    <td class="g">  94          </td>\n    <td class="g">  94 &lt;     </td>\n</tr>\n<tr>\n    <td>            35          </td>\n    <td>            21          </td>\n    <td class="r">  &lt; 63     </td>\n    <td class="y">  63          </td>\n    <td class="y">  111         </td>\n    <td class="y">  132         </td>\n    <td class="g">  181         </td>\n    <td class="g">  181 &lt;    </td>\n</tr>\n<tr>\n    <td>            40          </td>\n    <td>            24          </td>\n    <td class="r">  &lt; 157    </td>\n    <td class="y">  157         </td>\n    <td class="y">  274         </td>\n    <td class="y">  325         </td>\n    <td class="g">  443         </td>\n    <td class="g">  443 &lt;    </td>\n</tr>\n<tr>\n    <td>            45          </td>\n    <td>            27          </td>\n    <td class="r">  &lt; 729    </td>\n    <td class="y">  729         </td>\n    <td class="y">  1246         </td>\n    <td class="y">  1470         </td>\n    <td class="g">  1990         </td>\n    <td class="g">  1990 &lt;    </td>\n</tr>\n<tr>\n    <td>            46          </td>\n    <td>            27.6        </td>\n    <td class="r">  &lt; 1190   </td>\n    <td class="y">  1190        </td>\n    <td class="y">  2020        </td>\n    <td class="y">  2379        </td>\n    <td class="g">  3214        </td>\n    <td class="g">  3214 &lt;   </td>\n</tr>\n<tr>\n    <td>            47          </td>\n    <td>            28.2        </td>\n    <td class="r">  &lt; 2230   </td>\n    <td class="y">  2230        </td>\n    <td class="y">  3758        </td>\n    <td class="y">  4418        </td>\n    <td class="g">  5953        </td>\n    <td class="g">  5953 &lt;   </td>\n</tr>\n<tr>\n    <td>            48          </td>\n    <td>            28.8        </td>\n    <td class="r">  &lt; 5382   </td>\n    <td class="y">  5382        </td>\n    <td class="y">  8986        </td>\n    <td class="y">  10542       </td>\n    <td class="g">  14157       </td>\n    <td class="g">  14157 &lt;  </td>\n</tr>\n<tr>\n    <td>            49          </td>\n    <td>            29.4        </td>\n    <td class="r">  &lt; 24029  </td>\n    <td class="y">  24029       </td>\n    <td class="y">  39603       </td>\n    <td class="y">  46320       </td>\n    <td class="g">  61922       </td>\n    <td class="g">  61922 &lt;  </td>\n</tr>\n</table>',
  frontmatter:{path:"/en/cardano/transaction-assurance-level/",doc_title:"Transaction Assurance Level",author:null,date:null,language:"en",label:"docs",keywords:null,group:"cardano"}}}]}},pathContext:{}}}});
  //# sourceMappingURL=path---en-for-contributors-29bf88e3d986b5bdcf39.js.map