返回介绍

4.灵活机动性

发布于 2024-12-29 22:37:18 字数 2697 浏览 0 评论 0 收藏 0

从比特币 0.10 开始,RedeemScript 可以是机动的,这意味着通过比特币的脚本语言,你可以重新对 所有权 进行定义。

比如,我们可以支付款项给任何知道我生日(用 UTF8 格式序列化)的人,也可以给任何知道我秘钥(1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB)的人。

脚本语言的细节超出了我们讨论的范围,你可以很容易在很多网站上找到文档,它是一个基于栈的语言,所以任何做过汇编的人都可以读懂它。

那么,我们首先创建 RedeemScript,

BitcoinAddress address = new BitcoinAddress("1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB");
var birth = Encoding.UTF8.GetBytes("18/07/1988");
var birthHash = Hashes.Hash256(birth);
Script redeemScript = new Script(
    "OP_IF "
    + "OP_HASH256 " + Op.GetPushOp(birthHash.ToBytes()) + " OP_EQUAL " +
    "OP_ELSE "
    + address.ScriptPubKey + " " +
    "OP_ENDIF");

这个 RedeemScript 的意思是有 2 种途径支付这些 ScriptCoin:要么你知道可以得出 birthHash 的数据,要么你拥有比特币地址。

假设我们发送比特币到这个 redeemScript:

var tx = new Transaction();
tx.Outputs.Add(new TxOut(Money.Parse("0.0001"), redeemScript.Hash));

这样我们创建一个交易,用以支付这个 output:

//Create spending transaction
Transaction spending = new Transaction();
spending.AddInput(new TxIn(new OutPoint(tx, 0)));

首选工作就是取得我的生日,并且在 scriptSig 中证明:

////Option 1 : Spender knows my birthdate
Op pushBirthdate = Op.GetPushOp(birth);
Op selectIf = OpcodeType.OP_1; //go to if
Op redeemBytes = Op.GetPushOp(redeemScript.ToBytes());
Script scriptSig = new Script(pushBirthdate, selectIf, redeemBytes);
spending.Inputs[0].ScriptSig = scriptSig;

你可以看到在 scriptSig 我推送了 OP_1,这样我得以进入 RedeemScript 的 OP_IF:

因为没有模板,创建这样的 scriptSig,你可以参照手工创建 P2SH scriptSig。

然后你可以确认,scriptSig 证明了 scriptPubKey 的所有权:

//Verify the script pass
var result = spending
    .Inputs
    .AsIndexedInputs()
    .First()
    .VerifyScript(tx.Outputs[0].ScriptPubKey);
Console.WriteLine(result);
///////////

第二种支付比特币的方法就是证明这个所有权:1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB

///Option 2 : Spender knows my private key
BitcoinSecret secret = new BitcoinSecret("...");
var sig = spending.SignInput(secret, redeemScript, 0);
var p2pkhProof = PayToPubkeyHashTemplate
    .Instance
    .GenerateScriptSig(sig, secret.PrivateKey.PubKey);
selectIf = OpcodeType.OP_0; //go to else
scriptSig = p2pkhProof + selectIf + redeemBytes;
spending.Inputs[0].ScriptSig = scriptSig;

然后所有权也被证明了。

//Verify the script pass
result = spending
    .Inputs
    .AsIndexedInputs()
    .First()
    .VerifyScript(tx.Outputs[0].ScriptPubKey);
Console.WriteLine(result);
///////////

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文