区块链中文技术社区 - EOS-优秀转载
type: channel
link: https://bcskill.com/index.php/category/EOS-优秀转载/
items: Trust EVM 让EOS支持以太坊合约
items: Mandel 将于 2022 年收购 EOSIO
items: EVM+：帮助EOS实现EVM兼容
items: EOS 希望与 Dan Larimer 一起履行 2017 年的承诺
items: EOS的BFT-DPOS共识机制的进化过程及背后逻辑
items: 先进的EOSIO编程理念
items: 跨链技术的分析和思考
items: EOS区块结构、生产、打包、验证、存储等流程分析
items: 同步区块--p2p通信--notice_message
items: 同步区块--p2p通信--handshake_message

Trust EVM 让EOS支持以太坊合约
type: item
date: 2022-07-15T16:29:36+08:00
description: 先记录下，做个笔记，翻译来自谷歌，有能力看原文。。 https://docs.trust.one/ Trust 是基于 EOS 网络的以太坊虚拟机，为开发者提供了一个交钥匙解决方案，可以在完全兼容以太坊的链上运行他们的应用程序，同时享受 EOS 的高吞吐量、可扩展性、安全性和可靠性，以及低交易成本 他们的用户。 由于设计的高度兼容性，以太坊原生应用程序可以无缝移植到 Trust。 开发人员在这里使用他们的 Solidity 智能合约时可能会喜欢熟悉的以太坊工具。 特点： 确定性的Gas计算 指令集级别的EVM兼容性 完全的RPC兼容 技术实现 https://docs.trust.one/understanding-trust/architecture EVM 作为 EOS 网络中的智能合约实现。 在 EVM 网络中生成交易是通过调用 EOS 网络上的 EVM 合约来完成的，EVM 的状态可以从 EOS 上的信息中得出。 为了实现完全 RPC 兼容性的目标，我们利用功能齐全的以太坊节点（当前设计中的 Geth）来提供所有读取 API，而所有写入访问将被转发到一个小型服务，以将它们打包到对 EVM 合约的 EOS 调用中。 我们所做的是设置一个“翻译器”服务，该服务读取运行在 EOS 上的 EVM 智能合约的共识输出，将该信息翻译成相应的 ETH 格式块并将这些块提供给 Geth 节点。 然后我们可以公开以太坊客户端 Web3 JSON RPC API（如有必要，还可以公开其他 API）。 如果我们发现它们更适合这种情况，我们也可能会在不同的场景中使用以太坊节点的其他实现。 未来的改进 当前设计正在运行并提供预期的兼容性级别。 还有一些潜在的方法可以改进整个系统： 合并 Translator 服务和 Geth 节点，去除相对不可靠的 p2p eth/66 通道。 将所有内容合并到一个 EOSIO 插件中，以便于部署。 MetaMask测试 https://docs.trust.one/about-the-testnet/connect-metamask Network Name: Trust Network Testnet Preview Chain ID: 15555 New RPC URL*: https://api.testnet-dev.trust.one Currency Symbol: EVM Block Explorer URL (Optional): https://trustscan.one Faucet https://faucet.testnet-dev.trust.one/ https://www.odaily.news/post/5178155 https://www.odaily.news/post/5178155

