BIP-340/1:Schnorr 签名与 MAST
Schnorr 签名为了简便起见这里都用大整数取模运算下的方式来说明签名、验证过程,签名算法也可以同样地在椭圆曲线上实现
签名及验证Schnorr 签名的单一签名过程较为简单,它涉及到的函数只有哈希函数 $H$ 将消息映射为一个大整数,同时所有的运算在群 $G_p$ 下完成,$p$ 是一个大素数,$G_p$ 的生成元是 $g$
签名流程
Schnorr 签名方随机选取一个大整数 $x \in G_p$ 作为私钥,在群 $G_p$ 上运算 $y=g^x$ 作为它的公钥,同时签名方为消息 $m$ 进行签名
签名方选取随机数 $r \in G_p$,计算 $R = g^r$
签名方计算哈希值 $e = H(y||m)$
通过 $r$ 和 $h$,计算 $s=r+ex$
最后得到签名为 $\sigma = (R,s)$
这个过程表示为 $\sigma \leftarrow Sign(x,m,r,pp)$,$pp$ 是公开参数,包括群的相关信息以及哈希函数
签名验证
在签名验证方,它所具备的公开信息有签名方的公钥 $y=g^x$,签名消息 $m$ 以及签名 $\sigma=(R,s)$, ...
Bitcoin 支付方式及地址类型
info由于 Bitcoin 中的支付类型众多,这也导致地址各式各样,在 btcd 中提供了不同的函数来为公钥生成不同的地址。
这一篇作为 btcd:Golang 下的交易构建 的补充,说明各种支付方式和地址类型。
另外,这篇博文的大部分内容对应 Learn me a bitcoin [1] 的 Script,所以这篇博文更像一个学习记录
ScriptScript is a mini programming language used as a locking mechanism for outputs in bitcoin transactions.
脚本是一种迷你程序语言,用作比特币交易输出的锁定机制。
在每笔交易的输出上都会由一个锁定脚本,它对应了输出中的 $ScriptPubKey$ 字段;
每笔交易还需要提供对应每个输入的解锁脚本,用于在这笔交易中解锁前一笔交易的输出,这对应了输入中的 $ScriptSig$ 字段;
锁定脚本和解锁脚本在比特币中体现为二进制形式混合的操作码和数据,并且通过运行时栈来运行,如果最终栈内的唯一元素是OP_1或更大的元素,那么脚本就是有效 ...
btcd:Golang 下的交易构建
锲子
参与 Bitcoin 的相关生态难免需要涉及到链上的操作,相比于 Ethereum 这样简单的交易发送机制,Bitcoin 上构建交易则需要一定的编程能力,这篇博文记录一下 Bitcoin 上构建交易的各种姿势。(博文不间断更新)
这篇博文的前置知识:UTxO、交易结构与脚本语言,可以在 Learn me a bitcoin 学习,另外:
测试网交易池可视化:https://mempool.space/testnet
测试代币水龙头:https://bitcoinfaucet.uo1.net/
测试私钥生成(主网尽量不要使用):https://iancoleman.io/bip39/
golang 下的 Bitcoin 工具库为:github.com/btcsuite/btcd
简单交易的构建私钥与地址生成私钥生成私钥有多种形式,在 Bitcoin 中最为常见的是 WIF (Wallet Import Format)格式的私钥,也有 16 进制的私钥,这些私钥之间是可以相互转换的
事实上目前的大多数钱包插件都不支持 WIF 格式的私钥导入,只能使用一些软件钱包才能导入。 ...
go-libp2p 踩坑记
做区块链相关的项目难免会遇到需要构建一个 P2P 网络的时候,去年这个时候在 python 上使用的是一个已经停止维护了很久的 Kademlia 库;在今年转到 go 之后就注意到了 go-libp2p 这个库。go-libp2p 源自于 IPFS,它是用于构建 P2P 网络的模块化网络堆栈和库,功能特别强大,但是坑也特别多,主要的原因还是资料和文档都很少。在使用了一段时间后还是觉得需要写一篇博文来记录,还可以作为以后的一个文档吧。
对于 go-libp2p 的不同模块,可以参考 长安链P2P网络技术介绍(2):初识LibP2P[1]。当然,这是一个很笼统的介绍,而这篇博文也会比较简单(毕竟它所拥有的功能太多了),只会记录笔者所使用到的一些功能:连接建立、流处理、节点发现、消息广播及配置、资源限制;同时,官方的库中也有一些样例可以参考:examples - go-libp2p,这篇博文的完整代码可以在 libp2p-example 查看
连接建立先从最简单的 echo 功能开始:两个节点 A 和 B 在建立连接后,节点 A 向节点 B 发送消息 msg,节点 B 也返回消息 msg ...
Prometheus 指标监控
Prometheus 是由 SoundCloud 开源的监控告警解决方案[3],它可以被用于程序暴露一系列监控指标给外界,用于对程序的性能、运行状态进行监控,并且还提供了监控告警功能。
基本架构以下是官方给出的架构图
在图中,Prometheus 的组成部分有[3]:
Prometheus Server:抓取和存储时间序列化数据
Exporters:主动拉取数据的插件
Pushgateway:被动拉取数据的插件
Altermanager:告警信息发送模块
Prometheus web UI:界面化,包含结合 Grafana 进行数据展示或告警发送
其工作逻辑如下[4]:
Prometheus server 定期从静态配置的目标(target)或服务发现的目标中拉取指标(metric)数据;
拉取数据大于内存缓冲区大小时,将数据持久化到数据库(时序数据库);
Prometheus 可以配置规则,用于定时查询数据,在条件触发时将警告推送到配置的 Altermanager;
Altermanager 受到告警时,可以根据配置,聚合、去重、降噪,最后发送警告;
可以使用 API、Pr ...
Json Web Token
Json Web Token (JWT) 是一个开放标准(RFC 7519),它符合设计 Restful API 时的无状态原则,每一次从客户端向服务器发出的请求都是独立的。
JWT 由三个部分组成:Header、Payload 和 Signature,它是一个长字符串,每个子串之间不存在换行符,一般的格式是[Header].[Payload].[Signature]
其 Header 承载了两部分信息:类型和所使用的密码算法,例如
1234{ "alg": "HS256", "typ": "JWT}
Payload 存放了实际需要传递的数据,JWT 中所规定的 7 个可选用的常规字段如下,负载默认是不会进行加密的,所以不可以用来存放秘密信息
Field
Name
Desc
iss
Issuer
签发人
exp
Expiration Time
过期时间
sub
Subject
主题
aud
Audience
受众
nbf
Not Before
生效时间
...
Golang 泛型编程
这里涉及到要学习泛型是由于工程里面遇到一个问题,karmem 下在序列化和反序列化的时候所编写的代码在很大程度上是相似的
于是解决方案就是为不同的结构体都写对应的序列化和反序列化函数来封装
123456func DeserializeGeneralParams(byteParamsData []byte) (*common.GeneralParams, error) { generalParams := new(common.GeneralParams) generalParams.ReadAsRoot(karmem.NewReader(byteParamsData)) return generalParams, nil}
但是这样又存在一个问题,每次新增结构体都需要 copy 新的函数为它进行反序列化和序列化,那么就特别麻烦,所以考虑能不能通过泛型实现类似下面的操作
123456func DeserializeKarmemStruct[T KarmemStruct](byteParamsData []byte) (*T, error) { gener ...
BIP、闪电网络与 Trao
BIP 标准比特币改进建议(Bitcoin Improvement Proposal, BIP)是 Amir Taaki 在2001年的 BIP-0001 中提出,由 Luke Dash Jr. 在 BIP-0002 中对该标准进行了扩展[1]。
BIP stands for Bitcoin Improvement Proposal. A BIP is a design document providing information to the Bitcoin community, or describing a new feature for Bitcoin or its processes or environment. The BIP should provide a concise technical specification of the feature and a rationale for the feature.
BIP 代表比特币改进提案。BIP是向比特币社区提供信息的设计文档,或描述比特币或其流程或环境的新功能。BIP 应提供该功能的简明技术规范和功能的基本原理 ...
密码累加器
密码累加器用于高效地证明元素是否存在于集合中,定义:
集合 $X = \{x_1, …,x_n\}$
集合的累加值 $acc_X$
集合中的元素 $x_i$,对应一个证明 $w_i$
通过证据 $w_i$,可以证明元素 $x_i$ 存在于集合 $X$
累加器的三个性质:正确性、健壮性、不可区分性
正确性:对于所有诚实生成的密钥、所有诚实计算的累加值和证据,验证算法始终返回 1
健壮性:指无碰撞性,对于元素 $y\notin X$,很难找到其成员证明,而对于元素 $x_i \in X$,也很难找到其非成员证明
不可区分性:累加器和持有证明的用户都不会泄露有关累加集合 $X$ 的信息
发展历程
1993年首次被提出,其最初的构造为静态累加器,集合固定不变
2002年提出了动态累加器的概念,可以支持动态添加、删除元素
2007年,通用累加器被提出,可以姐姐成员证明和非成员证明
非通用累加器智能支持元素的成员证明,即证明 $x_i \in X$,无法提供 $y\notin X$ 的证明 $w_y$
模型一个密码累加器中有三个主体:
累加器管理员:生成密钥对,创建并发布累加 ...
Kademlia协议及广播方法
Kademlia 协议Kademlia[1]协议是一种分布式散列表(Distributed Hash Table, DHT) 技术。它可以被用来构建 P2P 网络,相比其他的散列表技术,提高了路由的查询速度。
在 Kademlia 协议中,利用异或来定义了节点之间的距离。这个距离是一个逻辑距离,而不是两个节点实际上的物理距离。在 Kademlia 协议中,每个节点都有一个随机生成的长度为160 bit的ID,而两个节点之间的距离就是把它们的 ID 异或后得到的值。
结合异或本身的性质,可以得到距离的一些特点[2]:
$A \bigotimes B = B \bigotimes A$:A 到 B 和 B 到 A 的距离是一样的
$A \bigotimes A = 0$:节点自身和自身的距离是0
$A \bigotimes B > 0$:任意两个不同节点之间的距离大于0
$(A \bigotimes B) + (B \bigotimes C) \ge (A \bigotimes C)$:A 经过 B 到达 C 的距离大于 A 直接到达 C 的距离
K-bucket在 Kade ...