UNPKG

@btc-vision/transaction

Version:

OPNet transaction library allows you to create and sign transactions for the OPNet network.

106 lines (105 loc) 4.35 kB
import { stringToBuffer } from '../utils/StringToBuffer.js'; import { Address } from '../keypair/Address.js'; import { EpochValidator } from './validator/EpochValidator.js'; import { BinaryWriter } from '../buffer/BinaryWriter.js'; import { MessageSigner } from '../keypair/MessageSigner.js'; export class ChallengeVerification { constructor(data) { this.epochHash = stringToBuffer(data.epochHash); this.epochRoot = stringToBuffer(data.epochRoot); this.targetHash = stringToBuffer(data.targetHash); this.targetChecksum = stringToBuffer(data.targetChecksum); this.startBlock = BigInt(data.startBlock); this.endBlock = BigInt(data.endBlock); this.proofs = Object.freeze(data.proofs.map((proof) => stringToBuffer(proof))); } } export class ChallengeSubmission { constructor(data, epochNumber) { this.epochNumber = epochNumber; this.publicKey = Address.fromString(data.publicKey); this.solution = stringToBuffer(data.solution); this.graffiti = data.graffiti ? stringToBuffer(data.graffiti) : undefined; this.signature = stringToBuffer(data.signature); } verifySignature() { const signatureDataWriter = new BinaryWriter(); signatureDataWriter.writeAddress(this.publicKey); signatureDataWriter.writeU64(this.epochNumber); signatureDataWriter.writeBytes(this.solution); if (this.graffiti) { signatureDataWriter.writeBytes(this.graffiti); } const buffer = signatureDataWriter.getBuffer(); return MessageSigner.verifySignature(this.publicKey, buffer, this.signature); } } export class ChallengeSolution { constructor(data) { this.epochNumber = BigInt(data.epochNumber); this.publicKey = Address.fromString(data.publicKey); this.solution = stringToBuffer(data.solution); this.salt = stringToBuffer(data.salt); this.graffiti = stringToBuffer(data.graffiti); this.difficulty = data.difficulty; this.verification = new ChallengeVerification(data.verification); this.submission = data.submission ? new ChallengeSubmission(data.submission, this.epochNumber + 2n) : data.submission; } static validateRaw(data) { return EpochValidator.validateEpochWinner(data); } verifySubmissionSignature() { if (!this.submission) { throw new Error('No submission provided in request.'); } return this.submission.verifySignature(); } getSubmission() { if (!this.submission) { return; } if (!this.verifySubmissionSignature()) { throw new Error('Invalid submission signature.'); } return this.submission; } verify() { return EpochValidator.validateChallengeSolution(this); } toBuffer() { return this.solution; } toHex() { return '0x' + this.solution.toString('hex'); } toRaw() { return { epochNumber: this.epochNumber.toString(), publicKey: this.publicKey.toHex(), solution: this.toHex(), salt: '0x' + this.salt.toString('hex'), graffiti: '0x' + this.graffiti.toString('hex'), difficulty: this.difficulty, verification: { epochHash: '0x' + this.verification.epochHash.toString('hex'), epochRoot: '0x' + this.verification.epochRoot.toString('hex'), targetHash: '0x' + this.verification.targetHash.toString('hex'), targetChecksum: '0x' + this.verification.targetChecksum.toString('hex'), startBlock: this.verification.startBlock.toString(), endBlock: this.verification.endBlock.toString(), proofs: this.verification.proofs.map((p) => '0x' + p.toString('hex')), }, }; } calculateSolution() { return EpochValidator.calculateSolution(this.verification.targetChecksum, this.publicKey.toBuffer(), this.salt); } checkDifficulty(minDifficulty) { return EpochValidator.checkDifficulty(this.solution, this.verification.targetHash, minDifficulty); } getMiningTargetBlock() { return EpochValidator.getMiningTargetBlock(this.epochNumber); } }