初链TrueChain主网Beta版技术探究

初链主网Beta版于新加坡时间2018年09月28日08:00正式上线


目录


无许可(Permissionless)环境下的混合共识公链,科学采用双链结构

初链TrueChain采用PBFT+PoW混合共识,起初预设将PBFT和PoW揉合到一条链上,但却发现这样的设计从数据结构的搭建和共识的验证上非常难以实现。经过反复的论证,初链最终决定变更为双链结构,将PBFT作为快链,而将PoW作为慢链,快链用于存储账本和达成交易,慢链用于挖矿和委员会选举,从而实现了公平和效率的有效融合,并使得数据结构变得更加清晰,使两种共识之间的通信变得更加容易。

快链(FastChain):

基础:PBFT
作用:用于存储账本和达成交易

慢链(SnailChain):

基础:PoW
作用:用于挖矿和委员会选举

PBFT的节点从POW的节点中选出,同时建立淘汰机制:任何超出安全边际,即超时、做假账或有偏向性记录的节点都将被淘汰。而这种淘汰机制的运行,运用POW来实现。由于PBFT计算复杂度的问题,上层负责记录的PBFT超级节点将始终保持在30个以内。但POW可以无限接纳新的节点。由此,速度、安全性和去中心化本质得到了兼顾。

PBFT+POW,一个负责性能扩展,一个负责记账的安全性,PBFT+POW能使应用的交易速度过到1万到10万tps,性能就是指计算速度,节点多了,速度就慢了,只用POW速度就慢了,但是安全性靠谱,PBFT节点有限,速度快,所以选出来的节点很重要,PBFT高速受限,POW低速安全,无限制,PBFT为了保持高速运转要把节点控制在30个以内,POW可以无限扩展,就相当于更多的人知道这笔交易,也就更真实,不容易产生假账POW可以淘汰PBFT里的虚假信息,相当于一笔帐同时记两个账本上,如果不一样那肯定有问题。

将水果链整合到PoW,发布自己的FPOW机制的公链

在目前的矿机生态下,PoW慢链需要避免Selfish Mining Attack和Eclipse Attack等问题。在寻求解决方案的过程中,初链TrueChain团队大胆尝试用fPoW协议(FruitChain)替代中本聪的原始PoW协议(Nakamoto PoW),从工程上实现了将水果链整合到PoW中,从而成为fPOW。水果链的实现,使得普通挖矿者可以更加公平地参与到挖矿过程中,并获得更加公平地奖励分配,这使初链成为名副其实的去中心化公链。

TrueHash,实现不依赖手动调整,从而根本上抗ASIC的挖矿算法

从 BTC 之后,很多区块链开发者一直在尝试各种不同的抗 ASIC 挖矿算法。从最终结果来看,这些尝试无疑都是失败的。在新一代公链中,初链研究团队作为PoW的捍卫者和拯救者,独创了本质上抗ASIC的挖矿算法,可以实现算法的随机切换,使得再强大的ASIC也无法绕过冯诺依曼瓶颈,从而保护普通矿工的权益。

Truehash算法的简要介绍

TrueChain采用混合共识技术,它使用PBFT作为快速链来处理交易,使用PoW作为snailchain来监督和选举委员会。Ponth算法是由Cynthia Dwork和Moni Naor于1993年提出的。其应用场景是抵御ddos和垃圾邮件的攻击。 1999年,Jacobsson提出了部分散列反演算法,这也是Satoshi Nakamoto在比特币网络中使用的方法。

在bitcion之后发布的数字货币,不难看出区块链开发人员正在尝试不同类型的挖掘算法来实现ASIC抗性。结果证明所有的尝试都失败了。他们的全部想法是将计算与ASIC的缺点相加,以使算法更难。然而,像Ethash和Equihash等算法可能只会延迟ASIC的出现时间,但不能从根本上抵制ASIC。为了进一步研究,我们必须理解为什么CPU / GPU比ASIC慢得多。主要原因是采用冯诺依曼架构进行多样性计算。

冯·诺依曼架构大致分为三个部分,即内部存储,控制单元和计算元素。操作程序和数据以DDR写入,并在执行计算时传送到计算元素。传输带宽引起的计算瓶颈称为von neumann瓶颈。

避免von neumann瓶颈的想法对于具有高唯一性的操作来说很简单,例如哈希值的计算,其思想是放弃von neumann架构并将算法直接写入计算元素以使其成为ASIC。这就是为什么ASIC在计算比特币Sha-256d时具有计算能力的惊人优势。即使这样,Ethash也采用了读取大表的方法,但基本上计算机程序仍然可以硬编码为计算元素。尽管ASIC周围有内存颗粒,但这只会增加成本。

为了从根本上实现ASIC抗性,我们可以借鉴Monero的经验,即周期性算法更改设计。 Monero的问题是社区对硬分叉的非专业投票。而他们面临的最大问题是,没有人知道项目团队(他们可以轻松操纵投票结果)是否为新算法准备了ASIC。

因此,我们必须保证这种机制在挖掘算法的控制之下。要从根本上实现ASIC抗性,必须满足以下规则:

命令S作为算法的集合,S中的所有算法必须通过von neumann瓶颈。
算法将改变每个T块,并且改变方法必须满足可验证和不可预测的条件。
算法切换无人为干预。
具体设计思路如下
Truehash的实现是将G设置为一个组,对于每个组成员g,使rho_V(G)成为向量空间V中G的展示。在普通的挖掘算法中,当使用诸如填充之类的操作计算blockheade,nonce和其他信息时依此类推,会形成一个Vector nonce。通过不同的随机数的耗尽来找到小于难度系数的结果。

Truehash的变化部分
将散列(v(nonce))更改为hash(rho(g)* v(nonce))。只要G(Truehash利用包含2048个元素的置换组)足够复杂,该算法集合就不会在计算元素中完全硬编码。由于算法会随机切换,因此von neumann的瓶颈将是不可避免的。

Truehash切换算法的原理是每12,000个PoW块改变组元素。 12,000个poW区块的生产时间为83天。新的组元素信息由前一周期中的块1-8192组成,并且通过分析块11001-11256的哈希值来生成组合方法。

因为块的哈希值是预先不可预测的,所以在11256块出现之前,任何人都不可能知道关于新算法的任何信息。从最后一个周期的第11,257个块到无效的算法,总共只有88天,因此在如此短的时间内生成ASIC是没有意义的。

文章下面有源码整理,详见truechain-engineering-code/consensus/目录

混合共识PBFT委员会的随机选举机制

初链“交易处理担当”主要为PBFT委员会,为保证公平和安全性,初链PBFT委员会将定期换届,如何在换届时公平地选举PBFT委员成为这一过程要重点攻克的问题。经过初链研究和技术团队的并肩作战,最终实现了随机算法,基于VRF(verify random function,可验证随机函数)可以实现PBFT节点等概率的公平选举。而这里面也会有一些过滤,过滤掉一些挖水果特别少的矿工,因为他们挖的特别少,可能他们的硬件设备或者网络情况不太好。从剩下满足处理交易条件的节点中,随机的公平的选举出来PBFT委员会成员。

在尚未实现Sharding技术情况下,在内测阶段的每秒钟交易速度TPS均值达到1200左右,峰值达到1900左右

在目前已经上线的在无许可(Permissionless)环境中运行的公链中,初链TrueChain主网Beta版的tps的性能已经非常高,在后期正式主网发布和加上Sharding分片技术的融入,TPS将达到更高的性能要求。

TrueChain或许是下一个千亿级项目?

相较于EOS:EOS其采用的是DPOS共识机制。对运行效率追求之致,但是丧失了区块链的根本去中心化的安全性。名义上是类中心化、半中心化,实际上已全然丧失了区块链去中心化的本质。单一共识机制舍弃去中心化本质,又面临着可见的服务速度上限,已无法满足开发者的需求。

和以太坊的关系:“初链”是构建在以太坊之上的区块链,但和以太坊拥有不同的共识策略。目前对于“初链”代码,最有研究价值的就是其混合共识和双链机制。


系统组成:

“初链”是构建在以太坊之上的区块链,所以主要组成部分相同

  • 账户(accounts)
  • 状态(state)
  • 损耗和费用(gas and fees)
  • 交易(transactions)
  • 区块(blocks)
  • 交易执行(transaction execution)
  • 挖矿(mining)
  • 工作量证明(proof of work)
  • 拜占庭管理委员会(PBFT)
  • 混合共识双链模式(FastChain&SnailChain)

账户

整个生态全局由很多小对象(账户)来组成,这些账户可以通过消息传递架构来与对方进行交互。每个账户都有一个与之关联的状态(state)和一个20字节的地址(address)。

账户类型
  • 合约账户:
    合约代码控制与代码关联,不可以自己发起一个交易,只有在接收到一个交易之后,为了响应此交易而触发一个交易。
    外部账户:
    私钥控制与代码无关联,可通过创建和用自己的私钥来对交易进行签名,来发送消息给另一个外部拥有账户或合约账户
    外部账户发送消息到外部账户:只是一个简单的价值转移。
    外部账户发送消息到合约账户:激活合约账户的代码,允许它执行各种动作,如:转移代币,写入内部存储,挖币,执行运算,创建新合约等

  • 账户状态
    nonce:交易序号或合约序号
    balance:此地址拥有Wei的数量(1Ether=10^18Wei)
    storageRoot: Merkle树根节点Hash值,会将此账户存储内容的Hash值进行编码,默认是空值
    codeHash: 此账户EVM代码的hash值

