├── block ├── p2pNode.cpp ├── blockChain.cpp ├── cryptography.cpp ├── threadPool.cpp ├── Makefile ├── cryptography.hpp ├── p2pNode.hpp ├── threadPool.hpp ├── blockChain.hpp └── main.cpp ├── holePunching ├── server.cpp └── Makefile ├── README.md ├── Makefile ├── LICENSE └── include └── p2pServer.hpp /block/p2pNode.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangn1989/shacoin/HEAD/block/p2pNode.cpp -------------------------------------------------------------------------------- /block/blockChain.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangn1989/shacoin/HEAD/block/blockChain.cpp -------------------------------------------------------------------------------- /block/cryptography.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangn1989/shacoin/HEAD/block/cryptography.cpp -------------------------------------------------------------------------------- /block/threadPool.cpp: -------------------------------------------------------------------------------- 1 | #include "threadPool.hpp" 2 | 3 | namespace ShaCoin 4 | { 5 | 6 | } -------------------------------------------------------------------------------- /holePunching/server.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangn1989/shacoin/HEAD/holePunching/server.cpp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shacoin 2 | C++从零开始实现的一个简单的基于区块链技术的电子货币记账系统,主要用来学习区块链的底层原理,相关博文[戳这里](https://blog.csdn.net/mumufan05/category_9292513.html)
3 | 还有一个以太坊智能合约的学习笔记,代码比较简单没有上传,看一下博文就够了,相关博文[戳这里](https://blog.csdn.net/mumufan05/article/category/8049023) 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DIRS = block holePunching 2 | 3 | all: subdirs 4 | 5 | .PHONY: subdirs clean 6 | 7 | subdirs: $(DIRS) 8 | for dir in $(DIRS); do make -C $$dir; done 9 | 10 | clean: 11 | @echo $(DIRS) 12 | for dir in $(DIRS); do make clean -C $$dir; done 13 | -------------------------------------------------------------------------------- /block/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | LINK = g++ 3 | CFLAGS = -g -Wall -rdynamic -I../include 4 | LFLAGS = -lcrypto -lssl -pthread 5 | LIBS = 6 | 7 | SRC_DIR = . 8 | SFIX = .cpp 9 | 10 | SOURCES := $(foreach x,${SRC_DIR},\ 11 | $(wildcard \ 12 | $(addprefix ${x}/*,${SFIX}) ) ) 13 | #SOURCES = $(wildcard *.cpp) 14 | OBJECTS = $(patsubst %.cpp, %.o, $(SOURCES)) 15 | TARGET = shacoin 16 | 17 | first: all 18 | 19 | %.o: %.cpp 20 | $(CC) -c $(CFLAGS) -o $@ $< 21 | 22 | all: $(TARGET) 23 | 24 | $(TARGET): $(OBJECTS) 25 | @echo $(TARGET) 26 | $(LINK) $(LIBS) $(OBJECTS) $(CFLAGS) $(LFLAGS) -o ../$(TARGET) 27 | 28 | .PHONY: clean 29 | 30 | clean: 31 | rm -f $(OBJECTS) ../$(TARGET) 32 | -------------------------------------------------------------------------------- /holePunching/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | LINK = g++ 3 | CFLAGS = -g -Wall -rdynamic -I../include 4 | LFLAGS = -lcrypto -lssl 5 | LIBS = 6 | 7 | SRC_DIR = . 8 | SFIX = .cpp 9 | 10 | SOURCES := $(foreach x,${SRC_DIR},\ 11 | $(wildcard \ 12 | $(addprefix ${x}/*,${SFIX}) ) ) 13 | #SOURCES = $(wildcard *.cpp) 14 | OBJECTS = $(patsubst %.cpp, %.o, $(SOURCES)) 15 | TARGET = p2pServer 16 | 17 | first: all 18 | 19 | %.o: %.cpp 20 | $(CC) -c $(CFLAGS) $(LFLAGS) -o $@ $< 21 | 22 | all: $(TARGET) 23 | 24 | $(TARGET): $(OBJECTS) 25 | @echo $(TARGET) 26 | $(LINK) $(LIBS) $(OBJECTS) $(CFLAGS) $(LFLAGS) -o ../$(TARGET) 27 | 28 | .PHONY: clean 29 | 30 | clean: 31 | rm -f $(OBJECTS) ../$(TARGET) 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 zhangn1989 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /include/p2pServer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __P2PSERVER_H 2 | #define __P2PSERVER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace ShaCoin 12 | { 13 | #define ALITEST 0 14 | 15 | #if ALITEST 16 | #define SERVERIP "47.94.162.207" 17 | #define LOCALPORT 10000 18 | //#define IF_NAME "eth0" 19 | #else //1 20 | #define SERVERIP "192.168.180.133" 21 | #define LOCALPORT 20000 22 | //#define IF_NAME "ens33" 23 | #endif //1 24 | 25 | #define SERVERPORT 9527 26 | 27 | typedef enum 28 | { 29 | cmd_register = 0x1000, 30 | cmd_unregister, 31 | cmd_getnode, 32 | cmd_max 33 | } Command; 34 | 35 | typedef struct st_node 36 | { 37 | int count; 38 | char queryIp[16]; 39 | int queryPort; 40 | char recvIp[16]; 41 | int recvPort; 42 | 43 | bool operator == (const struct st_node & value) const 44 | { 45 | return 46 | this->count == value.count && 47 | this->queryPort == value.queryPort && 48 | this->recvPort == value.recvPort && 49 | !strcmp(this->queryIp, value.queryIp) && 50 | !strcmp(this->recvIp, value.recvIp); 51 | } 52 | } __attribute__((packed)) 53 | Node; 54 | 55 | typedef struct st_nodeinfo 56 | { 57 | Command cmd; 58 | Node node; 59 | } __attribute__((packed)) 60 | NodeInfo; 61 | } 62 | #endif // __P2PSERVER_H -------------------------------------------------------------------------------- /block/cryptography.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __CRYPTOGRAPHY_H 2 | #define __CRYPTOGRAPHY_H 3 | 4 | #include 5 | #include 6 | 7 | namespace ShaCoin 8 | { 9 | typedef struct __keydata 10 | { 11 | size_t len; 12 | unsigned char key[256]; 13 | } KeyData; 14 | 15 | typedef struct __KeyPair 16 | { 17 | KeyData pubKey; 18 | KeyData priKey; 19 | } KeyPair; 20 | 21 | class Cryptography 22 | { 23 | public: 24 | static std::string GetHash(void const* buffer, std::size_t len); 25 | static std::string Base64Encode(const void*buff, int len); 26 | static void Base64Decode(const std::string &str64, void *outbuff, size_t outsize, size_t *outlen); 27 | static void Createkey(KeyPair &keyPair); 28 | static bool Signature(const KeyData &priKey, const void *data, int datalen, unsigned char *sign, size_t signszie, unsigned int *signlen); 29 | static int Verify(const KeyData &pubkey, const char *data, int datalen, const unsigned char *sign, size_t signszie, unsigned int signlen); 30 | static std::string StringToLower(const std::string &str); 31 | static bool CompareNoCase(const std::string &strA, const std::string &strB); 32 | static std::vector StringSplit(const std::string &str, const char sep); 33 | 34 | protected: 35 | Cryptography(); 36 | virtual ~Cryptography(); 37 | 38 | private: 39 | 40 | }; 41 | } 42 | 43 | #endif //__CRYPTOGRAPHY_H 44 | -------------------------------------------------------------------------------- /block/p2pNode.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __P2PNODE_H 2 | #define __P2PNODE_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "p2pServer.hpp" 10 | #include "threadPool.hpp" 11 | #include "cryptography.hpp" 12 | #include "blockChain.hpp" 13 | 14 | namespace ShaCoin 15 | { 16 | 17 | #define MAX_UDP_SIZE 65507 18 | #define MAX_P2P_SIZE (MAX_UDP_SIZE - sizeof(int) *2 - sizeof(P2PCommand) - sizeof(size_t) - 64) 19 | 20 | typedef enum 21 | { 22 | p2p_transaction = 0x2000, 23 | p2p_bookkeeping, 24 | p2p_result, 25 | p2p_merge, 26 | p2p_blockchain, 27 | p2p_max 28 | } P2PCommand; 29 | 30 | typedef struct st_broadcast 31 | { 32 | KeyData pubkey; 33 | char json[1024]; 34 | unsigned int signlen; 35 | unsigned char sign[1024]; 36 | } __attribute__((packed)) 37 | BroadcastMessage; 38 | 39 | typedef struct st_p2pMessage 40 | { 41 | int index; 42 | int total; 43 | char messHash[64]; 44 | P2PCommand cmd; 45 | size_t length; 46 | char mess[MAX_P2P_SIZE]; 47 | } __attribute__((packed)) 48 | P2PMessage; 49 | 50 | typedef struct st_p2pResult 51 | { 52 | int index; 53 | char messHash[64]; 54 | 55 | bool operator == (const struct st_p2pResult & value) const 56 | { 57 | return 58 | this->index == value.index && 59 | !strcmp(this->messHash, value.messHash); 60 | } 61 | } __attribute__((packed)) 62 | P2PResult; 63 | 64 | class P2PNode 65 | { 66 | public: 67 | static P2PNode *Instance(const char *if_name); 68 | void Listen(); 69 | void Broadcast(P2PCommand cmd, const BroadcastMessage &bm); 70 | void MergeChain(); 71 | 72 | protected: 73 | P2PNode(const char *if_name); 74 | virtual ~P2PNode(); 75 | 76 | private: 77 | int m_sock; 78 | Node m_selfNode; 79 | Node m_otherNode; 80 | char *m_otherIP; 81 | int m_otherPort; 82 | pthread_t m_tid; 83 | pthread_mutex_t m_mutexPack; 84 | pthread_mutex_t m_mutexResult; 85 | 86 | struct sockaddr_in m_serverAddr; 87 | struct sockaddr_in m_localAddr; 88 | struct sockaddr_in m_recvAddr; 89 | 90 | typedef struct st_package 91 | { 92 | int total; 93 | char messHash[64]; 94 | P2PCommand cmd; 95 | std::map mapMess; 96 | 97 | bool operator == (const struct st_package & value) const 98 | { 99 | return 100 | this->total == value.total && 101 | this->cmd == value.cmd && 102 | !strcmp(this->messHash, value.messHash); 103 | } 104 | } Package; 105 | 106 | std::list m_lstPackage; 107 | std::list m_lstResult; 108 | 109 | static void *threadFunc(void *arg); 110 | void threadHandler(); 111 | void combinationPackage(P2PMessage &mess); 112 | int get_local_ip(const char *ifname, char *ip); 113 | void sendMessage(P2PMessage &mess); 114 | void sendBlockChain(); 115 | }; 116 | } 117 | #endif //__P2PNODE_H 118 | -------------------------------------------------------------------------------- /block/threadPool.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __THREADPOOL_H 2 | #define __THREADPOOL_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace ShaCoin 9 | { 10 | template 11 | class ThreadPool 12 | { 13 | public: 14 | ThreadPool(int count); 15 | virtual ~ThreadPool(); 16 | 17 | void addTask(T1 t); 18 | int start(); 19 | void stop(); 20 | 21 | inline void setTaskFunc(T2 *t2, void(T2::*taskFunc) (T1 &t)) 22 | { 23 | m_t2 = t2; 24 | m_taskFunc = taskFunc; 25 | } 26 | 27 | private: 28 | int m_count; 29 | bool m_bStop; 30 | std::queue m_queue; 31 | std::vector m_vecTid; 32 | T2 *m_t2; 33 | void (T2::*m_taskFunc) (T1 &t); 34 | 35 | static pthread_mutex_t m_mutexPack; 36 | static pthread_cond_t m_cond; 37 | 38 | static void *threadFunc(void *arg); 39 | void threadHandler(); 40 | }; 41 | 42 | template 43 | pthread_mutex_t ThreadPool::m_mutexPack = PTHREAD_MUTEX_INITIALIZER; 44 | template 45 | pthread_cond_t ThreadPool::m_cond = PTHREAD_COND_INITIALIZER; 46 | 47 | template 48 | ThreadPool::ThreadPool(int count) 49 | { 50 | m_count = count; 51 | } 52 | 53 | template 54 | ThreadPool::~ThreadPool() 55 | { 56 | if (!m_bStop) 57 | stop(); 58 | } 59 | 60 | template 61 | void ThreadPool::addTask(T1 t) 62 | { 63 | pthread_mutex_lock(&m_mutexPack); 64 | m_queue.push(t); 65 | pthread_mutex_unlock(&m_mutexPack); 66 | pthread_cond_signal(&m_cond); 67 | } 68 | 69 | template 70 | int ThreadPool::start() 71 | { 72 | int i; 73 | pthread_t tid; 74 | 75 | if (!m_t2) 76 | return 0; 77 | 78 | if (!m_taskFunc) 79 | return 0; 80 | 81 | if (m_count < 1) 82 | return 0; 83 | 84 | m_bStop = false; 85 | 86 | for (i = 0; i < m_count; ++i) 87 | { 88 | if (pthread_create(&tid, NULL, threadFunc, this) == 0) 89 | m_vecTid.push_back(tid); 90 | } 91 | 92 | return i; 93 | } 94 | 95 | template 96 | void ThreadPool::stop() 97 | { 98 | m_bStop = true; 99 | pthread_cond_broadcast(&m_cond); 100 | 101 | std::vector::iterator it; 102 | for (it = m_vecTid.begin(); it != m_vecTid.end(); ++it) 103 | pthread_join(*it, NULL); 104 | } 105 | 106 | template 107 | void *ThreadPool::threadFunc(void *arg) 108 | { 109 | ThreadPool *p = (ThreadPool*)arg; 110 | p->threadHandler(); 111 | return NULL; 112 | } 113 | 114 | template 115 | void ThreadPool::threadHandler() 116 | { 117 | while (!m_bStop) 118 | { 119 | pthread_mutex_lock(&m_mutexPack); 120 | while (m_queue.size() <= 0) 121 | { 122 | pthread_cond_wait(&m_cond, &m_mutexPack); 123 | if (m_bStop) 124 | { 125 | pthread_mutex_unlock(&m_mutexPack); 126 | return ; 127 | } 128 | } 129 | T1 t = m_queue.front(); 130 | m_queue.pop(); 131 | pthread_mutex_unlock(&m_mutexPack); 132 | (m_t2->*m_taskFunc)(t); 133 | } 134 | } 135 | } 136 | 137 | #endif 138 | -------------------------------------------------------------------------------- /block/blockChain.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __BLOCK_H 2 | #define __BLOCK_H 3 | 4 | /* 5 | 6 | block = { 7 | 'index': 1, 8 | 'timestamp': 1506057125.900785, 9 | 'transactions': [ 10 | { 11 | 'sender': "8527147fe1f5426f9dd545de4b27ee00", 12 | 'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f", 13 | 'amount': 5, 14 | } 15 | ], 16 | 'proof': 324984774000, 17 | 'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" 18 | } 19 | 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "cryptography.hpp" 28 | 29 | namespace ShaCoin 30 | { 31 | typedef struct __transactions 32 | { 33 | std::string sender; 34 | std::string recipient; 35 | float amount; 36 | 37 | bool operator == (const struct __transactions & value) const 38 | { 39 | return 40 | this->sender == value.sender && 41 | this->recipient == value.recipient && 42 | this->amount == value.amount; 43 | } 44 | }Transactions; 45 | 46 | typedef struct __block 47 | { 48 | int index; 49 | time_t timestamp; 50 | std::list lst_ts; 51 | long int proof; 52 | std::string previous_hash; 53 | 54 | bool operator == (const struct __block & value) const 55 | { 56 | return 57 | this->index == value.index && 58 | this->timestamp == value.timestamp && 59 | this->previous_hash == value.previous_hash && 60 | this->lst_ts == value.lst_ts && 61 | this->proof == value.proof; 62 | } 63 | } Block; 64 | 65 | class BlockChain 66 | { 67 | public: 68 | static BlockChain *Instance(); 69 | 70 | std::string GetJsonFromBlock(Block &block); 71 | std::string GetJsonFromTransactions(Transactions &ts); 72 | Block GetBlockFromJson(const std::string &json); 73 | Transactions GetTransactionsFromJson(const std::string &json); 74 | std::string GetJsonFromBlockList(); 75 | std::string GetJsonFromTransactionsList(); 76 | std::list GetBlockListFromJson(const std::string &json); 77 | void GetTransactionsListFromJson(const std::string &json); 78 | std::string CreateNewAddress(const KeyPair &keyPair); 79 | Transactions CreateTransactions(const std::string &sender, const std::string &recipient, float amount); 80 | Block CreateBlock(int index, time_t timestamp, long int proof); 81 | int WorkloadProof(int last_proof); 82 | bool WorkloadVerification(int proof); 83 | std::string Mining(const std::string &addr); 84 | int CheckBalances(const std::string &addr); 85 | void DeleteDuplicateTransactions(const Block &block); 86 | void MergeBlockChain(const std::string &json); 87 | 88 | inline void InsertBlock(const Block &block) 89 | { 90 | pthread_mutex_lock(&m_mutexBlock); 91 | if (m_lst_block.end() == std::find(m_lst_block.begin(), m_lst_block.end(), block)) 92 | { 93 | m_lst_block.push_back(block); 94 | } 95 | pthread_mutex_unlock(&m_mutexBlock); 96 | } 97 | 98 | inline void InsertTransactions(const Transactions &ts) 99 | { 100 | pthread_mutex_lock(&m_mutexTs); 101 | if (m_lst_ts.end() == std::find(m_lst_ts.begin(), m_lst_ts.end(), ts)) 102 | { 103 | m_lst_ts.push_back(ts); 104 | } 105 | pthread_mutex_unlock(&m_mutexTs); 106 | } 107 | 108 | inline Block GetLastBlock() 109 | { 110 | Block block; 111 | pthread_mutex_lock(&m_mutexBlock); 112 | block = m_lst_block.back(); 113 | pthread_mutex_unlock(&m_mutexBlock); 114 | return block; 115 | } 116 | 117 | protected: 118 | BlockChain(); 119 | virtual ~BlockChain(); 120 | 121 | private: 122 | std::list m_lst_ts; 123 | std::list m_lst_block; 124 | pthread_mutex_t m_mutexTs; 125 | pthread_mutex_t m_mutexBlock; 126 | }; 127 | } 128 | 129 | #endif //__BLOCK_H -------------------------------------------------------------------------------- /block/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "p2pServer.hpp" 6 | #include "p2pNode.hpp" 7 | #include "blockChain.hpp" 8 | #include "cryptography.hpp" 9 | 10 | 11 | int main(int argc, char **argv) 12 | { 13 | if (argc < 2) 14 | { 15 | std::cout << "argc error!" << std::endl; 16 | return 0; 17 | } 18 | 19 | std::string strInputCmd; 20 | ShaCoin::P2PNode *p2pNode = ShaCoin::P2PNode::Instance(argv[1]); 21 | p2pNode->Listen(); 22 | 23 | ShaCoin::BlockChain *blockChain = ShaCoin::BlockChain::Instance(); 24 | 25 | while (1) 26 | { 27 | std::cout << "Please input command:" << std::endl; 28 | getline(std::cin, strInputCmd); 29 | std::vector vec_str = ShaCoin::Cryptography::StringSplit(strInputCmd, ' '); 30 | 31 | if (vec_str.size() < 1) 32 | continue; 33 | 34 | if (ShaCoin::Cryptography::CompareNoCase(vec_str[0], "addr")) 35 | { 36 | ShaCoin::KeyPair keyPair; 37 | ShaCoin::Cryptography::Createkey(keyPair); 38 | std::string addr = blockChain->CreateNewAddress(keyPair); 39 | 40 | std::cout << "Public key is " << ShaCoin::Cryptography::Base64Encode(keyPair.pubKey.key, keyPair.pubKey.len) << std::endl; 41 | std::cout << "Private key is " << ShaCoin::Cryptography::Base64Encode(keyPair.priKey.key, keyPair.priKey.len) << std::endl; 42 | std::cout << "Address is " << addr << std::endl; 43 | continue; 44 | } 45 | else if (ShaCoin::Cryptography::CompareNoCase(vec_str[0], "ts")) 46 | { 47 | if (vec_str.size() < 6) 48 | continue; 49 | 50 | ShaCoin::KeyPair kp; 51 | memset(&kp, 0, sizeof(kp)); 52 | ShaCoin::Cryptography::Base64Decode(vec_str[4], kp.pubKey.key, sizeof(kp.pubKey.key), &kp.pubKey.len); 53 | ShaCoin::Cryptography::Base64Decode(vec_str[5], kp.priKey.key, sizeof(kp.priKey.key), &kp.priKey.len); 54 | 55 | ShaCoin::Transactions ts = blockChain->CreateTransactions(vec_str[1], vec_str[2], stof(vec_str[3])); 56 | std::string strTsJson = blockChain->GetJsonFromTransactions(ts); 57 | std::string strHash = ShaCoin::Cryptography::GetHash(strTsJson.c_str(), strTsJson.length()); 58 | 59 | ShaCoin::BroadcastMessage tm; 60 | memset(&tm, 0, sizeof(tm)); 61 | tm.pubkey = kp.pubKey; 62 | strncpy(tm.json, strTsJson.c_str(), strTsJson.length()); 63 | if (ShaCoin::Cryptography::Signature(kp.priKey, strHash.c_str(), strHash.length(), tm.sign, sizeof(tm.sign), &tm.signlen)) 64 | p2pNode->Broadcast(ShaCoin::p2p_transaction, tm); 65 | 66 | continue; 67 | } 68 | else if (ShaCoin::Cryptography::CompareNoCase(vec_str[0], "Mining")) 69 | { 70 | if (vec_str.size() < 2) 71 | continue; 72 | 73 | int count; 74 | if (vec_str.size() >= 3) 75 | count = stoi(vec_str[2]); 76 | else 77 | count = 1; 78 | 79 | if (count < 1) 80 | count = 1; 81 | 82 | while (count) 83 | { 84 | std::string strMiningJson = blockChain->Mining(vec_str[1]); 85 | 86 | ShaCoin::BroadcastMessage bmMining; 87 | memset(&bmMining, 0, sizeof(bmMining)); 88 | strncpy(bmMining.json, strMiningJson.c_str(), strMiningJson.length()); 89 | p2pNode->Broadcast(ShaCoin::p2p_bookkeeping, bmMining); 90 | 91 | --count; 92 | } 93 | 94 | continue; 95 | } 96 | else if (ShaCoin::Cryptography::CompareNoCase(vec_str[0], "Merge")) 97 | { 98 | p2pNode->MergeChain(); 99 | continue; 100 | } 101 | else if (ShaCoin::Cryptography::CompareNoCase(vec_str[0], "Balances")) 102 | { 103 | if(vec_str.size() < 2) 104 | continue; 105 | 106 | std::cout << blockChain->CheckBalances(vec_str[1]) << std::endl; 107 | 108 | continue; 109 | } 110 | else if (ShaCoin::Cryptography::CompareNoCase(vec_str[0], "show")) 111 | { 112 | std::cout << blockChain->GetJsonFromBlockList() << std::endl; 113 | 114 | continue; 115 | } 116 | else if (ShaCoin::Cryptography::CompareNoCase(vec_str[0], "help")) 117 | { 118 | std::cout << " create a new address and key pair." << std::endl; 119 | std::cout << " initiate a new benefit,the parameters are in order:send address, recipient address, amount." << std::endl; 120 | std::cout << " mining.the parameters are in order:mining address,number of mining times" << std::endl; 121 | std::cout << " blockchain merge." << std::endl; 122 | std::cout << " get the balance.the parameters are in order:address" << std::endl; 123 | std::cout << " display blockchain in json format." << std::endl; 124 | std::cout << " quit." << std::endl; 125 | std::cout << " show this message." << std::endl; 126 | continue; 127 | } 128 | else if (ShaCoin::Cryptography::CompareNoCase(vec_str[0], "quit")) 129 | { 130 | break; 131 | } 132 | } 133 | 134 | return 0; 135 | } 136 | --------------------------------------------------------------------------------