Mandel 将于 2022 年收购 EOSIO
type: item
date: 2022-01-30T09:30:18+08:00
description: 自两年多前发布 EOSIO 2.0 以来，EOS 网络没有进行过重大升级。从那时起，block.one 产生了 EOSIO 2.1 和 EOSIO 2.2 的候选版本；然而，由于各种原因，Clarionos 团队和更广泛的 EOS 社区不希望所有代码都与最新版本捆绑在一起。 展望未来，Clarionos 团队会将 EOSIO 代码库分叉到一个新的代码库中，我们称之为 Mandel（Mandelbrot 的缩写）。在所有 EOSIO 驱动的区块链之间达成更广泛的共识之前，Mandel 名称是一个占位符。 Mandel 的第一个版本将是 3.0，并将从 EOSIO 2.0 派生，同时从 EOSIO 2.1 和 EOSIO 2.2 中挑选一些最有价值的增强功能。Mandel 3.0 还将引入两个新的硬分叉：合同支付、增强的可配置区块链参数。此外，它将从 EOSIO 2.1 中挑选可配置的 WASM 限制硬分叉。 虽然 EOS 区块生产者大部分仍使用 EOSIO 2.0，但一些 EOS 基础设施节点和其他下游软件已升级到 EOSIO 2.1。在迁移到 Mandel 3.0 之前要求这些节点“降级”到 EOSIO 2.0 可能会造成不必要的短期负担；因此，Clairionos 还将发布源自 EOSIO 2.1 的 Mandel 2.3 版本，该版本对 Mandel 3.0 启用的新硬分叉支持精选支持。EOSIO 2.1 节点应该能够无缝升级到 Mandel 2.3，同时与网络保持同步。 Clarionos 的目标是将尽可能多的 EOSIO 2.1 增强功能迁移到 Mandel 3.0，而不会延迟关键硬分叉的交付。 即将推出的硬分叉功能 1. 可配置的 WASM 限制 这种硬分叉允许区块生产者增加可以部署的智能合约的规模，这将允许部署更大、更强大的合约。出于安全目的，EOSIO 必须限制各种 wasm 参数，例如内存、函数数量等。一旦合约达到这些限制之一，开发人员就被迫将其代码划分为多个合约。早在 EOSVM 为 EOS 带来巨大的性能提升之前，就已经建立了最初的限制。我们现在认为增加这些限制是安全的。我们没有一次性增加，而是使它们可配置。这使网络有能力在未来扩展或在攻击者以某种方式利用额外容量时对其进行调整。 2. 合同支付 开发人员面临的最具挑战性的事情之一是使他们的应用程序易于使用。要求用户从网络租用 CPU、NET 和 RAM 资源以便与应用程序交互是一个主要的可用性障碍。在理想的世界中，智能合约将支付合约用户所需的所有资源。 当今存在的 EOS 要求每笔交易都必须由至少一个密钥签名，并且每个权限级别的阈值至少为 1。这限制了合约获取用户所需资源的潜力。 我们开发了一种不需要硬分叉的合同支付方法，但“黑客”涉及发布任何人都可以签名的“私人”密钥。当我们可以简单地允许相同的交易发生而没有任何密钥对其进行签名时，这会给网络带来不必要的负担。 在没有任何密钥的情况下可能发生的操作的一个示例是合约需要执行一些维护任务。合约愿意支付自己的维护费用，它不关心谁授权了交易。如果没有要执行的维护，那么合约将简单地拒绝交易并避免任何资源使用。维护任务的一个示例可能是当前由已弃用的延迟事务执行的许多任务。 通过合约支付，可以实现与比特币交易结构相同的交易。这消除了那些只想将 EOS 用作货币的人的帐户创建成本。它还将使实施 隐私令牌成为可能，而不会让您的隐私受到资源系统的损害。虽然这些事情将通过合同支付成为可能，但它们超出了当前路线图的范围。 有关合同付款的更多信息，请点击此处。 3. 增强的可配置区块链参数 这个硬分叉功能使添加/删除/配置未来的目标功能变得更加容易。不必为每个新功能或可配置参数添加新的本机内在函数，合约可以调用一个内在函数。这允许合约根据特征的存在或配置参数的值进行有条件的操作。此功能主要在 EOSIO 2.1 中实现，但经过审查，Clarionos 团队得出结论，需要进行一些小调整以确保更一致的操作。 系统合约升级 Clarionos 团队对 EOS 系统联系人有一个拉取请求，该请求将通过发布“私钥”来启用合同支付功能。这将允许应用程序在等待硬分叉生效的同时开发增强的用户体验。硬分叉后也需要利用该特性。 时间线 以下时间表是理想的，可能会随着发展的变化而变化。 2022 年 1 月 31 日— Mandel 3.0 的候选版本 2022 年 2 月— Mandel 3.0 测试网络启动和社区验证 2022 年 3 月 1 日— Mandel 3.0 最终版本 2022 年 3 月 2 日——网络部署 Contract Pays 系统合约 2022 年 4 月 1 日——Mandel 2.3 发布 2022 年 4 月 9 日——…