世界状态
  • Merkle树
    :由一系列节点组成的二叉树
    一个根节点,两个子节点的Hash值,代表着整棵树
    一系列的中间的节点,这些节点是两个子节点的Hash
    包含了源数据的大量叶子节点
    Merkle树要求每个值(value)对应key。key会告诉你顺着哪个子节点可以获得对应的值,值存在叶子节点。
    每个块都有一个头(header),保存了三个不同Merkle trie结构的根节点的Hash
    树结构用来存储交易和收据 ,分为三种状态树

    • 状态树(stateRoot)
    • 交易树(transactionsRoot)
    • 收据树(receiptsRoot)

    如果一个恶意用户试图用一个假交易来交换Merkle树底的交易,这个会改变它上面节点的hash值,而它上面节点的值的改变也会导致上上一个节点Hash值的改变,以此类推,一直到树的根节点。


PBFT(拜占庭容错)

基于拜占庭将军问题,一致性的确保主要分为这三个阶段:预准备(pre-prepare)、准备(prepare)和确认(commit)。流程如下图所示:

在这里插入图片描述

其中C为发送请求端,0123为服务端,3为宕机的服务端,具体步骤如下:

Request:请求端C发送请求到任意一节点,这里是0
Pre-Prepare:服务端0收到C的请求后进行广播,扩散至123
Prepare:123,收到后记录并再次广播,1->023,2->013,3因为宕机无法广播
Commit:0123节点在Prepare阶段,若收到超过一定数量的相同请求,则进入Commit阶段,广播Commit请求
5.Reply:0123节点在Commit阶段,若收到超过一定数量的相同请求,则对C进行反馈
根据上述流程,在 N ≥ 3F + 1 的情況下一致性是可能解決,N为总计算机数,F为有问题的计算机总数

N=4 F=0 时:

最终数据得到数据
A1 1 1 11
B1 1 1 11
C1 1 1 11
D1 1 1 11

N=4 F=1 时:

最终数据得到数据
A1 1 1 01
B1 1 0 11
C1 0 1 11
D0 1 1 11

N=4 F=2 时:

最终数据得到数据
A1 1 0 0NA
B1 0 0 1NA
C0 0 1 1NA
D0 1 1 0NA

由此可以看出,拜占庭容错能够容纳将近1/3的错误节点误差


truechain-engineering-code Truechain工程代码源码整理

cmd/getrue/

main.go Truechain的官方命令行客户端。

  • init:初始化CLI应用程序并启动Getrue
  • main:主函数
  • getrue:如果没有运行特殊子命令,则getrue是进入系统的主要入口点。它根据命令行参数创建一个默认节点,并以阻塞模式运行它,等待它关闭。
  • startNode:启动系统节点和所有已注册的协议,然后解锁所有请求的帐户,并启动RPC / IPC接口和矿工。
cmd/getrue/

chaincmd.go

包含:

initCommand, importCommand, exportCommand, importPreimagesCommand,
exportPreimagesCommand, copydbCommand, dumpCommand,

  • initGenesis:将初始化给定的JSON格式genesis文件,并将其写为创世区块
  • importChain:导入链
  • exportChain:导出链
  • importPreimages:从指定文件导入preimage数据。
  • exportPreimages:以流方式将preimage数据转储到指定的json文件。
  • copyDb:复制数据源
  • dump
  • hashish
cmd/getrue/

monitorcmd.go

包含:monitorCommand

  • monitor:基于终端UI的监控工具,用于请求的指标。
  • retrieveMetrics:与附加的getrue节点联系,并检索整个收集的系统指标集。
  • resolveMetrics:获取输入度量模式列表,并将每个模式解析为一个或更多规范的度量标准名称。
  • resolveMetric采用单个输入度量标准模式,并将其解析为一个或多个规范度量标准名称。
  • expandMetrics:将整个度量标准树扩展为一个平坦的路径列表。
  • fetchMetric:遍历度量标准映射并检索特定的度量标准映射。
  • refreshCharts:检索下一批度量标准,并将所有新值插入到活动数据集和图表中。
  • updateChart:将数据集插入折线图,适当缩放,并相应地更新图表标签。
  • createChart:使用默认配置创建一个空线图。
  • updateFooter:根据遇到的任何错误更新页脚内容。
cmd/send_transaction/

main.go

  • main:主函数
  • send:初始化发送事务
  • sendTransactions:发送多个交易
  • sendTransaction:发送单个交易
truechain-engineering-code/

interfaces.go 定义了与以太坊交互的接口。

  • Subscription interface:表示事件订阅,其中事件在数据通道上传递。
    Unsubscribe:订阅取消,向数据通道发送事件并关闭错误通道。
    Err:返回订阅错误频道。如果订阅存在问题(例如,已经关闭了传递事件的网络连接),则错误信道接收值。只会发送一个值。 Unsubscribe将关闭错误通道。

  • ChainReader interface:提供对区块链的访问。此接口中的方法从规范链(通过块编号请求)或先前由节点下载和处理的任何区块链分支访问原始数据。块编号参数可以为nil以选择最新的规范块。只要有可能,读取块头应优先于整个块。包含:BlockByHashBlockByNumberHeaderByHashHeaderByNumberTransactionCountTransactionInBlockSubscribeNewHead-此方法订阅有关规范链的头部块的更改的通知。

  • TransactionReader interface:提供对过去交易及其收据的访问。实现可能会对可以检索的事务和收据施加任意限制。可能无法获得历史交易。如果可能,请避免依赖此接口。合同日志(通过LogFilterer接口)更可靠,并且在链重组时通常更安全。如果请求的项目不存在,则返回的错误为NotFound

    TransactionByHash:除了区块链之外,TransactionByHash还会检查待处理事务池。 isPending返回值指示事务是否已被挖掘。请注意,即使交易未挂起,交易也可能不属于规范链。
    TransactionReceipt:返回已挖掘事务的收据。请注意,即使存在收据,交易也可能不包含在当前规范链中。

  • ChainStateReader interface:包含对规范区块链的状态trie的访问。请注意,接口的实现可能无法返回旧块的状态值。在许多情况下,使用CallContract可能比读取原始合同存储更可取。包含:BalanceAt,StorageAt,CodeAtNonceAt

  • SyncProgress struct:节点与以太坊网络同步时,SyncProgress会给出进度指示。

type SyncProgress struct {
	StartingBlock uint64 // 同步开始的块号
	CurrentBlock  uint64 // 同步所在的当前块编号
	HighestBlock  uint64 // 链中最高的块号
	PulledStates  uint64 // 已下载的状态trie条目数
	KnownStates   uint64 // 已知的状态trie条目总数
}

  • ChainSyncReader interface:包装对节点当前同步状态的访问。 如果当前没有正在运行的同步,则返回nil。包含:SyncProgress
  • CallMsg struct:包含合同调用的参数。
ype CallMsg struct {
	From     common.Address  // 'transaction'的发件人
	To       *common.Address // 目标合同(合同创建为零)
	Gas      uint64          //如果为0,则调用近无限燃料执行
	GasPrice *big.Int        // wei < - >燃料交换率
	Value    *big.Int        // 随着通讯一起发送的wei数量
	Data     []byte          // 输入数据,通常是ABI编码的合同方法调用invocation
}
  • ContractCaller interface:提供合同调用,实质上是由EVM执行但未开采到区块链中的事务。 ContractCall是执行此类调用的低级方法。对于围绕特定合同构建的应用程序,本机工具提供了更好,正确类型的方式来执行调用。包含:CallContract
  • FilterQuery struct:包含合同日志过滤选项。
type FilterQuery struct {
	FromBlock *big.Int         // 查询范围的开头,nil表示创世块
	ToBlock   *big.Int         // 范围的结尾,nil表示最新的块
	Addresses []common.Address // 限制匹配特定合同创建的事件

	// The Topic list restricts matches to particular event topics. Each event has a list
	// of topics. Topics matches a prefix of that list. An empty element slice matches any
	// topic. Non-empty elements represent an alternative that matches any of the
	// contained topics.
	//
	// Examples:
	// {} or nil          matches any topic list
	// {{A}}              matches topic A in first position
	// {{}, {B}}          matches any topic in first position, B in second position
	// {{A}, {B}}         matches topic A in first position, B in second position
	// {{A, B}}, {C, D}}  matches topic (A OR B) in first position, (C OR D) in second position
	Topics [][]common.Hash
}
  • LogFilterer interface:使用一次性查询或连续事件订阅提供对合同日志事件的访问。通过流式查询订阅接收的日志可能已将Removed设置为true,表示由于链重组而恢复了日志。包含:FilterLogsSubscribeFilterLogs
  • TransactionSender interface:包装事务发送。 SendTransaction方法将已签名的事务注入待处理的事务池以供执行。如果事务是创建合同,则可以使用TransactionReceipt方法在事务挖掘后检索合同地址。交易必须签署并包含有效的随机数。 API的使用者可以使用包帐户来维护本地私钥,并且需要使用PendingNonceAt检索下一个可用的nonce。包含:SendTransaction
  • GasPricer interface:包含燃料价格oracle,监测区块链以确定当前费用市场条件下的最佳汽油价格。包含:SuggestGasPrice
  • PendingStateReader interface:// PendingStateReader提供对挂起状态的访问,这是所有已知的可执行事务的结果,这些事务尚未包含在区块链中。它通常用于显示由用户发起的“未经证实的”动作(例如,钱包价值转移)的结果。 PendingNonceAt操作是检索特定帐户的下一个可用事务随机数的好方法。包含:PendingBalanceAtPendingStorageAtPendingCodeAtPendingNonceAtPendingTransactionCount
  • PendingContractCaller interface:可用于对待处理状态执行调用。包含:PendingCallContract
  • GasEstimator interface:包装EstimateGas,它试图根据待处理状态估算执行特定交易所需的气体。 无法保证这是真正的天然气限制要求,因为矿工可能会添加或删除其他交易,但它应该为设定合理的违约提供依据。包含:EstimateGas
  • PendingStateEventer interface:提供对有关挂起状态更改的实时通知的访问。包含:SubscribePendingTransactions
