Skip to content

Commit 535dd0e

Browse files
Update Program.cs
1 parent c85c4cf commit 535dd0e

File tree

1 file changed

+94
-62
lines changed

1 file changed

+94
-62
lines changed

3.1TransactionBuilder/Program.cs

Lines changed: 94 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -11,107 +11,139 @@ class Program
1111
{
1212
static void Main()
1313
{
14-
/* Create a fake transaction */
15-
var bob = new Key();
16-
var alice = new Key();
17-
var satoshi = new Key();
14+
//===========================================================================================
15+
//Chapter8. Using the TransactionBuilder
1816

19-
Script bobAlice =
20-
PayToMultiSigTemplate.Instance.GenerateScriptPubKey(
21-
2,
22-
bob.PubKey, alice.PubKey);
17+
//Now let’s gather some Coins.
18+
//For that, let us create a fake transaction with some funds on it.
19+
//Let’s say that the transaction has a P2PKH, P2PK, and multi-sig coin of Bob and Alice.
20+
RandomUtils.Random = new UnsecureRandom();
2321

24-
var init = new Transaction();
25-
init.Outputs.Add(new TxOut(Money.Coins(1m), bob.PubKey)); // P2PK
26-
init.Outputs.Add(new TxOut(Money.Coins(1m), alice.PubKey.Hash)); // P2PKH
27-
init.Outputs.Add(new TxOut(Money.Coins(1m), bobAlice));
28-
29-
/* Get the coins of the initial transaction */
30-
Coin[] coins = init.Outputs.AsCoins().ToArray();
22+
23+
//Private key generator.
24+
Key privateKeyGenerator = new Key();
25+
BitcoinSecret bitcoinSecretFromPrivateKeyGenerator = privateKeyGenerator.GetBitcoinSecret(Network.Main);
26+
Key privateKeyFromBitcoinSecret = bitcoinSecretFromPrivateKeyGenerator.PrivateKey;
27+
Console.WriteLine($"privateKeyFromBitcoinSecret.ToString(Network.Main): {privateKeyFromBitcoinSecret.ToString(Network.Main)}");
28+
//L5DZpEdbDDhhk3EqtktmGXKv3L9GxttYTecxDhM5huLd82qd9uvo is for Alice
29+
//KxMrK5EJeUZ1z3Jyo2zPkurRVtYFefab4WQitV5CyjKApHsWfWg9 is for Bob
30+
//KyStsAHgSehHvewS5YfGwhQGfEWYd8qY2XZg6q2M6TqaM8Q8rayg is for Satoshi
31+
//L2f9Ntm8UUeTLZFv25oZ8WoRW8kAofUjdUdtCq9axCp1hZrsLZja is for ScanKey
32+
33+
BitcoinSecret bitcoinSecretForAlice = new BitcoinSecret("L5DZpEdbDDhhk3EqtktmGXKv3L9GxttYTecxDhM5huLd82qd9uvo", Network.Main);
34+
BitcoinSecret bitcoinSecretForBob = new BitcoinSecret("KxMrK5EJeUZ1z3Jyo2zPkurRVtYFefab4WQitV5CyjKApHsWfWg9", Network.Main);
35+
BitcoinSecret bitcoinSecretForSatoshi = new BitcoinSecret("KyStsAHgSehHvewS5YfGwhQGfEWYd8qY2XZg6q2M6TqaM8Q8rayg", Network.Main);
36+
BitcoinSecret bitcoinSecretForScanKey = new BitcoinSecret("L2f9Ntm8UUeTLZFv25oZ8WoRW8kAofUjdUdtCq9axCp1hZrsLZja", Network.Main);
37+
38+
39+
Key bobPrivateKey = bitcoinSecretForAlice.PrivateKey;
40+
Key alicePrivateKey = bitcoinSecretForBob.PrivateKey;
41+
Key satoshiPrivateKey = bitcoinSecretForSatoshi.PrivateKey;
42+
Key privateKeyForScanKey = bitcoinSecretForScanKey.PrivateKey;
43+
44+
45+
Script scriptPubKeyOfBobAlice =
46+
PayToMultiSigTemplate.Instance.GenerateScriptPubKey(2, bobPrivateKey.PubKey, alicePrivateKey.PubKey);
47+
48+
//This transaction will send money to Bob and Alice.
49+
//The thing you should notice is that this transaction is added by various types of scriptPubKey, such as P2PK(bobPrivateKey.PubKey), P2PKH(alicePrivateKey.PubKey.Hash), and multi-sig ScriptPubKey(scriptPubKeyOfBobAlice).
50+
var txGettingCoinForBobAlice = new Transaction();
51+
txGettingCoinForBobAlice.Outputs.Add(new TxOut(Money.Coins(1m), bobPrivateKey.PubKey));
52+
txGettingCoinForBobAlice.Outputs.Add(new TxOut(Money.Coins(1m), alicePrivateKey.PubKey.Hash));
53+
txGettingCoinForBobAlice.Outputs.Add(new TxOut(Money.Coins(1m), scriptPubKeyOfBobAlice));
54+
55+
//Now let’s say they want to use the coins of this transaction to pay Satoshi.
56+
//First they have to get their coins.
57+
Coin[] coins = txGettingCoinForBobAlice.Outputs.AsCoins().ToArray();
3158

3259
Coin bobCoin = coins[0];
3360
Coin aliceCoin = coins[1];
3461
Coin bobAliceCoin = coins[2];
3562

36-
/* Build the transaction */
37-
var builder = new TransactionBuilder();
38-
Transaction tx = builder
63+
//Now let’s say Bob wants to send 0.2 BTC, Alice 0.3 BTC, and they agree to use bobAlice to send 0.5 BTC.
64+
//Build the transaction by using the features of the TransactionBuilder class.
65+
var builderForSendingCoinToSatoshi = new TransactionBuilder();
66+
Transaction txForSpendingCoinToSatoshi = builderForSendingCoinToSatoshi
3967
.AddCoins(bobCoin)
40-
.AddKeys(bob)
41-
.Send(satoshi, Money.Coins(0.2m))
42-
.SetChange(bob)
68+
.AddKeys(bobPrivateKey)
69+
.Send(satoshiPrivateKey, Money.Coins(0.2m))
70+
.SetChange(bobPrivateKey)
4371
.Then()
4472
.AddCoins(aliceCoin)
45-
.AddKeys(alice)
46-
.Send(satoshi, Money.Coins(0.3m))
47-
.SetChange(alice)
73+
.AddKeys(alicePrivateKey)
74+
.Send(satoshiPrivateKey, Money.Coins(0.3m))
75+
.SetChange(alicePrivateKey)
4876
.Then()
4977
.AddCoins(bobAliceCoin)
50-
.AddKeys(bob, alice)
51-
.Send(satoshi, Money.Coins(0.5m))
52-
.SetChange(bobAlice)
78+
.AddKeys(bobPrivateKey, alicePrivateKey)
79+
.Send(satoshiPrivateKey, Money.Coins(0.5m))
80+
.SetChange(scriptPubKeyOfBobAlice)
5381
.SendFees(Money.Coins(0.0001m))
5482
.BuildTransaction(sign: true);
83+
Console.WriteLine(txForSpendingCoinToSatoshi);
5584

56-
57-
/* Verify you did not screw up */
58-
Console.WriteLine(builder.Verify(tx)); // True
85+
//Then you can verify it is fully signed and ready to send to the network.
86+
//Verify you did not screw up.
87+
Console.WriteLine(builderForSendingCoinToSatoshi.Verify(txForSpendingCoinToSatoshi));
5988

6089

6190

91+
//============================================================================================
92+
//Do with a ScriptCoin.
6293

94+
var txGettingScriptCoinForBobAlice = new Transaction();
95+
txGettingScriptCoinForBobAlice.Outputs.Add(new TxOut(Money.Coins(1.0m), scriptPubKeyOfBobAlice.Hash));
6396

64-
/* ScriptCoin */
65-
init = new Transaction();
66-
init.Outputs.Add(new TxOut(Money.Coins(1.0m), bobAlice.Hash));
97+
coins = txGettingScriptCoinForBobAlice.Outputs.AsCoins().ToArray();
98+
ScriptCoin bobAliceScriptCoin = coins[0].ToScriptCoin(scriptPubKeyOfBobAlice);
6799

68-
coins = init.Outputs.AsCoins().ToArray();
69-
ScriptCoin bobAliceScriptCoin = coins[0].ToScriptCoin(bobAlice);
70-
71-
builder = new TransactionBuilder();
72-
tx = builder
100+
//Then the signature:
101+
var builderForSendingScriptCoinToSatoshi = new TransactionBuilder();
102+
var txForSendingScriptCoinToSatoshi = builderForSendingScriptCoinToSatoshi
73103
.AddCoins(bobAliceScriptCoin)
74-
.AddKeys(bob, alice)
75-
.Send(satoshi, Money.Coins(0.9m))
76-
.SetChange(bobAlice.Hash)
104+
.AddKeys(bobPrivateKey, alicePrivateKey)
105+
.Send(satoshiPrivateKey, Money.Coins(0.9m))
106+
.SetChange(scriptPubKeyOfBobAlice.Hash)
77107
.SendFees(Money.Coins(0.0001m))
78108
.BuildTransaction(true);
79-
Console.WriteLine(builder.Verify(tx)); // True
80-
81-
82-
109+
Console.WriteLine(builderForSendingScriptCoinToSatoshi.Verify(txForSendingScriptCoinToSatoshi));
110+
83111

84-
/* STEALTH COIN */
112+
//============================================================================================
113+
//Do with a StealthCoin.
85114

86-
Key scanKey = new Key();
87-
BitcoinStealthAddress darkAliceBob =
115+
//Let’s create a Bitcoin stealth address for Bob and Alice as in previous chapter:
116+
BitcoinStealthAddress bitcoinStealthAddressForBobAlice =
88117
new BitcoinStealthAddress
89118
(
90-
scanKey: scanKey.PubKey,
91-
pubKeys: new[] { alice.PubKey, bob.PubKey },
119+
scanKey: privateKeyForScanKey.PubKey,
120+
pubKeys: new[] { alicePrivateKey.PubKey, bobPrivateKey.PubKey },
92121
signatureCount: 2,
93122
bitfield: null,
94123
network: Network.Main
95124
);
96125

97-
//Someone sent to darkAliceBob
98-
init = new Transaction();
99-
darkAliceBob
100-
.SendTo(init, Money.Coins(1.0m));
101126

102-
//Get the stealth coin with the scanKey
127+
//Let’s say someone sent the coin to this transaction via the txGettingCoinForBobAliceToBitcoinStealthAddress which is a BitcoinStealthAddress:
128+
var txGettingCoinForBobAliceToBitcoinStealthAddress = new Transaction();
129+
bitcoinStealthAddressForBobAlice
130+
.SendTo(txGettingCoinForBobAliceToBitcoinStealthAddress, Money.Coins(1.0m));
131+
132+
//The scanner will detect the StealthCoin:
103133
StealthCoin stealthCoin
104-
= StealthCoin.Find(init, darkAliceBob, scanKey);
134+
= StealthCoin.Find(txGettingCoinForBobAliceToBitcoinStealthAddress, bitcoinStealthAddressForBobAlice, privateKeyForScanKey);
105135

106-
//Spend it
107-
tx = builder
136+
//And forward it to Bob and Alice, who will sign:
137+
//Let Bob and Alice sign and spend the coin.
138+
TransactionBuilder builderForBobAliceToBitcoinStealthAddress = new TransactionBuilder();
139+
txGettingCoinForBobAliceToBitcoinStealthAddress = builderForBobAliceToBitcoinStealthAddress
108140
.AddCoins(stealthCoin)
109-
.AddKeys(bob, alice, scanKey)
110-
.Send(satoshi, Money.Coins(0.9m))
111-
.SetChange(bobAlice.Hash)
141+
.AddKeys(bobPrivateKey, alicePrivateKey, privateKeyForScanKey)
142+
.Send(satoshiPrivateKey, Money.Coins(0.9m))
143+
.SetChange(scriptPubKeyOfBobAlice.Hash)
112144
.SendFees(Money.Coins(0.0001m))
113145
.BuildTransaction(true);
114-
Console.WriteLine(builder.Verify(tx)); // True
146+
Console.WriteLine(builderForBobAliceToBitcoinStealthAddress.Verify(txGettingCoinForBobAliceToBitcoinStealthAddress));
115147

116148
Console.ReadLine();
117149
}

0 commit comments

Comments
 (0)