EVM+：帮助EOS实现EVM兼容
type: item
date: 2022-01-29T09:59:34+08:00
description: 引言：EVM+工作组正在采取行动，在EOS上部署以太坊虚拟机 概述 EOS正在凝聚社区力量共同开发生态所需的关键项目，从而进一步推动EOS生态的复苏。我们拥有才华横溢的开发人员，能够做出重大贡献的社区领袖，以及责任心和行动力都非常强的EOS网络基金会。 EOS正在开辟自己的前进道路，并开启一个新的协作时代。 目前，由EOS网络基金会资助成立的六大核心工作组正在高速运行，每个工作组都在其领域发挥重要作用，其中API+、Core+、Wallet+和Audit+四个工作组蓝皮书已接近完成，每份蓝皮书都是重要的研究成果，将详细阐述发展目标，各自领域如何取得成功的可行策略等。 今天，我们将带领大家认识EVM+核心工作组，在正式介绍之前，我们先来了解一下六大核心工作组的概况。 六大核心工作组介绍 目前，EOS网络基金会赞助成立了六个核心工作组，他们分别是： API+：主要负责提供数据接口，帮助EOS生态以外的应用程序更好的集成EOS网络。 Core+：主要负责维护EOS系统使EOS更适合运行各种类别的应用程序。 Wallet+：主要负责配合软件将EOS集成到外部应用程序中。 Audit+：主要负责为EOS应用提供安全分析工具和合约审计的整体框架。 EVM+：主要负责实现与EVM的兼容以及探索EOS可行性的经济激励措施。 Recover+：主要负责建立危机处理框架，通过制定紧急联络、反应机制、DAO保险和白帽奖励等措施，帮助EOS项目在遭遇黑客攻击后以更合理有效的方式应对危机及追回丢失资产。 核心工作组将会与EOS生态中最有经验的人和组织合作，在落实EOS路线图方面发挥重要作用。这将是一个评估EOS生态现状、识别潜在问题并为未来发展制定路线图的绝佳机会。 每个工作组都收到了来自EOS网络基金会提供的20–25万美元的资助，另外EOS网络基金会还支出10万美元成立了一个监督小组，专门监督工作组的整体进展。 但出于社区呼声和生态需求的考虑，EVM+工作组与其他工作组的工作流程略有不同。在EOS Argentina的领导下，EVM+工作组将采取更敏捷的方式进行开发。 EVM+工作组不撰写蓝皮书，而是直接进行开发和产品交付，从而更快的在EOS智能合约层面实现EVM兼容。另外， EVM+工作组的初始预算资金为20万美元。 EVM+工作组介绍 EOS目前面临的最重要的问题之一是区块链的互操作性。 区块链领域最容易产生的问题是向内聚焦发展，而忽视了向外兼容取长补短，这样的问题在EOS表现的很明显。开发人员经常陷入一种思维逻辑：EOS拥有最好的技术，所以EOS是最好的地方，即使其他公链生态的人都还没有意识到EOS的潜力。 这样的想法会使EOS与更广阔的区块链世界隔绝开来，很容易坐井观天错过许多机会。许多开发者离开EOS，转投以太坊，原因就是虽然以太坊存在缺陷，但是却拥有更好的兼容性。 这也是我们成立EVM+工作组并加速这方面工作的重要原因，在EOS上部署以太坊虚拟机是一件非常重要的工作，我们需要推动EOS融入更广阔的区块链生态，不断的引进来、走出去，兼容并蓄快速发展。 从技术及业务角度来看，实现EVM兼容能够在释放EOS潜力方面发挥至关重要的作用。我们需要更多的以太坊开发者和用户加入EOS生态，而帮助EOS实现EVM兼容是吸引他们加入的最佳方式。 站在成功的肩膀上，吸引开发人才 EVM+工作组的领导团队是EOS创世区块生产者EOS Argentina，该团队也是Evodex和EOS Metamask钱包背后的开发人员。 为EVM+工作组提供协助的还有EOS生态的著名开发者Syed Jafri，他在2020年凭借EOSIO.EVM赢得了Block.one举办的EVM挑战赛， EOSIO.EVM使Solidity开发人员能够在EOSIO上快速启动并以高达100倍的速度和低于1000倍的成本运行应用程序。可以说，Syed Jafri在帮助EOS实现EVM兼容方面十分有经验。 EVM是EOS急需的创新。EOS公链在过去几年中面临的主要问题之一是资金匮乏。让我们和以太坊生态做一个对比： 以太坊速度更慢、效率更低而且Gas成本非常高，但以太坊和其他基于EVM的公链之间拥有更高的网络效应和代币流动性。另一方面，一部分以太坊上的开发人员能够通过创造基于Solidity编写的模块化、可重复利用、安全开源的智能合约获得高额回报，另一部分开发者可通过OpenZeppelin等组织的收录的代码库获得丰富的开发工具和教程。一个不可否认的事实是：EVM生态系统中的开发人员工具、代码库、可供dApp开发人员使用的开源代码一直在快速增长。 反观EOS生态，开发人员只能使用不太成熟的工具从头开始构建许多代码库，一个不恰当的比喻是：以太坊生态的开发者制造汽车就像是搭积木，把现成的车轮、方向盘…