accounts(账户)
/accounts /

accounts.go

  • Account struct:表示位于由可选URL字段定义的特定位置的以太坊帐户。
    Address:从密钥派生的以太坊帐户地址
    URL:后端中的可选资源定位符

  • Wallet interface:表示可能包含一个或多个帐户(从同一种子派生)的软件或硬件钱包。
    URL:检索可以访问此钱包的规范路径。上层用户可以定义来自多个后端的所有钱包的排序顺序。
    Status:返回文本状态以帮助用户处于钱包的当前状态。它还会返回一个错误,指示钱包可能遇到的任何故障。
    Open:初始化对钱包实例的访问。它并不意味着解锁或解密帐户密钥,而只是简单地建立与硬件钱包的连接和/或访问派生种子。密码短语参数可以或可以不由特定钱包实例的实现使用。没有无密码打开方法的原因是努力实现统一的钱包处理,无视不同的后端提供商。请注意,如果您打开钱包,则必须将其关闭以释放任何已分配的资源(在使用硬件钱包时尤其重要)。
    Close:释放打开的钱包实例持有的所有资源。
    Accounts:检索钱包当前知道的签名帐户列表。对于分层确定性钱包,列表不是详尽无遗的,而是仅包含在帐户派生期间明确固定的帐户。
    Contains:返回帐户是否属于此特定钱包的部分。
    Derive:尝试在指定的派生路径上显式派生层次确定性帐户。如果需要,派生的帐户将被添加到钱包的跟踪帐户列表中。
    SelfDerive:设置基本帐户派生路径,钱包从中尝试发现非零帐户,并自动将其添加到已跟踪帐户列表中。注意,self derivaton将增加指定路径的最后一个组件,该组件与下降到子路径相反,以允许从非零组件开始发现帐户。您可以通过使用nil链状态读取器调用SelfDerive来禁用自动帐户发现。
    SignHash:请求钱包签署给定的哈希值。
    它仅通过其中包含的地址查找指定的帐户,或者可选地借助嵌入的URL字段中的任何位置元数据。如果钱包需要额外的身份验证来签署请求(例如,用于解密帐户的密码,或PIN码以验证交易),则将返回AuthNeededError实例,其包含用户关于需要哪些字段或动作的信息。用户可以通过SignHashWithPassphrase或其他方式(例如,在密钥库中解锁帐户)提供所需的详细信息来重试。
    SignTx:请求钱包签署给定的交易。它仅通过其中包含的地址查找指定的帐户,或者可选地借助嵌入的URL字段中的任何位置元数据。如果钱包需要额外的身份验证来签署请求(例如用于解密帐户的密码,或用于验证交易的PIN码,将返回一个AuthNeededError实例,其中包含用户的信息关于需要哪些领域或行动。用户可以通过提供重试通过SignTxWithPassphrase或其他方式获得所需的详细信息(例如,在密钥库中解锁帐户)。
    SignHashWithPassphrase:请求钱包使用给定的密码作为额外的身份验证信息对给定的哈希进行签名。 它仅通过其中包含的地址查找指定的帐户,或者可选地借助嵌入的URL字段中的任何位置元数据。
    SignTxWithPassphrase:请求钱包签署给定的事务,并将给定的密码作为额外的身份验证信息。它仅通过其中包含的地址查找指定的帐户,或者可选地借助嵌入的URL字段中的任何位置元数据。

  • Backend interface:“钱包提供者”,可能包含一批他们可以根据请求签署交易的账户
    Wallets:检索后端当前知道的钱包列表。默认情况下不会打开返回的钱包。对于软件HD钱包,这意味着没有基础种子被解密,并且对于没有建立实际连接的硬件钱包。所得到的钱包列表将根据其后端分配的内部URL按字母顺序排序。由于钱包(尤其是硬件)可能来来往往,因此在后续检索期间,相同的钱包可能会出现在列表中的不同位置。
    Subscribe:会创建异步订阅,以便在后端检测到钱包的到达或离开时接收通知。

  • WalletEventType:表示钱包订阅子系统可以触发的不同事件类型。

  • WalletEvent struct:在检测到钱包到达或离开时由帐户后端触发的事件。
    Wallet Wallet:钱包实例到达或离开
    Kind:系统中发生的事件类型

accounts/abi/bind/backends/

simulated.go(模拟)

  • SimulatedBackend struct:主要目的是进行简单的合同绑定测试,database-在内存数据库中存储测试数据,blockchain-以太坊区块链处理共识,pendingBlock-根据请求导入的当前待处理块,pendingState-当前待处理状态,events-过滤日志事件的事件系统,config-配置文件。
  • NewSimulatedBackend:使用模拟区块链创建新的绑定后端。
  • Commit:将所有挂起的事务作为单个块导入并提交,并启动一个全新的状态。
  • Rollback:中止所有挂起的事务,恢复到上次提交的状态。
  • CodeAt:返回与区块链中某个帐户关联的代码。
  • BalanceAt:返回区块链中某个帐户的wei余额。
  • NonceAt:返回区块链中某个帐户的nonce
  • StorageAt:返回区块链中帐户存储的密钥值。
  • TransactionReceipt:返回事务的接收。
  • PendingCodeAt:返回与处于暂挂状态的帐户关联的代码。
  • CallContract:执行合同调用。
  • PendingCallContract:在挂起状态下执行合同调用。
  • PendingNonceAt:实现PendingStateReader.PendingNonceAt,检索当前为该帐户挂起的nonce
  • SuggestGasPrice:实现了ContractTransactor.SuggestGasPrice。由于模拟链条没有矿工,我们只需为任何通话返回1的燃料价格。
  • EstimateGas:针对当前待处理的块/状态执行请求的代码,并返回使用的燃料量。
  • callContract:在正常和挂起的合同调用之间实现公共代码。在执行期间如果修改了状态,需要在必要时复制它。
  • SendTransaction:更新挂起的块以包含给定的事务。如果事务无效,则会发生混乱。
  • FilterLogs:执行日志过滤操作,在执行期间阻塞并在一个批处理中返回所有结果。
  • SubscribeFilterLogs:创建后台日志过滤操作,立即返回订阅,可用于流式传输找到的事件。
  • AdjustTime:为模拟时钟添加时移。
  • callmsg struct:实现core.Message以允许将其作为事务模拟器传递。
  • filterBackend struct:实现filters.Backend以支持对日志的过滤,而不考虑bloom-bits加速结构。
  • ChainDb:返回ethdb.Database
  • HeaderByNumber:返回core.BlockChainHeader数量
  • GetReceipts:返回原始数据库的阅读数据
  • GetLogs:获取日志
  • SubscribeNewTxsEvent:订阅服务器
  • SubscribeChainEvent:订阅事件
  • SubscribeRemovedLogsEvent:订阅删除日志事件
  • SubscribeLogsEvent:订阅日志事件
  • BloomStatus:返回定值4096
  • ServiceFilter:服务过滤器
accounts/abi/bind/

auth.go

  • NewTransactor:从加密的json密钥流和相关的密码短语中轻松创建事务签名者。
  • NewKeyedTransactor:从单个私钥轻松创建事务签名者。
accounts/abi/bind/

backend.go

  • 错误信息:
    ErrNoCode:给定地址没有合同代码-由调用和事务操作返回,对于该操作,请求的操作所在的收件人合同在状态db中不存在,或者没有任何与之关联的代码(即自杀);
    ErrNoPendingState:后端不支持挂起状态-尝试在未实现PendingContractCaller的后端上执行挂起状态操作时,会引发此错误;
    ErrNoCodeAfterDeploy:部署后没有合同代码-如果合同创建留下空契约,则WaitDeployed会返回此错误。
  • ContractCaller interface:定义允许以只读方式操作合约所需的方法。
  • PendingContractCaller interface:定义了对挂起状态执行合同调用的方法。当请求访问挂起状态时,调用将尝试发现此接口。如果后端不支持挂起状态,则Call返回ErrNoPendingState
  • ContractTransactor interface:定义允许以只写方式运行合同所需的方法。除了交易方法之外,剩余部分是当用户不提供某些所需值时使用的助手,而是由交易者决定。包含:PendingCodeAtPendingNonceAtSuggestGasPriceEstimateGasSendTransaction
  • ContractFilterer interface:使用一次性查询或连续事件订阅定义访问日志事件所需的方法。包含:FilterLogsSubscribeFilterLogs
  • DeployBackend interface:包装WaitMined和WaitDeployed所需的操作。包含:TransactionReceiptCodeAt
  • ContractBackend interface:定义了以读写方式处理合同所需的方法。包含:ContractCallerContractTransactorContractFilterer
accounts/abi/bind/

base.go

  • SignerFn func:当签约要求在提交前签署交易的方法时,SignerFn是签名者函数回调。

  • CallOpts struct:是用于微调合同呼叫请求的选项集合。
    Pending-是否在待处理状态或最后一个已知状态下运行
    From-可选发件人地址,否则使用第一个帐户
    Context-支持取消和超时的网络上下文

  • TransactOpts:创建有效的以太坊交易所需的授权数据集合。
    From-以太坊帐户发送事务
    Nonce-用于事务执行的Nonce
    Signer-用于签署交易的方法
    Value:交易转移的资金
    GasPrice:用于交易执行的燃料价格
    GasLimit:为事务执行设置的燃料限制
    Context:支持取消和超时的网络上下文

  • FilterOpts struct:对绑定合同中的事件进行微调过滤的选项集合。StartEndContext

  • WatchOpts struct:用于微调订阅绑定合同中的事件。

  • BoundContract struct:反映以太坊网络合同的基础包装器对象。它包含一系列方法,供更高级别的合同绑定使用。
    address:以太坊区块链合同的部署地址
    abi:基于ABI以访问正确的以太坊方法
    caller:读取与区块链交互的界面
    transactor:写入接口以与区块链交互
    filterer:与区块链交互的事件过滤

  • NewBoundContract:创建一个低级合约接口,通过该接口可以进行调用和交易。

  • DeployContract:将合同部署到以太坊区块链,并使用Go包装器绑定部署地址。

  • Call:以params作为输入值(常量)调用contract方法并将输出设置为结果。

  • Transact:使用params作为输入值(paid)调用合同方法。

  • Transfer:启动普通交易以将资金转移到合约,如果有可用的方法,则调用它的默认方法。

  • FilterLogs:过滤过去块的合约日志。

  • WatchLogs:过滤器订阅未来块的合同日志,返回可用于拆除观察者的订阅对象。

  • UnpackLog:将检索到的日志解压缩到提供的输出结构中。

  • ensureContext:是一个帮助方法,用于确保上下文不为nil,即使用户指定了它也是如此。

accounts/abi/bind/

bind.go

  • Bind:在合约ABI周围生成一个Go包装器。这个包装器不是要在客户端代码中使用,而是作为一个中间结构,它强制执行编译时类型安全和命名约定,而不必手动维护在运行时中断的硬编码字符串。
  • bindType :是一组类型绑定器,它将Solidity类型转换为某些受支持的编程语言类型。
  • wrapArray:绑定生成器的辅助函数。它在内部类型匹配后读取不匹配的字符,(因为内部类型是总类型声明的前缀),查找包含内部类型的有效数组(可能是动态数组) ,并返回这些数组的大小。返回的数组大小与实体签名的顺序相同; 内部数组大小优先。阵列大小也可以是“”,表示动态数组。
  • arrayBindingGo :将数组大小转换为内部类型(嵌套)数组的Go-lang声明。如果arraySizes为空,则返回内部类型。
  • bindTypeGo:将Solidity类型转换为Go one类型。由于没有从所有Solidity类型到Go的类型(例如uint17)的清晰映射,那些无法精确映射的将使用放大类型(例如* big.Int)。
  • bindUnnestedTypeGo:bindTypeGo的内部函数,它找到stringKind的内部类型。
  • arrayBindingJava:将数组大小转换为内部类型(嵌套)数组的Java声明。如果arraySizes为空,则返回内部类型。
  • bindTypeJava:将Solidity类型转换为Java类型。由于没有从所有Solidity类型到Java(例如uint17)的清晰映射,因此无法精确映射的那些将使用放大类型(例如BigDecimal)。
  • bindUnnestedTypeJava:bindTypeJava的内部函数,它查找stringKind的内部类型。
  • bindTopicType:bindTopicType是一组类型绑定器,它将Solidity类型转换为某些受支持的编程语言主题类型。
  • bindTopicTypeGo:bindTypeGo将Solidity主题类型转换为Go one。 它与简单类型几乎相同,但动态类型转换为哈希。
  • bindTopicTypeJava:bindTypeGo将Solidity主题类型转换为Java主题类型。它与简单类型几乎相同,但动态类型转换为哈希。
  • namedType:namedType是一组函数,它们将特定于语言的类型转换为在方法名称中使用的命名版本。
  • namedTypeJava:将一些原始数据类型转换为可用作方法名称部分的命名变体。
  • methodNormalizer:methodNormalizer是一个名称转换器,它修改Solidity方法名称以符合目标语言命名概念。
  • capitalise:capitalize创建一个以大写字符开头的camel-case字符串。
  • decapitalisedecapitalise创建一个以小写字符开头的驼峰字符串。
  • toCamelCase:将under-score字符串转换为camel-case字符串。
  • structured:检查ABI数据类型列表是否有足够的信息通过正确的Go结构进行操作。
accounts/abi/bind/

template.go

  • tmplData struct:填充绑定模板所需的数据结构。
    Package:用于放置生成的文件的包的名称
    Contracts:生成此文件的合同列表
  • tmplContract struct:包含生成单个合同绑定所需的数据。
    Type:键入主合同绑定的名称
    InputABI:JSON ABI用作生成绑定的输入
    InputBin:用于从中删除部署代码的可选EVM字节码
    Constructor:用于部署参数化的契约构造函数
    Calls:只读取状态数据的契约调用
    Transacts:写入状态数据的合同调用
    Events:合同事件访问器
  • tmplMethod struct:abi.Method的包装器,包含一些预处理和缓存的数据字段。
    Original:由abi包解析的原始方法
    Normalized:解析方法的规范化版本
    Structured:是否应将返回累加到结构中
  • tmplSource:语言到模板的映射,包含程序包可以生成的所有支持的编程语言。
  • tmplSourceGo:是用于生成基于合同绑定的Go源模板。
  • tmplSourceJava:用于生成契约绑定的Java源模板。
accounts/abi/bind/

topics.go

  • makeTopics:将过滤器查询参数列表转换为过滤器主题集。
  • parseTopics:将索引的主题字段转换为实际的日志字段值。
accounts/abi/bind/

util.go

  • WaitMined:等待在区块链上挖掘tx(types.Transaction)。当取消上下文时它会停止等待。
  • WaitDeployed:等待合同部署事务,并在挖掘时返回链上合同地址。 当ctx(context.Context)被取消时它停止等待。
accounts/abi/

abi.go

  • ABI struct:ABI保存有关合同上下文和可用的可调用方法的信息。它允许您键入检查函数调用并相应地打包数据。包含:ConstructorMethodsEvents
  • JSON:返回已解析的ABI接口,如果失败则返回错误。
  • Pack:打包给定的方法名称以符合abi。方法调用的数据将包含method_id,args0,arg1,... argN。方法id由4个字节组成,参数全部为32个字节。方法ID是从方法字符串签名的散列的前4个字节创建的。 (signature = baz(uint32,string32))
  • Unpack:根据abi规范在interface{}中解压缩输出。
  • UnmarshalJSON:实现json.Unmarshaler接口。
  • MethodById:按4字节的id查找方法。
accounts/abi/

argument.go

  • Argument struct:保存参数的名称和相应的类型。在打包和测试参数时使用类型。包含:NameTypeIndexed-仅由事件使用。
  • UnmarshalJSON:实现json.Unmarshaler接口。
  • LengthNonIndexed:在不计算“索引”值时返回参数个数。只有事件可以有“索引”参数,对于方法输入/输出的参数应该始终为false。
  • NonIndexed:返回带有索引参数的参数。
  • isTuple:为非原子结构返回true,如(uint,uint)uint []
  • Unpack:执行操作hexdata - > Go格式。
  • PackValues:执行操作Go - > Hexdata
  • unpackTuple:解压缩元组。
  • unpackAtomic:解压(hexdata-> go)单个值。
  • getArraySize:计算数组的完整大小; 即计数嵌套数组,计算解包的大小。
  • UnpackValues:用于根据ABI规范解压缩ABI编码的hexdata,而无需提供解压缩的结构。相反,此方法返回包含值的列表。原子参数将是包含一个元素的列表。
  • Pack:执行操作Go format - > Hexdata
  • capitalise:使字符串的第一个字符为大写,同时从变量名中删除任何前缀下划线。
accounts/abi/

error.go

  • formatSliceString:使用给定的slice大小格式化反射种类,并返回格式化的字符串表示形式。
  • sliceTypeCheck:检查给定slice是否可以分配给Type中的反射类型。
  • typeCheck:检查给定的反射值是否可以分配给Type中的反射类型。
  • typeErr:返回格式化的类型转换错误。
accounts/abi/

event.go

  • Event struct:是可能由EVM的LOG机制触发的事件。事件包含有关输出的输出的类型信息(输入)。匿名事件不会将签名规范表示作为第一个LOG主题。包含:NameAnonymousInputs
  • Id:返回abi定义用于标识事件名称和类型的事件签名的规范表示。
accounts/abi/

method.go

  • Sig:根据ABI规范返回方法字符串签名。
accounts /keystore/

account_cache.go

  • AmbiguousAddrError struct:尝试解锁存在多个文件的地址时返回,包含:AddrMatches
  • accountCache struct:密钥库中所有帐户的实时索引。包含:keydirwatchermuallbyAddrthrottlenotifyfileC
  • newAccountCache:新的账户缓存。
  • accounts:账户
  • hasAddress:地址
  • add:添加新账户
  • delete:注意:删除后必须是唯一的(即必须设置文件和地址)。
  • deleteByFile:删除给定路径引用的帐户。
  • removeAccount:移除账户。
  • find:如果存在唯一匹配,则find返回地址的缓存帐户。
  • maybeReload:刷新缓存
  • close:关闭
  • scanAccounts:检查文件系统是否发生了任何更改,并相应地更新帐户缓存
accounts /keystore/

file_cache.go

  • fileCache struct:在密钥库扫描期间看到的文件缓存。
    all:来自keystore文件夹的所有文件的集合
    lastMod:修改文件的上次实例
    musync.RWMutex
  • scan:对给定目录执行新扫描,与已缓存的文件名进行比较,并返回文件集:创建,删除,更新。
  • skipKeyFile:忽略编辑器备份,隐藏文件和文件夹/符号链接。
accounts /keystore/

key.go

  • Key struct:包含Iduuid.UUID-版本4random表示未从密钥数据派生的唯一ID;Address;PrivateKey:只存储privkey,因为pubkey / address可以从中派生出来。
  • keyStore interface:包含GetKey-从磁盘加载和解密密钥;StoreKey-写入并加密密钥;JoinPath-将文件名与密钥目录连接起来,除非它已经是绝对的。
  • plainKeyJSON structAddressPrivateKeyIdVersion
  • encryptedKeyJSONV3 structAddressCryptoIdVersion
  • encryptedKeyJSONV1 structAddressCryptoIdVersion
  • cryptoJSON structCipherCipherTextCipherParamsKDFKDFParamsMAC
  • newKeyFromECDSA:源于ECDSAkey
  • NewKeyForDirectICAP:生成一个密钥,其地址适合<155位,因此它可以适合Direct ICAP规范。为简单起见,与其他库更容易兼容,重试直到第一个字节为0。
  • newKey:新的key
  • storeNewKey:商店秘钥
  • writeKeyFile:创建具有适当权限的密钥库目录,以防它尚不存在。
  • keyFileName:实现密钥文件的命名约定::UTC--<created_at UTC ISO8601>-<address hex>
  • toISO8601:ISO8601标准
accounts /keystore/

keystore_passphrase.go

  • GetKey:从密钥库加载密钥并解密其内容
  • StoreKey:生成密钥,使用'auth'加密并存储在给定目录中
  • EncryptKey:使用指定的scrypt参数将密钥加密到json blob中,以后可以对其进行解密。
  • DecryptKey:从json blob解密密钥,返回私钥本身。
accounts /keystore/

keystore_wallet.go

  • keystoreWallet:实现原始密钥库的accounts.Wallet接口。
  • URL:实现accounts.Wallet,返回帐户的URL
  • Status:返回密钥库钱包持有的帐户是否已解锁。
  • Open:实现accounts.Wallet,但是对于普通钱包是noop,因为访问帐户列表不需要连接或解密步骤。
  • Close:实现accounts.Wallet,但是对于普通钱包是noop,因为没有有意义的打开操作。
  • Accounts:实现accounts.Wallet,返回一个帐户列表,该列表由普通kestore钱包包含的单个帐户组成。
  • Contains:返回此钱包实例是否包含特定帐户。
  • Derive:对于普通钱包是noop,因为普通密钥库帐户没有分层帐户派生的概念。
  • SelfDerive:实现accounts.Wallet,尝试使用给定帐户签署给定哈希。如果钱包没有包装此特定帐户,则会返回错误以避免帐户泄漏(即使理论上我们可以通过我们的共享密钥库后端进行签名)。
  • SignTx:尝试使用给定帐户签署给定事务。如果钱包没有包装此特定帐户,则会返回错误以避免帐户泄漏(即使理论上我们可以通过我们的共享密钥库后端进行签名)。
  • SignHashWithPassphrase:尝试使用密码作为额外身份验证,使用给定帐户签署给定哈希。
  • SignTxWithPassphrase:尝试使用密码短语作为额外身份验证,使用给定帐户签署给定事务。
/build/

ci.go

Continuous Integration脚本调用ci命令。
用法:go run build/ci.go <command> <command flags/arguments>

可用的命令:

install [ -arch architecture ] [ -cc compiler ] [ packages… ] – 构建包和可执行文件
test [ -coverage ] [ packages… ] – 运行测试
lint – 运行某些预选项
archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] – 建立档案
importkeys – imports 从env导入签名密钥
debsrc [ -signer key-id ] [ -upload dest ] – 创建一个debian源包
nsis – 创建Windows NSIS安装程序
aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] – 创建一个Android档案
xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] – 创建一个iOS XCode框架
xgo [ -alltools ] [ options ] – 根据选项交叉构建
purge [ -store blobstore ] [ -days threshold ] – 从blobstore中清除旧档案
对于所有命令,-n可防止执行外部程序(空运行模式)。

