Transaction Pool 생성
export class Chain {
private blockchain: Block[];
private unspentTxOuts: unspentTxOut[];
private transactionPool: ITransaction[];
constructor() {
this.blockchain = [Block.getGenesis()];
this.unspentTxOuts = [];
this.transactionPool = [];
}
-- 생략 --
public getTransactionPool(): ITransaction[] {
return this.transactionPool;
}
public appendTransactionPoll(_Transaction: ITransaction): void {
this.transactionPool.push(_Transaction);
}
public updateTransactionPool(_newBlcok: IBlock): void {
let txPool: ITransaction[] = this.getTransactionPool();
_newBlcok.data.forEach((tx: ITransaction) => {
txPool = txPool.filter((txp) => {
txp.hash !== tx.hash;
});
});
this.transactionPool = txPool;
}
chain Class
에 Transaction Pool
을 빈배열로 생성해주고 Transaction Pool
내용을 가져오는 메서드 getTransactionPool
와 Transaction Pool
에 Transaction
을 추가하는 메서드 appendTransactionPoll
를 만들어주었습니다.
블록을 생성할때 Transaction Pool
내용에 있는 Transaction
들을 data
로 넣어줄때 data
에 넣은 Transaction
들은 삭제해주어야 하니 updateTransactionPool
메서드를 만들어서 TrnasactionPool
의 내용과 새로운 블록의 Transaction
내용을 비교하여 일치하는 것들은 사용한값이니 일치하지 않은 값들을 TransactionPool
에 담아줍니다.
블록을 생성할때 Transaction Pool 내용 넣기 및 Transacion Pool 업데이트
public miningBlock(_account: string): Failable<Block, string> {
const txin: ITxIn = new TxIn('', this.getLastestBlock().height + 1);
const txout: ITxOut = new TxOut(_account, 50);
const transaction: Transaction = new Transaction([txin], [txout]);
return this.addBlcok([transaction, ...this.getTransactionPool()]);
}
public addBlcok(data: ITransaction[]): Failable<Block, string> {
const previousBlock = this.getLastestBlock();
const adjustmentBlock: Block = this.getAdjustmentBlock();
const newBlock = Block.generateBlock(previousBlock, data, adjustmentBlock);
const isVaild = Block.isValidNewBlock(newBlock, previousBlock);
if (isVaild.isError) return { isError: true, error: isVaild.error };
this.blockchain.push(newBlock);
newBlock.data.forEach((_tx: ITransaction) => {
this.updateUTXO(_tx);
});
this.updateTransactionPool(newBlock);
return { isError: false, value: newBlock };
}
mining Block
에서 블록을 생성하려고 할때 addBlock
의 인자값으로 코인베이스 transaction
과 Transaction Pool
에 담긴 Transaction
내용들을 보내줍니다.
addBlock
메서드에서 Block
을 성공적으로 생성했더라면 updateTransactionPool
메서드를 사용하여 블록을 만드는데 사용한 Transaction
을 TransactionPool
배열에서 삭제해줍니다.
블록을 받았을때 Transaction Poll 업데이트
public addToChain(_receviedBlock: Block): Failable<undefined, string> {
const isValid = Block.isValidNewBlock(_receviedBlock, this.getLastestBlock());
if (isValid.isError) return { isError: true, error: isValid.error };
this.blockchain.push(_receviedBlock);
_receviedBlock.data.forEach((tx) => {
this.updateUTXO(tx);
});
this.updateTransactionPool(_receviedBlock);
return { isError: false, value: undefined };
}
-- 중략 --
replaceChain(receivedChain: Block[]): Failable<undefined, string> {
const latestReceivedBlock: Block = receivedChain[receivedChain.length - 1];
const latestBlock: Block = this.getLastestBlock();
if (latestReceivedBlock.height === 0) {
return { isError: true, error: '받은 최신블록이 제네시스 블록입니다. ' };
}
if (latestReceivedBlock.height <= latestBlock.height) {
return { isError: true, error: '자신의 체인이 더 길거나 같습니다. ' };
}
if (latestReceivedBlock.previousHash === latestBlock.hash) {
return { isError: true, error: '블록이 하나 모자랍니다. ' };
}
this.blockchain = receivedChain;
this.blockchain.forEach((_block: IBlock) => {
this.updateTransactionPool(_block);
_block.data.forEach((_tx) => {
this.updateUTXO(_tx);
});
});
return { isError: false, value: undefined };
}
addToChain
메서드와 replaceChain
메서드로 블록을 새로 추가해야할 경우에도 Transaction Pool
를 수정해주어야 합니다.