diff --git a/coinlib/lib/src/network.dart b/coinlib/lib/src/network.dart index b58bdc8..ec75e04 100644 --- a/coinlib/lib/src/network.dart +++ b/coinlib/lib/src/network.dart @@ -16,6 +16,49 @@ class Network { required this.feePerKb, }); + // copyWith function + Network copyWith({ + int? wifPrefix, + int? p2pkhPrefix, + int? p2shPrefix, + int? privHDPrefix, + int? pubHDPrefix, + String? bech32Hrp, + String? messagePrefix, + BigInt? minFee, + BigInt? minOutput, + BigInt? feePerKb, + }) { + return Network( + wifPrefix: wifPrefix ?? this.wifPrefix, + p2pkhPrefix: p2pkhPrefix ?? this.p2pkhPrefix, + p2shPrefix: p2shPrefix ?? this.p2shPrefix, + privHDPrefix: privHDPrefix ?? this.privHDPrefix, + pubHDPrefix: pubHDPrefix ?? this.pubHDPrefix, + bech32Hrp: bech32Hrp ?? this.bech32Hrp, + messagePrefix: messagePrefix ?? this.messagePrefix, + minFee: minFee ?? this.minFee, + minOutput: minOutput ?? this.minOutput, + feePerKb: feePerKb ?? this.feePerKb, + ); + } + + @override + String toString() { + return 'Network(\n' + ' wifPrefix: $wifPrefix,\n' + ' p2pkhPrefix: $p2pkhPrefix,\n' + ' p2shPrefix: $p2shPrefix,\n' + ' privHDPrefix: 0x${privHDPrefix.toRadixString(16)},\n' + ' pubHDPrefix: 0x${pubHDPrefix.toRadixString(16)},\n' + ' bech32Hrp: "$bech32Hrp",\n' + ' messagePrefix: "$messagePrefix",\n' + ' minFee: $minFee,\n' + ' minOutput: $minOutput,\n' + ' feePerKb: $feePerKb\n' + ')'; + } + static final mainnet = Network( wifPrefix: 183, p2pkhPrefix: 55, diff --git a/coinlib/lib/src/scripts/operations.dart b/coinlib/lib/src/scripts/operations.dart index 83430cb..9497620 100644 --- a/coinlib/lib/src/scripts/operations.dart +++ b/coinlib/lib/src/scripts/operations.dart @@ -1,9 +1,11 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/bytes.dart'; import 'package:coinlib/src/common/hex.dart'; import 'package:coinlib/src/common/serial.dart'; import 'package:coinlib/src/crypto/ec_public_key.dart'; import 'package:coinlib/src/tx/inputs/input_signature.dart'; + import 'codes.dart'; class InvalidScriptAsm implements Exception {} @@ -153,6 +155,16 @@ abstract class ScriptOp { /// Returns true when the other [ScriptOp] matches this one. /// [ScriptPushDataMatcher] will match with a push data of a particular size. bool match(ScriptOp other); + + @override + String toString() => "$runtimeType(" + "compiled: $compiled, " + "asm: $asm, " + "number: $number, " + "ecdsaSig: $ecdsaSig, " + "schnorrSig: $schnorrSig, " + "publicKey: $publicKey" + ")"; } /// Represents a [ScriptOp] that is an op code diff --git a/coinlib/lib/src/scripts/program.dart b/coinlib/lib/src/scripts/program.dart index e318037..35790a2 100644 --- a/coinlib/lib/src/scripts/program.dart +++ b/coinlib/lib/src/scripts/program.dart @@ -1,11 +1,12 @@ import 'dart:typed_data'; + +import 'programs/multisig.dart'; import 'programs/p2pkh.dart'; import 'programs/p2sh.dart'; import 'programs/p2tr.dart'; +import 'programs/p2witness.dart'; import 'programs/p2wpkh.dart'; import 'programs/p2wsh.dart'; -import 'programs/p2witness.dart'; -import 'programs/multisig.dart'; import 'script.dart'; /// Thrown when a script doesn't match the program being constructed @@ -61,6 +62,11 @@ abstract class Program { Program.match(Script.decompile(script, requireMinimal: requireMinimal)); factory Program.fromAsm(String asm) => Program.match(Script.fromAsm(asm)); + + @override + String toString() => "$runtimeType(" + "script: $script" + ")"; } /// A program that is not recognised and merely wraps a [Script]. @@ -68,4 +74,9 @@ class RawProgram implements Program { @override final Script script; RawProgram(this.script); + + @override + String toString() => "$runtimeType(" + "script: $script" + ")"; } diff --git a/coinlib/lib/src/scripts/programs/multisig.dart b/coinlib/lib/src/scripts/programs/multisig.dart index e9c38a1..d71bc08 100644 --- a/coinlib/lib/src/scripts/programs/multisig.dart +++ b/coinlib/lib/src/scripts/programs/multisig.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/bytes.dart'; import 'package:coinlib/src/crypto/ec_public_key.dart'; import 'package:coinlib/src/scripts/operations.dart'; @@ -102,4 +103,11 @@ class MultisigProgram implements Program { : this.fromScript(Script.decompile(compiled)); MultisigProgram.fromAsm(String asm) : this.fromScript(Script.fromAsm(asm)); + + @override + String toString() => "$runtimeType(" + "script: $script, " + "threshold: $threshold, " + "pubkeys: $pubkeys" + ")"; } diff --git a/coinlib/lib/src/scripts/programs/p2pkh.dart b/coinlib/lib/src/scripts/programs/p2pkh.dart index 6e86178..29bbf88 100644 --- a/coinlib/lib/src/scripts/programs/p2pkh.dart +++ b/coinlib/lib/src/scripts/programs/p2pkh.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/bytes.dart'; import 'package:coinlib/src/crypto/ec_public_key.dart'; import 'package:coinlib/src/crypto/hash.dart'; @@ -34,4 +35,10 @@ class P2PKH implements Program { P2PKH.fromPublicKey(ECPublicKey pk) : this.fromHash(hash160(pk.data)); Uint8List get pkHash => Uint8List.fromList(_pkHash); + + @override + String toString() => "$runtimeType(" + "script: $script, " + "pkHash: $_pkHash" + ")"; } diff --git a/coinlib/lib/src/scripts/programs/p2sh.dart b/coinlib/lib/src/scripts/programs/p2sh.dart index ce3b562..f8092aa 100644 --- a/coinlib/lib/src/scripts/programs/p2sh.dart +++ b/coinlib/lib/src/scripts/programs/p2sh.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/bytes.dart'; import 'package:coinlib/src/crypto/hash.dart'; import 'package:coinlib/src/scripts/operations.dart'; @@ -33,4 +34,10 @@ class P2SH implements Program { : this.fromHash(hash160(redeemScript.compiled)); Uint8List get scriptHash => Uint8List.fromList(_scriptHash); + + @override + String toString() => "$runtimeType(" + "script: $script, " + "scriptHash: $_scriptHash" + ")"; } diff --git a/coinlib/lib/src/scripts/programs/p2tr.dart b/coinlib/lib/src/scripts/programs/p2tr.dart index 6b7dbc5..2a41423 100644 --- a/coinlib/lib/src/scripts/programs/p2tr.dart +++ b/coinlib/lib/src/scripts/programs/p2tr.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/bytes.dart'; import 'package:coinlib/src/crypto/ec_public_key.dart'; import 'package:coinlib/src/scripts/program.dart'; @@ -29,4 +30,12 @@ class P2TR extends P2Witness { P2TR.fromTaproot(Taproot taproot) : this.fromTweakedKey(taproot.tweakedKey); ECPublicKey get tweakedKey => ECPublicKey.fromXOnly(data); + + @override + String toString() => "$runtimeType(" + "script: $script, " + "version: $version, " + "data: $data, " + "tweakedKey: $tweakedKey" + ")"; } diff --git a/coinlib/lib/src/scripts/programs/p2witness.dart b/coinlib/lib/src/scripts/programs/p2witness.dart index a53a69c..780e3dd 100644 --- a/coinlib/lib/src/scripts/programs/p2witness.dart +++ b/coinlib/lib/src/scripts/programs/p2witness.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; + import 'package:coinlib/src/scripts/operations.dart'; import 'package:coinlib/src/scripts/program.dart'; import 'package:coinlib/src/scripts/script.dart'; @@ -53,4 +54,11 @@ class P2Witness implements Program { /// The data of the "witness program". It is called "data" and not "program" /// to avoid confusion with the more general [Program] class. Uint8List get data => Uint8List.fromList(_data); + + @override + String toString() => "$runtimeType(" + "script: $script, " + "version: $version, " + "data: $data" + ")"; } diff --git a/coinlib/lib/src/scripts/programs/p2wpkh.dart b/coinlib/lib/src/scripts/programs/p2wpkh.dart index 4b5e412..fd0a534 100644 --- a/coinlib/lib/src/scripts/programs/p2wpkh.dart +++ b/coinlib/lib/src/scripts/programs/p2wpkh.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/bytes.dart'; import 'package:coinlib/src/crypto/ec_public_key.dart'; import 'package:coinlib/src/crypto/hash.dart'; @@ -24,4 +25,12 @@ class P2WPKH extends P2Witness { P2WPKH.fromPublicKey(ECPublicKey pk) : this.fromHash(hash160(pk.data)); Uint8List get pkHash => data; + + @override + String toString() => "$runtimeType(" + "script: $script, " + "version: $version, " + "data: $data, " + "pkHash: $pkHash" + ")"; } diff --git a/coinlib/lib/src/scripts/programs/p2wsh.dart b/coinlib/lib/src/scripts/programs/p2wsh.dart index 5807425..c165e42 100644 --- a/coinlib/lib/src/scripts/programs/p2wsh.dart +++ b/coinlib/lib/src/scripts/programs/p2wsh.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/bytes.dart'; import 'package:coinlib/src/crypto/hash.dart'; import 'package:coinlib/src/scripts/program.dart'; @@ -27,4 +28,12 @@ class P2WSH extends P2Witness { : this.fromHash(sha256Hash(witnessScript.compiled)); Uint8List get scriptHash => data; + + @override + String toString() => "$runtimeType(" + "script: $script, " + "version: $version, " + "data: $data, " + "scriptHash: $scriptHash" + ")"; } diff --git a/coinlib/lib/src/scripts/script.dart b/coinlib/lib/src/scripts/script.dart index af213a6..1cebe02 100644 --- a/coinlib/lib/src/scripts/script.dart +++ b/coinlib/lib/src/scripts/script.dart @@ -1,6 +1,8 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/serial.dart'; import 'package:collection/collection.dart'; + import 'operations.dart'; class Script { @@ -84,4 +86,10 @@ class Script { ScriptOp operator [](int i) => ops[i]; int get length => ops.length; + + @override + String toString() => "$runtimeType(" + "ops: $ops, " + "asm: $asm" + ")"; } diff --git a/coinlib/lib/src/tx/inputs/input.dart b/coinlib/lib/src/tx/inputs/input.dart index c471b79..cbb2e53 100644 --- a/coinlib/lib/src/tx/inputs/input.dart +++ b/coinlib/lib/src/tx/inputs/input.dart @@ -1,7 +1,9 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/serial.dart'; import 'package:coinlib/src/scripts/script.dart'; import 'package:coinlib/src/tx/outpoint.dart'; + import 'input_signature.dart'; import 'p2pkh_input.dart'; import 'p2sh_multisig_input.dart'; @@ -54,4 +56,12 @@ abstract class Input with Writable { return null; } } + + @override + String toString() => "$runtimeType(" + "prevOut: $prevOut, " + "scriptSig: $scriptSig, " + "sequence: $sequence, " + "signedSize: $signedSize" + ")"; } diff --git a/coinlib/lib/src/tx/outpoint.dart b/coinlib/lib/src/tx/outpoint.dart index 73bf644..bd2a11e 100644 --- a/coinlib/lib/src/tx/outpoint.dart +++ b/coinlib/lib/src/tx/outpoint.dart @@ -1,8 +1,10 @@ import 'dart:typed_data'; + import 'package:coinlib/src/common/bytes.dart'; import 'package:coinlib/src/common/checks.dart'; import 'package:coinlib/src/common/hex.dart'; import 'package:coinlib/src/common/serial.dart'; + import 'output.dart'; /// Reference to an [Output] by transaction hash and index @@ -45,4 +47,10 @@ class OutPoint with Writable { @override int get hashCode => _hash[1] | _hash[2] << 8 | _hash[3] << 16 | _hash[4] << 24 | n; + + @override + String toString() => "$runtimeType(" + "hash: $_hash, " + "n: $n" + ")"; } diff --git a/coinlib/lib/src/tx/output.dart b/coinlib/lib/src/tx/output.dart index a8118fe..aeee7c8 100644 --- a/coinlib/lib/src/tx/output.dart +++ b/coinlib/lib/src/tx/output.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; + import 'package:coinlib/src/address.dart'; import 'package:coinlib/src/common/checks.dart'; import 'package:coinlib/src/common/serial.dart'; @@ -57,4 +58,11 @@ class Output with Writable { } Uint8List get scriptPubKey => Uint8List.fromList(_scriptPubKey); + + @override + String toString() => "Output(" + "value: $value, " + "scriptPubKey: $_scriptPubKey, " + "program: $program" + ")"; } diff --git a/coinlib/lib/src/tx/transaction.dart b/coinlib/lib/src/tx/transaction.dart index c0c7b72..99c1a84 100644 --- a/coinlib/lib/src/tx/transaction.dart +++ b/coinlib/lib/src/tx/transaction.dart @@ -466,4 +466,18 @@ class Transaction with Writable { required int blockHeight, }) => !locktimeIsEnforced || locktime.isUnlocked(medianTime, blockHeight); + + @override + String toString() => "Transaction(" + "version: $version, " + "locktime: $locktime, " + "isWitness: $isWitness, " + "isCoinBase: $isCoinBase, " + "isCoinStake: $isCoinStake, " + "complete: $complete, " + "hashHex: $hashHex, " + "txid: $txid, " + "inputs: $inputs, " + "outputs: $outputs" + ")"; }