common
/consensus/

consensus.go

  • ChainReader interface:定义了在header和/或uncle验证期间访问本地区块链所需的一小部分方法。
    Config:检索区块链的链配置。
    CurrentHeader:从本地链中检索当前标头。
    GetHeader:通过哈希和数字从数据库中检索块头。
    GetHeaderByNumber:按编号从数据库中检索块头。
    GetHeaderByHash:通过哈希从数据库中检索块头。
    GetBlock:通过哈希和数字从数据库中检索一个块。

  • SnailChainReader interface:定义了在header和/或uncle验证期间访问本地区块链所需的一小部分方法。snail的临时接口包含接口如上。

  • Engine interface:一种算法不可知的共识引擎。
    Author:检索创建给定块的帐户的以太坊地址,如果共识引擎基于签名,则可能与标头的coinbase不同。
    AuthorSnail
    VerifyHeader:检查标头是否符合给定引擎的共识规则。可以在此处选择性地验证密封,或者通过VerifySeal方法明确地验证密封。
    VerifySnailHeader
    VerifyHeaders:VerifyHeaders与VerifyHeader类似,但同时验证一批标头。该方法返回退出通道以中止操作,并返回结果通道以检索异步验证(顺序是输入slice的顺序)。
    VerifySnailHeaders:VerifySnailHeaders与VerifySnailHeader类似,但同时验证一批标题.VerifySnailHeaders仅验证verifies snail header而不是fruit header.
    VerifySnailUncles:验证给定块的uncles是否符合给定引擎的共识规则。
    VerifySnailSeal:根据给定引擎的共识规则检查标头上的加密密封是否有效。
    VerifyFreshness
    VerifySigns
    Prepare:根据特定引擎的规则初始化块头的共识字段。更改以内联方式执行。
    PrepareSnail
    Finalize:运行任何事务后状态修改(例如块奖励)并组装最终块。注意:可以更新块头和状态数据库以反映在最终确定时发生的任何共识规则(例如块奖励)。
    FinalizeSnail
    Seal:使用本地矿工为给定的输入块生成一个新块
    ConSeal:为给定的输入块生成一个新块,本地矿工的密封位置在顶部。
    CalcSnailDifficulty
    GetDifficulty
    APIs:返回此共识引擎提供的RPC API。

  • CommitteeElection interface:选举模块实施委员会接口
    VerifySigns:批量验证快速链委员会签名
    GetCommittee:获取委员会成员名单

  • PoW interface:基于工作量证明的共识引擎
    Hashrate:返回PoW共识引擎的当前挖掘哈希值。

