- 1.前言
- 2.为什么是区块链编程而不是比特币编程?
- 3.为什么是 C#?
- 4.预备条件
- 5.本书众筹
- 6.补充阅读
- 7.图标
- 8.许可: CC (ASA 3U)
- 9.项目设置
- 1.比特币地址
- 2.交易
- 3.区块链
- 4. 区块链不仅仅是比特币
- 5.支付比特币
- 6.作为真实性验证方法的所有权证明
- 1.足够随机了吗?
- 2.秘钥加密
- 3.秘钥的生成
- 1.P2PK[H] (向公钥付款 [Hash])
- 2.多重签名
- 3.P2SH ( 向脚本哈希付款)
- 4.灵活机动性
- 5.使用 TransactionBuilder
- 1.颜色币
- 2.发行一项资产
- 3.传输资产
- 4.单元测试
- 5.李嘉图合约
- 6.流动的民主
- 7.烧钱和声誉证明
- 8.存在性证明
- 1.比特币发展的挑战
- 2.如何证明一个币存在于区块链上
- 3.如何证明一个颜色币存在于区块链上
- 4.断开与第三方 API 的信任关系
- 5.防止延展性攻击
- 6.保护你的私钥
3.P2SH ( 向脚本哈希付款)
如前所述,在代码层面多重签名可以轻而易举地运转起来,然而,在 p2sh 出现前,用户还没有办法像支付给比特币地址那样简单地向多重签名的 scriptPubKey 付款。
P2SH 也就是 Pay To Script Hash,是一种表示 scriptPubKey 的简便方法,无论它多么复杂,都可以像 Bitcoin Script Address 一样简单。
让我们看一下在前面部分中我们创建的多重签名长啥样。
Key bob = new Key();
Key alice = new Key();
Key satoshi = new Key();
var scriptPubKey = PayToMultiSigTemplate
.Instance
.GenerateScriptPubKey(2, new[] { bob.PubKey, alice.PubKey, satoshi.PubKey });
Console.WriteLine(scriptPubKey);
很复杂吧?
那么,我们来看看作为 P2SH 支付的 scriptPubKey 是什么样子的:
Key bob = new Key();
Key alice = new Key();
Key satoshi = new Key();
Script redeemScript =
PayToMultiSigTemplate
.Instance
.GenerateScriptPubKey(2, new[] { bob.PubKey, alice.PubKey, satoshi.PubKey });
Console.WriteLine(redeemScript.Hash.ScriptPubKey);
发现不同点了吗?p2sh 的 scriptPubKey 代表多重签名的哈希值(redeemScript.Hash.ScriptPubKey)。
既然它是一个哈希值,你就可以轻易地将它转换为基于 base58 格式的字符串 BitcoinScriptAddress。
Key bob = new Key();
Key alice = new Key();
Key satoshi = new Key();
Script redeemScript =
PayToMultiSigTemplate
.Instance
.GenerateScriptPubKey(2, new[] { bob.PubKey, alice.PubKey, satoshi.PubKey });
//Console.WriteLine(redeemScript.Hash.ScriptPubKey);
Console.WriteLine(redeemScript.Hash.GetAddress(Network.Main));
这样的地址所有用户钱包都能识别,就算它们不理解什么是多重签名。
在 P2SH 支付中,我们提到的 Redeem Script, scriptPubKey 都是经过哈希计算的。
因为付款人只知道 RedeemScript 的哈希值,他不知道 RedeemScript,在我们的例子中甚至都不需要知道他正在给 Bob/Satoshi/Alice 的多重签名支付款项。
对这些交易进行签名跟之前的做法很像,唯一的区别就是当你为 TransactionBuilder 创建 Coin 的时候需要提供 Redeem Script。
设想一下,在一个叫 received 的交易中,多重签名 P2SH 收到一个币。
Script redeemScript =
PayToMultiSigTemplate
.Instance
.GenerateScriptPubKey(2, new[] { bob.PubKey, alice.PubKey, satoshi.PubKey });
////Console.WriteLine(redeemScript.Hash.ScriptPubKey);
//Console.WriteLine(redeemScript.Hash.GetAddress(Network.Main));
Transaction received = new Transaction();
//Pay to the script hash
received.Outputs.Add(new TxOut(Money.Coins(1.0m), redeemScript.Hash));
提醒:支付款项被送到了 redeemScript.Hash,而不是 redeemScript!
然后,当 alice/bob/satoshi 想要将他们收到的币支付出去的时候,他们不是创建一个 Coin 而是创建一个 ScriptCoin。
//Give the redeemScript to the coin for Transaction construction
//and signing
ScriptCoin coin = received.Outputs.AsCoins().First()
.ToScriptCoin(redeemScript);
关于交易生成的剩余代码和签名就跟前面提到的一般多重签名完全一样了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论