使用push_back将Block类实例添加到vector时运行时终止

时间:2017-12-07 07:51:30

标签: c++ c++11

我正在编写一个项目来模拟区块链(过于简化的版本)。我写了一个名为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 ++有点生疏,特别是构建和使用我自己的类。如果有人有任何想法,我真的很感激!如果您需要我的代码的任何其他部分,请告诉我。

0 个答案:

没有答案