> For the complete documentation index, see [llms.txt](https://programmingblockchain.gitbook.io/programmingblockchain-japanese/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://programmingblockchain.gitbook.io/programmingblockchain-japanese/other_types_of_ownership/arbitrary.md).

# 任意性

ビットコインコアのバージョン0.10から、**RedeemScript** の内容は任意とすることができるようになった。それはビットコインのスクリプト言語を用いて、「所有権」が何を意味するかに関して自分の定義を作ることができるようになったということだ。

たとえば僕が、UTF8にバイト化された僕の誕生日を知っている人、もしくは **1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB** に対応する秘密鍵を知っている人になら、誰でもビットコインをあげられるとしよう。

スクリプト言語の詳細についてはスコープ外だが、いろいろなウェブサイト上で簡単にドキュメントを見つけられるし、スタックベースの言語なのでアセンブラを触っていた人ならだれでも読むことができるはずだ。

> **注釈**：([nopara73](https://github.com/nopara73))僕は [Davide De Rosa's tutorial](http://davidederosa.com/basic-blockchain-programming/bitcoin-script-language-part-one/) が1番楽しいチュートリアルだと思う。

さあ最初は **RedeemScript** を作ってみよう。

> **注釈**：このコードが正しく動くようにするために、**プロジェクト** -> **参照の編集** -> **System.Numerics** の順番にクリックして参照を設定しよう。

```csharp
BitcoinAddress address = BitcoinAddress.Create("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");
```

この **RedeemScipt** は、**ScriptCoin** を使う2つの方法を示している。2つの方法とは、1つが **birthHash**（僕の誕生日）を導出してくれるデータを知っていることで、もう1つがそのビットコインアドレスを持っていることだ。

たとえば、この **redeemScript** にビットコインを送ったとしよう。

```csharp
var tx = new Transaction();
tx.Outputs.Add(new TxOut(Money.Parse("0.0001"), redeemScript.Hash));
ScriptCoin scriptCoin = tx.Outputs.AsCoins().First().ToScriptCoin(redeemScript);
```

そのアウトプットを使うトランザクションを作ってみよう。

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

最初の選択肢は僕の誕生日を知っていて、**scriptSig** の中でそれを証明することだ。

```csharp
////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** の所有権を証明することを確認できる。

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

このビットコインを使用する2番目の方法は、**1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB** が自分のビットコインアドレスであることを証明することだ。

```
////Option 2 : Spender knows my private key
BitcoinSecret secret = new BitcoinSecret("...");
var sig = spending.SignInput(secret, scriptCoin);
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;
```

以下でビットコインアドレスが自分のものであることの証明の結果を確認できる。

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://programmingblockchain.gitbook.io/programmingblockchain-japanese/other_types_of_ownership/arbitrary.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