/consensus/minerva/

minerva.go
minverva实现了truechain混合共识引擎。

var (
	// 代表2 ^ 256-1
	maxUint256 = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0))

	maxUint128 = new(big.Int).Exp(big.NewInt(2), big.NewInt(128), big.NewInt(0))

	//可以在多个用户之间共享的完整实例。
	sharedMinerva = New(Config{"", 3, 0, "", 1, 0, ModeNormal})

	//用于文件命名的数据结构版本。
	algorithmRevision = 1

	// 数据集转储标头,用于检查数据转储的完整性。
	dumpMagic = []uint32{0xbaddcafe, 0xfee1dead}

	//SnailBlock  最初奖励116.48733*10^18
	SnailBlockRewardsInitial = new(big.Int).Mul(big.NewInt(11648733), big.NewInt(1e13))

	//SnailBlock 基础奖励值 115.555555555555 * 10^12
	SnailBlockRewardsBase = 115555555555555

	//up to wei  SnailBlockRewardsBase * this is wei
	Big1e6 = big.NewInt(1e6)

	//Snail block 奖励更改间隔4500块
	SnailBlockRewardsChangeInterval = 4500

	//Snail block 奖励更改间隔减少%2
	SnailBlockRewardsChangePercentage = 2

	//BaseBig
	BaseBig = big.NewInt(1e18)

	//主网段的数量当前固定为1
	NetworkFragmentsNuber = 1

	//挖掘常数为20
	MiningConstant = 20

	//pbft和矿工分配常数
	//生成公式:TestOutSqrt
	SqrtMin = 25
	SqrtMax = 6400

	//Snail block 初始水果 30*10^15
	SnailBlockBodyFruitInitial = new(big.Int).Mul(big.NewInt(30), big.NewInt(1e15))

	//Snail block 奖励水果比例10%
	SnailBlockRewardsFruitRatio = 0.1

	//委员会数量
	CommitteesCount = new(big.Int).SetInt64(1)

	//矿工数量
	MinerCount = new(big.Int).SetInt64(1)
)

  • isLittleEndian:返回本地系统是以小字节还是大字节顺序运行。

  • memoryMap:尝试内存映射uint32s文件以进行只读访问。

  • memoryMapFile:尝试对已打开的文件描述符进行内存映射。

  • memoryMapAndGenerate:尝试对uint32s的临时文件进行内存映射以进行写访问,使用生成器中的数据填充它,然后将其移动到请求的最终路径中。

  • lru struct:按照上次使用时间跟踪缓存或数据集,最多保留N个。

  • newlru:为验证缓存或挖掘数据集创建一个新的最近最少使用的缓存。

  • get:获取或创建给定时期的项目。第一个返回值始终为非零。如果lru认为某个项目在不久的将来会有用,则第二个返回值为非零。

  • dataset struct:使用一些元数据包装truehash数据集,以便更容易并发使用。

  • newDataset:创建一个新的truehash挖掘数据集

  • Mode:定义了minerva引擎生成的PoW验证的类型和数量。

  • Config struct:minerva的配置参数。

  • Minerva struct:实现truechain fpow算法的工作量的共识引擎。
    config
    dataset:在内存数据集中,以避免过于频繁地重新生成

    //挖掘相关领域
    rand:适当播种随机源的随机数
    threads:挖掘时要挖掘的线程数
    update:更新挖掘参数的通知通道
    hashrate:Meter跟踪平均哈希值

    //下面的字段是用于测试的钩子
    shared:共享PoW验证程序以避免缓存重新生成
    fakeFail:即使在假模式下也无法检查PoW的块号
    fakeDelay:从验证返回之前的睡眠时间延迟

    lock:确保内存缓存和挖掘字段的线程安全

    sbc:onsensus.SnailChainReader
    election:选举共识

  • New:创建了一个完整大小的minerva混合共识方案。

  • SetSnailChainReader:实例化后附加接口SnailChainReader

  • SetElection:在实例化后附加接口SnailChainReader

  • NewTester:创建一个小型的minerva方案,仅用于测试目的。

  • NewFaker:使用伪PoW方案创建minerva共识引擎,该方案接受所有块的封印有效,但它们仍然必须符合以太坊共识规则。

  • NewFakeFailer:使用伪PoW方案创建一个minerva共识引擎,该方案接受除了指定的单个块之外的所有块都有效

  • NewFakeDelayer:使用伪PoW方案创建minerva共识引擎,该方案接受所有块作为有效,但延迟验证一段时间

  • NewFullFaker:使用完整的假方案创建minerva共识引擎,该方案接受所有块有效,而不检查任何共识规则。

  • NewShared:创建在同一进程中运行的所有请求者之间共享的完整大小的minerva。

  • Threads:返回当前启用的挖掘线程数。 这并不一定意味着采矿正在运行!

  • SetThreads:更新当前启用的挖掘线程数。 调用此方法不会开始挖掘,只设置线程计数。 如果指定为零,则矿工将使用机器的所有核心。 允许将线程数设置为零以下并且将导致矿工空闲,而不进行任何工作。

  • Hashrate:实现PoW,返回最后一分钟每秒搜索调用的测量速率。

  • APIs

  • SeedHash:是用于生成验证缓存和挖掘的种子


