@@ -10,14 +10,23 @@ namespace NBitcoin
10
10
{
11
11
public class Bitcoin : INetworkSet
12
12
{
13
+ public const string DEFAULT_SIGNET_NAME = "signet" ;
14
+
15
+ public const string DEFAULT_SIGNET_CHALLENGE = "512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae" ;
16
+
17
+ public const string DEFAULT_SIGNET_GENESIS_BLOCK = "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a008f4d5fae77031e8ad222030101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000" ;
18
+
13
19
private Bitcoin ( )
14
20
{
15
21
}
16
22
17
- private Network CreateSignet ( )
23
+ private Network CreateSignet (
24
+ string name = DEFAULT_SIGNET_NAME ,
25
+ string challenge = DEFAULT_SIGNET_CHALLENGE ,
26
+ string genesisBlock = DEFAULT_SIGNET_GENESIS_BLOCK )
18
27
{
19
28
NetworkBuilder builder = new NetworkBuilder ( ) ;
20
- builder . SetChainName ( SignetName ) ;
29
+ builder . SetChainName ( name == DEFAULT_SIGNET_NAME ? SignetName : new ChainName ( name ) ) ;
21
30
builder . SetNetworkSet ( this ) ;
22
31
builder . SetConsensus ( new Consensus ( )
23
32
{
@@ -32,7 +41,7 @@ private Network CreateSignet()
32
41
PowAllowMinDifficultyBlocks = false ,
33
42
PowNoRetargeting = false ,
34
43
RuleChangeActivationThreshold = 1916 ,
35
- MinerConfirmationWindow = 2016 ,
44
+ MinerConfirmationWindow = 2016 ,
36
45
CoinbaseMaturity = 100 ,
37
46
SupportSegwit = true ,
38
47
SupportTaproot = true
@@ -45,35 +54,40 @@ private Network CreateSignet()
45
54
. SetBech32 ( Bech32Type . WITNESS_PUBKEY_ADDRESS , "tb" )
46
55
. SetBech32 ( Bech32Type . WITNESS_SCRIPT_ADDRESS , "tb" )
47
56
. SetBech32 ( Bech32Type . TAPROOT_ADDRESS , "tb" )
48
- . SetMagic ( GetSignetMagic ( ) )
57
+ . SetMagic ( GetSignetMagic ( challenge ) )
49
58
. SetPort ( 38333 )
50
59
. SetRPCPort ( 38332 )
51
- . SetName ( "signet" )
52
- . AddAlias ( "bitcoin-signet" )
53
- . AddAlias ( "btc-signet" )
60
+ . SetName ( name )
54
61
#if ! NOSOCKET
55
62
. AddSeeds ( new [ ]
56
63
{
57
64
"178.128.221.177" ,
58
65
"2a01:7c8:d005:390::5"
59
66
} . Select ( o => new Protocol . NetworkAddress ( System . Net . IPAddress . Parse ( o ) ) ) )
60
67
#endif
61
- . SetGenesis ( "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a008f4d5fae77031e8ad222030101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000" ) ;
68
+ . SetGenesis ( genesisBlock ) ;
69
+
70
+ if ( name == DEFAULT_SIGNET_NAME )
71
+ {
72
+ builder . AddAlias ( "bitcoin-signet" ) ;
73
+ builder . AddAlias ( "btc-signet" ) ;
74
+ }
75
+
62
76
var network = builder . BuildAndRegister ( ) ;
63
77
#if ! NOFILEIO
64
78
var data = Network . GetDefaultDataFolder ( "bitcoin" ) ;
65
79
if ( data != null )
66
80
{
67
- var signetCookie = Path . Combine ( data , "signet" , ".cookie" ) ;
81
+ var signetCookie = Path . Combine ( data , DEFAULT_SIGNET_NAME , ".cookie" ) ;
68
82
RPC . RPCClient . RegisterDefaultCookiePath ( network , signetCookie ) ;
69
83
}
70
84
#endif
71
85
return network ;
72
86
}
73
87
74
- private static uint GetSignetMagic ( )
88
+ private static uint GetSignetMagic ( string challengeHex )
75
89
{
76
- var challengeBytes = DataEncoders . Encoders . Hex . DecodeData ( "512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae" ) ;
90
+ var challengeBytes = DataEncoders . Encoders . Hex . DecodeData ( challengeHex ) ;
77
91
var challenge = new Script ( challengeBytes ) ;
78
92
MemoryStream ms = new MemoryStream ( ) ;
79
93
BitcoinStream bitcoinStream = new BitcoinStream ( ms , true ) ;
@@ -99,9 +113,12 @@ public Network Signet
99
113
{
100
114
get
101
115
{
102
- return _Signet ??= Network . GetNetwork ( "signet" ) ;
116
+ return _Signet ??= Network . GetNetwork ( DEFAULT_SIGNET_NAME ) ;
103
117
}
104
118
}
119
+
120
+ static Dictionary < ChainName , Network > _CustomSignets = new Dictionary < ChainName , Network > ( ) ;
121
+
105
122
public Network GetNetwork ( ChainName chainName )
106
123
{
107
124
if ( chainName == null )
@@ -114,12 +131,24 @@ public Network GetNetwork(ChainName chainName)
114
131
return Regtest ;
115
132
if ( chainName == SignetName )
116
133
return Signet ;
134
+ if ( _CustomSignets . TryGetValue ( chainName , out var network ) )
135
+ return network ;
117
136
return null ;
118
137
}
119
138
120
139
internal Network InitSignet ( )
121
140
{
122
141
return _Signet = CreateSignet ( ) ;
123
142
}
143
+
144
+ public Network InitCustomSignet ( string name , string challenge , string genesisBlock )
145
+ {
146
+ if ( _CustomSignets . TryGetValue ( new ChainName ( name ) , out var network ) )
147
+ return network ;
148
+
149
+ var customSignet = CreateSignet ( name , challenge ?? DEFAULT_SIGNET_CHALLENGE , genesisBlock ?? DEFAULT_SIGNET_GENESIS_BLOCK ) ;
150
+ _CustomSignets . Add ( customSignet . ChainName , customSignet ) ;
151
+ return customSignet ;
152
+ }
124
153
}
125
154
}
0 commit comments