从c#连接到比特币核心

问题描述 投票:0回答:1

我从这里下载比特币核心https://bitcoin.org/en/download并尝试从C#连接到它我使用这里的演示代码

https://github.com/cryptean/bitcoinlib

我这样设置bitcoin.conf:

server=1 
rpcport=8332 
rpcuser=myuser 
rpcpass=mypass
txindex=1

这是app.config:

    <!-- Bitcoin settings start -->
    <add key="Bitcoin_DaemonUrl" value="http://127.0.0.1:8332" />
    <add key="Bitcoin_DaemonUrl_Testnet" value="http://127.0.0.1:18332" />
    <add key="Bitcoin_WalletPassword" value="" />
    <add key="Bitcoin_RpcUsername" value="myuser" />
    <add key="Bitcoin_RpcPassword" value="mypass" />
    <!-- Bitcoin settings end -->

当我运行演示时,发生了错误,这是错误消息:

Connecting to Bitcoin MainNet via RPC at http://127.0.0.1:8332...The RPC request was either not understood by the server or there was a problem executing the request
   at BitcoinLib.RPC.Connector.RpcConnector.MakeRequest[T](RpcMethods rpcMethod, Object[] parameters) in C:\Users\pc\Downloads\bitcoinlib-master\bitcoinlib-master\src\BitcoinLib\RPC\Connector\RpcConnector.cs:line 125
   at BitcoinLib.Services.CoinService.GetDifficulty() in C:\Users\pc\Downloads\bitcoinlib-master\bitcoinlib-master\src\BitcoinLib\Services\RpcServices\RpcService\RpcService.cs:line 225
   at ConsoleClient.Program.Main() in C:\Users\pc\Downloads\bitcoinlib-master\bitcoinlib-master\demo\Program.cs:line 104

