99 lines
2.8 KiB
Dart
99 lines
2.8 KiB
Dart
import 'package:crypto/crypto.dart';
|
|
|
|
class Bitcoin {
|
|
final String ALPHABET =
|
|
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
|
|
List<int> bigIntToByteArray(BigInt data) {
|
|
String str;
|
|
bool neg = false;
|
|
if (data < BigInt.zero) {
|
|
str = (~data).toRadixString(16);
|
|
neg = true;
|
|
} else str = data.toRadixString(16);
|
|
int p = 0;
|
|
int len = str.length;
|
|
|
|
int blen = (len + 1) ~/ 2;
|
|
int boff = 0;
|
|
List bytes;
|
|
if (neg) {
|
|
if (len & 1 == 1) {
|
|
p = -1;
|
|
}
|
|
int byte0 = ~int.parse(str.substring(0, p + 2), radix: 16);
|
|
if (byte0 < -128) byte0 += 256;
|
|
if (byte0 >= 0) {
|
|
boff = 1;
|
|
bytes = new List<int>(blen + 1);
|
|
bytes[0] = -1;
|
|
bytes[1] = byte0;
|
|
} else {
|
|
bytes = new List<int>(blen);
|
|
bytes[0] = byte0;
|
|
}
|
|
for (int i = 1; i < blen; ++i) {
|
|
int byte = ~int.parse(str.substring(p + (i << 1), p + (i << 1) + 2),
|
|
radix: 16);
|
|
if (byte < -128) byte += 256;
|
|
bytes[i + boff] = byte;
|
|
}
|
|
} else {
|
|
if (len & 1 == 1) {
|
|
p = -1;
|
|
}
|
|
int byte0 = int.parse(str.substring(0, p + 2), radix: 16);
|
|
if (byte0 > 127) byte0 -= 256;
|
|
if (byte0 < 0) {
|
|
boff = 1;
|
|
bytes = new List<int>(blen + 1);
|
|
bytes[0] = 0;
|
|
bytes[1] = byte0;
|
|
} else {
|
|
bytes = new List<int>(blen);
|
|
bytes[0] = byte0;
|
|
}
|
|
for (int i = 1; i < blen; ++i) {
|
|
int byte =
|
|
int.parse(str.substring(p + (i << 1), p + (i << 1) + 2), radix: 16);
|
|
if (byte > 127) byte -= 256;
|
|
bytes[i + boff] = byte;
|
|
}
|
|
}
|
|
return bytes;
|
|
}
|
|
|
|
List<int> arrayCopy(bytes, srcOffset, result, destOffset, bytesLength) {
|
|
for (int i = srcOffset; i < bytesLength; i++) {
|
|
result[destOffset + i] = bytes[i];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
List<int> decodeBase58To25Bytes(String input) {
|
|
BigInt number = BigInt.zero;
|
|
for (String t in input.split('')) {
|
|
int p = ALPHABET.indexOf(t);
|
|
if (p == (-1))
|
|
return null;
|
|
number = number * (BigInt.from(58)) + (BigInt.from(p));
|
|
}
|
|
List<int> result = new List<int>(24);
|
|
List<int> numBytes = bigIntToByteArray(number);
|
|
return arrayCopy(
|
|
numBytes, 0, result, result.length - numBytes.length, numBytes.length);
|
|
}
|
|
|
|
validateAddress(String address) {
|
|
List<int> decoded = new List.from(decodeBase58To25Bytes(address));
|
|
List<int> temp = new List<int>.from(decoded);
|
|
temp.insert(0, 0);
|
|
List<int> hash1 = sha256.convert(temp.sublist(0, 21)).bytes;
|
|
List<int> hash2 = sha256.convert(hash1).bytes;
|
|
if (hash2[0] != decoded[20] ||
|
|
hash2[1] != decoded[21] ||
|
|
hash2[2] != decoded[22] ||
|
|
hash2[3] != decoded[23]) return false;
|
|
return true;
|
|
}
|
|
}
|