mining submit work

This commit is contained in:
Ben Wilson
2023-06-11 13:17:07 -04:00
parent 4ed46315b1
commit e8a5e263b0
6 changed files with 142 additions and 45 deletions
+44 -14
View File
@@ -5,11 +5,17 @@ import { IBlockTemplate, IBlockTemplateTx } from './bitcoin-rpc/IBlockTemplate';
import { randomUUID } from 'crypto';
import { MerkleTree } from 'merkletreejs'
interface AddressObject {
address: string;
percentage: number;
}
export class MiningJob {
public id: number;
public method: eResponseMethod.MINING_NOTIFY;
public params: string[];
public target: string;
public merkleRoot: Buffer;
public job_id: string; // ID of the job. Use this ID while submitting share generated from this job.
public prevhash: string; // The hex-encoded previous block hash.
@@ -21,9 +27,12 @@ export class MiningJob {
public ntime: string; // Current ntime/
public clean_jobs: boolean; // When true, server indicates that submitting shares from previous jobs don't have a sense and such shares will be rejected. When this flag is set, miner should also drop all previous jobs too.
public response: string;
constructor(blockTemplate: IBlockTemplate) {
this.job_id = randomUUID();
this.target = blockTemplate.target;
this.prevhash = blockTemplate.previousblockhash;
this.version = blockTemplate.version.toString();
@@ -39,7 +48,7 @@ export class MiningJob {
console.log('TRANSACTION FEES', transactionFees);
console.log('MINING REWARD', miningReward);
const { coinbasePart1, coinbasePart2 } = this.createCoinbaseTransaction('', blockTemplate.height, transactionFees + miningReward);
const { coinbasePart1, coinbasePart2 } = this.createCoinbaseTransaction([{ address: '', percentage: 100 }], blockTemplate.height, transactionFees + miningReward);
this.coinb1 = coinbasePart1;
this.coinb2 = coinbasePart2;
@@ -62,6 +71,8 @@ export class MiningJob {
this.merkle_branch = branch;
this.merkleRoot = tree.getRoot();
}
private calculateMiningReward(blockHeight: number): number {
@@ -81,26 +92,43 @@ export class MiningJob {
return buffer.toString('hex');
}
private createCoinbaseTransaction(address: string, blockHeight: number, reward: number): { coinbasePart1: string, coinbasePart2: string } {
private createCoinbaseTransaction(addresses: AddressObject[], blockHeight: number, reward: number): { coinbasePart1: string, coinbasePart2: string } {
// Generate coinbase script
const coinbaseScript = `03${blockHeight.toString(16).padStart(8, '0')}54696d652026204865616c74682021`;
// Create coinbase transaction
const version = '01000000';
const inputs = '01' + '0000000000000000000000000000000000000000000000000000000000000000ffffffff';
const inputCount = '01';
const inputs = '0000000000000000000000000000000000000000000000000000000000000000ffffffff';
const coinbaseScriptSize = coinbaseScript.length / 2;
const coinbaseScriptBytes = coinbaseScriptSize.toString(16).padStart(2, '0');
const coinbaseTransaction = inputs + coinbaseScriptBytes + coinbaseScript + '00000000';
const coinbaseTransaction = inputCount + inputs + coinbaseScriptBytes + coinbaseScript + '00000000';
// Create output
const outputCount = '01';
const satoshis = '0f4240'; // 6.25 BTC in satoshis (1 BTC = 100,000,000 satoshis)
const script = '1976a914' + address + '88ac'; // Change this to your desired output script
const locktime = '00000000';
// Create outputs
const outputCount = addresses.length;
const outputCountHex = outputCount.toString(16).padStart(2, '0');
let remainingPayout = reward;
const outputs = addresses
.map((addressObj) => {
const percentage = addressObj.percentage / 100;
const satoshis = Math.floor(reward * percentage).toString(16).padStart(16, '0');
remainingPayout -= parseInt(satoshis, 16);
const script = '1976a914' + Buffer.from(addressObj.address, 'hex').toString('hex') + '88ac'; // Convert address to hex
return satoshis + script;
})
.join('');
// Distribute any remaining satoshis to the first address
const firstAddressSatoshis = (parseInt(outputs.substring(0, 16), 16) + remainingPayout).toString(16).padStart(16, '0');
const firstAddressOutput = firstAddressSatoshis + outputs.substring(16);
const modifiedOutputs = firstAddressOutput + outputs.slice(16);
// Combine coinbasePart1 and coinbasePart2
const coinbasePart1 = version + coinbaseTransaction + outputCount + satoshis;
const coinbasePart2 = script + locktime;
const coinbasePart1 = version + coinbaseTransaction + outputCountHex;
const coinbasePart2 = modifiedOutputs + '00000000';
return { coinbasePart1, coinbasePart2 };
}
@@ -110,9 +138,9 @@ export class MiningJob {
}
public response() {
public constructResponse() {
return {
const job = {
id: 0,
method: eResponseMethod.MINING_NOTIFY,
params: [
@@ -126,7 +154,9 @@ export class MiningJob {
this.ntime,
this.clean_jobs
]
}
};
this.response = JSON.stringify(job);
}