EOS 希望与 Dan Larimer 一起履行 2017 年的承诺
type: item
date: 2022-01-21T22:32:34+08:00
description: 关键要点 EOS 网络基金会通过招募网络架构师 Dan Larimer，在加强其独立于 Block.one 方面迈出了重要一步。 Larimer 和他的团队将分叉 EOSIO 代码库。 多年来，该项目的创始公司 Block.one 一直未能兑现承诺，社区普遍对此表示不满，但这些进展都是如此。 EOS 网络基金会已聘请 EOSIO 的创始开发者 Dan Larimer 帮助其接管 EOS 生态系统的方向。该合作伙伴关系是在 EOS 社区投票停止授予其创始支持者 Block.one 之后的。 EOS Network Foundation 的目标是更美好的未来 EOS 网络基金会的目标是复兴。 Dan Larimer 是 EOS 的架构师，之前是该项目的创始支持者 Block.one 的一部分，现在将帮助该基金会重振该项目的生态系统。为了进一步建立与 Block.one 的独立性，Larimer 和他的团队将分叉 EOSIO 代码库。 分叉将发生在两个主要升级中：Mandel 2.3 和 Mandel 3.0。EOS Network Foundation 获得了 200,000 EOS 来帮助 Larimer 和他的团队执行分叉。 Larimer 在新闻稿中表示，Mandel 代码分叉是“通往 EOS 独立的最短路径”。他还将分叉描述为“振兴 EOS 多年计划的第一步”。 今天宣布的事态发展是在 EOS 社区多年的困境之后发生的。EOS 在 2017 年声名鹊起，当时 Block.one 通过 ICO 筹集了 41 亿美元来资助该项目。它是加密社区中被称为“以太坊杀手”的几个区块链之一。然而，它未能兑现承诺。在筹集资金之后，Block.one 提出了一些在几年后仍未推出的举措。 Block.one 的失误导致 EOS 社区内长期存在分歧。该公司被指控阻碍了该项目的进展，EOS 网络基金会的首席执行官不断声称由于 Block.one 未能执行而遭受了损失。在两个阵营之间多年的紧张关系之后，EOS 区块生产者在 12 月投票停止了 6700 万个 EOS 代币的归属，这些代币计划在未来六到七年内为 Block.one 解锁。该拨款目前价值约 1.8 亿美元。 EOS 网络基金会希望加入 Larimer 将使该项目更接近于实现其最初的愿景。上周，它从 EOS 社区获得了 2100 万美元的资金，以实现其目标。能否卷土重来，还有待观察。 英文原文：https://cryptobriefing.com/eos-wants-fulfill-2017-promises-with-dan-larimer/

EOS的BFT-DPOS共识机制的进化过程及背后逻辑
type: item
date: 2022-01-14T17:30:22+08:00
description: 不知道是阅读量到了质变，还是后面引用的这篇文章太好，我终于对BFT-DPOS有了更深刻的理解 POS: 出块不再由算力说了算，由节点持有的stake说了算，解决了POW算力资源被大量无用消耗，但由于无条件信任代表，节点作恶非常容易 , 比如nothing at stake攻击 DPOS： 动态产生一定数量的代表比如21个节点代表，只由这21个节点生成区块，降低了作恶的概率，同时用事后惩罚限制节点代表作恶行为，但始终不够安全(怎么惩罚，使用抵押物？抵押物需要多少？作恶导致的失败交易的损失都是可以量化的吗？如果不能量化抵押物就没有意义)，同时确认速度确实也慢(需要14个block） BFT+DPOS： 一个区块生产后通过BFT协议立马确认，解决了DPOS确认慢问题，需要超过1/3节点才能作恶，相比POW 51%作恶条件，这个1/3值相对来说还是偏低了点，但是这是一个折中，也只能这样了 BFT + DPOS + 小块： 该协议是为了加快出块速度，该改进的核心思想是让同一个节点产生6个小块。这个能提升性能的核心原因是6个小块的产生没有等待确认的环节。在BFT+DPOS算法中，一个节点要创建新块，必须等上一个块被确认(或者超时)，因为它不确定上一个节点是否作恶是否会被确认，所以它只能等。但是如果上一个块时也是该节点产生的，它自然不需要等上一块确认，因为它知道上一个块是真实的，不是作恶的块，最后肯定会被确认，所以安心生产下一块。 可见DPOS+BFT+小块机制中，区块生成和确认以pipeline的方式进行，是同时进行的，加快了出块速度。 何为作恶： 各种共识算法，节点基本都会进行数据检验功能，因而数据伪造作恶基本不可能。那真正的作恶是什么？ 主动作恶：节点主动生产两个区块，给一部分节点发送新区块A，另外一部分节点发送区块A1,这样系统就产生分叉了。 被动作恶： 块传播因为网络延时或者中断，会导致一部分节点缺失该块的信息，进而会产生分叉，然后后续区块生产者发现分叉后，如果遵循只选择一个分支生产区块就会让分叉收敛(能收敛最后就能达成共识)，但是如果继续保持并加重这个分叉，最后就会导致整个链变成一颗森林，最后节点就永远没法达成共识, 这是被动作恶。比如POS的noting at stake攻击，当系统出现分叉时，生产者基于自己的利益会在两个分叉区块上各自生成一个区块(这样不管哪个分叉获胜，自己都能获得收益)，这其实间接助长和加重了分叉 因而要阻止这些作恶行为，有三种方法: 1)机制保证，让生产者没有时间来生成2个区块(POW) 2)利益保证，生成两个区块最后肯定没用(BFT算法, 大家最后只会认可一个快)，生产者获取不了什么好处，自然没必要生产两个区块 3）事后惩罚，比如DPOS，这种方法其实没啥用，因为事后发现作恶节点后，系统没法回溯区块，只能惩罚作恶节点，但是这个作恶损失是不确定的(前面提到过)，起不到惩罚作用，且抵押物模式是一种限制，不利于生态发展 引用原文 区块链中最重要的便是共识算法，比特币使用的是POW（Proof of Work，工作量证明），以太币使用的POS（Proof of Stake，股权证明）而EOS使用的是BFT-DPOS。 什么是BFT-DPOS呢？即拜占庭容错式的委任权益证明。 要想明白BFT-DPOS的运行机制，首先就要先明白什么是DPOS。 由于POW在比特币的共识算法中极大地消耗了算法的资源。而且会有算法集中的问题，所以在2014年的时候Dan Larimer提出了一个相较于POW来说更加高效，轻便的共识机制即DPOS。该共识机制一边能让网络成本小型化，另一方面有回复语每个持股人一定的投票权。 这些超级节点呢能够：供相关计算资源和网络资源，保证节点的正常运行;当轮到某超级节点拥有出块权时，超级节点收集该时段内的所有交易，并对交易验证后打包成区块广播至其他超级节点，其他节点验证后把区块添加到自己的数据库中。这种共识机制采用随机的见证人出块顺序，出块速度为 3 秒，交易不可逆需要45秒。为什么需要 45 秒呢？因为 DPoS 下，见证人生产一个新区块，才表示他对之前的整条区块链进行了确认，表明这个见证人认可目前的整条链。而一个交易要达到不可逆状态，需要 三分之二以上的见证人确认，在 EOS 里就是 14 个见证人。DPoS共识算法也有极强的抗分叉能力，因为区块添加到一条区块链分叉的速率与拥有该共识的超级节点比例是相关的。当一个超级节点设法在两条分叉上同时生产区块时，EOS的持有者会在下一轮投票中将该超级节点删掉，并且EOS社区会给予相关恶意节点一定的惩罚。因此，在一般情况下，使用DPoS的EOS都是很难经历分叉的。 其次，我们还要明白BFT所代表的的意义。 拜占庭容错技术（Byzantine Fault Tole…

