internal static ExpressChain CreateChain(int nodeCount, byte?addressVersion) { if (nodeCount != 1 && nodeCount != 4 && nodeCount != 7) { throw new ArgumentException("invalid blockchain node count", nameof(nodeCount)); } var settings = ProtocolSettings.Default with { Network = ExpressChain.GenerateNetworkValue(), AddressVersion = addressVersion ?? ProtocolSettings.Default.AddressVersion }; var wallets = new List <(DevWallet wallet, WalletAccount account)>(nodeCount); for (var i = 1; i <= nodeCount; i++) { var wallet = new DevWallet(settings, $"node{i}"); var account = wallet.CreateAccount(); account.IsDefault = true; wallets.Add((wallet, account)); } var keys = wallets.Select(t => t.account.GetKey().PublicKey).ToArray(); var contract = Contract.CreateMultiSigContract((keys.Length * 2 / 3) + 1, keys); foreach (var(wallet, account) in wallets) { var multiSigContractAccount = wallet.CreateAccount(contract, account.GetKey()); multiSigContractAccount.Label = "Consensus MultiSigContract"; } var nodes = wallets.Select((w, i) => new ExpressConsensusNode { TcpPort = GetPortNumber(i, 3), WebSocketPort = GetPortNumber(i, 4), RpcPort = GetPortNumber(i, 2), Wallet = w.wallet.ToExpressWallet() }); return(new ExpressChain() { Network = settings.Network, AddressVersion = settings.AddressVersion, ConsensusNodes = nodes.ToList(), });