我正在编写一个项目来模拟区块链(过于简化的版本)。我写了一个名为Block
的类来管理区块链中的块:
(您可能会注意到我引用了一些未在顶部的#include
语句中列出的其他类/标题。据我所知,所有依赖项都由makefile充分处理。)< / p>
#include "Block.h"
/**** constructors ****/
Block::Block()
{
prevHash = "";
merkleRoot = "";
nonce = "";
}
Block::Block(std::string str)
{
std::vector<std::string> strings;
std::string word;
int pos = str.find(" ");
while(pos != std::string::npos)
{
word = str.substr(0, pos);
strings.push_back(word);
pos = str.find(" ");
str = str.substr(pos+1);
}
if(strings.size() != 3)
{
prevHash = "";
merkleRoot = "";
nonce = "";
}
else
{
prevHash = strings.at(0);
merkleRoot = strings.at(1);
nonce = strings.at(2);
}
}
Block::Block(std::vector<Block> &blocks, std::string merkle)
{
// use prev block from Block vector to get hash of prev block
Block prevBlock = blocks.at(0);
prevHash = picosha2::hash256_hex_string(utils::hexToString(prevBlock.toString()));
merkleRoot = merkle;
nonce = mine();
}
Block::Block(std::string hash, std::string merkle, std::string n)
{
prevHash = hash;
merkleRoot = merkle;
nonce = n;
}
Block::Block(const Block &b) //copy constructor
{
prevHash = b.getPrevHash();
merkleRoot = b.getMerkleRoot();
nonce = b.mine();
}
Block::~Block() //destructor
{
}
/**** public methods ****/
bool Block::isValid()
{
std::string hash = picosha2::hash256_hex_string(utils::hexToString(this->toString()));
if(hash[0] == '0')
return true;
return false;
}
std::string Block::toString()
{
return prevHash + merkleRoot + nonce;
}
std::string Block::mine() const
{
// brute force nonces so hash begins with zero/block is valid
for(int i = 0; i < pow(2, 8); i++)
{
Block temp(this->getPrevHash(), this->getMerkleRoot(), std::to_string(i));
if(temp.isValid())
{
// convert i to hex string and return
std::stringstream stream;
stream << std::hex << std::to_string(i);
return stream.str();
}
}
std::cout << "No nonce found." << std::endl;
return "";
}
// calculate this block's hash
std::string Block::calcHash()
{
std::string hash = picosha2::hash256_hex_string(utils::hexToString(this->toString()));
return hash;
}
std::string Block::getPrevHash() const
{
return prevHash;
}
std::string Block::getMerkleRoot() const
{
return merkleRoot;
}
std::string Block::getNonce() const
{
return nonce;
}
所以,实际问题:我无法将Block类的实例添加到我的Blocks向量(或块数组中,就此而言;我也尝试过)。我可以创建一个Block,打印出来,基本上我想要的任何东西。但是如果我将它添加到矢量,我的计算机会抛出运行时错误。下面是我的主文件和运行的输出:
#include "main.h"
// function prototype
std::string merkleRoot(std::vector<Transaction> &);
int main(int argc, char ** argv)
{
int numblocks = 0;
int numtransactions = 0;
std::vector<Block> blocks;
std::vector<Transaction> transactions;
if(argc != 3)
{
std::cout << "Usage: main [blockchain.txt] [transaction.txt]" << std::endl;
exit(1);
}
std::string blockchainFileName = argv[1];
std::string transactionFileName = argv[2];
std::cout << "blockchainFileName: " << blockchainFileName << std::endl;
std::cout << "transactionFileName: " << transactionFileName << std::endl;
std::ifstream blockchainFile(blockchainFileName);
std::ifstream transactionFile(transactionFileName);
if(!blockchainFile)
{
std::cout << "Cannot open " << blockchainFileName << std::endl;
exit(1);
}
if(!transactionFile)
{
std::cout << "Cannot open " << transactionFileName << std::endl;
exit(1);
}
/*** Read in blockchain ***/
std::string line;
int count = 0;
while(std::getline(blockchainFile, line))
{
std::vector<Block> temp;
std::cout << "line number " << ++count << std::endl;
Block newBlock(line);
std::cout << newBlock.toString() << std::endl;
blocks.push_back(newBlock);
}
}
输出:
$ ./main textfiles/blockchain_1.txt textfiles/transactions_1.txt
blockchainFileName: textfiles/blockchain_1.txt
transactionFileName: textfiles/transactions_1.txt
line number 1
026765a1c8235d4ac23d2582cda3b9f5c062f805540320173eb9e9148c0dc518704b42e4b11ca131b443c2b02a07ec0b45407f1b125027e3e68b86ace692445800000001
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string
Abort trap: 6
blockchain_1.txt
档案:
026765a1c8235d4ac23d2582cda3b9f5c062f805540320173eb9e9148c0dc518 704b42e4b11ca131b443c2b02a07ec0b45407f1b125027e3e68b86ace6924458 00000001
0b53181ae351f4508363cdc3e8fb3e819fb706c4ba98a3005a980a837561074a 06aa7a8cbda7ac4351c0cae116c589c2eb0ca96cb4c90844812945cb4ffe27c5 00000019
000000000000000000ad6e90c0790e83760a9d13728c23474352a2c8c7a6e0eb 2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3 0000000f
transactions_1.txt
档案:
Bob Alice 5.0
Alice Bob 1.0
John Bill 2.4
Bill Alice 1.3
John Bill 2.7
Bob John 7.9
Tom Todd 4.5
Todd Bob 12.0
我现在已经挖了好几个小时了,而且我有点不合时宜。我会说我对C ++有点生疏,特别是构建和使用我自己的类。如果有人有任何想法,我真的很感激!如果您需要我的代码的任何其他部分,请告诉我。