先进的EOSIO编程理念
type: item
date: 2019-08-28T10:43:58+08:00
description: 在审查EOS智能合约时，我注意到每个开发人员都有自己的编程风格，并且有许多不同的方法可以执行相同的操作，例如处理时间或将操作发送到其他合约。这篇文章是一些EOSIO库函数的思想转述，我觉得这些函数很优雅且有用。 1. eosio::same_payer 第一个只是一个常量表达式，可以在修改多索引表的条目时使用。使用eosio::same_payer时，将使用的新RAM（如果有）将分配给已为表条目支付的同一帐户。 用法： statstable.modify( st, eosio::same_payer, [&]( auto& s ) { s.supply += quantity; }); 它在[multi_index.hpp]中定义，只是空name(value:0)""_n 或者name(0)的常量表达式，一些开发人员仍然使用它来表示同一个付款人。 2. get_first_receiver，get_self() 在contracts.hpp中定义的两个getters get_self和get_first_receiver返回正在运行的操作的执行上下文的一部分。（在EOSIO.CDT1.6中实现了get_first_receiver以支持旧的get_code，现在不推荐使用。）get_self方法返回当前运行代码的合约，而get_first_receiver返回动作源自的帐户。除非涉及通过require_recipient的通知，否则这两个帐户是相同的。 例如，通过侦听eosio.token的传输操作的通知，get_self()返回你的合约部署到的帐户，而get_first_receiver()返回eosio.token帐户。这是因为该行为来自向你的合约帐户发送转移操作到eosio.token帐户的帐户。 用法： transfer") void cryptoship::transfer(name from, name to, const asset &quantity, string memo) { print(get_self()); // cryptoship print(get_first_receiver()); // eosio.token } 3.action_wrapper 许多用例需要将合约代码中的新操作发送到另一个合约。这是合约可以相互积极沟通的唯一方式。同样，有很多方法可以做到这一点，但最优雅的方法之一是使用eosio::action_wrappers。它为特定智能合约代码的特定操作创建操作模板，然后可用于调用此操作。 第一个参数是操作名称，第二个参数是操作的方法声明。 用法 eosio.token标头为eosio.token.hpp header file中的所有操作定义了动作包装器： action void create( name issuer, asset maximum_supply); action void issue( name to, asset quantity, string memo ); action void retire( asset quantity, string memo ); action void transfer( name from, name to, asset quantity, string memo ); // ... using create_action = eosio::action_wrapper<"create"_n, &token::create>; using issue_action = eosio::action_wrapper<"issue"_n, &token::issue>; using retire_action = eosio::action_wrapper<"retire"_n, &token::retire>; using transfer_action = eosio::action_wrapper<"transfer"_n, &token::transfer>; // ... 我们现在可以通过包含此头文件向任何eosio.token合约发送内联操作。 需要注意的是，只需要包含带有声明的头文件。意思是，即使对于具有未知实现细节的闭源合约，也可以轻松编写动作包装器。只需要写出声明，动作签名，可以从ABI获得。 使用eosio-cpp的-I标志包含头文件的附加包含目录。 包含头文件后，将发送内联传输操作，如下所示： #include <eosio_token/include…

