Skip to content
This repository was archived by the owner on Dec 5, 2019. It is now read-only.

Commit 1388d6f

Browse files
committed
Improved isValidAddress Function and added tests
1 parent 76b0af2 commit 1388d6f

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed

src/packages/core/common.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
export const HASH_LENGTH = 34;
22
export const ADDRESS_LENGTH = 23;
3+
export const DEFAULT_ADDRESS_TYPE = 1;
4+
export const CONTRACT_ADDRESS_TYPE = 2;
35
export const P2SH_ADDRESS_TYPE = 3;
6+
7+
export const MAIN_NET_VERSION = 1;
8+
49
export const CONSENSUS_LOCK_TIME = -1;
510

611
export const BLACK_HOLE_ADDRESS = 'Nse5FeeiYk1opxdc5RqYpEWkiUDGNuLs';
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { isValidAddress } from '../crypto';
2+
3+
jest.unmock('crypto');
4+
jest.unmock('secp256k1');
5+
6+
describe('Address validation checks', () => {
7+
8+
beforeEach(() => {
9+
jest.restoreAllMocks();
10+
});
11+
12+
it('check validity of different addresses', () => {
13+
14+
expect(isValidAddress("TTavFTDgdQNeYgVQBaNTF6SeK54nswH5")).toEqual(true);
15+
expect(isValidAddress("Nsdwnd4auFisFJKU6iDvBxTdPkeg8qkB")).toEqual(true);
16+
expect(isValidAddress("Nse3uLgeCBWP48GCGh8L54gnELfpnSG9")).toEqual(true);
17+
expect(isValidAddress("NseBuUpi4iwbJsj1UrUb4eiAWav9UY4C")).toEqual(true);
18+
expect(isValidAddress("Nse7MZAwVTbdWXxWwgN6vfcPwBYC1izz")).toEqual(true);
19+
20+
21+
expect(isValidAddress("avFTDgdQNeYgVQBaNTF6SeK54nswH5")).toEqual(false);
22+
expect(isValidAddress("TTavFTDgdQNeYgVQBaNTF6SeK54nswH5DXXD")).toEqual(false);
23+
expect(isValidAddress("")).toEqual(false);
24+
25+
});
26+
});

src/packages/core/utils/crypto.ts

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@ import * as bs58 from 'bs58';
22
import RIPEMD160 from 'ripemd160';
33
import * as secp256k1 from 'secp256k1';
44
import * as shajs from 'sha.js';
5-
import { HASH_LENGTH } from '../common';
5+
import {
6+
HASH_LENGTH,
7+
ADDRESS_LENGTH,
8+
P2SH_ADDRESS_TYPE,
9+
DEFAULT_ADDRESS_TYPE,
10+
CONTRACT_ADDRESS_TYPE,
11+
} from '../common';
612
import { isHex } from './serialize';
713

814
export const PRIVATE_KEY_LENGTH = 64;
@@ -53,9 +59,50 @@ export function isValidPrivateKey(privateKey: string): boolean {
5359

5460
}
5561

62+
/*
63+
https://github.com/nuls-io/nuls/blob/b8e490a26eeec7b16d924d8398a67ede24ff86ca/core-module/kernel/src/main/java/io/nuls/kernel/utils/AddressTool.java#L77-L117
64+
*/
5665
export function isValidAddress(address: string): boolean {
5766

58-
return /^(Ns|TT)([a-zA-Z-0-9]{30})$/.test(address);
67+
if(!/^(Ns|TT)([a-zA-Z-0-9]{30})$/.test(address))
68+
return false;
69+
70+
let bytes: Buffer;
71+
72+
try {
73+
bytes = Buffer.from(bs58.decode(address));
74+
if(bytes.length != ADDRESS_LENGTH + 1)
75+
return false;
76+
} catch {
77+
return false;
78+
}
79+
80+
let chainId: Number;
81+
let type: Number;
82+
83+
try {
84+
chainId = bytes.readInt16LE(0);
85+
//bytes.readInt16LE(0);
86+
type = bytes.readInt8(2);
87+
//console.log("Chain ID is ");
88+
//console.log(chainId);
89+
//console.log("Type is ");
90+
//console.log(type);
91+
} catch {
92+
return false;
93+
}
94+
95+
if (DEFAULT_ADDRESS_TYPE != type && CONTRACT_ADDRESS_TYPE != type && P2SH_ADDRESS_TYPE != type) {
96+
return false;
97+
}
98+
99+
try {
100+
checkXOR(bytes);
101+
} catch {
102+
return false;
103+
}
104+
105+
return true;
59106

60107
}
61108

@@ -89,6 +136,19 @@ export function getXOR(bytes: Buffer): number {
89136

90137
}
91138

139+
/*
140+
https://github.com/nuls-io/nuls/blob/b8e490a26eeec7b16d924d8398a67ede24ff86ca/core-module/kernel/src/main/java/io/nuls/kernel/utils/AddressTool.java#L169-L183
141+
*/
142+
export function checkXOR(hashs: Buffer) {
143+
144+
var body: Buffer = hashs.slice(0, ADDRESS_LENGTH);
145+
let xor = getXOR(body);
146+
147+
if (xor != hashs[ADDRESS_LENGTH]) {
148+
throw new Error('Nuls Runtime Exception: Data Error (10014)');
149+
}
150+
}
151+
92152
export function addressFromHash(hash: AddressHash): string {
93153

94154
return bs58.encode(Buffer.concat([hash, Buffer.from([getXOR(hash)])]));

0 commit comments

Comments
 (0)