truechain-consensus-core源码整理

config(配置文件)
  • hosts 127.0.0.1 主机配置地址
  • logistics_bft.cfg 路径配置文件
  • tunables_bft.yaml 测试平台公共配置文件
docs(文档)
support(支持)
  • scripts Shell脚本文件
    build.sh 构建脚本
    check.sh 检测脚本
    install.sh 安装脚本
    test.sh 测试脚本

  • toolchain 工具链文件
    Dockerfile Docker文件
    fetch.sh 用于从远程URL下载文件并验证,SHA1或SHA256校验
    patch.tar.xz 补丁包

tests/core-consensus(测试/核心共识)

keygen_tests.go 秘钥生成测试文件

trueconsensus:true共识
  • client/client.go 客户端
    包含方法:
    Start():客户端初始状态的通知程序
    LoadPbftClientConfig():加载客户端配置
    addSig(txnData *pb.TxnData):添加信号量
    NewRequest(msg string, k int, timeStamp int64):新请求,参数为客户端的新请求消息和时间戳,在此方法内进行广播请求,包含数据有AccountNonce,Price,GasLimit,Recipient,AmountPayload,然后调用addSig(txnreq.Data)方法,获取新建快链客户端pb.NewFastChainClient,对PBFT节点进行事物请求
    main():主函数,初始请求数量,解析flag,加载PBFT客户端配置cl.LoadPbftClientConfig(),执行cl.Start()以防客户端有一些初始逻辑,进行交易请求,交易结束,计算时间成本。

  • common/utils.go公用工具类
    包含公共方法:
    BytesToHash(b []byte):字节转哈希,规则如果byte大于len(h)byte将从左侧裁剪
    BigToHash(b *big.Int):将big.int的字节表示设置为hash
    HexToHash(s string):将string的字节表示设置为hash
    Bytes():Bytes获取底层哈希的字节表示
    Big():将哈希值转换为大整数
    Hex():将哈希值转换为十六进制字符串
    TerminalString():实现log.TerminalStringer,格式化控制台的字符串,在记录期间输出
    String():实现stringer接口,记录器也使用它,完整登录文件
    Format(s fmt.State, c rune):格式实现fmt.Formatter,强制字节切片按原样格式化,无需通过用于记录的stringer接口。
    UnmarshalText(input []byte):以十六进制语法分析哈希值
    UnmarshalJSON(input []byte):以十六进制语法分析哈希值
    MarshalText():返回Hash的十六进制表示
    SetBytes(b []byte):将哈希值设置为byte的值
    Generate(rand *rand.Rand, size int):实现快速测试生成器
    HashTxns(txns []*pb.Transaction):使用Merkle Patricia返回所有事务的哈希值
    HashBlockHeader(header *pb.PbftBlockHeader):返回块头的哈希值
    MyPrint(t int, format string, args ...interface{}):提供自定义的彩色输出功能;
    日志级别:0:信息,1:强调, 2:警告,3:错误
    CheckErr(e error):检查错误
    MakeDirIfNot(dir string):处理目录创建操作
    FetchPublicKeyBytes(kpath string):以[]byte形式提取ECDSA公钥
    FetchPublicKey(kpath string):从存储在磁盘上的文件中读取和解码公钥
    FetchPrivateKey(kpath string):从存储在磁盘上的文件中读取和解码私钥
    EncodeECDSAKeys(privateKey *ecdsa.PrivateKey, publicKey *ecdsa.PublicKey):为密钥对接收ECDSA对象并返回编码的[]byte格式

  • dapps/ 去中心化移动应用

  • fastchain/proto/fastchain.pb.go
    包含方法:
    Reset():请求重置
    String():压缩字符串
    Descriptor():文件描述
    GetInner():获取内部请求
    Request_Inner struct:Id,Seq,View,Type,Block,Timestamp,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    PbftNode struct:Addr,Pubkey,Privkey,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    GetAddr:获取地址
    GetPubkey:获取公钥
    GetPrivkey:获取私钥
    Nodes struct:Nodes,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    TxnData struct:AccountNonce,Price,GasLimit,Recipient,Amount,Payload,Signature,Hash,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    Transaction struct:Data,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    PbftBlockHeader struct:Number,GasLimit,GasUsed,Timestamp,ParentHash,TxnsHash,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    PbftBlock struct:Header,Txns,Signs,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    TrueChain struct:Blocks,LastBlockHeader,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    GenericResp struct:Msg,XXX_NoUnkeyedLiteral,XXX_unrecognized,XXX_sizecache
    FastChainClient:将新事务发送到假定的领导者节点
    fastChainClient struct:cc *grpc.ClientConn
    FastChainServer:FastChain服务的服务器API
    RegisterFastChainServer:注册
    _FastChain_NewTxnRequest_Handler:新Txn请求

  • fastchain/proto/fastchain.proto
    service FastChain:由pbft委员会节点公开的接口
    message Request,message PbftNode,message Nodes,message TxnData,message Transaction,message PbftBlockHeader,message PbftBlock,message TrueChain,message GenericResp

  • fastchain/bft_consensus.go:BFT共识
    DailyBFTNode接口:将快速链/委员会的共识暴露给编排机制

