diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b5c6b3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ + +bitcoind +*.o +cryptopp/*.o + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5700871 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ + +CXXFLAGS= -DNOPCH -DFOURWAYSSE2 -O3 -ffast-math -march=native \ + -msse2 -msse3 -Wno-invalid-offsetof -Wformat -pthread \ + -I"/usr/local/openssl-0.9.8/include" + +OBJS = rpc.o main.o util.o script.o db.o net.o irc.o \ + init.o sha256.o cryptopp/sha.o cryptopp/cpu.o + +LDFLAGS = $(CXXFLAGS) -L/usr/local/openssl-0.9.8/lib + +LIBS = -l boost_system-mt -l boost_filesystem-mt \ + -l boost_program_options-mt -l boost_thread-mt \ + -l db_cxx -l crypto -l gthread-2.0 + +all: bitcoind + +.cpp.o: + g++ $(CXXFLAGS) -c $< -o $@ + +clean: + rm -f bitcoind $(OBJS) + +bitcoind: $(OBJS) + g++ $(LDFLAGS) -o bitcoind $(OBJS) $(LIBS) + diff --git a/base58.h b/base58.h index 828f8d5..e377b35 100644 --- a/base58.h +++ b/base58.h @@ -152,7 +152,7 @@ inline bool DecodeBase58Check(const string& str, vector& vchRet) -#define ADDRESSVERSION ((unsigned char)(fTestNet ? 111 : 0)) +#define ADDRESSVERSION ((unsigned char)(fTestNet ? 111 : fDataNet ? 120 : 0)) inline string Hash160ToAddress(uint160 hash160) { diff --git a/init.cpp b/init.cpp index 61ca4d2..54e8093 100644 --- a/init.cpp +++ b/init.cpp @@ -211,6 +211,13 @@ bool AppInit2(int argc, char* argv[]) fPrintToDebugger = GetBoolArg("-printtodebugger"); fTestNet = GetBoolArg("-testnet"); + if (!fTestNet) + fDataNet = GetBoolArg("-datanet"); + + { + fprintf(stderr, "Take off the training wheels.\n"); + exit(1); + } if (fCommandLine) { diff --git a/irc.cpp b/irc.cpp index 1734d76..0a7dfff 100644 --- a/irc.cpp +++ b/irc.cpp @@ -341,8 +341,10 @@ void ThreadIRCSeed2(void* parg) } } - Send(hSocket, fTestNet ? "JOIN #bitcoinTEST\r" : "JOIN #bitcoin\r"); - Send(hSocket, fTestNet ? "WHO #bitcoinTEST\r" : "WHO #bitcoin\r"); + Send(hSocket, fTestNet ? "JOIN #bitcoinTEST\r" : + fDataNet ? "JOIN #bitcoinDATA\r" : "JOIN #bitcoin\r"); + Send(hSocket, fTestNet ? "WHO #bitcoinTEST\r" : + fDataNet ? "WHO #bitcoinDATA\r" :"WHO #bitcoin\r"); int64 nStart = GetTime(); string strLine; diff --git a/main.cpp b/main.cpp index 10d482d..5ba4dd2 100644 --- a/main.cpp +++ b/main.cpp @@ -964,7 +964,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) bool IsInitialBlockDownload() { - if (pindexBest == NULL || (!fTestNet && nBestHeight < 74000)) + if (pindexBest == NULL || (!fTestNet && !fDataNet && nBestHeight < 74000)) return true; static int64 nLastUpdate; static CBlockIndex* pindexLastBest; @@ -1526,7 +1526,7 @@ bool CBlock::AcceptBlock() return error("AcceptBlock() : contains a non-final transaction"); // Check that the block chain matches the known block chain up to a checkpoint - if (!fTestNet) + if (!fTestNet && !fDataNet) if ((nHeight == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) || (nHeight == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) || (nHeight == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) || @@ -1726,6 +1726,15 @@ bool LoadBlockIndex(bool fAllowNew) pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; } + else if (fDataNet) + { + hashGenesisBlock = uint256("0x0000000224b1593e3ff16a0e3b61285bbc393a39f78c8aa48c456142671f7110"); // FIXME: do not use testnet genesis block! + bnProofOfWorkLimit = CBigNum(~uint256(0) >> 28); + pchMessageStart[0] = 0xbe; + pchMessageStart[1] = 0xda; + pchMessageStart[2] = 0xc0; + pchMessageStart[3] = 0xed; + } // // Load block index @@ -1767,7 +1776,7 @@ bool LoadBlockIndex(bool fAllowNew) block.nBits = 0x1d00ffff; block.nNonce = 2083236893; - if (fTestNet) + if (fTestNet || fDataNet) { block.nTime = 1279232055; block.nBits = 0x1d07fff8; @@ -3860,3 +3869,150 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee); } + + +bool CreateDataTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64 nTxFee, string strData) +{ + CRITICAL_BLOCK(cs_main) + { + // txdb must be opened before the mapWallet lock + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + loop + { + wtxNew.vin.clear(); + wtxNew.vout.clear(); + wtxNew.fFromMe = true; + if (nValue < 0) + return false; + int64 nValueOut = nValue; + int64 nTotalValue = nValue + nTxFee; + + // Choose coins to use + set setCoins; + if (!SelectCoins(nTotalValue, setCoins)) + return false; + int64 nValueIn = 0; + foreach(CWalletTx* pcoin, setCoins) + nValueIn += pcoin->GetCredit(); + + // Fill a vout to the payee + bool fChangeFirst = GetRand(2); + if (!fChangeFirst) + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + + // Fill a vout back to self with any change + int64 nChange = nValueIn - nTotalValue; + if (nChange >= CENT) + { + // Note: We use a new key here to keep it from being obvious which side is the change. + // The drawback is that by not reusing a previous key, the change may be lost if a + // backup is restored, if the backup doesn't have the new private key for the change. + // If we reused the old key, it would be possible to add code to look for and + // rediscover unknown transactions that were written with keys of ours to recover + // post-backup change. + + // Reserve a new key pair from key pool + vector vchPubKey = reservekey.GetReservedKey(); + assert(mapKeys.count(vchPubKey)); + + // Fill a vout to ourself, using same address type as the payment + CScript scriptChange; + if (scriptPubKey.GetBitcoinAddressHash160() != 0) + scriptChange.SetBitcoinAddress(vchPubKey); + else + scriptChange << vchPubKey << OP_CHECKSIG; + wtxNew.vout.push_back(CTxOut(nChange, scriptChange)); + } + else + reservekey.ReturnKey(); + + // Fill a vout to the payee + if (fChangeFirst) + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + + // Fill vin + foreach(CWalletTx* pcoin, setCoins) + for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) + if (pcoin->vout[nOut].IsMine()) + wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut)); + + // Sign + int nIn = 0; + foreach(CWalletTx* pcoin, setCoins) + for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) + if (pcoin->vout[nOut].IsMine()) { + CScript scr = + CScript() << ParseHex(strData) << OP_MEMO; + if (!SignSignature(*pcoin, wtxNew, nIn++, + SIGHASH_ALL, scr)) + return false; + } + + // Limit size + unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK); + if (nBytes >= MAX_BLOCK_SIZE_GEN/5) + return false; + + // Check that enough fee is included + int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000); + int64 nMinFee = wtxNew.GetMinFee(); + if (nTxFee < max(nPayFee, nMinFee)) + return false; + + // Fill vtxPrev by copying from previous transactions vtxPrev + wtxNew.AddSupportingTransactions(txdb); + wtxNew.fTimeReceivedIsTxTime = true; + + break; + } + } + } + return true; +} + +string SendMoneyAndData(CScript scriptPubKey, int64 nValue, int64 nTxFee, + string strData, CWalletTx& wtxNew) +{ + CRITICAL_BLOCK(cs_main) + { + CReserveKey reservekey; + if (!CreateDataTransaction(scriptPubKey, nValue, wtxNew, reservekey, + nTxFee, strData)) + { + string strError; + if (nValue + nTxFee > GetBalance()) + strError = strprintf(_("Error: insufficient balance for %s + %s "), + FormatMoney(nValue).c_str(), + FormatMoney(nTxFee).c_str()); + else + strError = _("Error: Transaction creation failed "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + + if (!CommitTransaction(wtxNew, reservekey)) + return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); + } + MainFrameRepaint(); + return ""; +} + + +string SendDataToBitcoinAddress(string strAddress, int64 nValue, + int64 nTxFee, string strData, CWalletTx& wtxNew) +{ + // Check amount + if (nValue <= 0) + return _("Invalid amount"); + if (nValue + nTxFee > GetBalance()) + return _("Insufficient funds"); + + // Parse bitcoin address + CScript scriptPubKey; + if (!scriptPubKey.SetBitcoinAddress(strAddress)) + return _("Invalid bitcoin address"); + + return SendMoneyAndData(scriptPubKey, nValue, nTxFee, strData, wtxNew); +} diff --git a/main.h b/main.h index 0b950e8..3e89e57 100644 --- a/main.h +++ b/main.h @@ -81,6 +81,9 @@ bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); bool BroadcastTransaction(CWalletTx& wtxNew); string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); +string SendDataToBitcoinAddress(string strAddress, int64 nValue, + int64 nTxFee, string strData, + CWalletTx& wtxNew); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); CBlock* CreateNewBlock(CReserveKey& reservekey); @@ -501,12 +504,16 @@ public: bool IsStandard() const { + if (fDataNet) + return true; + foreach(const CTxIn& txin, vin) if (!txin.scriptSig.IsPushOnly()) return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str()); foreach(const CTxOut& txout, vout) if (!::IsStandard(txout.scriptPubKey)) return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str()); + return true; } @@ -874,9 +881,11 @@ public: } void GetAccountAmounts(string strAccount, const set& setPubKey, - int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const + int64& nGenerated, int64& nReceived, int64& nSent, + int64& nFee, string &strData) const { nGenerated = nReceived = nSent = nFee = 0; + strData = ""; // Generated blocks count to account "" if (IsCoinBase()) @@ -888,9 +897,13 @@ public: // Received foreach(const CTxOut& txout, vout) - if (setPubKey.count(txout.scriptPubKey)) + if (setPubKey.count(txout.scriptPubKey)) { nReceived += txout.nValue; + if (fDataNet) + ExtractMemo(txout.scriptPubKey, strData); + } + // Sent if (strFromAccount == strAccount) { diff --git a/net.cpp b/net.cpp index 3c80644..4a16423 100644 --- a/net.cpp +++ b/net.cpp @@ -940,7 +940,8 @@ void ThreadOpenConnections2(void* parg) // Add seed nodes if IRC isn't working static bool fSeedUsed; bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); - if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet) + if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && + !fTestNet && !fDataNet) { for (int i = 0; i < ARRAYLEN(pnSeed); i++) { diff --git a/net.h b/net.h index f070816..12a5e04 100644 --- a/net.h +++ b/net.h @@ -12,7 +12,14 @@ extern int nBestHeight; -inline unsigned short GetDefaultPort() { return fTestNet ? htons(18333) : htons(8333); } +inline unsigned short GetDefaultPort() +{ + if (fTestNet) + return htons(18333); + if (fDataNet) + return htons(19333); + return htons(8333); +} static const unsigned int PUBLISH_HOPS = 5; enum { diff --git a/rpc.cpp b/rpc.cpp index b9ed61d..bcfc310 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -277,6 +277,7 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("hashespersec", gethashespersec(params, false))); obj.push_back(Pair("testnet", fTestNet)); + obj.push_back(Pair("datanet", fDataNet)); obj.push_back(Pair("keypoololdest", (boost::int64_t)GetOldestKeyPoolTime())); obj.push_back(Pair("paytxfee", (double)nTransactionFee / (double)COIN)); obj.push_back(Pair("errors", GetWarnings("statusbar"))); @@ -446,6 +447,31 @@ Value sendtoaddress(const Array& params, bool fHelp) return wtx.GetHash().GetHex(); } +Value senddata(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 4) + throw runtime_error( + "senddata \n" + " and are a real and is rounded to the nearest 0.01"); + + if (!fDataNet) + throw JSONRPCError(-5, "senddata RPC only works on datanet"); + + string strAddress = params[0].get_str(); + int64 nAmount = AmountFromValue(params[1]); + int64 nTxFee = AmountFromValue(params[2]); + string strData = params[3].get_str(); + + CWalletTx wtx; + + string strError = SendDataToBitcoinAddress(strAddress, nAmount, nTxFee, + strData, wtx); + if (strError != "") + throw JSONRPCError(-4, strError); + return wtx.GetHash().GetHex(); +} + + Value getreceivedbyaddress(const Array& params, bool fHelp) { @@ -562,8 +588,9 @@ int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinD if (!wtx.IsFinal()) continue; + string strData; int64 nGenerated, nReceived, nSent, nFee; - wtx.GetAccountAmounts(strAccount, setPubKey, nGenerated, nReceived, nSent, nFee); + wtx.GetAccountAmounts(strAccount, setPubKey, nGenerated, nReceived, nSent, nFee, strData); if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) nBalance += nReceived; @@ -863,8 +890,11 @@ void ListAccountTransactions(CWalletDB& walletdb, const string& strAccount, int if (!wtx.IsFinal()) continue; + string strData; int64 nGenerated, nReceived, nSent, nFee; - wtx.GetAccountAmounts(strAccount, setPubKey, nGenerated, nReceived, nSent, nFee); + wtx.GetAccountAmounts(strAccount, setPubKey, nGenerated, nReceived, + nSent, nFee, strData); + bool have_data = (strData != ""); // Generated blocks count to account "" if (nGenerated != 0) @@ -872,6 +902,8 @@ void ListAccountTransactions(CWalletDB& walletdb, const string& strAccount, int Object entry; entry.push_back(Pair("category", "generate")); entry.push_back(Pair("amount", ValueFromAmount(nGenerated))); + if (have_data) + entry.push_back(Pair("data", strData)); WalletTxToJSON(wtx, entry); ret.insert(make_pair(wtx.GetTxTime(), entry)); } @@ -882,6 +914,8 @@ void ListAccountTransactions(CWalletDB& walletdb, const string& strAccount, int Object entry; entry.push_back(Pair("category", "send")); entry.push_back(Pair("amount", ValueFromAmount(-nSent))); + if (have_data) + entry.push_back(Pair("data", strData)); entry.push_back(Pair("fee", ValueFromAmount(-nFee))); WalletTxToJSON(wtx, entry); ret.insert(make_pair(wtx.GetTxTime(), entry)); @@ -893,6 +927,8 @@ void ListAccountTransactions(CWalletDB& walletdb, const string& strAccount, int Object entry; entry.push_back(Pair("category", "receive")); entry.push_back(Pair("amount", ValueFromAmount(nReceived))); + if (have_data) + entry.push_back(Pair("data", strData)); WalletTxToJSON(wtx, entry); ret.insert(make_pair(wtx.GetTxTime(), entry)); } @@ -1159,6 +1195,7 @@ pair pCallTable[] = make_pair("getaddressesbyaccount", &getaddressesbyaccount), make_pair("getaddressesbylabel", &getaddressesbyaccount), // deprecated make_pair("sendtoaddress", &sendtoaddress), + make_pair("senddata", &senddata), make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress make_pair("getreceivedbyaddress", &getreceivedbyaddress), @@ -1529,7 +1566,7 @@ void ThreadRPCServer2(void* parg) asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback(); asio::io_service io_service; - ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332)); + ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", fDataNet ? 9332 : 8332)); ip::tcp::acceptor acceptor(io_service, endpoint); #ifdef USE_SSL @@ -1700,13 +1737,13 @@ Object CallRPC(const string& strMethod, const Array& params) SSLStream sslStream(io_service, context); SSLIOStreamDevice d(sslStream, fUseSSL); iostreams::stream stream(d); - if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"))) + if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", fDataNet ? "9332" : "8332"))) throw runtime_error("couldn't connect to server"); #else if (fUseSSL) throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries."); - ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")); + ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", fDataNet ? "9332" : "8332")); if (stream.fail()) throw runtime_error("couldn't connect to server"); #endif @@ -1794,6 +1831,8 @@ int CommandLineRPC(int argc, char *argv[]) if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "senddata" && n > 1) ConvertTo(params[1]); + if (strMethod == "senddata" && n > 2) ConvertTo(params[2]); if (strMethod == "getamountreceived" && n > 1) ConvertTo(params[1]); // deprecated if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); diff --git a/script.cpp b/script.cpp index a85c371..b2ee754 100644 --- a/script.cpp +++ b/script.cpp @@ -153,7 +153,7 @@ bool EvalScript(vector >& stack, const CScript& script, co // case OP_NOP: case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: - case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: + case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: break; case OP_IF: @@ -324,6 +324,7 @@ bool EvalScript(vector >& stack, const CScript& script, co break; case OP_DROP: + case OP_MEMO: { // (x -- ) if (stack.size() < 1) @@ -968,8 +969,14 @@ bool Solver(const CScript& scriptPubKey, vector >& vSo // Standard tx, sender provides pubkey, receiver adds signature vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG); + //FIXME: is this correct? + vTemplates.push_back(CScript() << OP_MEMO << OP_PUBKEY << OP_CHECKSIG); + // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG); + + //FIXME: is this correct? + vTemplates.push_back(CScript() << OP_MEMO << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG); } // Scan templates @@ -1145,6 +1152,26 @@ bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret) } +bool ExtractMemo(const CScript& scriptPubKey, string &strData) +{ + strData = ""; + + vector > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_MEMO) + { + strData = HexStr(item.second); + return true; + } + } + return false; +} + + bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType) { vector > stack; diff --git a/script.h b/script.h index da904ef..85b966d 100644 --- a/script.h +++ b/script.h @@ -146,7 +146,7 @@ enum opcodetype OP_NOP7, OP_NOP8, OP_NOP9, - OP_NOP10, + OP_MEMO, @@ -216,6 +216,7 @@ inline const char* GetOpName(opcodetype opcode) case OP_IFDUP : return "OP_IFDUP"; case OP_DEPTH : return "OP_DEPTH"; case OP_DROP : return "OP_DROP"; + case OP_MEMO : return "OP_MEMO"; case OP_DUP : return "OP_DUP"; case OP_NIP : return "OP_NIP"; case OP_OVER : return "OP_OVER"; @@ -293,7 +294,6 @@ inline const char* GetOpName(opcodetype opcode) case OP_NOP7 : return "OP_NOP7"; case OP_NOP8 : return "OP_NOP8"; case OP_NOP9 : return "OP_NOP9"; - case OP_NOP10 : return "OP_NOP10"; @@ -705,5 +705,6 @@ bool IsStandard(const CScript& scriptPubKey); bool IsMine(const CScript& scriptPubKey); bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector& vchPubKeyRet); bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret); +bool ExtractMemo(const CScript& scriptPubKey, string &strData); bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript()); bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0); diff --git a/util.cpp b/util.cpp index 42256a9..7bc6635 100644 --- a/util.cpp +++ b/util.cpp @@ -17,6 +17,7 @@ bool fDaemon = false; bool fCommandLine = false; string strMiscWarning; bool fTestNet = false; +bool fDataNet = false; @@ -680,6 +681,14 @@ void GetDataDir(char* pszDir) strcpy(p, "testnet"); nVariation += 2; } + else if (fDataNet) + { + char* p = pszDir + strlen(pszDir); + if (p > pszDir && p[-1] != '/' && p[-1] != '\\') + *p++ = '/'; + strcpy(p, "datanet"); + nVariation += 2; + } static bool pfMkdir[4]; if (!pfMkdir[nVariation]) { diff --git a/util.h b/util.h index f57e401..93cc02a 100644 --- a/util.h +++ b/util.h @@ -146,6 +146,7 @@ extern bool fDaemon; extern bool fCommandLine; extern string strMiscWarning; extern bool fTestNet; +extern bool fDataNet; void RandAddSeed(); void RandAddSeedPerfmon();