跨链技术的分析和思考
type: item
date: 2019-07-05T17:56:33+08:00
description: 前由 当前的区块链底层技术平台百花齐放，不同的业务、不同的技术底层的区块链之间缺乏统一的互联互通的机制，这极大限制了区块链技术和应用生态的健康发展。跨链的需求由此而来，本文通过分析几种主流的跨链方案探讨跨链技术的本质及相应的解决思路。 跨链的类型 跨链交互根据所跨越的区块链底层技术平台的不同可以分为同构链跨链和异构链跨链：同构链之间安全机制、共识算法、网络拓扑、区块生成验证逻辑都一致，它们之间的跨链交互相对简单。而异构链的跨链交互相对复杂，比如比特币采用PoW算法而联盟链Fabric采用传统确定性共识算法，其区块的组成形式和确定性保证机制均有很大不同，直接跨链交互机制不易设计。异构链之间的跨链交互一般需要第三方辅助服务辅助跨链交互。 主流跨链机制概述 截至目前，主流的区块链跨链技术方案按照其具体的实现方式主要分为三大类，分别是公证人机制、侧链/中继和哈希锁定： 公证人机制（Notary schemes）: 公证人也称见证人机制，公证人机制本质上是一种中介的方式。具体而言，假设区块链A和B本身是不能直接进行互操作的，那么他们可以引入一个共同信任的第三方作为中介，由这个共同信任的中介进行跨链消息的验证和转发。公证人机制的优点在于能够灵活地支持各种不同结构的区块链（前提是公证人能够访问相关方的链上信息），缺点在于存在中心化风险 2.哈希锁定（Hash-locking）: 哈希锁定技术主要是支持跨链中的原子资产交换，最早起源自比特币的闪电网络。其典型实现是哈希时间锁定合约HTLC(Hashed TimeLock Contract)。哈希锁定的原理是通过时间差和影藏哈希值来达到资产的原子交换。哈希锁定只能做到交换而不能做到资产或者信息的转移，因此其使用场景有限。 3.侧链/中继链（Sidechains / Relays）: 侧链是指完全拥有某链的功能的另一条区块链，侧链可以读取和验证主链上的信息。主链不知道侧链的存在，由侧链主动感知主链信息并进行相应的动作。而中继链则是侧链和公证人机制的结合体，中继链具有访问需要和验证进行互操作的链的关键信息并对两条链的跨链消息进行转移。从这个角度看中继链也是一种去中心的公证人机制。 下面就这几种跨链方式的典型实现方式进行详细分析： 典型跨链机制实现分析 公证人机制 最传统的公证人机制是基于中心化交易所得跨链资产交换，这种跨链的方式比较单一，只支持资产的交换，如下图演示了Alice通过交易所，用比特币和Bob交换ETH的过程。 Alice 通过交易所钱包将自己的比特币打入交易所地址; Alice 在交易所上挂上卖单1个BTC卖出20ETH价格； Bob需要将自己的ETH打入交易所的以太坊地址； Bob通过交易所挂出购买比特币的单子 20ETH买一个比特币； 交易所将Alice的卖单和Bob的卖单进行撮合； 交易所将Alice在交易所存储的1BTC 转移给Bob的比特币地址； 交易所将Bob在交易所存储的20ETH 转移给Alice的以太坊地址； 至此完成了Alice和Bob的BTC和ETH的交换（案例中省去了交易所的服务费）。通过该例子可以看出交易所的方式目前仅能够支持资产的交换，且资产交换的原子性、安全性完全由中心化的交易所保障存在较大的中心化风险。 除此之外还有一种著名的分布式账本技术Ripple，也是采用类似公证人的机制来解决全球金融机构之间的资产交换。Ripple的系统架构如上图所示，Ripple系统中交易通过网络中的验证者进行交易的验证，验证者验证的交易通过加密算法保护交易内容不能被验证着窥探从而保证交易的隐私性。 公证人机制的跨链技术实现简单，且能够比较灵活地支持不同类型的底层区块链体系。公证人机制的主要问题在于公证人机制的安全性保障完全由公证人系统保障。参与跨链的相关方需要对中间人给予较大的信任。 哈希锁定 哈希时间锁定（HTLC）最早出现在比特币的闪电网络，跨链资产交换支持一定数量的A链资产和一定数量的B链资产进行原子交换。哈希时间锁定巧妙地采用了哈希锁和时间锁，迫使资产的接收方在deadline内确定收款并产生一种收款证明给打款人，否则资产会归还给打款人。收款证明能够被付款人用来获取接收人区块链上的等量价值的数量资产或触发其他事件。 如下图所示，我们用一个例子来阐述如何使用哈希时间锁定进行跨链的原子资产交换，假设Alice和Bob有资产交换的需求，Alice想用1个BTC和Bob换20个ETH. 那么首先需要在两条链上设置哈希时间锁定合约，然后执行如下步骤： Alice 随机构建一个字符串s，并计算出其哈希 h = hash(s)； Alice 将h发送给Bob的合约； Alice锁定自己的1个BTC资产，并设置一个较长的锁定时间t1, 并设置了获取该BTC的一个条件：谁能够提供h的原…

