- 区块链
- Web3
【免费下载链接】grin
Minimal implementation of the Mimblewimble protocol.
导读
Grin 区块链不支持脚本语言,但这并不意味着它无法承载复杂的链上合约。本文以仓库中的 doc/contract_ideas.md 与 doc/contracts.md 为核心线索,系统梳理 Mimblewimble 生态中多位密码学家(Andrew Poelstra、John Tromp 等)提出的合约构想:从 Pedersen 承诺与 Schnorr 聚合签名两大内置原语出发,逐层推导无脚本原子互换(Atomic Swap)、类哈希原像挑战、闪电网络(Lightning Network)、锁时交易(Lock-time)与零知识条件支付(ZKCP)的代数构造。读者读完本文将掌握这些合约背后"签名即脚本"的数学原理,并能在 Grin 源码中找到对应的内核特征(KernelFeatures)、聚合签名接口与锁高校验实现,理解理论构想与工程落地之间的对应关系。
背景:无脚本链的合约思路
Grin 是一个 Mimblewimble 协议的最小实现(见仓库根目录 README.md),其链上没有图灵完备脚本,也没有比特币式的OP_*操作码。合约能力完全来自链本身内置的少数密码学原语,再以"越来越巧妙的方式"组合而成(如 doc/contracts.md 开篇所述)。
值得强调的是:这些构造方式并非 Grin 开发团队原创,主要归功于 Torben Pryds Pedersen、Gregory Maxwell、Andrew Poelstra、John Tromp、Claus Peter Schnorr 等一批密码学家。本文所依据的doc/contract_ideas.md正是这些思想的原始记录汇编——其内容大量来自 Mimblewimble 邮件列表上的技术讨论(消息编号 msg00022、msg00036、msg00047、msg00086 等),可以视为该项目的"合约思想备忘录"。
要理解这些合约,必须先明确三个内置原语:
- Pedersen 承诺:所有输出形如
r*G + v*H,其中r是盲因子、v是金额、G与H是同一椭圆曲线群上的两个独立生成元。 - 聚合签名(Schnorr / MuSig):可对任意消息做多方签名聚合。
- 锁高(lock_height):交易核可携带一个绝对或相对高度,未达高度前区块拒绝包含该核。
下文先回顾这三个原语的工程实现,再进入contract_ideas.md的合约世界。
内置原语回顾:合约的地基
Pedersen 承诺:金额被盲因子隐藏
在 Grin 中,所有 UTXO 都由r*G + v*H形式的 Pedersen 承诺表示。由于H的离散对数未知,承诺只暴露"值"而不暴露"谁拥有",这也正是后续"无脚本合约"能成立的隐藏性基础。源码侧,承诺的求和处理集中在 core/src/core/committed.rs 的Committedtrait 中:
sum_commitments收集输入、输出承诺并处理overage(手续费或奖励);sum_kernel_excesses汇总所有内核 excess;verify_kernel_sums校验"内核 excess 之和 == 输出承诺之和(扣除输入与手续费)",不匹配时返回KernelSumMismatch。
这套"承诺可相加"的性质,是所有下文合约(多方输出、条件锁时、原子互换)能进行代数运算的根本原因。
聚合签名:用标量算术构建合约
最简单的聚合签名构造如下(doc/contracts.md 1.2 节):
- 待签名消息
M(Grin 中为手续费,或fee | lock_height); - 私钥
x与公钥x*G; - 一次性随机数
k(nonce)。
构造挑战e = SHA256(M | k*G | x*G)与标量s = k + e*x,完整签名即为(s, k*G)。验证时重算e并检查:
s*G = k*G + e * x*G对 Grin 交易而言,令私钥x等于"输出盲因子之和减去输入盲因子之和",即可为整笔交易构造内核签名——内核中保存 excess 承诺与其签名,从而在隐藏所有金额的同时证明"交易不增发货币"并签署手续费。
在源码中,这一层由 core/src/libtx/aggsig.rs 封装,与底层rust-secp256k1-zkp的 aggsig 模块对接:
calculate_partial_sig:给定签名者私钥、私密 nonce、所有参与者的公钥 nonce 之和(nonce_sum)、可选的公钥之和(pubkey_sum)与消息,产出部分签名;verify_partial_sig:用相同的pub_nonce_sum、公钥与消息验证部分签名;add_signatures:将多个部分签名与 nonce 之和聚合成完整签名;subtract_signature:从完整签名中减去一个部分签名——这正是后文无脚本原子互换中"计算差值s' - s"的底层操作;sign_with_blinding:直接用盲因子(BlindingFactor)签署消息,用于交易内核 excess 签名(见 core/src/libtx/build.rs 中kernel.excess_sig = aggsig::sign_with_blinding(...)的用法)。
因为签名只是"标量 + 公钥",所以可以仅用简单算术(加减乘)把多个交易"绑"在一起——这就是contract_ideas.md中所有无脚本构造的数学源泉。
绝对锁时交易与相对锁时交易
绝对锁时(类比比特币 nLockTime):交易可花费的高度h被写进待签名消息与交易核:
M = fee | h- 锁高
h包含在交易内核中 - 含"锁高大於当前区块高度"内核的区块会被拒绝
在 Grin 源码中,内核特征由 core/src/core/transaction.rs 的KernelFeatures枚举表达,其中HeightLocked { fee, lock_height }即绝对锁时内核;kernel_sig_msg()计算待签消息:hash(features || fee_fields || lock_height)。区块校验在 core/src/core/block.rs 的verify_kernel_lock_heights中完成:任何lock_height > self.header.height的内核直接返回KernelLockHeight错误;交易池在入池时也会调用 chain/src/chain.rs 的verify_tx_lock_height(校验tx.lock_height() <= next_block_height),不满足则报ImmatureTransaction(见 pool/src/transaction_pool.rs 与 pool/src/types.rs)。
相对锁时:把锁高定义成"相对某个内核首次进入链状态的高度"。Tx2 需满足:自 Tx1(通过其内核承诺C)被包含后经过h个区块才能生效,且待签消息变为M = fee | h | C,并需附上包含C的 Merkle 证明。
在源码中,相对锁时由KernelFeatures::NoRecentDuplicate { fee, relative_height }(即 NRD 内核)实现:relative_height为NRDRelativeHeight,取值限定在1..=WEEK_HEIGHT(一周高度)之间(见 core/src/core/transaction.rs)。相对高度的合法性校验可见 chain/tests/nrd_validation_rules.rs。
原子互换:从哈希原像到完全无脚本
contract_ideas.md的第一大主题是原子互换(Atomic Swap)——两条链上的两方在不信任彼此的前提下交换资产,且要么双方都成功、要么双方都回滚。
基于哈希原像的版本
Poelstra 在 msg00022 中的基本描述:
在另一条链上,Igno 向我发送代币,而我只有通过揭示某个哈希原像(他知道、我不知道)才能赎回。在 MW 链上我们做同样的交换,使 Igno 能通过揭示原像拿走我的代币;当他取走代币时必然揭示原像,从而我也能取走我的代币。
注意这要求两条链都支持哈希原像:所有比特币脚本衍生链、以太坊、以及 Mimblewimble 都支持。这一版本的完整协议细节(2-of-2 多签、锁时退款、原像换取签名)在本文"锁时交易与 ZKCP"部分有更详细的展开,contracts.md的"原子互换"一节也给出了同构的六步构造(Bob 发送sr' = kr + x + e*rr与x*G,Alice 广播后计算sr' - sr得到原像x)。
无脚本版本:转换密钥 sconv
Poelstra 在 msg00036 中提出了更进一步的思想:没有原像的原子互换。代数上,假设我要把 1 个 MW1 链上的币给 Igno,换取另一条链上的 MW2 币:
- 与经典方案相同,双方先在每条链上把币放入 2-of-2 输出。双方各自拒绝在对方给出锁时"退款"交易前移动自己的币;锁定时间设置为"我能比对方更早取回我的币"。(这与 Tier Nolan 的经典比特币原子互换一致;锁定时间差是因为协议中段 Igno 能先取走他的币而我暂时不能,我必须确保他不能"取走并同时反悔"。)
- Igno 和我构造把锁定币转移到最终目的地的交易。我们就内核与签名 nonce,特别是挑战
e与e'达成一致。 - Igno 给我一个"转换密钥"
sconv,满足:
sconv * G = R - R' + eP - e'P'- 我签署 MW1 交易(把币给 Igno)并把签名发给他。
- 现在 Igno 签署 MW1 交易给自己取币。为此他加上自己的签名
s = k + xe,其中k是他的私密 nonce、x是他的私钥——这两个值我不知道,但其公钥部分已被锁进挑战e。 - 我随后计算
s' = s + sconv——这恰好是 Igno 在 MW2 交易中那一半签名——于是我能取走我的币。
关键观察:
- 我在第 3 步就能验证
sconv的合法性;该验证方程足以保证:我算出的s'通过验证当且仅当s通过验证。 - 一旦两个签名公开,任何人都能算出
sconv = s' - s。由此得到两个性质:- 不泄露任何密钥:分享
sconv无害,因为任何拿到最终签名的人本就可以算出它; - 可否认性(deniability):该方案依赖"Igno 在我知道
s'之前给我sconv",这一点双方都无法证明;任何一对签名,我们中的任意一方都能伪造出上面的完整交互记录。
- 不泄露任何密钥:分享
Poelstra 的结论是:这种"多交易原子链接"是一个相当通用的原语,可用于链接闪电通道等场景——也许我们根本不需要哈希原像。
John Tromp 的六步双链完整方案
msg00047 中,John Tromp 给出了上述思想在 MW 链与 MW' 链之间、从 2-of-2 持仓输出出发的完整六步协议,并配以逐笔交易的代数表格。记号约定:小写字母表示角色(r 为盲因子、k 为 nonce),大写字母表示由谁选取/计算(I=Igno,A=Andrew),数字为序号,'表示另一条链。前提是MW 与 MW' 使用同一条曲线与相同的生成元 G、H,且双方共享所有对盲因子与 nonce 的承诺;为简化讨论,忽略找零与手续费(Tromp 特别提醒:手续费必须写入内核并签名,防止中继节点或矿工劫持——中继可自行添加输出与内核截留一半手续费,矿工则可规避 coinbase 锁时)。
步骤 1:把原始输出转入 2-of-2 持仓输出
| 链 | 角色 | input | blinding/output | kernel | nonce/challenge | signature |
|---|---|---|---|---|---|---|
| MW | Igno | rI0*G+a*H | rI1 | rI1-rI0 | kI1 | sI1=kI1+e1*(rI1-rI0) |
| MW | Andrew | rA1 | rA1 | kA1 | sA1=kA1+e1*rA1 | |
| MW | tx1 | (rI1+rA1)*G+a*H | rI1+rA1-rI0 | e1=H(kI1*G+kA1*G) | s1=sI1+sA1 | |
| MW' | Igno | rI1' | rI1' | kI1' | sI1'=kI1'+e1'*rI1' | |
| MW' | Andrew | rA0'*G+a'*H | rA1' | rA1'-rA0' | kA1' | sA1'=kA1'+e1'*(rA1'-rA0') |
| MW' | tx1' | (rI1'+rA1')*G+a*H | rI1'+rA1'-rA0' | e1'=H(kI1'*G+kA1'*G) | s1'=sI1'+sA1' |
双方还必须为 2-of-2 输出构造范围证明(range proof),此处从略。构成签名sI1, sA1, sI1', sA1'此刻还不能共享——只有在退款有保障时,锁仓才是安全的。
步骤 2:准备锁时退款交易(防互换失败)
| 链 | 角色 | input | output | kernel | nonce/challenge | signature |
|---|---|---|---|---|---|---|
| MW | Igno | rI2*G+a*H | rI2-rI1 | kI2 | sI2=kI2+e2*(rI2-rI1) | |
| MW | Andrew | -rA1 | kA2 | sA2=kA2+e2*-rA1 | ||
| MW | tx2 | (rI1+rA1)*G+a*H | rI2-rI1-rA1 | e2=H(L||kI2*G+kA2*G) | s2=sI2+sA2 |
构成签名sI2与sA2由双方共享并验证。MW' 上的 tx2' 类似构造,但锁定时间L'更早。此时共享步骤 1 的四个构成签名才安全,它们被求和为 tx1 的s1与 tx1' 的s1'。
该步骤可简化:令rI2 == rI1,省略kI2与sI2,直接取s2 = sA2。Andrew 对此的评语是:"在 MW 中复用密钥极其容易制造 footgun。不过我认为这里实际是安全的,你只是在直接反转第一笔交易。"
当 tx1 与 tx1' 都确认后进入步骤 3;若后续任何步骤失败,任一方都可广播自己的退款交易。
步骤 3:构造 2-of-2 输出上的互换交易
| 链 | 角色 | input | output | kernel | nonce/challenge | signature |
|---|---|---|---|---|---|---|
| MW | Igno | -rI1 | kI3 | sI3=kI3+e3*-rI1 | ||
| MW | Andrew | rA3*G+a*H | rA3-rA1 | kA3 | sA3=kA3+e3*(rA3-rA1) | |
| MW | tx3 | (rI1+rA1)*G+a*H | -rI1+rA3-rA1 | e3=H(kI3*G+kA3*G) | s3=sI3+sA3 |
| 链 | 角色 | input | output | kernel | nonce/challenge | signature |
|---|---|---|---|---|---|---|
| MW' | Igno | rI3'*G+a'*H | rI3'-rI1' | kI3' | sI3'=kI3'+e3'*(rI3'-rI1') | |
| MW' | Andrew | -rA1' | kA3' | sA3'=kA3'+e3'*-rA1' | ||
| MW' | tx3' | (rI1'+rA1')*G+a'*H | rI3'-rI1'-rA1' | e3'=H(kI3'*G+kA3'*G) | s3'=sI3'+sA3' |
至此,原子互换被归结为s3' 与 s3 的交换:需要 Igno 揭示 s3' 的同时让 Andrew 得到 s3——办法是让 Andrew 知道sI3与sI3'之差。
步骤 4:可验证地链接 Igno 在两个交易中的签名
Igno 揭示:
sconv = sI3 - sI3' = kI3 + e3*(-rI1) - (kI3' + e3'*(rI3'-rI1'))Andrew 验证:
sconv*G = kI3*G - e3*rI1*G - kI3'*G + e3'*(rI3'-rI1')*G步骤 5:让 Igno 在 MW' 上取得互换所得
tx3' 出现在 MW' 链上即揭示了s3'。
步骤 6:让 Andrew 在 MW 上取得互换所得
Andrew 计算:
s3 = sI3 + sA3 = sconv + sI3' + sA3 = sconv + s3' - sA3' + sA3然后广播 tx3。整个协议完成。
这个方案的工程落地点在于:签名只是标量,sconv的传递与验证完全依赖 core/src/libtx/aggsig.rs 中的subtract_signature/add_signatures这类"签名算术"接口——理论表格中的每一列s = k + e*(blind),都能对应到calculate_partial_sig的一次调用。
闪电网络(LNs):类哈希原像挑战与重盲化
从 HTLC 到新构造
Poelstra 在 msg00022 中记录:他向 Thaddeus Dryja 展示了如何用锁时与哈希原像实现 HTLC(哈希时间锁合约),Dryja 认为这足以创建闪电通道——"原则上我们获得了完整的闪电支持"。msg00029 则是一堆回复,无特别具体内容。
随后在 msg00086 中,Poelstra 给出一个**行为更像哈希原像挑战、且支持重盲化(reblinding)**的新构造。核心思想:把x -> xG当作哈希函数,x是xG的"原像"。有两种相关但不同的能力:
- (a) 构造一个揭示原像的签名;
- (b) 构造一个"预签名"(pre-signature),在原像的帮助下变成正式签名。
基本构造:收到币的条件是揭示 x
假设我把xG发给 Rusty,他想"在我给他x的前提下"给我打币。我有密钥P1、nonceR1;他有密钥P2、nonceR2。我们共同构造公钥为P1 + P2的多签,而 Rusty 会安排得让我不告诉他x就无法完成签名:
- 双方就
R1, R2, P1, P2达成一致。 - 双方都可计算挑战
e = H(P1 + P2 || R1 + R2 || tx)。 - 我发送
s' = k1 - x - x1e(其中R1 = k1G,P1 = x1G)。他可用s'G = R1 - xG - eP1验证。 - 他发来
s2 = k2 - x2e(他那一半多签)。 - 我补上
s1 = k1 - x1e完成签名,最终签名为(s1 + s2, R1 + R2)。
只要这个签名公开,我就能算出x = s1 - s'——签名本身就成了原像的载体。
中间跳:不知道 x 也能中转
如果 Rusty 是闪电通道的中间跳(他希望在自己揭示x的前提下收到币),他自己并不知道x,不能像上面第 3 步那样直接构造s' = k1 - x - x1e。于是角色反转,Rusty 从 Tadge 那里收币:
- 双方就
R1, R2, P1, P2达成一致。Tadge 的密钥与 nonce 是R1与P1,但关键:R1 - xG = k1G——即 Tadge 的 nonce 被k1G偏移。 - 双方计算
e = H(P1 + P2 || R1 + R2 || tx)。 - Tadge 发送"预签名"
s' = k1 - x1e;Rusty 用s'G = R1 - xG - eP1验证。 - 一旦 Rusty 得到
x,他就能算s1 = s' - x——这即 Tadge 那一半最终签名。 - Rusty 自己算
s2并完成签名。
重盲化:防止路径关联
真正的 Rusty 抱怨过:他在我这边与在 Tadge 那边使用同一个xG是隐私泄露——在洋葱路由闪电通道中,xG复用会让路径上任意两个参与者(即使不直接相连)在串通时发现彼此同属一条路径。
修复很简单:Rusty 选一个重盲化因子rG。我把x给他(如前),但 Tadge 要求他提供的是(x + r)(我把xG作为挑战给 Rusty,他转成xG + rG给 Tadge)。由于 Rusty 知道r,他能完成转换。对任何观察者而言,两个挑战表现为均匀独立随机。
组合成闪电路径
假设 Andrew 想通过 Bob 和 Carol 给 Drew 打币,路径为:
A --> B --> C --> D每个箭头是一条闪电通道。只有 Andrew 知道完整路径,他对每个参与者做洋葱加密(每个参与者只知道前后邻居)。
Andrew 从 D 处取得挑战T = xG,从 B、C 处取得重盲化因子U、V。利用上面的技巧:
- A → B:A 给 B 打币,条件是他学会
T + U + V的离散对数; - B → C:B 给 C 打币,条件是他学会
T + V的离散对数(B 知道U的离散对数,足以满足 A 的挑战); - C → D:C 给 D 打币,条件是他学会
T的离散对数——即 D 的原始挑战(C 知道V的离散对数,足以满足 B 的挑战)。
最终路径上的交易全部由单个、均匀随机、相互独立的 Schnorr 签名签署——尽管它们都属于同一条原子的闪电路径。这正是"无脚本闪电"的威力所在。
两点工程注意:
- 每次交易内容变化(以及 nonce 变化),
s'值都必须重新传递;由于它依赖对方 nonce,每次通道更新可能需要额外一轮交互; - 上述构造完全不依赖被签内容:它同样适用于 Mimblewimble、Bitcoin+Schnorr、Monero(多签环机密交易)、Ethereum+Schnorr,甚至可以跨链链接交易。
锁时交易(Lock-time):2-of-2 持仓 + 锁时退款
msg00022 给出一个自包含的锁时协议:我要向 Igno 发送一个比特币,条件是他揭示哈希原像。他给我哈希e。流程如下:
- 我把币发送到一个由我们两人 2-of-2 控制的多签输出,但我不完成签署结果 excess 值的那一半。
- Igno 构造一笔把我币退回的交易,锁时到未来某个时间;我们完成这笔交易(Igno 做他那部分,我可以稍后再做)。
- (2a)我广播第一笔交易,于是链上出现只有经双方同意才能花费的币。
- 我构造把币转给 Igno 的交易:在 excess 中用哈希
e签署、锁时留空,并完成我这部分签名。
此时 Igno 有两个选择:(a) 完成交易——做他那部分签名并向网络(包括我)揭示原像;(b) 什么都不做——那么锁时过后我把币取回。
这一模式正是多方限时锁定的雏形:contracts.md中将其形式化为——Alice 用与 Bob 共享的输出构造 2-of-2 交易但不参与内核签名;Bob 构造锁时退款交易(如 1440 个区块、约 24 小时后);双方完成 2-of-2 交易并广播。此后双方可用锁定的资金自由构造更多交易;若 Bob 拒绝合作,Alice 只需在锁时过后广播退款。该合约可直接用于单向支付通道。
ZKCP:零知识条件支付
msg00022 中 Poelstra 回忆了 ZKCP(Zero-Knowledge Contingent Payments)的场景:Igno 生成一个零知识证明,证明哈希原像能解密某个我关心的问题的解。他给我加密后的解、哈希与证明,然后我们执行前述的"以原像换金钱"的交换。
本质上是把"锁时 + 原像"合约与零知识证明组合:金钱的释放条件从"揭示原像"升级为"原像 + 该原像确实解密出正确结果"。这展示了 Mimblewimble 无脚本合约的可组合性——contract_ideas.md中"Scripting etc."一节收录的 msg00025 与 msg00029 正是对这一方向的进一步讨论(以邮件列表中的多轮回复形式存在)。
衍生合约矩阵:从原语到工程
综合contract_ideas.md与contracts.md,可以把整个合约谱系归纳如下(每一项都能在 Grin 现有原语上找到落点):
| 合约 | 需要的原语 | 在 Grin 中的实现对应 |
|---|---|---|
| 无需信任交易(交互式构造) | 聚合签名 | aggsig::calculate_partial_sig/verify_partial_sig,三步数据交换 |
| 多方输出(多签) | Pedersen 承诺 + 聚合签名 + 范围证明 | committed::verify_kernel_sums,盲因子之和ra+rb构成内核 excess |
| 多方限时锁定 | 2-of-2 + 锁时 | KernelFeatures::HeightLocked+verify_kernel_lock_heights |
| 条件输出锁时 | 承诺可加性 + 绝对锁时 | 两个内核承诺C1+C2由Key3=Key1+Key2支配 |
| 相对条件输出锁时 | 上述 + 相对锁时 | KernelFeatures::NoRecentDuplicate(NRD 内核) |
| 原子互换 | 锁时 + 2-of-2 + 原像/转换密钥 | subtract_signature计算sconv |
| 哈希时间锁(闪电) | 锁时 + 原像 + 重盲化 | 内核消息M = fee | h,签名算术可迁移 |
其中"条件输出锁时"值得一提的细节(contracts.md2.5 节):因为私钥可加(Key3 = Key1 + Key2)、承诺可加(C3 = C1 + C2),把两笔相关交易的输出"纠缠"在一起,就能把一个无条件锁时变成有条件锁时——Tx1(含 Out1)可立即上链确认,Tx2 未达锁高前不可广播;若 Alice 只知道Key3,Out1 只能在锁高后被她花费;而知道Key2的 Bob 可以立即花费 Out1。这与比特币的OP_CHECKLOCKTIMEVERIFY语义相对应。
源码印证:理论与实现的对照
理论文档中的每个公式,都可以在仓库中找到对应实现:
- 聚合签名接口:core/src/libtx/aggsig.rs 提供
calculate_partial_sig(对应s = k + e*x)、verify_partial_sig(对应s*G = k*G + e*x*G验证)、add_signatures(对应s = sum(si))与subtract_signature(对应原子互换中的s' - s)。 - 内核结构与锁时:core/src/core/transaction.rs 的
KernelFeatures::HeightLocked { fee, lock_height }是绝对锁时的载体,kernel_sig_msg()按hash(features || fee || lock_height)生成待签消息,TxKernel::verify()用 excess 作为公钥验证签名。 - 区块拒绝未来锁高:core/src/core/block.rs 的
verify_kernel_lock_heights对每个HeightLocked内核检查lock_height > self.header.height,违反即报KernelLockHeight。 - 交易池门槛:pool/src/transaction_pool.rs 在入池时调用 chain/src/chain.rs 的
verify_tx_lock_height,未到期的交易以ImmatureTransaction拒绝——这与文档中"锁定高度大于当前高度的交易会被拒绝"完全一致。 - 测试用例:core/tests/core.rs 的
test_block_with_timelocked_tx验证了lock_height=1(等于当前高度)的区块合法、lock_height=2的区块抛出KernelLockHeight(2)——这是文档锁时语义的直接工程证据。 - 相对锁时:chain/tests/nrd_validation_rules.rs 以及 core/src/core/transaction.rs 的
NRDRelativeHeight(取值1..=WEEK_HEIGHT)实现了文档中"相对锁时交易"的构想。 - 整体校验逻辑:doc/validation/validation_logic.md 的 Block 一节明确列出"Verify no kernels have a future lock height"与"Verify the big sum",与
committed.rs的verify_kernel_sums一一对应。
这些实现表明:contract_ideas.md中的构想不是停留在纸面的空想——聚合签名、锁时内核、承诺求和三大原语已经在 Grin 主链中落地,原子互换、闪电通道、条件支付等合约只需在这些原语之上按文档中的代数步骤组合即可。
结语:无脚本合约的边界与可能性
回顾doc/contract_ideas.md的整条脉络,可以得出三点结论:
- 签名即脚本:Mimblewimble 虽无脚本,但 Schnorr 聚合签名的线性算术(
s = k + e*x)提供了比哈希原像更通用的"挑战-响应"原语,足以实现原子互换与闪电网络; - 可组合性:承诺相加、密钥相加、签名相加三个性质让合约可以像搭积木一样叠加——2-of-2 持仓 + 锁时退款 + 转换密钥即构成原子互换,再加重盲化即构成洋葱闪电路径;
- 可否认与隐私:无脚本方案天然具备可否认性(任何一方都能伪造交互记录),而重盲化让路径参与者无法关联——这是比特币脚本方案难以同时获得的性质。
对于想要进一步探索的读者,仓库中的 doc/contracts.md(含中文版 doc/translations/contracts_ZH-CN.md)提供了更结构化的合约推导,而 core/src/libtx/aggsig.rs、core/src/core/transaction.rs 与 core/src/core/committed.rs 则是验证这些构造的最佳源码现场。
- 区块链
- Web3
【免费下载链接】grin
Minimal implementation of the Mimblewimble protocol.
相关推荐
PaddlePaddle UVDoc错误排查手册:10个常见问题及解决方案
PaddlePaddle UVDoc错误排查手册:10个常见问题及解决方案 PaddlePaddle UVDoc_safetensors是飞桨生态中用于文档处理
工业异常检测新标杆:PatchCore昇腾Ascend910B NPU适配版深度解析
工业异常检测新标杆:PatchCore昇腾Ascend910B NPU适配版深度解析 PatchCore昇腾Ascend910B NPU适配版是一种基于内存库(
Uniswap V3 闪电贷实战:Dapp-Learning 闪电贷合约源码解析与回调机制
Uniswap V3 闪电贷实战:Dapp Learning 闪电贷合约源码解析与回调机制 本文基于 Dapp Learning 仓库中 uniswapv3 闪
示例工程区块链
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考