Eleven  committed 69f530d

Add creatForeignMultisigAddress for users,
Add IForeignClient, CForeignClient for signers to connect other blockchain using jsonrpcclient. Add -ljsoncpp -ljsonrpccpp-client -ljsonrpccpp-common
Add other blockchain rpc server config file

Comments (0)

Files changed (9)

File bcexchange.pro Modified

View file
  • Ignore whitespace
  • Hide word diff
     src/qt/assetvotedialog.h \
     src/qt/addassetvotedialog.h \
     src/asset.h \
-    src/exchange.h
+    src/exchange.h \
+    src/foreignclient.h
 
 SOURCES += src/qt/bitcoin.cpp \
     src/qt/bitcoingui.cpp \
     src/exchange.cpp \
     src/rpcexchange.cpp \
     src/random.cpp \
+    src/foreignclient.cpp 
 
 RESOURCES += src/qt/bitcoin.qrc
 
 # Set libraries and includes at end, to use platform-defined defaults if not overridden
 INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH $$QRENCODE_INCLUDE_PATH
 LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,) $$join(QRENCODE_LIB_PATH,,-L,)
-LIBS += -lcurl -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX
+LIBS += -lcurl -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX -ljsoncpp -ljsonrpccpp-client -ljsonrpccpp-common
 # -lgdi32 has to happen after -lcrypto (see  #681)
 win32:LIBS += -lws2_32 -lshlwapi -lmswsock -lole32 -loleaut32 -luuid -lgdi32
 LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX

File src/base58.h Modified

View file
  • Ignore whitespace
  • Hide word diff
 #include <boost/format.hpp>
 #include "script.h"
 #include "allocators.h"
+#include "coinmetadata.h"
 
 static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
-
+extern std::map<std::string, int> mapMultisigPrefix;
+extern std::map<std::string, int> mapMultisigPrefixTest;
 // Encode a byte sequence as a base58-encoded string
 inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
 {
     bool operator()(const CNoDestination &no) const;
 };
 
+class CForeignAddress : public CBase58Data
+{
+public:
+    CForeignAddress(const CTxDestination &dest, uint32_t assetId)
+    {
+        SetData(assetId, &dest, 20);
+    }
+    void SetData(uint32_t assetId, const void* pdata, size_t nSize)
+	{
+		std::string assetSymbol;
+    	assetSymbol = GetAssetSymbol(assetId);
+    	if(fTestNet)
+    	{
+        	if(mapMultisigPrefixTest.find(assetSymbol) != mapMultisigPrefixTest.end())
+        	{
+            	nVersion = mapMultisigPrefix[assetSymbol];
+            	vchData.resize(nSize);
+            	if (!vchData.empty())
+                	memcpy(&vchData[0], pdata, nSize);
+        	}
+        	else
+            	throw std::runtime_error("assetSymbol does not exist\n");
+    	}
+    	else
+    	{
+        	if(mapMultisigPrefix.count(assetSymbol))
+        	{
+            	nVersion = mapMultisigPrefix[assetSymbol];
+            	vchData.resize(nSize);
+            	if (!vchData.empty())
+                	memcpy(&vchData[0], pdata, nSize);
+        	}	
+        	else
+            	throw std::runtime_error("assetSymbol does not exist\n");
+    	}	
+	}
+};
 class CBitcoinAddress : public CBase58Data
 {
 public:

File src/coinmetadata.cpp Modified

View file
  • Ignore whitespace
  • Hide word diff
         (EncodeAssetId("SDC"),   coin_metadata("SDC",   "ShadowCash",   8))
         ;
 
+std::map<std::string, int> mapMultisigPrefix = map_list_of
+    ("BTC", 5)
+	("PPC", 117)
+    ;
+std::map<std::string, int> mapMultisigPrefixTest = map_list_of
+    ("BTC", 196)
+	("PPC", 196)
+	;
 std::string GetAssetSymbol(uint32_t gid)
 {
     coin_metadata_map::const_iterator itMetadata = COIN_METADATA.find(gid);

File src/init.cpp Modified

View file
  • Ignore whitespace
  • Hide word diff
             Shutdown();
         }
         ReadConfigFile(mapArgs, mapMultiArgs);
+        ReadForeignRpcConfigFile(mapForeignRpcData);
 
         if (mapArgs.count("-?") || mapArgs.count("--help"))
         {

File src/main.cpp Modified

View file
  • Ignore whitespace
  • Hide word diff
 
 static string strProtocolWarning;
 
+extern string createForeignMultisigAddress(const vector<CPubKey>& pubKeys, uint8_t nRequiredSigners, uint32_t assetId);
 
 
 //////////////////////////////////////////////////////////////////////////////
 
             // Add multisig address to trade database
             uint8_t requiredSigners = assets[assetId].nRequiredDepositSigners;
+            /*
             CScript scriptMultiSig;
             scriptMultiSig.SetMultisig(requiredSigners, pubKeys);
             CScriptID scriptMultiSigId = scriptMultiSig.GetID();
             // TODO: the address should be created with the unit of asset. Using BKS for now...
             CBitcoinAddress multisigAddress(scriptMultiSigId, '8');
-            string address = multisigAddress.ToString();
+            */
+            string address = createForeignMultisigAddress(pubKeys, requiredSigners, assetId);
             if(!ptradeDB->AddDepositAddress(userPubKey, assetId, address, pubKeys, requiredSigners))
                 return error("CheckTradeMessage() : Adding deposit address to trade database failed\n");
         }

File src/qt/bitcoin.cpp Modified

View file
  • Ignore whitespace
  • Hide word diff
     }
     ReadConfigFile(mapArgs, mapMultiArgs);
     ReadDividendConfigFile(mapDividendArgs);
