简体   繁体   中英

How to add using post API

I am trying to write this project about blockchain it has functions for getting blocks and gets the chain also for adding a new block. What I am struggling with is adding a new block in the chain using API. now the program is adding the block in that way:

const BChain = new bs.BlockChain();

BChain.addBlock({sender: "Customer-A", reciver: "Supplier-4", amount: 100});

BlockChain.js

class Block {
   constructor(index, data, prevHash, timestamp, hash) {


       this.index = index;
      if(timestamp === undefined)  this.timestamp = Math.floor(Date.now() / 1000); else this.timestamp = timestamp;
       this.data = data;
       this.prevHash = prevHash;
       if(hash === undefined)    this.hash=this.getHash();else this.hash = hash;
   }

   getHash() {
       let encript=JSON.stringify(this.data) + this.prevHash + this.index + this.timestamp;
       let hash=crypto.createHmac('sha256', "secret")
       .update(encript)
       .digest('hex');
       return hash;
   }
}


class BlockChain {
   constructor() {
    if(arguments.length>0)
    {
         Object.assign(this, arguments[0]);
         for (var i = 0; i <    this.chain.length; i++) {
            this.chain[i] = new Block(this.chain[i].index, this.chain[i].data, this.chain[i].prevHash, this.chain[i].timestamp,this.chain[i].hash);

        }
    }
    else{
        this.chain = [];
    }
   }


   addBlock(data) {
       let index = this.chain.length;
       let prevHash = this.chain.length !== 0 ? this.chain[this.chain.length - 1].hash : 0;
       let block = new Block(index, data, prevHash);
       this.chain.push(block);
   }


    getBlockByID(id){
        for(let i=0;i<this.chain.length;i++){
            if(this.chain[i].index == id)
            return this.chain[i];
        }

    }

    storeChain(path){
        let str = JSON.stringify(this);
        fs.writeFileSync(path,str);
    }
}

function loadChain(path) {
    let str = fs.readFileSync(path)
    let obj = JSON.parse(str);
    const BChain2 =new BlockChain(obj);
    return BChain2

}


module.exports ={
    Block: Block,
    BlockChain : BlockChain,
    loadChain: loadChain
};

Index.js

const port = 8000;

const app = express();



const BChain = new bs.BlockChain();
BChain.addBlock({sender: "Customer-A", reciver: "Supplier-4", amount: 100});
BChain.addBlock({sender: "OEM-7", reciver: "Customer-B", invoice: '908987897'});
BChain.addBlock({sender: "Test5", reciver: "Customer-A", amount: 75});



const chain_path = path.resolve(__dirname, '..','./data/chain.json');
const data_path = path.resolve(__dirname, '..','./data/');


if (!fs.existsSync(data_path)){
    fs.mkdirSync(data_path);
}


BChain.storeChain(chain_path);


BChain2 = bs.loadChain(chain_path);

app.get('/' ,(req,res)=>{
res.send('Hello World');
});

app.get('/api/getchain' ,(req,res)=>{
    res.send(JSON.stringify(BChain2.chain));
});


app.get('/api/getblock' ,(req,res)=>{
    let id = req.query.id;
    console.log(id);
    res.send(JSON.stringify(BChain2.getBlockByID(id)));

});


app.post('/api/addblock', (req , res) =>{

    const BChain2 = new bs.BlockChain();

    res.send(JSON.stringify(BChain2.addBlock));


});


app.listen(port,()=> console.log("I am alive"));

You do not add any block to blockchain via the api, you make a request to the api endpoint and blockchain will MINE the block. What I mean is you do not send any data. For adding something, you make a "POST" request but in this case you make a get request to the endpoint.

I think your approach is wrong. Because you define a BLOCK class and BLOCKCHAIN class. Those are different classes however mining is a method inside a blockchain. Since every instance of Blockchain class will have this method, it is better to put in porototype.

    Blockchain.prototype.createNewBlock=function(){}

Think Blockchain as a notebook which has unlimited pages. All the pages are same size and you record the transactions inside the pages. Once you filled the page, you have to securely sign it before you pass to next blank page. This signature is called hash. You take the last block's hash, transaction's inside the page and nonce of this page which is the proof of work, and you put inside sha256 function to create a hexadecimal 64 characters of hash. Since you securely signed the page, you need to write a label for this page with those properties: index, nonce, previousBlockHash, currentHash,timestamp and transactions. once it is done, you can add this to the chain, so you should have a property inside Blockchain class to keep track of the blocks.

  this.chain = [];//everytime you create a new block, you push them here

You should have an array of transactions inside your blockchain.

          this.pendingTransactions = [];

Then as you create new transactions, you should populate this array with the new transaction. you also need to create a prototype method for creating transactions.

creating Block method:

Blockchain.prototype.createNewBlock = function(nonce, previousBlockHash, hash) {
  const newBlock = {
    index: this.chain.length + 1,//
    timestamp: Date.now(),
    transactions: this.pendingTransactions,
    nonce: nonce,
    hash: hash,
    previousBlockHash: previousBlockHash
  };
  //after a block is hashed, we cleared up the pendingTransactions[] for the new block 
  this.pendingTransactions = [];
  this.chain.push(newBlock);
  return newBlock;
};

after you created the block, you need to create an endpoint to MINE the block.

app.get("/mine", (req, res) => {
  const lastBlock = blockchain.getLastBlock();// this.chain[this.chain.length - 1]
  const previousBlockHash = lastBlock["hash"];
  const currentBlockData = {
    transactions: blockchain.pendingTransactions,
    index: lastBlock["index"] + 1
  };
  const nonce = blockchain.proofOfWork(previousBlockHash, currentBlockData);//based on your algorithm find the nonce
  const blockHash = blockchain.hashBlock(
    previousBlockHash,
    currentBlockData,
    nonce
  );

  blockchain.createNewTransaction(6.25, "00", "address of the miner");// you need to reward the miner so create a new transaction
  const newBlock = blockchain.createNewBlock(nonce, previousBlockHash, blockHash);

  res.send({ note: "NEW BLOCK IS CREATED", blocks: newBlock });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM