Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | 1x 1x 1x 1x 1x 13x 13x 13x 1x 1x 1x 58x 313x 49x 264x 264x 14082x 14082x 1x 14081x 591976x 591976x 591976x 14081x 1x 262x 262x 30x 30x 30x 30x 30x 3x 27x 277x 277x 277x 277x 277x 7x 270x 131x 131x 131x 6787x 6787x 325476x 325476x 325476x 6787x 9044x 9044x 131x 262x 130x 132x 131x 131x 3x 3x 3x 126x 126x 126x 49x 49x 3324x 3324x 1x 3323x 144393x 144393x 144393x 3323x 2425x 48x 51x 4x 47x 48x 48x 403x 403x 33x 33x | import {ripemd160} from '@noble/hashes/legacy.js'
import {sha256} from '@noble/hashes/sha2.js'
import {arrayEquals} from './utils'
import {Bytes, BytesType} from './chain'
export namespace Base58 {
export enum ErrorCode {
E_CHECKSUM = 'E_CHECKSUM',
E_INVALID = 'E_INVALID',
}
export class DecodingError extends Error {
static __className = 'DecodingError'
constructor(
message: string,
public readonly code: ErrorCode,
public readonly info: Record<string, any> = {}
) {
super(message)
}
}
const chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
const charMap = new Int16Array(0xff).fill(-1)
for (let i = 0; i < 58; ++i) {
charMap[chars.charCodeAt(i)] = i
}
/** Decode a Base58 encoded string. */
export function decode(s: string, size?: number): Bytes {
if (size == null) {
return decodeVar(s)
}
const result = new Uint8Array(size)
for (let i = 0; i < s.length; ++i) {
let carry = charMap[s.charCodeAt(i)]
if (carry < 0) {
throw new DecodingError(
'Invalid Base58 character encountered',
ErrorCode.E_INVALID,
{char: s[i]}
)
}
for (let j = 0; j < size; ++j) {
const x = result[j] * 58 + carry
result[j] = x
carry = x >> 8
}
if (carry) {
throw new DecodingError('Base58 value is out of range', ErrorCode.E_INVALID)
}
}
result.reverse()
return new Bytes(result)
}
/** Decode a Base58Check encoded string. */
export function decodeCheck(encoded: string, size?: number) {
const decoded = decode(encoded, size != null ? size + 4 : size)
const data = decoded.array.subarray(0, -4)
const expected = decoded.array.subarray(-4)
const actual = dsha256Checksum(data)
if (!arrayEquals(expected, actual)) {
throw new DecodingError('Checksum mismatch', ErrorCode.E_CHECKSUM, {
actual,
expected,
data,
hash: 'double_sha256',
})
}
return new Bytes(data)
}
/** Decode a Base58Check encoded string that uses ripemd160 instead of double sha256 for the digest. */
export function decodeRipemd160Check(encoded: string, size?: number, suffix?: string) {
const decoded = decode(encoded, size != null ? size + 4 : size)
const data = decoded.array.subarray(0, -4)
const expected = decoded.array.subarray(-4)
const actual = ripemd160Checksum(data, suffix)
if (!arrayEquals(expected, actual)) {
throw new DecodingError('Checksum mismatch', ErrorCode.E_CHECKSUM, {
actual,
expected,
data,
hash: 'ripemd160',
})
}
return new Bytes(data)
}
/** Encode bytes to a Base58 string. */
export function encode(data: BytesType) {
data = Bytes.from(data)
const result = [] as number[]
for (const byte of data.array) {
let carry = byte
for (let j = 0; j < result.length; ++j) {
const x = (charMap[result[j]] << 8) + carry
result[j] = chars.charCodeAt(x % 58)
carry = (x / 58) | 0
}
while (carry) {
result.push(chars.charCodeAt(carry % 58))
carry = (carry / 58) | 0
}
}
for (const byte of data.array) {
if (byte) {
break
} else {
result.push('1'.charCodeAt(0))
}
}
result.reverse()
return String.fromCharCode(...result)
}
export function encodeCheck(data: BytesType) {
data = Bytes.from(data)
data = data.appending(dsha256Checksum(data.array))
return encode(data)
}
export function encodeRipemd160Check(data: BytesType, suffix?: string) {
data = Bytes.from(data)
data = data.appending(ripemd160Checksum(data.array, suffix))
return encode(data)
}
/** @internal */
function decodeVar(s: string) {
const result: number[] = []
for (let i = 0; i < s.length; ++i) {
let carry = charMap[s.charCodeAt(i)]
if (carry < 0) {
throw new DecodingError(
'Invalid Base58 character encountered',
ErrorCode.E_INVALID,
{char: s[i]}
)
}
for (let j = 0; j < result.length; ++j) {
const x = result[j] * 58 + carry
result[j] = x & 0xff
carry = x >> 8
}
if (carry) {
result.push(carry)
}
}
for (const ch of s) {
if (ch === '1') {
result.push(0)
} else {
break
}
}
result.reverse()
return Bytes.from(result)
}
/** @internal */
function ripemd160Checksum(data: Uint8Array, suffix?: string) {
const input = suffix ? new Uint8Array([...data, ...new TextEncoder().encode(suffix)]) : data
return ripemd160(input).slice(0, 4)
}
/** @internal */
function dsha256Checksum(data: Uint8Array) {
const round1 = sha256(data)
const round2 = sha256(round1)
return round2.slice(0, 4)
}
}
|