+    ReadForeignRpcConfigFile(mapForeignRpcData);
 
     // Application identification (must be set before OptionsModel is initialized,
     // as it is used to locate QSettings)

File src/rpcexchange.cpp Modified

View file
  • Ignore whitespace
  • Hide word diff
 #include "wallet.h"
 #include "walletdb.h"
 #include "util.h"
-#include <boost/lexical_cast.hpp>
+#include "foreignclient.h"
+//#include <boost/lexical_cast.hpp>
 using namespace json_spirit;
 using namespace std;
 
 extern map<uint160, bool> mapUsedOrderId;
+extern map<string, string> mapForeignRpcData;
 Value sendkeylist(const Array& params, bool fHelp)
 {
     if(fHelp || params.size() < 3 || params.size() > 3)
     return ret;
 }
 
+std::string createForeignMultisigAddress(const std::vector<CPubKey>& pubKeys, uint8_t nRequiredSigners, uint32_t assetId)
+{
+    CScript redeemScript;
+    redeemScript.SetMultisig(nRequiredSigners, pubKeys);
+    return CForeignAddress(redeemScript.GetID(), assetId).ToString();
+}
 Value senddepositaddressrequest(const Array& params, bool fHelp)
 {
     if(fHelp || params.size() < 3 || params.size() > 3)
     if(assets.find(assetId) == assets.end())
         throw JSONRPCError(-101, "This asset is not supported.");
     uint8_t totalSigners = assets[assetId].nTotalDepositSigners;
+    uint8_t nRequiredSigners = assets[assetId].nRequiredDepositSigners;
     if(pks.size() != totalSigners)
         throw JSONRPCError(-101, "Wrong number of public keys for asset.");
 
             throw JSONRPCError(-101, "Each public key must have a different signer.");
         bestSigners.erase(signerPubKey);
     }
-
+    depositAddress = createForeignMultisigAddress(pubkeys, nRequiredSigners, assetId);
     // Create transaction
     CWalletTx wtx;
     {
     }
     return wtx.GetHash().GetHex();
 }
+Value createstdforeignmultisig(const Array& params, bool fHelp)
+{
+    if(fHelp)
+        throw runtime_error(
+            "createstdforeignmultisig <asset id> [<pubkey>, <pubkey>...]\n"
+            "<asset id> is the id of deposit asset\n"
+            "[<pubkey>...] is a vector of published compressed public keys\n");
+    multisig_t ret;
+    uint8_t nRequired;
+    uint32_t assetId = EncodeAssetId(params[0].get_str());
+    if(!IsValidAssetId(assetId))
+        throw JSONRPCError(-3, "Invalid asset id");
+    map<uint32_t, CAsset> assets;
+    if(!pindexBest->GetEffectiveAssets(assets))
+        throw JSONRPCError(-4, "Could not get assets");
+    if(assets.find(assetId) == assets.end())
+        throw JSONRPCError(-101, "This asset is not supported.");
+    nRequired = assets[assetId].nRequiredDepositSigners;
+    string symbol = GetAssetSymbol(assetId);
+
+    Array pks = params[1].get_array();
+
+    foreignclientdata_t rpcData;
+    string rpcUser = symbol + "." + "user";
+    string rpcPassword = symbol + "." + "password";
+    string rpcHost = symbol + "." + "host";
+    string rpcPort = symbol + "." + "port";
+    if(mapForeignRpcData.find(rpcUser) == mapForeignRpcData.end())
+        throw JSONRPCError(-111, "rpcUser does not exit");
+    rpcData.user = mapForeignRpcData[rpcUser];
+    if(mapForeignRpcData.find(rpcPassword) == mapForeignRpcData.end())
+        throw JSONRPCError(-111, "rpcPassword does not exit");
+    rpcData.password = mapForeignRpcData[rpcPassword];
+    if(mapForeignRpcData.find(rpcHost) == mapForeignRpcData.end())
+        throw JSONRPCError(-111, "rpcHost does not exit");
+    rpcData.host = mapForeignRpcData[rpcHost];
+    if(mapForeignRpcData.find(rpcPort) == mapForeignRpcData.end())
+        throw JSONRPCError(-111, "rpcPort does not exit");
+    rpcData.port = mapForeignRpcData[rpcPort];
+
+    vector<string> pubKeys;
+    BOOST_FOREACH(Value pk, pks)
+    {
+        pubKeys.push_back(pk.get_str());
+    }
+
+    CForeignClient rpcClient(rpcData.user, rpcData.password, rpcData.host, rpcData.port);
+
+    ret = rpcClient.createmultisig(nRequired, pubKeys);
+    Object result;
+    result.push_back(Pair("address", ret.address));
+    result.push_back(Pair("redeemScript", ret.redeemScript));
+    return result;
+
+}

File src/util.cpp Modified

View file
  • Ignore whitespace
  • Hide word diff
 map<string, string> mapArgs;
 map<string, vector<string> > mapMultiArgs;
 map<string, string> mapDividendArgs;
+map<string, string> mapForeignRpcData;
 bool fDebug = false;
 bool fDebugNet = false;
 bool fPrintToConsole = false;
     return pathConfigFile;
 }
 
+boost::filesystem::path GetForeignRpcConfigFile()
+{
+    namespace fs = boost::filesystem;
+    fs::path pathConfigFile(GetArg("-foreignconf", "foreign.conf"));
+    if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile;
+    return pathConfigFile;
+}
+
 void ReadConfigFile(map<string, string>& mapSettingsRet,
                     map<string, vector<string> >& mapMultiSettingsRet)
 {
     }
 }
 
+void ReadForeignRpcConfigFile(map<string, string>& mapForeignRpcDataRet)
+{
+    namespace fs = boost::filesystem;
+    namespace pod = boost::program_options::detail;
+
+    fs::ifstream streamConfig(GetForeignRpcConfigFile());
+    if(!streamConfig.good())
+        return; // just need signers have this file
+    set<string> setOptions;
+    setOptions.insert("*");
+
+    for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
+    {
+        string strKey = it->string_key;
+        mapForeignRpcDataRet[strKey] = it->value[0];
+
+    }
+}
+
 boost::filesystem::path GetPidFile()
 {
     boost::filesystem::path pathPidFile(GetArg("-pid", "bcexchange.pid"));

File src/util.h Modified

View file
  • Ignore whitespace
  • Hide word diff
 extern std::map<std::string, std::string> mapArgs;
 extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
 extern std::map<std::string, std::string> mapDividendArgs;
+extern std::map<std::string, std::string> mapForeignRpcData;
 extern bool fDebug;
 extern bool fDebugNet;
 extern bool fPrintToConsole;
 #endif
 void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
 void ReadDividendConfigFile(std::map<std::string, std::string>& mapSettingsRet);
+void ReadForeignRpcConfigFile(std::map<std::string, std::string>& mapForeignRpcDataRet);
 #ifdef WIN32
 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
 #endif