Merge branch 'return_bytes_primitive' into 'development'
Use Bytes Primitive See merge request GeneralProtocols/xo/stack!113
This commit is contained in:
@@ -23,15 +23,18 @@ import { hash256 } from '@bitauth/libauth';
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export class BlockHeader {
|
export class BlockHeader {
|
||||||
|
protected readonly bytes: Bytes;
|
||||||
|
|
||||||
// View of our data so that we can extract as numbers.
|
// View of our data so that we can extract as numbers.
|
||||||
private view: DataView;
|
protected readonly view: DataView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new BlockHeader instance.
|
* Creates a new BlockHeader instance.
|
||||||
* @param bytes The bytes representing our Block Header (Big Endian)
|
* @param bytes The bytes representing our Block Header (Big Endian)
|
||||||
*/
|
*/
|
||||||
protected constructor(private readonly bytes: Uint8Array) {
|
protected constructor(bytes: Bytes | Uint8Array) {
|
||||||
this.view = new DataView(bytes.buffer);
|
this.bytes = Bytes.from(bytes);
|
||||||
|
this.view = new DataView(this.bytes.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +61,7 @@ export class BlockHeader {
|
|||||||
* @returns A new BlockHeader instance
|
* @returns A new BlockHeader instance
|
||||||
* @throws Error if the byte array length is not 80
|
* @throws Error if the byte array length is not 80
|
||||||
*/
|
*/
|
||||||
static fromBytes(bytes: Uint8Array): BlockHeader {
|
static fromBytes(bytes: Bytes | Uint8Array): BlockHeader {
|
||||||
if (bytes.length !== 80) {
|
if (bytes.length !== 80) {
|
||||||
throw new Error('Invalid block header length');
|
throw new Error('Invalid block header length');
|
||||||
}
|
}
|
||||||
@@ -134,7 +137,7 @@ export class BlockHeader {
|
|||||||
* Serializes the block header to a byte array.
|
* Serializes the block header to a byte array.
|
||||||
* @returns 80-byte array containing the serialized block header
|
* @returns 80-byte array containing the serialized block header
|
||||||
*/
|
*/
|
||||||
toBytes(): Uint8Array {
|
toBytes(): Bytes {
|
||||||
return this.bytes;
|
return this.bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,9 +176,9 @@ export class HDPrivateNode {
|
|||||||
*
|
*
|
||||||
* @returns The Node's Private Key (as a Uint8Array).
|
* @returns The Node's Private Key (as a Uint8Array).
|
||||||
*/
|
*/
|
||||||
public toBytes(): Uint8Array {
|
public toBytes(): Bytes {
|
||||||
// Encode the XPriv from our node info.
|
// Encode the XPriv from our node info.
|
||||||
return this.node.privateKey;
|
return Bytes.from(this.node.privateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,16 +33,16 @@ import {
|
|||||||
*/
|
*/
|
||||||
export class PrivateKey {
|
export class PrivateKey {
|
||||||
// The raw bytes representing the Private Key.
|
// The raw bytes representing the Private Key.
|
||||||
protected readonly bytes: Uint8Array;
|
protected readonly bytes: Bytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new Private Key.
|
* Construct a new Private Key.
|
||||||
*
|
*
|
||||||
* @throws {Error} If Private Key cannot be constructed.
|
* @throws {Error} If Private Key cannot be constructed.
|
||||||
*
|
*
|
||||||
* @param bytes {Uint8Array} The raw bytes (32) for the Private Key.
|
* @param bytes The raw bytes (32) for the Private Key.
|
||||||
*/
|
*/
|
||||||
protected constructor(bytes: Uint8Array) {
|
protected constructor(bytes: Bytes | Uint8Array) {
|
||||||
// Ensure that the Private Key is valid.
|
// Ensure that the Private Key is valid.
|
||||||
if (!secp256k1.validatePrivateKey(bytes)) {
|
if (!secp256k1.validatePrivateKey(bytes)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -50,7 +50,7 @@ export class PrivateKey {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bytes = bytes;
|
this.bytes = Bytes.from(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +62,7 @@ export class PrivateKey {
|
|||||||
*
|
*
|
||||||
* @returns The created Private Key Primitive.
|
* @returns The created Private Key Primitive.
|
||||||
*/
|
*/
|
||||||
public static from(privateKey: Uint8Array | string) {
|
public static from(privateKey: Bytes | Uint8Array | string) {
|
||||||
if (privateKey instanceof Uint8Array) {
|
if (privateKey instanceof Uint8Array) {
|
||||||
return this.fromBytes(privateKey);
|
return this.fromBytes(privateKey);
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ export class PrivateKey {
|
|||||||
*
|
*
|
||||||
* @returns {PrivateKey} The created Private Key Entity.
|
* @returns {PrivateKey} The created Private Key Entity.
|
||||||
*/
|
*/
|
||||||
public static fromBytes(privateKeyBytes: Uint8Array): PrivateKey {
|
public static fromBytes(privateKeyBytes: Bytes | Uint8Array): PrivateKey {
|
||||||
return new this(privateKeyBytes);
|
return new this(privateKeyBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,9 +194,9 @@ export class PrivateKey {
|
|||||||
/**
|
/**
|
||||||
* Convert this Private Key to a raw 32 byte representation.
|
* Convert this Private Key to a raw 32 byte representation.
|
||||||
*
|
*
|
||||||
* @returns {Uint8Array} The raw Private Key as a Uint8Array.
|
* @returns The raw Private Key as a Uint8Array.
|
||||||
*/
|
*/
|
||||||
public toBytes(): Uint8Array {
|
public toBytes(): Bytes {
|
||||||
// Return the raw bytes for this Private Key.
|
// Return the raw bytes for this Private Key.
|
||||||
return this.bytes;
|
return this.bytes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,15 +24,15 @@ import { secp256k1, sha256, ripemd160, utf8ToBin } from '@bitauth/libauth';
|
|||||||
*/
|
*/
|
||||||
export class PublicKey {
|
export class PublicKey {
|
||||||
// The raw bytes representing the Public Key.
|
// The raw bytes representing the Public Key.
|
||||||
protected readonly bytes: Uint8Array;
|
protected readonly bytes: Bytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new Public Key.
|
* Construct a new Public Key.
|
||||||
*
|
*
|
||||||
* @param bytes The raw bytes (33) for the Public Key.
|
* @param bytes The raw bytes (33) for the Public Key.
|
||||||
*/
|
*/
|
||||||
protected constructor(bytes: Uint8Array) {
|
protected constructor(bytes: Bytes | Uint8Array) {
|
||||||
this.bytes = bytes;
|
this.bytes = Bytes.from(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +44,7 @@ export class PublicKey {
|
|||||||
*
|
*
|
||||||
* @returns The created Public Key Primitive.
|
* @returns The created Public Key Primitive.
|
||||||
*/
|
*/
|
||||||
public static from(publicKey: Uint8Array | string) {
|
public static from(publicKey: Bytes | Uint8Array | string) {
|
||||||
return publicKey instanceof Uint8Array
|
return publicKey instanceof Uint8Array
|
||||||
? this.fromBytes(publicKey)
|
? this.fromBytes(publicKey)
|
||||||
: this.fromHex(publicKey);
|
: this.fromHex(publicKey);
|
||||||
@@ -59,7 +59,7 @@ export class PublicKey {
|
|||||||
*
|
*
|
||||||
* @returns The created Public Key entity.
|
* @returns The created Public Key entity.
|
||||||
*/
|
*/
|
||||||
public static fromBytes(publicKeyBytes: Uint8Array): PublicKey {
|
public static fromBytes(publicKeyBytes: Bytes | Uint8Array): PublicKey {
|
||||||
// Ensure that exactly 33 Bytes are given.
|
// Ensure that exactly 33 Bytes are given.
|
||||||
if (!secp256k1.validatePublicKey(publicKeyBytes)) {
|
if (!secp256k1.validatePublicKey(publicKeyBytes)) {
|
||||||
throw new Error(`Invalid Public Key.`);
|
throw new Error(`Invalid Public Key.`);
|
||||||
@@ -90,7 +90,7 @@ export class PublicKey {
|
|||||||
*
|
*
|
||||||
* @returns A new instance of this primitive.
|
* @returns A new instance of this primitive.
|
||||||
*/
|
*/
|
||||||
public static fromRaw(bytes: Uint8Array) {
|
public static fromRaw(bytes: Bytes | Uint8Array) {
|
||||||
return new this(bytes);
|
return new this(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ export class PublicKey {
|
|||||||
*
|
*
|
||||||
* @returns The raw bytes of the Public Key.
|
* @returns The raw bytes of the Public Key.
|
||||||
*/
|
*/
|
||||||
public toBytes(): Uint8Array {
|
public toBytes(): Bytes {
|
||||||
// Return the raw bytes for this Public Key.
|
// Return the raw bytes for this Public Key.
|
||||||
return this.bytes;
|
return this.bytes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ import {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export class Script {
|
export class Script {
|
||||||
protected readonly bytes: Uint8Array;
|
protected readonly bytes: Bytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new Script
|
* Construct a new Script
|
||||||
*
|
*
|
||||||
* @param bytes {Uint8Array} The raw bytes of the Script.
|
* @param bytes {Uint8Array} The raw bytes of the Script.
|
||||||
*/
|
*/
|
||||||
protected constructor(bytes: Uint8Array) {
|
protected constructor(bytes: Bytes | Uint8Array) {
|
||||||
this.bytes = bytes;
|
this.bytes = Bytes.from(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +48,7 @@ export class Script {
|
|||||||
*
|
*
|
||||||
* @returns The created Script Primitive.
|
* @returns The created Script Primitive.
|
||||||
*/
|
*/
|
||||||
public static from(script: Uint8Array | string) {
|
public static from(script: Bytes | Uint8Array | string) {
|
||||||
return script instanceof Uint8Array
|
return script instanceof Uint8Array
|
||||||
? this.fromBytes(script)
|
? this.fromBytes(script)
|
||||||
: this.fromHex(script);
|
: this.fromHex(script);
|
||||||
@@ -63,7 +63,7 @@ export class Script {
|
|||||||
*
|
*
|
||||||
* @returns {Script} The created Script Entity.
|
* @returns {Script} The created Script Entity.
|
||||||
*/
|
*/
|
||||||
public static fromBytes(bytes: Uint8Array): Script {
|
public static fromBytes(bytes: Bytes | Uint8Array): Script {
|
||||||
// Disassemble the bytecode.
|
// Disassemble the bytecode.
|
||||||
const disassembledBytecode = disassembleBytecodeBCH(bytes);
|
const disassembledBytecode = disassembleBytecodeBCH(bytes);
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ export class Script {
|
|||||||
*
|
*
|
||||||
* @returns {Uint8Array} The compiled bytes.
|
* @returns {Uint8Array} The compiled bytes.
|
||||||
*/
|
*/
|
||||||
public toBytes(): Uint8Array {
|
public toBytes(): Bytes {
|
||||||
return this.bytes;
|
return this.bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import { Bytes } from '../src/bytes';
|
|||||||
describe('Success cases', () => {
|
describe('Success cases', () => {
|
||||||
// Test cases with different block header representations
|
// Test cases with different block header representations
|
||||||
type BlockHeaderCase = {
|
type BlockHeaderCase = {
|
||||||
raw: Uint8Array;
|
raw: Bytes;
|
||||||
representations: {
|
representations: {
|
||||||
bytes: Uint8Array;
|
bytes: Bytes;
|
||||||
hex: string;
|
hex: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -16,11 +16,11 @@ describe('Success cases', () => {
|
|||||||
{
|
{
|
||||||
raw: Bytes.fromHex(
|
raw: Bytes.fromHex(
|
||||||
'0000602093ea70b294aeef69db85981bd387285824fc5af732e487010000000000000000135576e1ba9cae5509d60b4fbb9e66612f35b5ee8db264cb12612d46cc8db60b5e34a164d46b021864abbb1d',
|
'0000602093ea70b294aeef69db85981bd387285824fc5af732e487010000000000000000135576e1ba9cae5509d60b4fbb9e66612f35b5ee8db264cb12612d46cc8db60b5e34a164d46b021864abbb1d',
|
||||||
).toUint8Array(),
|
),
|
||||||
representations: {
|
representations: {
|
||||||
bytes: Bytes.fromHex(
|
bytes: Bytes.fromHex(
|
||||||
'0000602093ea70b294aeef69db85981bd387285824fc5af732e487010000000000000000135576e1ba9cae5509d60b4fbb9e66612f35b5ee8db264cb12612d46cc8db60b5e34a164d46b021864abbb1d',
|
'0000602093ea70b294aeef69db85981bd387285824fc5af732e487010000000000000000135576e1ba9cae5509d60b4fbb9e66612f35b5ee8db264cb12612d46cc8db60b5e34a164d46b021864abbb1d',
|
||||||
).toUint8Array(),
|
),
|
||||||
hex: '0000602093ea70b294aeef69db85981bd387285824fc5af732e487010000000000000000135576e1ba9cae5509d60b4fbb9e66612f35b5ee8db264cb12612d46cc8db60b5e34a164d46b021864abbb1d',
|
hex: '0000602093ea70b294aeef69db85981bd387285824fc5af732e487010000000000000000135576e1ba9cae5509d60b4fbb9e66612f35b5ee8db264cb12612d46cc8db60b5e34a164d46b021864abbb1d',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -35,19 +35,19 @@ describe('Success cases', () => {
|
|||||||
fromMethods.forEach(({ name, key }) => {
|
fromMethods.forEach(({ name, key }) => {
|
||||||
it.each(testCases)(`${name}()`, ({ raw, representations }) => {
|
it.each(testCases)(`${name}()`, ({ raw, representations }) => {
|
||||||
const blockHeader = BlockHeader[name](representations[key]);
|
const blockHeader = BlockHeader[name](representations[key]);
|
||||||
expect(blockHeader.toRaw()).toStrictEqual(raw);
|
expect(blockHeader.toRaw()).toEqual(raw);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test generic from method
|
// Test generic from method
|
||||||
it.each(testCases)('from(Uint8Array)', ({ raw, representations }) => {
|
it.each(testCases)('from(Uint8Array)', ({ raw, representations }) => {
|
||||||
const blockHeader = BlockHeader.from(representations.bytes);
|
const blockHeader = BlockHeader.from(representations.bytes);
|
||||||
expect(blockHeader.toRaw()).toStrictEqual(raw);
|
expect(blockHeader.toRaw()).toEqual(raw);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each(testCases)('from(string)', ({ raw, representations }) => {
|
it.each(testCases)('from(string)', ({ raw, representations }) => {
|
||||||
const blockHeader = BlockHeader.from(representations.hex);
|
const blockHeader = BlockHeader.from(representations.hex);
|
||||||
expect(blockHeader.toRaw()).toStrictEqual(raw);
|
expect(blockHeader.toRaw()).toEqual(raw);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test to methods with their respective types
|
// Test to methods with their respective types
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
import { describe, it, expect } from 'vitest';
|
||||||
import { Bytes } from '~/src/bytes';
|
import { Bytes } from '../src/bytes';
|
||||||
import { Script } from '~/src/script';
|
import { Script } from '../src/script';
|
||||||
|
|
||||||
describe('Success cases', () => {
|
describe('Success cases', () => {
|
||||||
// Test cases with different script representations
|
// Test cases with different script representations
|
||||||
type ScriptCase = {
|
type ScriptCase = {
|
||||||
raw: Uint8Array;
|
raw: Bytes;
|
||||||
representations: {
|
representations: {
|
||||||
bytes: Uint8Array;
|
bytes: Bytes;
|
||||||
asm: string;
|
asm: string;
|
||||||
hex: string;
|
hex: string;
|
||||||
};
|
};
|
||||||
@@ -15,13 +15,11 @@ describe('Success cases', () => {
|
|||||||
|
|
||||||
const testCases: ScriptCase[] = [
|
const testCases: ScriptCase[] = [
|
||||||
{
|
{
|
||||||
raw: Bytes.fromHex(
|
raw: Bytes.fromHex('76a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac'),
|
||||||
'76a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac',
|
|
||||||
).toUint8Array(),
|
|
||||||
representations: {
|
representations: {
|
||||||
bytes: Bytes.fromHex(
|
bytes: Bytes.fromHex(
|
||||||
'76a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac',
|
'76a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac',
|
||||||
).toUint8Array(),
|
),
|
||||||
asm: 'OP_DUP\nOP_HASH160\nOP_PUSHBYTES_20\n0x876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d6\nOP_EQUALVERIFY\nOP_CHECKSIG',
|
asm: 'OP_DUP\nOP_HASH160\nOP_PUSHBYTES_20\n0x876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d6\nOP_EQUALVERIFY\nOP_CHECKSIG',
|
||||||
hex: '76a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac',
|
hex: '76a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { type WalletUTXO } from './types.js';
|
import { type TransactionTemplate, type WalletUTXO } from './types.js';
|
||||||
|
|
||||||
import { type UTXOSet, ExtMap, Outpoint } from '@xocash/primitives';
|
import { type UTXOSet, ExtMap, Outpoint } from '@xocash/primitives';
|
||||||
|
|
||||||
@@ -28,13 +28,26 @@ import {
|
|||||||
*/
|
*/
|
||||||
export class TransactionBuilder {
|
export class TransactionBuilder {
|
||||||
static build(
|
static build(
|
||||||
transaction: TransactionTemplateFixed<CompilerBCH>,
|
txTemplate: Partial<TransactionTemplate>,
|
||||||
unspents: Array<WalletUTXO> = [],
|
unspents: Array<WalletUTXO> = [],
|
||||||
changeLockingBytecode: Uint8Array,
|
changeLockingBytecode: Uint8Array,
|
||||||
sourceOutputs: UTXOSet = new ExtMap(),
|
sourceOutputs: UTXOSet = new ExtMap(),
|
||||||
) {
|
) {
|
||||||
|
// Populate the final transaction template by merging with defaults.
|
||||||
|
// NOTE: This is just a convenience to make this utility easier to use.
|
||||||
|
const txTemplateFinal: TransactionTemplate = {
|
||||||
|
...{
|
||||||
|
version: 2,
|
||||||
|
locktime: 0,
|
||||||
|
inputs: [],
|
||||||
|
outputs: [],
|
||||||
|
},
|
||||||
|
...txTemplate,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build the template.
|
||||||
const txBuilder = new TransactionBuilder(
|
const txBuilder = new TransactionBuilder(
|
||||||
transaction,
|
txTemplateFinal,
|
||||||
unspents,
|
unspents,
|
||||||
sourceOutputs,
|
sourceOutputs,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -305,18 +305,6 @@ export class WalletHD extends BaseWallet {
|
|||||||
async signTransaction(
|
async signTransaction(
|
||||||
txTemplate: Partial<TransactionTemplate>,
|
txTemplate: Partial<TransactionTemplate>,
|
||||||
): Promise<TransactionBuilder> {
|
): Promise<TransactionBuilder> {
|
||||||
// Populate the final transaction template by merging with defaults.
|
|
||||||
// NOTE: This is just a convenience to make "send" easier to use.
|
|
||||||
const txTemplateFinal: TransactionTemplate = {
|
|
||||||
...{
|
|
||||||
version: 2,
|
|
||||||
locktime: 0,
|
|
||||||
inputs: [],
|
|
||||||
outputs: [],
|
|
||||||
},
|
|
||||||
...txTemplate,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the receiving address of this wallet.
|
// Get the receiving address of this wallet.
|
||||||
// NOTE: As per BIP44 spec, we set the change address to use the internal chain.
|
// NOTE: As per BIP44 spec, we set the change address to use the internal chain.
|
||||||
const changeAddress = await this.getReceivingAddress(CHAIN_EXTERNAL);
|
const changeAddress = await this.getReceivingAddress(CHAIN_EXTERNAL);
|
||||||
@@ -329,7 +317,7 @@ export class WalletHD extends BaseWallet {
|
|||||||
|
|
||||||
// Build the transaction.
|
// Build the transaction.
|
||||||
return TransactionBuilder.build(
|
return TransactionBuilder.build(
|
||||||
txTemplateFinal,
|
txTemplate,
|
||||||
unspents.toArray(),
|
unspents.toArray(),
|
||||||
changeLockingBytecode,
|
changeLockingBytecode,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -338,18 +338,6 @@ export class WalletP2PKH extends BaseWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async signTransaction(txTemplate: Partial<TransactionTemplate>) {
|
async signTransaction(txTemplate: Partial<TransactionTemplate>) {
|
||||||
// Populate the final transaction template by merging with defaults.
|
|
||||||
// NOTE: This is just a convenience to make "send" easier to use.
|
|
||||||
const txTemplateFinal: TransactionTemplate = {
|
|
||||||
...{
|
|
||||||
version: 2,
|
|
||||||
locktime: 0,
|
|
||||||
inputs: [],
|
|
||||||
outputs: [],
|
|
||||||
},
|
|
||||||
...txTemplate,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the receiving address of this wallet.
|
// Get the receiving address of this wallet.
|
||||||
const receivingAddress = await this.getReceivingAddress();
|
const receivingAddress = await this.getReceivingAddress();
|
||||||
|
|
||||||
@@ -361,7 +349,7 @@ export class WalletP2PKH extends BaseWallet {
|
|||||||
|
|
||||||
// Build the transaction.
|
// Build the transaction.
|
||||||
return TransactionBuilder.build(
|
return TransactionBuilder.build(
|
||||||
txTemplateFinal,
|
txTemplate,
|
||||||
unspents.toArray(),
|
unspents.toArray(),
|
||||||
changeLockingBytecode,
|
changeLockingBytecode,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user