processRequest:请求过程broadcast:广播
ProxyProcessPrePrepare:代理进程重组broadcastByRPC:RPC广播
ProxyProcessPrepare:预处理过程checkPrepareMargin:检查准备余量
ProxyProcessCommit:主动进程提交checkCommittedMargin:检查委员会余量
processViewChange:代理进程视图更改recordCommit:提交记录
ProxyProcessNewView:代理进程新视图record:记录
ProxyProcessCheckpoint:进程处理检查点recordPBFTCommit:提交PBFT记录
processRequest:处理请求recordPBFT:PBFT记录
processPrePrepare:过程准备viewProcessCheckPoint:查看流程检查点
processPrepare:过程准备viewProcessPrepare:查看流程准备
processCommit :进程提交newViewProcessPrePrepare:新视图流程预备
processViewChange:进程查看更改newViewProcessView:新视图过程视图
processNewView:处理新视图NewClientRequest:新的客户端请求
processCheckpoint:处理检查点createRequest:创建请求
clean:清理initializeKeys:初始化密钥
suicide:自毁resetMsgDicts:重置消息字典
serverLoop:服务池verifyMsg:验证消息
handleTimeout:处理超时incPrepDict:预案
beforeShutdown:关机前incCommDict:合并输出字典
setupConnections:设置连接isInClientLog:客户端日志
execute:执行isInNodeLog:节点日志
executeInOrder:执行顺序addClientLog:添加客户端日志
addNodeHistory:添加节点历史记录
  • fastchain/block.go:区块

    NewPbftBlockHeader:创建并返回一个新的块头
    NewPbftBlock:创建并返回一个新的区块

  • fastchain/config.go:配置

    Testbed struct:包含Total,ClientID,InitServerID,ThreadingEnabled,MaxRetries,MaxRequests,BatchSize

    BftCommittee struct:包含Blocksize,BlockFrequency,Lambda,WaitTimeout,Tbft,Th,ActualDelta,Delta,Alpha,Csize

    BftCommittee struct:定义泛型可调参数,包含MaxFail,BasePort,OutputThreshold,MaxLogSize,GrpcBasePort,RequestTimeout

    Tunables struct:可调参数分组在服务器的struct Configcocoon params下,struct标签,用于向结构的字段添加元数据,包含Testbed,Slowchain,General,BftCommittee

    Logistics struct:包含与以下环境变量相对应的路径:TRUE_CONF_DIR ='/etc/ truechain/' - 包含主机,可调参数和后勤配置;TRUE_LOG_DIR ='/var /log/truechain' - 包含所有分类帐和日志;TRUE_LIB_DIR ='/var/lib/truechain' - 包含密钥和所有内容db
    包含LedgerLoc,LD,ServerLog,ClientLog,KD -密钥目录,其中存储了pub/priva ECDSA密钥

    Network struct:每个节点用于与连接池详细信息交互的通用结构
    包含N-要启动的节点数,IPList-存储属于BFT节点的IP地址列表,Ports-存储属于BFT节点的Ports列表,GrpcPorts-存储提供grpc请求的端口列表,NumQuest-从客户端发送的请求数,NumKeys-参与的IP地址(BFT节点)的数量,HostsFile-包含服务器/客户端/对等体的网络地址

    Config struct:包含Tunables-可调参数,Logistics,Network

    包含方法:
    DefaultTunables:包含Tunables的默认值,以防万一找不到配置文件
    LoadLogisticsCfg:加载Logistics配置文件
    LoadTunablesConfig:加载.yaml文件
    GenerateKeysToFile:为文件夹生成ECDSA公私密钥对
    GetIPConfigs:加载~/hosts文件中的所有IP
    ValidateConfig:检查异常和荷载的结构配置以及tunables和logistics变量
    CheckConfigErr:首先打印配置特定的错误消息(为消息添加上下文参数)然后重定向到项目范围CheckErr
    GetPbftConfig:返回基本PBFT配置

  • fastchain/config_test.go:测试配置文件

  • fastchain/genesis.go:GetDefaultGenesisBlock返回默认的创世块

  • fastchain/genkeys.go:生成密钥
    包含方法:
    GetCWD:提供当前工作目录的绝对文件路径
    WriteNewKeys:生成kcount的ECDSA公钥 - 私钥对并写入,进入kdir文件夹。

  • fastchain/node.go:节点文件
    包含方法:
    ToGOB64:一个go语言的base64编码器
    FromGOB64:base64解码器
    GetHash:为字符串生成sha512哈希
    ApplyMsg struct:ApplyMsg跟踪消息及其索引,服务器和客户端共同使用,IndexContent
    clientMessageLogItem struct:客户端消息日志,clientID,timestamp
    viewDictKey struct:查看字典key值,seq,id
    nodeMsgLog struct:节点消息日志,mucontent
    getset方法
    commitDictItem struct:numberOfCommitcommittedpreparedreq
    viewDictItem struct:storeholder1holder2
    Node struct:包含节点的基本属性:
    cfgmuclientMupeersportkillFlagListenReadySetupReadyEcdsaKeyhelloSignatureconnectionsIDNviewviewInUseflowBoundPrimaryseqlastExecutedlastStableCheckpointcheckpointProofvminvmaxwaitingtimeoutclientBufferactivepreparedprepDictcommDictviewDictKeyDictoutputLogcommitLognodeMessageLogclientMessageLogcommittedBlocktxPoolgenesistc

    reqCounter struct:number,prepared,req
    Log struct:由BFT委员会成员签署的最终每日日志,未实现
    ActiveItem struct:跟踪当前活动的请求和消息摘要,reqtclientID
    RequestInner struct:请求的核心结构,IDSeqViewReqtypeMsgBlockTimestamp
    MsgSignature struct:EC坐标,R,S
    Request struct:节点之间的对象,Inner,Dig,Sig
    createRequest:创建请求
    AddSig:使用节点的私钥签名消息
    verifyDig:挖掘验证
    resetMsgDicts:重置消息字典
    suicide:自毁
    ProxyProcessPrePrepareArg struct:保存委员会的上下文,将请求映射到客户端,Req,ClientID
    ProxyProcessPrePrepareReply struct:一个atm存根,回复确认,未实现
    ProxyProcessPrepareArg struct:保存PBFT准备阶段的客户端请求上下文,Req,ClientID
    ProxyProcessPrepareReply struct:未实现
    ProxyProcessCommitArg:保存Commit Phase声明的args,Req
    ProxyProcessCommitReply struct:PBFT提交阶段回复ack,未实现
    ProxyProcessViewChangeArg struct:保存先前请求的视图更改上下文,ReqFrom
    ProxyProcessViewChangeReply struct:保存视图更改回复上下文,未实现
    ProxyProcessNewViewArg:为客户端请求保存新的视图arg,ReqClientID
    ProxyProcessNewViewReply struct:回复新视图请求的确认,未实现
    ProxyProcessCheckpointArg:保存PBFT检查点的checkPoint args,ReqClientID
    ProxyProcessCheckpointReply:用于PBFT检查点的ProxyProcessCheckpointReply确认,未实现
    broadcast:广播
    ProxyProcessPrePrepare:触发预准备请求
    ProxyProcessPrepare:准备PBFT的阶段触发
    ProxyProcessCommit:PBFT的提交阶段触发
    ProxyProcessViewChange:视图更改进程请求触发
    ProxyProcessNewView:从当前请求触发并构建新视图
    ProxyProcessCheckpoint:处理PBFT分类帐的检查点
    broadcastByRPC:向所有同伴广播
    executeInOrder:执行命令
    serverLoop:服务池
    clean:清理,未实现
    processCheckpoint:添加检查点支持,未实现
    isInClientLog:客户端日志
    addClientLog:添加客户端日志
    handleTimeout:处理超时
    newClientRequest:处理来自客户端的事务请求,并将其从主副本广播到其他PBFT节点
    initializeKeys:初始化密钥
    incPrepDict:预案
    incCommDict:合并输出字典
    checkPrepareMargin:检查准备余量
    VerifySender:通过将从事务签名获取的公钥与期望的公钥进行匹配来验证事务发送方
    VerifyBlockTxs:通过检查发件人和帐户nonce来验证块中的事务
    processPrePrepare:过程准备
    recordCommit:记录提交
    record:记录
    recordPBFTCommit:记录PBFT提交
    recordPBFT:记录PBFT
    addNodeHistory:添加节点历史记录
    processPrepare:准备过程
    newTrueChain:创建一个新的区块链

func (nd *Node) newTrueChain() {

	tc := &pb.TrueChain{}

	tc.Blocks = make([]*pb.PbftBlock, 0)
	tc.Blocks = append(tc.Blocks, nd.genesis)
	tc.LastBlockHeader = nd.genesis.Header

	nd.tc = tc
}

appendBlock:将一个块附加到区块链

func (nd *Node) appendBlock(block *pb.PbftBlock) {
	nd.tc.Blocks = append(nd.tc.Blocks, block)
	nd.tc.LastBlockHeader = block.Header
}