我没有使用测试网,这里是代码:

  private static void Main()
        {
            try
            {
             var data = RequestServer("getblockcount", new List<string>() { "value" });
                Console.WriteLine(data);

                return;

                Console.Write("\n\nConnecting to {0} {1}Net via RPC at {2}...", CoinService.Parameters.CoinLongName, (CoinService.Parameters.UseTestnet ? "Test" : "Main"), CoinService.Parameters.SelectedDaemonUrl);

                //  Network difficulty
               var networkDifficulty = CoinService.GetDifficulty();
               // networkDifficulty.ToString();
                     Console.WriteLine("[OK]\n\n{0} Network Difficulty: {1}", CoinService.Parameters.CoinLongName, networkDifficulty.ToString("#,###", CultureInfo.InvariantCulture));

                      // Mining info
                      var miningInfo = CoinService.GetMiningInfo();
                Console.WriteLine("[OK]\n\n{0} NetworkHashPS: {1}", CoinService.Parameters.CoinLongName, miningInfo.NetworkHashPS.ToString("#,###", CultureInfo.InvariantCulture));

                //  My balance
                var myBalance = CoinService.GetBalance();
                Console.WriteLine("\nMy balance: {0} {1}", myBalance, CoinService.Parameters.CoinShortName);

                //  Current block
                Console.WriteLine("Current block: {0}",
                    CoinService.GetBlockCount().ToString("#,#", CultureInfo.InvariantCulture));

                //  Wallet state
                Console.WriteLine("Wallet state: {0}", CoinService.IsWalletEncrypted() ? "Encrypted" : "Unencrypted");

                //  Keys and addresses
                if (myBalance > 0)
                {
                    //  My non-empty addresses
                    Console.WriteLine("\n\nMy non-empty addresses:");

                    var myNonEmptyAddresses = CoinService.ListReceivedByAddress();

                    foreach (var address in myNonEmptyAddresses)
                    {
                        Console.WriteLine("\n--------------------------------------------------");
                        Console.WriteLine("Account: " + (string.IsNullOrWhiteSpace(address.Account) ? "(no label)" : address.Account));
                        Console.WriteLine("Address: " + address.Address);
                        Console.WriteLine("Amount: " + address.Amount);
                        Console.WriteLine("Confirmations: " + address.Confirmations);
                        Console.WriteLine("--------------------------------------------------");
                    }

                    //  My private keys
                    if (bool.Parse(ConfigurationManager.AppSettings["ExtractMyPrivateKeys"]) && myNonEmptyAddresses.Count > 0 && CoinService.IsWalletEncrypted())
                    {
                        const short secondsToUnlockTheWallet = 30;

                        Console.Write("\nWill now unlock the wallet for " + secondsToUnlockTheWallet + ((secondsToUnlockTheWallet > 1) ? " seconds" : " second") + "...");
                        CoinService.WalletPassphrase(CoinService.Parameters.WalletPassword, secondsToUnlockTheWallet);
                        Console.WriteLine("[OK]\n\nMy private keys for non-empty addresses:\n");

                        foreach (var address in myNonEmptyAddresses)
                        {
                            Console.WriteLine("Private Key for address " + address.Address + ": " + CoinService.DumpPrivKey(address.Address));
                        }

                        Console.Write("\nLocking wallet...");
                        CoinService.WalletLock();
                        Console.WriteLine("[OK]");
                    }

                    //  My transactions 
                    Console.WriteLine("\n\nMy transactions: ");
                    var myTransactions = CoinService.ListTransactions(null, int.MaxValue, 0);

                    foreach (var transaction in myTransactions)
                    {
                        Console.WriteLine("\n---------------------------------------------------------------------------");
                        Console.WriteLine("Account: " + (string.IsNullOrWhiteSpace(transaction.Account) ? "(no label)" : transaction.Account));
                        Console.WriteLine("Address: " + transaction.Address);
                        Console.WriteLine("Category: " + transaction.Category);
                        Console.WriteLine("Amount: " + transaction.Amount);
                        Console.WriteLine("Fee: " + transaction.Fee);
                        Console.WriteLine("Confirmations: " + transaction.Confirmations);
                        Console.WriteLine("BlockHash: " + transaction.BlockHash);
                        Console.WriteLine("BlockIndex: " + transaction.BlockIndex);
                        Console.WriteLine("BlockTime: " + transaction.BlockTime + " - " + UnixTime.UnixTimeToDateTime(transaction.BlockTime));
                        Console.WriteLine("TxId: " + transaction.TxId);
                        Console.WriteLine("Time: " + transaction.Time + " - " + UnixTime.UnixTimeToDateTime(transaction.Time));
                        Console.WriteLine("TimeReceived: " + transaction.TimeReceived + " - " + UnixTime.UnixTimeToDateTime(transaction.TimeReceived));

                        if (!string.IsNullOrWhiteSpace(transaction.Comment))
                        {
                            Console.WriteLine("Comment: " + transaction.Comment);
                        }

                        if (!string.IsNullOrWhiteSpace(transaction.OtherAccount))
                        {
                            Console.WriteLine("Other Account: " + transaction.OtherAccount);
                        }

                        if (transaction.WalletConflicts != null && transaction.WalletConflicts.Any())
                        {
                            Console.Write("Conflicted Transactions: ");

                            foreach (var conflictedTxId in transaction.WalletConflicts)
                            {
                                Console.Write(conflictedTxId + " ");
                            }

                            Console.WriteLine();
                        }

                        Console.WriteLine("---------------------------------------------------------------------------");
                    }

                    //  Transaction Details
                    Console.WriteLine("\n\nMy transactions' details:");
                    foreach (var transaction in myTransactions)
                    {
                        // Move transactions don't have a txId, which this logic fails for
                        if (transaction.Category == "move")
                        {
                            continue;
                        }
                        
                        var localWalletTransaction = CoinService.GetTransaction(transaction.TxId);
                        IEnumerable<PropertyInfo> localWalletTrasactionProperties = localWalletTransaction.GetType().GetProperties();
                        IList<GetTransactionResponseDetails> localWalletTransactionDetailsList = localWalletTransaction.Details.ToList();

                        Console.WriteLine("\nTransaction\n-----------");

                        foreach (var propertyInfo in localWalletTrasactionProperties)
                        {
                            var propertyInfoName = propertyInfo.Name;

                            if (propertyInfoName != "Details" && propertyInfoName != "WalletConflicts")
                            {
                                Console.WriteLine(propertyInfoName + ": " + propertyInfo.GetValue(localWalletTransaction, null));
                            }
                        }

                        foreach (var details in localWalletTransactionDetailsList)
                        {
                            IEnumerable<PropertyInfo> detailsProperties = details.GetType().GetProperties();
                            Console.WriteLine("\nTransaction details " + (localWalletTransactionDetailsList.IndexOf(details) + 1) + " of total " + localWalletTransactionDetailsList.Count + "\n--------------------------------");

                            foreach (var propertyInfo in detailsProperties)
                            {
                                Console.WriteLine(propertyInfo.Name + ": " + propertyInfo.GetValue(details, null));
                            }
                        }
                    }

                    //  Unspent transactions
                    Console.WriteLine("\nMy unspent transactions:");
                    var unspentList = CoinService.ListUnspent();

                    foreach (var unspentResponse in unspentList)
                    {
                        IEnumerable<PropertyInfo> detailsProperties = unspentResponse.GetType().GetProperties();

                        Console.WriteLine("\nUnspent transaction " + (unspentList.IndexOf(unspentResponse) + 1) + " of " + unspentList.Count + "\n--------------------------------");

                        foreach (var propertyInfo in detailsProperties)
                        {
                            Console.WriteLine(propertyInfo.Name + " : " + propertyInfo.GetValue(unspentResponse, null));
                        }
                    }
                }

                Console.ReadLine();
            }
            catch (RpcInternalServerErrorException exception)
            {
               
                var errorCode = 0;
                var errorMessage = string.Empty;

                if (exception.RpcErrorCode.GetHashCode() != 0)
                {
                    errorCode = exception.RpcErrorCode.GetHashCode();
                    errorMessage = exception.RpcErrorCode.ToString();
                }

                Console.WriteLine("[Failed] {0} {1} {2}", exception.Message, errorCode != 0 ? "Error code: " + errorCode : string.Empty, !string.IsNullOrWhiteSpace(errorMessage) ? errorMessage : string.Empty);
            }
            catch (Exception exception)
            {
                //Console.WriteLine("[Failed]\n\nPlease check your configuration and make sure that the daemon is up and running and that it is synchronized. \n\nException: " + exception);
                Console.WriteLine(exception.Message+"\n"+exception.StackTrace.ToString());
            }
        }