EOS区块结构、生产、打包、验证、存储等流程分析
type: item
date: 2019-07-02T10:09:00+08:00
description: Table of Content 总览 环境 预备知识 chain分析 基本数据结构 producer_plugin controller chainbase分析 基本数据结构 智能合约的持久化存储和database的交互 总览 本文主要致力于EOS区块结构、生产、打包、验证、存储等流程分析，当然其他部分源码也有涉及，但在此不做详细讨论。 环境 Mac OS High Sierra 10.13.6 EOS源码版本1.2.1 CLion CMake 预备知识 文档 C++11新特性学习 chain分析 blockchain基本数据结构 区块结构: block_header,定义在：libraries/chain/include/eosio/chain/block_header.hpp第7行 struct block_header { block_timestamp_type timestamp; //区块产生时间 account_name producer; //区块生产者 uint16_t confirmed = 1; //dpos确认数 block_id_type previous; //前一个区块的头的hash值 checksum256_type transaction_mroot; //区块包含的transactions的merkel树根 checksum256_type action_mroot; //区块包含的actions的merkel树根，这些actions实际包含在transactions中 uint32_t schedule_version = 0; optional<producer_schedule_type> new_producers; extension_type header_extension; } signed_block_header,定义在：libraries/chain/include/eosio/chain/block_header.hpp第45行 struct signed_block_header : public block_header { signature_type producer_signature; //生产者的签名 } signed_block,定义在：libraries/chain/include/eosio/chain/block.hpp 57行 struct signed_block : public signed_block_header { vector<transacton_receipt> transactions; //区块包含的transactions执行后得到的回执 extrension_type block_extensions; } transaction_receipt_header,定义在：libraries/chain/include/eosio/chain/block.hpp 12行 struct transaction_receipt_header { enum status_enum { executed = 0, //transaction成功执行，没有错误发生 soft_fail = 1, // hard_fail = 2, delayed = 3, expired = 4 }; fc::enum_type<uint8_t,status_enum> status; uint32_t cpu_usage_us; //总CPU使用时间，单位为微秒 fc::unsigned_int net_usage_words;//总网络使用量 } transaction_receipt,定义在：libraries/chain/include/eosio/chain/block.hpp 33行 struct transaction_receipt : public transaction_receipt_header { fc::static_variant<transaction_id_type,packed_transaction> trx; //已经执行过的transactions } transaction_header,定义在：libraries/chain/include/eosio/chain/transaction.hpp 30行 struct transaction_header { time_point_sec expiration; //过期时间 uint16_t ref_block_num = 0U; //用于TaPos验证 uint32_t ref_block_prefix = 0UL; //用于TaPos验证 fc::…

同步区块--p2p通信--notice_message
type: item
date: 2019-07-02T09:38:06+08:00
description: 上篇笔记写到远程节点给本地节点发送notice消息，通知本地节点同步区块。本篇笔记继续学习本地节点如何从远程节点同步区块，这次重点写notice消息的发送与处理过程。 1、notice_message消息结构 //消息结构 定义部分 struct notice_message { notice_message () : known_trx(), known_blocks() {} ordered_txn_ids known_trx; ordered_blk_ids known_blocks; }; //选择查看定义，跳转到 using ordered_txn_ids = select_ids<transaction_id_type>; using ordered_blk_ids = select_ids<block_id_type>; //选择查看定义，跳转到 template<typename T> struct select_ids { select_ids () : mode(none),pending(0),ids() {} id_list_modes mode; uint32_t pending; vector<T> ids; //模板类 bool empty () const { return (mode == none || ids.empty()); } }; notice_message消息类型包括id_list_modes类型的变量，该类型为一个枚举类型，包括enum id_list_modes { none, catch_up, last_irr_catch_up, normal };，pending表示区块数目。 2、发送notice_message消息 远程节点给本地节点发送notice_message，通知本地节点同步到不可逆区块。 //远程节点给本地节点发送的通知消息内容 消息调用部分 if (lib_num > msg.head_num ) { fc_dlog(logger, "sync check state 2"); if (msg.generation > 1 || c->protocol_version > proto_base) { notice_message note; note.known_trx.pending = lib_num; note.known_trx.mode = last_irr_catch_up; //类型为不可逆区块类型 note.known_blocks.mode = last_irr_catch_up; note.known_blocks.pending = head; c->enqueue( note ); } c->syncing = true; return; } 远程节点发送的notice_message消息内容比较简单，包括不可逆区块数、最新区块数、同步方式（同步到不可逆区块或者同步到最新区块），然后放入到消息队列等待发送出去。 3、接收notice_message消息 同上篇笔记所写的一样，处理notice_message消息同样在一个handle_message的重载函数里进行，参数为当前通信的远程节点的connect对象指针和消息。 void net_plugin_impl::handle_message( connection_ptr c, const notice_message &msg) { // peer tells us about one or more blocks or txns. When done syncing, forward on // notices of previously unknown blocks or txns, // peer_ilog(c, "received notice_message"); c->connecting = false; request_message req; bool send_req = false; if (msg.known_trx.mode != none) { fc_dlog(logger,"this is a ${m} notice with ${n} blocks", ("m",modes_str(msg.known_trx.mode))("n",msg.known_trx.pending)); } switch (msg.known_trx.mode) { case none: break; case last_irr_catch_up: { c->last_handshake_recv.head_num = msg.known_trx.pending; …

同步区块--p2p通信--handshake_message
type: item
date: 2019-07-02T09:37:17+08:00
description: 上一篇整体上学习了net_plugin插件，但是具体的内容没有写。从这篇笔记开始，重点分析各节点之间是如何通过p2p插件同步区块的。首先，启动一个节点之后，当前节点向远程节点发送的第一个数据包就是handshake_message类型的（time时间戳类型除外），所以这篇笔记中分析handshake_message类型数据包的发送过程和接收过程。 运行环境：CLion编译器，并配置连接到主网节点。 1、handshake_message消息结构 struct handshake_message { uint16_t network_version = 0; ///< incremental value above a computed base chain_id_type chain_id; ///< used to identify chain fc::sha256 node_id; ///< used to identify peers and prevent self-connect chain::public_key_type key; ///< authentication key; may be a producer or peer key, or empty tstamp time; fc::sha256 token; ///< digest of time to prove we own the private key of the key above chain::signature_type sig; ///< signature for the digest string p2p_address; uint32_t last_irreversible_block_num = 0; block_id_type last_irreversible_block_id; uint32_t head_num = 0; block_id_type head_id; string os; string agent; int16_t generation; }; 握手包内容包括：网络版本、chain_id、node_id、p2p_address、节点名称等配置信息，以及链的状态（当前节点的不可逆区块数、不可逆区块id、最新区块id、最新区块数）。其中区块数是指区块编号（1、2、3......），区块id是指32位的hash值。 2、发送handshake_message消息 启动本地节点之后，会连接到配置文件中的p2p节点，并获取当前链信息、配置信息，然后构建handshake_message包并发送到其他p2p节点。 void connection::send_handshake( ) { handshake_initializer::populate(last_handshake_sent); //填充消息内容 last_handshake_sent.generation = ++sent_handshake_count; fc_dlog(logger, "Sending handshake generation ${g} to ${ep}", ("g",last_handshake_sent.generation)("ep", peer_name())); enqueue(last_handshake_sent); //构建完成握手包之后，放入队列中 } 发送的数据包内容如下： //大小 348个字节 连接之后发送的报文 0040 5c 01 00 00 00 b6 04 ac a3 76 f2 06 b8 fc 2Ñ\....¶.¬£vò.¸ü 0050 25 a6 ed 44 db dc 66 54 7c 36 c6 c3 3e 3a 11 9f %¦íDÛÜfT|6ÆÃ>:.. 0060 fb ea ef 94 36 42 f0 e9 06 da b2 ea 2d 82 ce 71 ûêï.6Bðé.Ú²ê-.Îq 0070 45 c4 74 df 2f 3f 5f d9 df 11 af 8c 70 62 06 7a EÄtß/?_Ùß.¯.pb.z 0080 5d de 3e 6b 87 10 22 18 0c 00 00 00 00 00 00 00 ]Þ>k.."......... 0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00a0 00 00 00 00 00 00 00 00 00 00 00 aa 8b b8 81 00 ...........ª.¸.. 00b0 77 05 00 00 00 00…