mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 01:37:54 +00:00
88 lines
2.2 KiB
Dart
88 lines
2.2 KiB
Dart
|
import 'dart:typed_data';
|
||
|
|
||
|
import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib;
|
||
|
|
||
|
const OP_EXCHANGEADDR = 0xe0;
|
||
|
|
||
|
class EXP2PKHAddress implements coinlib.Address {
|
||
|
/// The 160bit public key or redeemScript hash for the base58 address
|
||
|
final Uint8List _hash;
|
||
|
|
||
|
/// The network and address type version of the address
|
||
|
final Uint8List version;
|
||
|
|
||
|
String? _encodedCache;
|
||
|
|
||
|
EXP2PKHAddress._(Uint8List hash, this.version) : _hash = hash {
|
||
|
if (version.length != 3) {
|
||
|
throw ArgumentError(
|
||
|
"version bytes length must be 3",
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
factory EXP2PKHAddress.fromString(String encoded, Uint8List versionBytes) {
|
||
|
if (versionBytes.length != 3) {
|
||
|
throw ArgumentError(
|
||
|
"version bytes length must be 3",
|
||
|
);
|
||
|
}
|
||
|
|
||
|
final data = coinlib.base58Decode(encoded);
|
||
|
if (data.length != 23) throw coinlib.InvalidAddress();
|
||
|
|
||
|
final version = data.sublist(0, 3);
|
||
|
|
||
|
for (int i = 0; i < 3; i++) {
|
||
|
if (version[i] != versionBytes[i]) {
|
||
|
throw Exception("EX address version bytes do not match");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
final payload = data.sublist(3);
|
||
|
|
||
|
final addr = EXP2PKHAddress._(payload, version);
|
||
|
|
||
|
addr._encodedCache = encoded;
|
||
|
return addr;
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
String toString() => _encodedCache.toString();
|
||
|
|
||
|
@override
|
||
|
coinlib.Program get program => EXP2PKH.fromHash(_hash);
|
||
|
}
|
||
|
|
||
|
class EXP2PKH implements coinlib.Program {
|
||
|
static const template =
|
||
|
"OP_EXCHANGEADDR OP_DUP OP_HASH160 <20-bytes> OP_EQUALVERIFY OP_CHECKSIG";
|
||
|
|
||
|
@override
|
||
|
final coinlib.Script script;
|
||
|
|
||
|
EXP2PKH.fromScript(this.script);
|
||
|
|
||
|
factory EXP2PKH.fromHash(Uint8List pkHash) {
|
||
|
final List<coinlib.ScriptOp> ops = [
|
||
|
coinlib.ScriptOpCode(OP_EXCHANGEADDR),
|
||
|
];
|
||
|
final parts = template.split(" ").sublist(1);
|
||
|
for (final name in parts) {
|
||
|
if (name.startsWith("OP_")) {
|
||
|
ops.add(
|
||
|
coinlib.ScriptOpCode(
|
||
|
coinlib.scriptOpNameToCode[name.substring(3)]!,
|
||
|
),
|
||
|
);
|
||
|
} else if (name == "<20-bytes>") {
|
||
|
ops.add(coinlib.ScriptPushData(pkHash));
|
||
|
} else {
|
||
|
throw Exception("Something went wrong in this hacked code");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return EXP2PKH.fromScript(coinlib.Script(ops));
|
||
|
}
|
||
|
}
|