SenShaMart/blockchain/payment.js
2023-07-13 11:32:02 +10:00

88 lines
No EOL
2 KiB
JavaScript

const ChainUtil = require('../util/chain-util');
const outputValidation = {
publicKey: ChainUtil.validateIsPublicKey,
amount: ChainUtil.createValidateIsIntegerWithMin(1)
};
function validateOutputs(t) {
let validateRes = ChainUtil.validateArray(t, function (output) {
return ChainUtil.validateObject(output, outputValidation);
});
if (!validateRes.result) {
return validateRes
}
if (t.length <= 0) {
return {
result: false,
reason: "Outputs length isn't positive"
};
}
return {
result: true
};
}
const baseValidation = {
input: ChainUtil.validateIsPublicKey,
counter: ChainUtil.createValidateIsIntegerWithMin(1),
rewardAmount: ChainUtil.createValidateIsIntegerWithMin(0),
outputs: validateOutputs,
signature: ChainUtil.validateIsSignature
}
class Payment {
constructor(senderKeyPair, counter, outputs, rewardAmount) {
this.input = senderKeyPair.getPublic().encode('hex');
this.counter = counter;
this.rewardAmount = rewardAmount;
this.outputs = outputs;
this.signature = senderKeyPair.sign(Payment.hashToSign(this));
const verification = Payment.verify(this);
if (!verification.result) {
throw new Error(verification.reason);
}
}
static hashToSign(transaction) {
return ChainUtil.hash([
transaction.counter,
transaction.rewardAmount,
transaction.outputs]);
}
static createOutput(recipient, amount) {
return {
publicKey: recipient,
amount: amount
};
}
static verify(transaction) {
const validationRes = ChainUtil.validateObject(transaction, baseValidation);
if (!validationRes.result) {
return validationRes;
}
const verifyRes = ChainUtil.verifySignature(
transaction.input,
transaction.signature,
Payment.hashToSign(transaction));
if (!verifyRes.result) {
return verifyRes;
}
return {
result: true,
};
}
static name() {
return "Payment";
}
}
module.exports = Payment;