processCommit:进程提交
viewProcessCheckPoint:查看进程检查点
verifyMsg:验证消息
viewProcessPrepare:视图处理程序
processViewChange:进程视图更改
newViewProcessPrePrepare:新视图处理程序
newViewProcessView:基于检查摘要和消息验证,判断vchangeList是否是真的
beforeShutdown:关闭输出日志文件缓冲区
setupConnections:从客户端拨打与节点的RPC连接
createInternalPbftReq:来自客户端的事务请求,以便在pbft节点之间进行内部rpc通信
createBlockAndBroadcast:创建块大小长度的切片并创建块,一旦提交了上一个块,就进行广播
Make:注册所有节点配置对象

func Make(cfg *Config, me int, port int, view int) *Node {
	gob.Register(&ApplyMsg{})
	gob.Register(&RequestInner{})
	gob.Register(&Request{})
	gob.Register(&checkpointProofType{})
	gob.Register(&ProxyProcessPrePrepareArg{})
	gob.Register(&ProxyProcessPrePrepareReply{})
	gob.Register(&ProxyProcessCheckpointArg{})
	gob.Register(&ProxyProcessCheckpointReply{})
	gob.Register(&ProxyProcessCommitArg{})
	gob.Register(&ProxyProcessCommitReply{})
	gob.Register(&ProxyProcessNewViewArg{})
	gob.Register(&ProxyProcessNewViewReply{})
	gob.Register(&ProxyProcessPrepareArg{})
	gob.Register(&ProxyProcessPrepareReply{})
	gob.Register(&ProxyProcessViewChangeArg{})
	gob.Register(&ProxyProcessViewChangeReply{})

	nd := &Node{}
	//rpc.Register(nd)
	nd.cfg = cfg
	nd.N = cfg.Network.N
	nd.f = (nd.N - 1) / 3
	common.MyPrint(2, "Going to tolerate %d adversaries\n", nd.f)
	nd.lowBound = 0
	nd.highBound = 0
	nd.view = view
	nd.viewInUse = true
	nd.Primary = view % nd.cfg.Network.N
	nd.port = port
	nd.seq = 0
	nd.lastExecuted = 0
	nd.lastStableCheckpoint = 0
	nd.checkpointProof = make([]checkpointProofType, 0)
	nd.timeout = 600
	//nd.mu = sync.Mutex{}
	nd.clientBuffer = ""
	//nd.clientMu = sync.Mutex{}
	nd.KeyDict = make(map[int]keyItem)
	nd.checkpointInterval = 100

	nd.vmin = 0
	nd.vmax = 0
	nd.waiting = nil
	nd.killFlag = false
	nd.ID = me
	nd.active = make(map[DigType]ActiveItem)
	nd.prepDict = make(map[DigType]reqCounter)
	nd.commDict = make(map[DigType]reqCounter)
	nd.nodeMessageLog = nodeMsgLog{}
	nd.nodeMessageLog.content = make(map[int](map[int](map[int]Request)))
	nd.prepared = make(map[int]Request)
	common.MyPrint(2, "Initial Node Config %+v\n", nd)
	nd.cfg.Logistics.LD = path.Join(GetCWD(), "logs/")
	// kfpath := path.Join(cfg.Logistics.KD, filename)

	nd.genesis = GetDefaultGenesisBlock()
	common.MyPrint(0, "Genesis block generated: %x\n\n", nd.genesis.Header.TxnsHash)

	nd.newTrueChain()

	// Buffered channel of size 1 contains the newly committed block to be added to
	// the blockchain by pbft-server
	nd.committedBlock = make(chan *pb.PbftBlock, 1)

	// Create empty transaction pool
	nd.txPool = newTxPool()

	common.MakeDirIfNot(nd.cfg.Logistics.LD) //handles 'already exists'
	fi, err := os.Create(path.Join(nd.cfg.Logistics.LD, "PBFTLog"+strconv.Itoa(nd.ID)+".txt"))
	if err == nil {
		nd.outputLog = fi
	} else {
		panic(err)
	}
	fi2, err2 := os.Create(path.Join(nd.cfg.Logistics.LD, "PBFTBuffer"+strconv.Itoa(nd.ID)+".txt"))
	if err2 == nil {
		nd.commitLog = fi2
	} else {
		panic(err)
	}

	nd.clientMessageLog = make(map[clientMessageLogItem]Request)
	nd.initializeKeys()
	nd.ListenReady = make(chan bool)
	nd.SetupReady = make(chan bool)
	nd.waiting = make(map[int]Request)
	go nd.setupConnections()

	go nd.serverLoop()

	if nd.ID == nd.Primary {
		nd.createBlockAndBroadcast()
	}

	go func() {
		for {
			block := <-nd.committedBlock
			nd.appendBlock(block)
		}
	}()

	return nd
}
  • fastchain/pbft_server.go:PBFT服务
    Server定义pbft节点服务器的基本属性
    Server struct:IP,Port,Nd,Cfg,committed
    fastChainServer struct:pbftSv
    Start:开始 - 初始服务器逻辑在这里
    RegisterPbftGrpcListener:在grpcPort上侦听客户端的新事务请求
    BuildServer:BuildServer启动Server资源属性并侦听客户端,消息请求以及与频道的交互

  • fastchain/transportation.go
    MakeTransportations: 所有网络相关功能在这里定义。

  • fastchain/txlist.go
    nonceHeap是heap.Interface实现,超过64位无符号整数,从可能有缺口的未来队列中检索已排序的事务。
    Len:长度
    Less:返回较小值
    Swap:交互
    push:放入
    Pop:弹出
    txSortedMap struct:以nonce-incrementing方式迭代内容,itemsindex
    newTxSortedMap:创建一个新的随机数排序的事务映射
    Get:获取检索与给定nonce关联的当前事务
    Put:将新事务插入到map中,同时更新map的随机数,索引如果已存在具有相同nonce的事务,则会覆盖该事务。
    priceHeap:priceHeap是heap.Interface的实现,用于检索事务,价格分类的交易在池填满时丢弃,同时包含Len,Swap,Less,Push,Pop
    txPricedList struc:txPricedList是一个价格排序堆,允许在事务池上操作,内容以价格递增的方式,all,items,lock
    newTxPricedList:创建一个新的按价格排序的事务堆
    func (l *txPricedList) Put(tx *pb.Transaction) {}:将新事务插入堆中
    func (l *txPricedList) Get() *pb.Transaction {}:获取基于相关价格返回新交易
    func (l *txPricedList) Len() int {}:Len返回定价列表堆中的项目数

  • fastchain/txpool.go
    TxPool定义事务池
    TxPool struct:txMap-根据帐户nonce排序的帐户到帐户的映射,all-允许查找的所有事务,priced-所有交易按价格排序,count-维护事务数量的计数,lock
    newTxPool:新的事务池
    Add:添加从发件人帐户向事务池添加新事务
    Get:如果事务包含在池中,则返回事务,否则为零
    Remove:从事务池中删除事务
    GetTxCount:返回当前事务池中的事务数
    txLookup struct:定义了一个允许查找事务的结构,alllock
    newTxLookup:返回一个新的txLookup结构
    Range:范围在map上显示的每个键和值上调用f
    func (t *txLookup) Get(hash common.Hash) *pb.Transaction {}:如果查询中存在事务,则返回事务,如果未找到,则返回nil。
    func (t *txLookup) Count() int {:返回查找中的当前项目数
    func (t *txLookup) Add(tx *pb.Transaction) {}:Add将事务添加到查找中。
    func (t *txLookup) Remove(hash common.Hash) {}:从查找中删除事务。

  • logging/log.go
    Logger interface:在内部定义gophoton-core使用的日志记录接口
    InitRootLoger:初始化根记录器
    pbftLog:将传递的模块添加到日志消息中

  • log_impl.go
    LogFor:检索上下文的记录器
    logger struc:entry入口
    LoggerIdentity struct:存储记录器的上下文,RequestIDUserIDSessionID
    setContext:设置上下文
    LoggerWith:记账
    func SetLogProps() map[string]string {}:创建日志属性的映射
    GetLogger:返回记录器

  • minerva/pbftserverengine.go
    StartPbftServers:使用numq消息计数启动设置
    main

func main() {

	// initial the root logger
	logging.InitRootLoger()
	StartPbftServers()
	cfg.GenerateKeysToFile()

	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt)

	go func() {
		select {
		case sig := <-c:
			fmt.Printf("Got %s signal. Aborting...\n", sig)
			os.Exit(1)
		}
	}()

	// Use the main goroutine as signal handling loop
	sigCh := make(chan os.Signal)
	signal.Notify(sigCh)
	for s := range sigCh {
		switch s {
		case unix.SIGTERM:
			fallthrough
		case unix.SIGINT:
			return
		default:
			continue
		}
	}
}
  • snailchain/vrf.go
  • vendor/manifest
CHANGELOG.md:更新日志
CODE_OF_CONDUCT.md:行为守则
CONTRIBUTIONS.md:贡献指南
LICENSE:许可
MAINTAINERS.md:维护人员

以上仅供参考


初链主网上线技术解读之——PBFT委员会选举
初链主网上线技术解读之——混合共识
Truechain主网Beta版交易流程解析

源码地址:https://github.com/truechain

再分享一下文章在互联网之外另起炉灶的DAPP是否是一个伪命题?
革命尚未成功,同志仍需努力。也许TRUE就是颠覆如今互联网模式的契机也未可知。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值