我也尝试这个代码:

public static string RequestServer(string methodName, List<string> parameters)
        {

            string ServerIp = "http://127.0.0.1:8332";
            string UserName = "myuser";
            string Password = "mypass";

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(ServerIp);
            webRequest.Credentials = new NetworkCredential(UserName, Password);

            webRequest.ContentType = "application/json-rpc";
            webRequest.Method = "POST";

            string respVal = string.Empty;

            JObject joe = new JObject();
            joe.Add(new JProperty("jsonrpc", "1.0"));
            joe.Add(new JProperty("id", "1"));
            joe.Add(new JProperty("method", methodName));

            JArray props = new JArray();
            foreach (var parameter in parameters)
            {
                props.Add(parameter);
            }

            joe.Add(new JProperty("params", props));

            // serialize json for the request
            string s = JsonConvert.SerializeObject(joe);
            byte[] byteArray = Encoding.UTF8.GetBytes(s);
            webRequest.ContentLength = byteArray.Length;
            Stream dataStream = webRequest.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            StreamReader streamReader = null;
            try
            {
                WebResponse webResponse = webRequest.GetResponse();

                streamReader = new StreamReader(webResponse.GetResponseStream(), true);

                respVal = streamReader.ReadToEnd();
                var data = JsonConvert.DeserializeObject(respVal).ToString();
                return data;
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp.Message + "\n" + exp.StackTrace.ToString());
            }
            finally
            {
                if (streamReader != null)
                {
                    streamReader.Close();
                }

            }
            return string.Empty;
        }



             var data = RequestServer("getblockcount", new List<string>() { "value" });
                Console.WriteLine(data);

