From Bitcoin 0.10, the RedeemScript can be arbitrary, which means that with the script language of Bitcoin, you can create your own definition of what “ownership” means.
For example, I can give money to whoever knows either my date of birth (dd/mm/yyyy) serialized in UTF-8 or the private key of 1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB.
The details of the script language are out of scope. You can easily find the documentation on various websites. The Bitcoin script language is a stack based language so everyone having done some assembler should be able to read it.
This RedeemScript means that there are 2 ways of spending such ScriptCoin: Either you know the data that gives birthHash (my birthdate) or you own the bitcoin address.
Let’s say I sent money to such redeemScript:
var tx =Network.Main.CreateTransaction();tx.Outputs.Add(Money.Parse("0.0001"),redeemScript.Hash);ScriptCoin scriptCoin =tx.Outputs.AsCoins().First().ToScriptCoin(redeemScript);
So let’s create a transaction that wants to spend such output:
You can see that in the scriptSig I push OP_1 so I enter in the OP_IF of my RedeemScript.
Since there is no backed-in template, for creating such scriptSig, you can see how to build a P2SH scriptSig by hand.
Then you can check that the scriptSig proves the ownership of the scriptPubKey:
//Verify the script passvar result = spending .Inputs .AsIndexedInputs() .First() .VerifyScript(tx.Outputs[0].ScriptPubKey);Console.WriteLine(result); // True
The second way of spending the coin is by proving ownership of 1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB.
////Option 2 : Spender knows my private keyBitcoinSecret secret =newBitcoinSecret("...",Network.Mainnet);var sig =spending.SignInput(secret, scriptCoin);var p2pkhProof = PayToPubkeyHashTemplate .Instance .GenerateScriptSig(sig,secret.PrivateKey.PubKey);selectIf =OpcodeType.OP_0; //go to elsescriptSig = p2pkhProof + selectIf + redeemBytes;spending.Inputs[0].ScriptSig= scriptSig;