SenShaMart/wallet/transaction.js
2022-11-24 12:03:27 +11:00

69 lines
No EOL
1.9 KiB
JavaScript

const ChainUtil = require('../chain-util');
const { MINING_REWARD } = require('../config');
class Transaction {
constructor() {
this.id = ChainUtil.id();
this.input = null;
this.outputs = [];
}
update(senderWallet, recipient, amount) {
const senderOutput = this.outputs.find(output => output.address === senderWallet.publicKey);
if (amount > senderOutput.amount) {
console.log(`Amount: ${amount} exceeds balance.`);
return;
}
senderOutput.amount = senderOutput.amount - amount;
this.outputs.push({ amount, address: recipient });
Transaction.signTransaction(this, senderWallet);
return this;
}
static transactionWithOutputs(senderWallet, outputs) {
const transaction = new this();
transaction.outputs.push(...outputs);
Transaction.signTransaction(transaction, senderWallet);
return transaction;
}
static newTransaction(senderWallet, recipient, amount) {
if (amount > senderWallet.balance) {
console.log(`Amount: ${amount} exceeds balance.`);
return;
}
return Transaction.transactionWithOutputs(senderWallet, [
{ amount: senderWallet.balance - amount, address: senderWallet.publicKey },
{ amount, address: recipient }
]);
}
static rewardTransaction(minerWallet, blockchainWallet) {
return Transaction.transactionWithOutputs(blockchainWallet, [{
amount: MINING_REWARD, address: minerWallet.publicKey
}]);
}
static signTransaction(transaction, senderWallet) {
transaction.input = {
timestamp: Date.now(),
amount: senderWallet.balance,
address: senderWallet.publicKey,
signature: senderWallet.sign(ChainUtil.hash(transaction.outputs))
}
}
static verifyTransaction(transaction) {
return ChainUtil.verifySignature(
transaction.input.address,
transaction.input.signature,
ChainUtil.hash(transaction.outputs)
);
}
}
module.exports = Transaction;