@@ -11,107 +11,139 @@ class Program
11
11
{
12
12
static void Main ( )
13
13
{
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
18
16
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 ( ) ;
23
21
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 ( ) ;
31
58
32
59
Coin bobCoin = coins [ 0 ] ;
33
60
Coin aliceCoin = coins [ 1 ] ;
34
61
Coin bobAliceCoin = coins [ 2 ] ;
35
62
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
39
67
. 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 )
43
71
. Then ( )
44
72
. 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 )
48
76
. Then ( )
49
77
. 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 )
53
81
. SendFees ( Money . Coins ( 0.0001m ) )
54
82
. BuildTransaction ( sign : true ) ;
83
+ Console . WriteLine ( txForSpendingCoinToSatoshi ) ;
55
84
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 ) ) ;
59
88
60
89
61
90
91
+ //============================================================================================
92
+ //Do with a ScriptCoin.
62
93
94
+ var txGettingScriptCoinForBobAlice = new Transaction ( ) ;
95
+ txGettingScriptCoinForBobAlice . Outputs . Add ( new TxOut ( Money . Coins ( 1.0m ) , scriptPubKeyOfBobAlice . Hash ) ) ;
63
96
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 ) ;
67
99
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
73
103
. 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 )
77
107
. SendFees ( Money . Coins ( 0.0001m ) )
78
108
. BuildTransaction ( true ) ;
79
- Console . WriteLine ( builder . Verify ( tx ) ) ; // True
80
-
81
-
82
-
109
+ Console . WriteLine ( builderForSendingScriptCoinToSatoshi . Verify ( txForSendingScriptCoinToSatoshi ) ) ;
110
+
83
111
84
- /* STEALTH COIN */
112
+ //============================================================================================
113
+ //Do with a StealthCoin.
85
114
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 =
88
117
new BitcoinStealthAddress
89
118
(
90
- scanKey : scanKey . PubKey ,
91
- pubKeys : new [ ] { alice . PubKey , bob . PubKey } ,
119
+ scanKey : privateKeyForScanKey . PubKey ,
120
+ pubKeys : new [ ] { alicePrivateKey . PubKey , bobPrivateKey . PubKey } ,
92
121
signatureCount : 2 ,
93
122
bitfield : null ,
94
123
network : Network . Main
95
124
) ;
96
125
97
- //Someone sent to darkAliceBob
98
- init = new Transaction ( ) ;
99
- darkAliceBob
100
- . SendTo ( init , Money . Coins ( 1.0m ) ) ;
101
126
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:
103
133
StealthCoin stealthCoin
104
- = StealthCoin . Find ( init , darkAliceBob , scanKey ) ;
134
+ = StealthCoin . Find ( txGettingCoinForBobAliceToBitcoinStealthAddress , bitcoinStealthAddressForBobAlice , privateKeyForScanKey ) ;
105
135
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
108
140
. 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 )
112
144
. SendFees ( Money . Coins ( 0.0001m ) )
113
145
. BuildTransaction ( true ) ;
114
- Console . WriteLine ( builder . Verify ( tx ) ) ; // True
146
+ Console . WriteLine ( builderForBobAliceToBitcoinStealthAddress . Verify ( txGettingCoinForBobAliceToBitcoinStealthAddress ) ) ;
115
147
116
148
Console . ReadLine ( ) ;
117
149
}
0 commit comments