Skip to content

Commit

Permalink
v0.4.3, added correct parsing of auxpow, transaction fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
cf committed Aug 5, 2024
1 parent 8387f3b commit a8cf59b
Show file tree
Hide file tree
Showing 17 changed files with 548 additions and 103 deletions.
1 change: 1 addition & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ module.exports = {
singleQuote: true,
trailingComma: 'es5',
arrowParens: 'always',
semi: true,
printWidth: 80,
}
11 changes: 9 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "doge-sdk",
"version": "0.4.2",
"version": "0.5.0",
"description": "An ultra-lightweight, fully featured dogecoin library for the browser and node.js.",
"types": "dist/types/index.d.js",
"exports": {
Expand Down Expand Up @@ -66,6 +66,7 @@
"@types/jest": "^29.5.12",
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"doge-test-data": "^0.2.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^8.10.0",
"eslint-plugin-prettier": "^5.1.3",
Expand Down
92 changes: 92 additions & 0 deletions src/block/auxpow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Transaction } from '../transaction';
import { BytesBuilder } from '../utils/bytesBuilder';
import { BytesReader } from '../utils/bytesReader';
import { hexToU8Array, u8ArrayToHex } from '../utils/data';
import { IMerkleBranch, IStandardBlockHeader } from './types';
import {
merkleBranchEncodingLength,
readMerkleBranch,
readStandardBlockHeader,
writeMerkleBranch,
writeStandardBlockHeader,
} from './utils';

class AuxPow {
coinbaseTransaction: Transaction;
blockHash: string;
coinbaseBranch: IMerkleBranch;
blockchainBranch: IMerkleBranch;
parentBlock: IStandardBlockHeader;

constructor(
coinbaseTransaction: Transaction,
blockHash: string,
coinbaseBranch: IMerkleBranch,
blockchainBranch: IMerkleBranch,
parentBlock: IStandardBlockHeader
) {
this.coinbaseTransaction = coinbaseTransaction;
this.blockHash = blockHash;
this.coinbaseBranch = coinbaseBranch;
this.blockchainBranch = blockchainBranch;
this.parentBlock = parentBlock;
}

byteLength(): number {
return (
this.coinbaseTransaction.byteLength(true) +
32 +
merkleBranchEncodingLength(this.coinbaseBranch) +
merkleBranchEncodingLength(this.blockchainBranch) +
80
);
}

writeToBytesBuilder(builder: BytesBuilder): BytesBuilder {
this.coinbaseTransaction.writeToBytesBuilder(builder, true, null);
builder.writeBytes(hexToU8Array(this.blockHash));
writeMerkleBranch(builder, this.coinbaseBranch);
writeMerkleBranch(builder, this.blockchainBranch);
writeStandardBlockHeader(builder, this.parentBlock);
return builder;
}

toBuffer(): Uint8Array {
return this.writeToBytesBuilder(
new BytesBuilder(this.byteLength())
).toBuffer();
}

toHex() {
return u8ArrayToHex(this.toBuffer());
}

static fromBuffer(buffer: Uint8Array): AuxPow {
return AuxPow.fromBytesReader(new BytesReader(buffer));
}

static fromHex(hex: string): AuxPow {
return AuxPow.fromBuffer(hexToU8Array(hex));
}

static fromBytesReader(reader: BytesReader): AuxPow {
const coinbaseTransaction = Transaction.fromBytesReader(reader);
const blockHash = u8ArrayToHex(reader.readBytes(32));
const coinbaseBranch = readMerkleBranch(reader);
const blockchainBranch = readMerkleBranch(reader);
const parentBlock = readStandardBlockHeader(reader);

return new AuxPow(
coinbaseTransaction,
blockHash,
coinbaseBranch,
blockchainBranch,
parentBlock
);
}
}


export {
AuxPow,
}
84 changes: 84 additions & 0 deletions src/block/header.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { BytesBuilder } from '../utils/bytesBuilder';
import { BytesReader } from '../utils/bytesReader';
import { hexToU8Array, u8ArrayToHex } from '../utils/data';
import { AuxPow } from './auxpow';
import { IStandardBlockHeaderAuxPow } from './types';
import { readStandardBlockHeader, writeStandardBlockHeader } from './utils';

class BlockHeader implements IStandardBlockHeaderAuxPow {
auxData?: AuxPow | undefined;
version: number;
prevHash: string;
merkleRoot: string;
timestamp: number;
bits: number;
nonce: number;

constructor({
version,
prevHash,
merkleRoot,
timestamp,
bits,
nonce,
auxData,
}: IStandardBlockHeaderAuxPow) {
this.version = version;
this.prevHash = prevHash;
this.merkleRoot = merkleRoot;
this.timestamp = timestamp;
this.bits = bits;
this.nonce = nonce;
this.auxData = auxData;
}

byteLength(): number {
return this.auxData ? (80 + this.auxData.byteLength()) : 80;
}

writeToBytesBuilder(builder: BytesBuilder): BytesBuilder {
writeStandardBlockHeader(builder, this);
if(this.auxData) {
this.auxData.writeToBytesBuilder(builder);
}
return builder;
}

toBuffer(): Uint8Array {
return this.writeToBytesBuilder(
new BytesBuilder(this.byteLength())
).toBuffer();
}

toHex(): string {
return u8ArrayToHex(this.toBuffer());
}

static fromBytesReader(reader: BytesReader): BlockHeader {
const block = new BlockHeader(
readStandardBlockHeader(reader),
);
if ((block.version & 0x100) !== 0) {
block.auxData = AuxPow.fromBytesReader(reader);
}
return block;
}

static fromBuffer(buffer: Uint8Array): BlockHeader {
if (buffer.length < 80) {
throw new Error('Block must be at least 80 bytes long');
}
const reader = new BytesReader(buffer);
return this.fromBytesReader(reader);
}

static fromHex(hex: string): BlockHeader {
return this.fromBuffer(hexToU8Array(hex));
}

}


export {
BlockHeader,
}
Loading

0 comments on commit a8cf59b

Please sign in to comment.