mirror of
https://github.com/benjamin-wilson/public-pool.git
synced 2026-09-29 09:05:06 -07:00
mining submit work
This commit is contained in:
+44
-14
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user