但是发生了错误:

401 unauthorized ....

我通过命令运行bitcoind:

bitcoind.exe -server

这是输出:


C:\Program Files\Bitcoin\daemon>bitcoind.exe -server
2023-01-01T19:01:43Z Ignoring unknown configuration value rpcpass
2023-01-01T19:01:43Z Bitcoin Core version v22.0.0 (release build)
2023-01-01T19:01:43Z Assuming ancestors of block 00000000000000000008a89e854d57e5667df88f1cdef6fde2fbca1de5b639ad have valid signatures.
2023-01-01T19:01:43Z Setting nMinimumChainWork=00000000000000000000000000000000000000001fa4663bbbe19f82de910280
2023-01-01T19:01:43Z Using the 'shani(1way,2way)' SHA256 implementation
2023-01-01T19:01:43Z Using RdSeed as additional entropy source
2023-01-01T19:01:43Z Using RdRand as an additional entropy source
2023-01-01T19:01:43Z Default data directory C:\Users\pc\AppData\Roaming\Bitcoin
2023-01-01T19:01:43Z Using data directory C:\Users\pc\AppData\Roaming\Bitcoin
2023-01-01T19:01:43Z Config file: C:\Users\pc\AppData\Roaming\Bitcoin\bitcoin.conf
2023-01-01T19:01:43Z Config file arg: rpcport="8332"
2023-01-01T19:01:43Z Config file arg: rpcuser=****
2023-01-01T19:01:43Z Config file arg: server="1"
2023-01-01T19:01:43Z Config file arg: txindex="1"
2023-01-01T19:01:43Z Setting file arg: wallet = ["btc1313"]
2023-01-01T19:01:43Z Command-line arg: server=""
2023-01-01T19:01:43Z Using at most 125 automatic connections (2048 file descriptors available)
2023-01-01T19:01:43Z Using 16 MiB out of 32/2 requested for signature cache, able to store 524288 elements
2023-01-01T19:01:43Z Using 16 MiB out of 32/2 requested for script execution cache, able to store 524288 elements
2023-01-01T19:01:43Z Script verification uses 7 additional threads
2023-01-01T19:01:43Z scheduler thread start
2023-01-01T19:01:43Z HTTP: creating work queue of depth 16
2023-01-01T19:01:43Z Using random cookie authentication.
2023-01-01T19:01:43Z Generated RPC authentication cookie C:\Users\pc\AppData\Roaming\Bitcoin\.cookie
2023-01-01T19:01:43Z HTTP: starting 4 worker threads
2023-01-01T19:01:43Z Using wallet directory C:\Users\pc\AppData\Roaming\Bitcoin\wallets
2023-01-01T19:01:43Z init message: Verifying wallet(s)…
2023-01-01T19:01:43Z Using BerkeleyDB version Berkeley DB 4.8.30: (April  9, 2010)
2023-01-01T19:01:43Z Using wallet C:\Users\pc\AppData\Roaming\Bitcoin\wallets\btc1313\wallet.dat
2023-01-01T19:01:43Z BerkeleyEnvironment::Open: LogDir=C:\Users\pc\AppData\Roaming\Bitcoin\wallets\btc1313\database ErrorFile=C:\Users\pc\AppData\Roaming\Bitcoin\wallets\btc1313\db.log
2023-01-01T19:01:43Z init message: Loading banlist…
2023-01-01T19:01:43Z SetNetworkActive: true
2023-01-01T19:01:43Z Using /16 prefix for IP bucketing
2023-01-01T19:01:43Z Cache configuration:
2023-01-01T19:01:43Z * Using 2.0 MiB for block index database
2023-01-01T19:01:43Z * Using 56.0 MiB for transaction index database
2023-01-01T19:01:43Z * Using 8.0 MiB for chain state database
2023-01-01T19:01:43Z * Using 384.0 MiB for in-memory UTXO set (plus up to 286.1 MiB of unused mempool space)
2023-01-01T19:01:43Z init message: Loading block index…
2023-01-01T19:01:43Z Switching active chainstate to Chainstate [ibd] @ height -1 (null)
2023-01-01T19:01:43Z Opening LevelDB in C:\Users\pc\AppData\Roaming\Bitcoin\blocks\index
2023-01-01T19:01:43Z Opened LevelDB successfully
2023-01-01T19:01:43Z Using obfuscation key for C:\Users\pc\AppData\Roaming\Bitcoin\blocks\index: 0000000000000000
2023-01-01T19:01:48Z LoadBlockIndexDB: last block file = 3337
2023-01-01T19:01:48Z LoadBlockIndexDB: last block file info: CBlockFileInfo(blocks=82, size=82069535, heights=769632...769908, time=2022-12-31...2023-01-01)
2023-01-01T19:01:48Z Checking all blk files are present...
2023-01-01T19:01:49Z Opening LevelDB in C:\Users\pc\AppData\Roaming\Bitcoin\chainstate
2023-01-01T19:01:49Z Opened LevelDB successfully
2023-01-01T19:01:49Z Using obfuscation key for C:\Users\pc\AppData\Roaming\Bitcoin\chainstate: 6343dde5e7e6e386
2023-01-01T19:01:49Z Loaded best chain: hashBestChain=000000000000000000039b1c6364ff45a20a879f9a834fe4ed5292cf63cf942a height=769908 date=2023-01-01T18:50:35Z progress=0.999998
2023-01-01T19:01:49Z init message: Verifying blocks…
2023-01-01T19:01:49Z Verifying last 6 blocks at level 3
2023-01-01T19:01:49Z [0%]...[16%]...[33%]...[50%]...[66%]...[83%]...[99%]...[DONE].
2023-01-01T19:01:56Z No coin database inconsistencies in last 6 blocks (9918 transactions)
2023-01-01T19:01:56Z  block index           12583ms
2023-01-01T19:01:56Z Opening LevelDB in C:\Users\pc\AppData\Roaming\Bitcoin\indexes\txindex
2023-01-01T19:01:56Z Opened LevelDB successfully
2023-01-01T19:01:56Z Using obfuscation key for C:\Users\pc\AppData\Roaming\Bitcoin\indexes\txindex: 0000000000000000
2023-01-01T19:01:56Z txindex thread start
2023-01-01T19:01:56Z init message: Loading wallet…
2023-01-01T19:01:56Z txindex is enabled at height 769908
2023-01-01T19:01:56Z txindex thread exit
2023-01-01T19:01:56Z BerkeleyEnvironment::Open: LogDir=C:\Users\pc\AppData\Roaming\Bitcoin\wallets\btc1313\database ErrorFile=C:\Users\pc\AppData\Roaming\Bitcoin\wallets\btc1313\db.log
2023-01-01T19:01:56Z [btc1313] Wallet File Version = 169900
2023-01-01T19:01:56Z [btc1313] Keys: 2001 plaintext, 0 encrypted, 2001 w/ metadata, 2001 total. Unknown wallet records: 0
2023-01-01T19:01:56Z [btc1313] Wallet completed loading in              53ms
2023-01-01T19:01:56Z [btc1313] setKeyPool.size() = 2000
2023-01-01T19:01:56Z [btc1313] mapWallet.size() = 0
2023-01-01T19:01:56Z [btc1313] m_address_book.size() = 0
2023-01-01T19:01:56Z block tree size = 769909
2023-01-01T19:01:56Z nBestHeight = 769908
2023-01-01T19:01:56Z loadblk thread start
2023-01-01T19:01:56Z torcontrol thread start
2023-01-01T19:01:56Z Bound to 127.0.0.1:8334
2023-01-01T19:01:56Z Bound to [::]:8333
2023-01-01T19:01:56Z Bound to 0.0.0.0:8333
2023-01-01T19:01:56Z Leaving InitialBlockDownload (latching to false)
2023-01-01T19:01:56Z init message: Loading P2P addresses…
2023-01-01T19:01:56Z Loaded 63213 addresses from peers.dat  116ms
2023-01-01T19:01:56Z Loaded 2 addresses from "anchors.dat"
2023-01-01T19:01:56Z 2 block-relay-only anchors will be tried for connections.
2023-01-01T19:01:56Z init message: Starting network threads…
2023-01-01T19:01:56Z opencon thread start
2023-01-01T19:01:56Z addcon thread start
2023-01-01T19:01:56Z dnsseed thread start
2023-01-01T19:01:56Z Waiting 300 seconds before querying DNS seeds.
2023-01-01T19:01:56Z msghand thread start
2023-01-01T19:01:56Z init message: Done loading
2023-01-01T19:01:56Z net thread start
2023-01-01T19:01:57Z Imported mempool transactions from disk: 695 succeeded, 0 failed, 0 expired, 0 already there, 0 waiting for initial broadcast
2023-01-01T19:01:57Z loadblk thread exit
2023-01-01T19:01:57Z New outbound peer connected: version: 70016, blocks=769909, peer=0 (block-relay-only)
2023-01-01T19:01:58Z New outbound peer connected: version: 70015, blocks=769909, peer=1 (block-relay-only)
2023-01-01T19:01:59Z New outbound peer connected: version: 70016, blocks=769909, peer=2 (outbound-full-relay)
2023-01-01T19:02:04Z UpdateTip: new best=00000000000000000006266ea0383ab08afa37496e4b35ae218e1b03e26b607e height=769909 version=0x32bce000 log2_work=93.924929 tx=792623260 date='2023-01-01T19:00:40Z' progress=1.000000 cache=1.3MiB(9604txo)
2023-01-01T19:02:16Z New outbound peer connected: version: 70016, blocks=769909, peer=3 (outbound-full-relay)
2023-01-01T19:02:16Z New outbound peer connected: version: 70016, blocks=769909, peer=4 (outbound-full-relay)
2023-01-01T19:02:18Z P2P peers available. Skipped DNS seeding.
2023-01-01T19:02:18Z dnsseed thread exit
2023-01-01T19:02:23Z New outbound peer connected: version: 70016, blocks=769909, peer=5 (outbound-full-relay)
2023-01-01T19:02:35Z New outbound peer connected: version: 70016, blocks=769909, peer=6 (outbound-full-relay)
2023-01-01T19:08:44Z ThreadRPCServer incorrect password attempt from 127.0.0.1:49244
2023-01-01T19:08:44Z ThreadRPCServer incorrect password attempt from 127.0.0.1:49208
2023-01-01T19:08:44Z New outbound peer connected: version: 70015, blocks=769909, peer=39 (outbound-full-relay)
2023-01-01T19:08:44Z New outbound peer connected: version: 70016, blocks=769909, peer=41 (outbound-full-relay)
2023-01-01T19:08:44Z New outbound peer connected: version: 70015, blocks=769909, peer=43 (outbound-full-relay)

我还阅读了有关此库的信息NBitcoin,但我找不到如何使用它的简单示例。我的问题:从 C# 连接比特币核心的步骤是什么,使用它的最佳库是什么?如何修复我上面提到的这些错误?有使用 NBitcoin 的简单示例吗?谢谢。

c# bitcoin bitcoin-testnet bitcoinlib nbitcoin
1个回答
1
投票

一个小错误,bitcoin.conf 中的单词:

rpcpass=mypass

错了一定是:

rpcpassword=mypass

我改变了它,效果很好

© www.soinside.com 2019 - 2024. All rights reserved.