Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
328 changes: 303 additions & 25 deletions e2e/infrastructure/TransactionHttp.spec.ts

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
"typescript-require": "^0.2.9-1"
},
"dependencies": {
"@types/crypto-js": "^3.1.43",
"crypto-js": "^3.1.9-1",
"js-joda": "^1.6.2",
"nem2-library": "^0.9.5",
"request": "^2.83.0",
Expand Down
23 changes: 19 additions & 4 deletions src/model/transaction/HashType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,32 @@

/**
* Hash type. Supported types are:
* 0: SHA3_512.
* 0: Op_Sha3_256 (default).
* 1: Op_Keccak_256 (ETH compatibility).
* 2: Op_Hash_160 (first with SHA-256 and then with RIPEMD-160 (BTC compatibility))
* 3: Op_Hash_256: input is hashed twice with SHA-256 (BTC compatibility)
*/
import {convert} from 'nem2-library';

export enum HashType {
SHA3_512 = 0,
Op_Sha3_256 = 0,
Op_Keccak_256 = 1,
Op_Hash_160 = 2,
Op_Hash_256 = 3,
}

export function HashTypeLengthValidator(hashType: HashType, input: string): boolean {
if (hashType === HashType.SHA3_512 && convert.isHexString(input)) {
return input.length === 128;
if (convert.isHexString(input)) {
switch (hashType) {
case HashType.Op_Sha3_256:
case HashType.Op_Hash_256:
case HashType.Op_Keccak_256:
return input.length === 64;
case HashType.Op_Hash_160:
return input.length === 40;
default:
break;
}
}
return false;
}
59 changes: 52 additions & 7 deletions test/model/transaction/HashTypeLengthValidator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,66 @@
* limitations under the License.
*/
import {expect} from 'chai';
import {sha3_256, sha3_512} from 'js-sha3';
import * as CryptoJS from 'crypto-js';
import {keccak_256, sha3_256, sha3_512} from 'js-sha3';
import {HashType, HashTypeLengthValidator} from '../../../src/model/transaction/HashType';

describe('HashTypeLengthValidator', () => {
it('HashType.SHA3_512 should be exactly 128 chars length', () => {
expect(HashTypeLengthValidator(HashType.SHA3_512, sha3_512.create().update('abcxyz').hex())).to.be.equal(true);
it('HashType.SHA3_256 should be exactly 64 chars length', () => {
expect(HashTypeLengthValidator(HashType.Op_Sha3_256, sha3_256.create().update('abcxyz').hex())).to.be.equal(true);
});

it('HashType.SHA3_512 should return false if it is not 128 chars length', () => {
expect(HashTypeLengthValidator(HashType.SHA3_512, sha3_256.create().update('abcxyz').hex())).to.be.equal(false);
it('HashType.SHA3_256 should return false if it is not 64 chars length', () => {
expect(HashTypeLengthValidator(HashType.Op_Sha3_256, sha3_512.create().update('abcxyz').hex())).to.be.equal(false);
});

it('HashType.SHA_512 should return false if it is not a hash valid', () => {
it('HashType.SHA_256 should return false if it is not a hash valid', () => {
const invalidHash = 'zyz6053bb910a6027f138ac5ebe92d43a9a18b7239b3c4d5ea69f1632e50aeef28184e46cd22ded096b76631858' +
'0a569e74521a9d63885cc8d5e8644793be928';
expect(HashTypeLengthValidator(HashType.SHA3_512, invalidHash)).to.be.equal(false);
expect(HashTypeLengthValidator(HashType.Op_Sha3_256, invalidHash)).to.be.equal(false);
});

it('HashType.Keccak_256 should be exactly 64 chars length', () => {
expect(HashTypeLengthValidator(HashType.Op_Keccak_256, keccak_256.create().update('abcxyz').hex())).to.be.equal(true);
});

it('HashType.Keccak_256 should return false if it is not 64 chars length', () => {
expect(HashTypeLengthValidator(HashType.Op_Keccak_256, sha3_512.create().update('abcxyz').toString())).to.be.equal(false);
});

it('HashType.Keccak_256 should return false if it is not a hash valid', () => {
const invalidHash = 'zyz6053bb910a6027f138ac5ebe92d43a9a18b7239b3c4d5ea69f1632e50aeef28184e46cd22ded096b76631858' +
'0a569e74521a9d63885cc8d5e8644793be928';
expect(HashTypeLengthValidator(HashType.Op_Keccak_256, invalidHash)).to.be.equal(false);
});

it('HashType.Op_Hash_256 should be exactly 64 chars length', () => {
// tslint:disable-next-line:max-line-length
expect(HashTypeLengthValidator(HashType.Op_Hash_256, CryptoJS.SHA256(CryptoJS.SHA256('abcxyz').toString(CryptoJS.enc.Hex)).toString(CryptoJS.enc.Hex))).to.be.equal(true);
});

it('HashType.Op_Hash_256 should return false if it is not 64 chars length', () => {
expect(HashTypeLengthValidator(HashType.Op_Hash_256, sha3_512.create().update('abcxyz').toString())).to.be.equal(false);
});

it('HashType.Op_Hash_256 should return false if it is not a hash valid', () => {
const invalidHash = 'zyz6053bb910a6027f138ac5ebe92d43a9a18b7239b3c4d5ea69f1632e50aeef28184e46cd22ded096b76631858' +
'0a569e74521a9d63885cc8d5e8644793be928';
expect(HashTypeLengthValidator(HashType.Op_Hash_256, invalidHash)).to.be.equal(false);
});

it('HashType.Op_Hash_160 should be exactly 40 chars length', () => {
// tslint:disable-next-line:max-line-length
expect(HashTypeLengthValidator(HashType.Op_Hash_160, CryptoJS.RIPEMD160(CryptoJS.SHA256('abcxyz').toString(CryptoJS.enc.Hex)).toString(CryptoJS.enc.Hex))).to.be.equal(true);
});

it('HashType.Op_Hash_160 should return false if it is not 64 chars length', () => {
expect(HashTypeLengthValidator(HashType.Op_Hash_160, sha3_512.create().update('abcxyz').toString())).to.be.equal(false);
});

it('HashType.Op_Hash_160 should return false if it is not a hash valid', () => {
const invalidHash = 'zyz6053bb910a6027f138ac5ebe92d43a9a18b7239b3c4d5ea69f1632e50aeef28184e46cd22ded096b76631858' +
'0a569e74521a9d63885cc8d5e8644793be928';
expect(HashTypeLengthValidator(HashType.Op_Hash_160, invalidHash)).to.be.equal(false);
});
});
122 changes: 112 additions & 10 deletions test/model/transaction/SecretLockTransaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
* limitations under the License.
*/
import {expect} from 'chai';
import {sha3_512} from 'js-sha3';
import * as CryptoJS from 'crypto-js';
import {keccak_256, sha3_256} from 'js-sha3';
import {convert} from 'nem2-library';
import {Address} from '../../../src/model/account/Address';
import {NetworkType} from '../../../src/model/blockchain/NetworkType';
Expand All @@ -26,36 +27,137 @@ import {UInt64} from '../../../src/model/UInt64';

describe('SecretLockTransaction', () => {

it('should be created', () => {
const proof = 'B778A39A3663719DFC5E48C9D78431B1E45C2AF9DF538782BF199C189DABEAC7680ADA57' +
'DCEC8EEE91C4E3BF3BFA9AF6FFDE90CD1D249D1C6121D7B759A001B1';
it('should be created with HashType: Op_Sha3_256 secret', () => {
const proof = 'B778A39A3663719DFC5E48C9D78431B1E45C2AF9DF538782BF199C189DABEAC7';
const recipient = Address.createFromRawAddress('SDBDG4IT43MPCW2W4CBBCSJJT42AYALQN7A4VVWL');
const secretLockTransaction = SecretLockTransaction.create(
Deadline.create(),
XEM.createAbsolute(10),
UInt64.fromUint(100),
HashType.SHA3_512,
sha3_512.create().update(convert.hexToUint8(proof)).hex(),
HashType.Op_Sha3_256,
sha3_256.create().update(convert.hexToUint8(proof)).hex(),
recipient,
NetworkType.MIJIN_TEST,
);
expect(secretLockTransaction.mosaic.id).to.be.equal(XEM.MOSAIC_ID);
expect(secretLockTransaction.mosaic.amount.equals(UInt64.fromUint(10))).to.be.equal(true);
expect(secretLockTransaction.duration.equals(UInt64.fromUint(100))).to.be.equal(true);
expect(secretLockTransaction.hashType).to.be.equal(0);
expect(secretLockTransaction.secret).to.be.equal('d23859866f93f2698a5b48586543c608d85a57c74e9ce92d86a0b25065d' +
'8155c16754d840026b8c536f2bcb963a7d867f034ec241b87162ac33daf7b707cb5f7');
expect(secretLockTransaction.secret).to.be.equal('9b3155b37159da50aa52d5967c509b410f5a36a3b1e31ecb5ac76675d79b4a5e');
expect(secretLockTransaction.recipient).to.be.equal(recipient);
});

it('should throw exception when the input is not related to HashType', () => {
it('should throw exception when the input is not related to HashTyp: Op_Sha3_256', () => {
expect(() => {
const recipient = Address.createFromRawAddress('SDBDG4IT43MPCW2W4CBBCSJJT42AYALQN7A4VVWL');
const secretLockTransaction = SecretLockTransaction.create(
Deadline.create(),
XEM.createAbsolute(10),
UInt64.fromUint(100),
HashType.SHA3_512,
HashType.Op_Sha3_256,
'non valid hash',
recipient,
NetworkType.MIJIN_TEST,
);
}).to.throw(Error);
});

it('should be created with HashType: Op_Keccak_256 secret', () => {
const proof = 'B778A39A3663719DFC5E48C9D78431B1E45C2AF9DF538782BF199C189DABEAC7';
const recipient = Address.createFromRawAddress('SDBDG4IT43MPCW2W4CBBCSJJT42AYALQN7A4VVWL');
const secretLockTransaction = SecretLockTransaction.create(
Deadline.create(),
XEM.createAbsolute(10),
UInt64.fromUint(100),
HashType.Op_Keccak_256,
keccak_256.create().update(convert.hexToUint8(proof)).hex(),
recipient,
NetworkType.MIJIN_TEST,
);
expect(secretLockTransaction.mosaic.id).to.be.equal(XEM.MOSAIC_ID);
expect(secretLockTransaction.mosaic.amount.equals(UInt64.fromUint(10))).to.be.equal(true);
expect(secretLockTransaction.duration.equals(UInt64.fromUint(100))).to.be.equal(true);
expect(secretLockTransaction.hashType).to.be.equal(1);
expect(secretLockTransaction.secret).to.be.equal('241c1d54c18c8422def03aa16b4b243a8ba491374295a1a6965545e6ac1af314');
expect(secretLockTransaction.recipient).to.be.equal(recipient);
});

it('should throw exception when the input is not related to HashTyp: Op_Keccak_256', () => {
expect(() => {
const recipient = Address.createFromRawAddress('SDBDG4IT43MPCW2W4CBBCSJJT42AYALQN7A4VVWL');
const secretLockTransaction = SecretLockTransaction.create(
Deadline.create(),
XEM.createAbsolute(10),
UInt64.fromUint(100),
HashType.Op_Keccak_256,
'non valid hash',
recipient,
NetworkType.MIJIN_TEST,
);
}).to.throw(Error);
});
it('should be created with HashType: Op_Hash_160 secret', () => {
const proof = 'B778A39A3663719DFC5E48C9D78431B1E45C2AF9';
const recipient = Address.createFromRawAddress('SDBDG4IT43MPCW2W4CBBCSJJT42AYALQN7A4VVWL');
const secretLockTransaction = SecretLockTransaction.create(
Deadline.create(),
XEM.createAbsolute(10),
UInt64.fromUint(100),
HashType.Op_Hash_160,
CryptoJS.RIPEMD160(CryptoJS.SHA256(proof).toString(CryptoJS.enc.Hex)).toString(CryptoJS.enc.Hex),
recipient,
NetworkType.MIJIN_TEST,
);
expect(secretLockTransaction.mosaic.id).to.be.equal(XEM.MOSAIC_ID);
expect(secretLockTransaction.mosaic.amount.equals(UInt64.fromUint(10))).to.be.equal(true);
expect(secretLockTransaction.duration.equals(UInt64.fromUint(100))).to.be.equal(true);
expect(secretLockTransaction.hashType).to.be.equal(2);
expect(secretLockTransaction.secret).to.be.equal('3fc43d717d824302e3821de8129ea2f7786912e5');
expect(secretLockTransaction.recipient).to.be.equal(recipient);
});

it('should throw exception when the input is not related to HashTyp: Op_Hash_160', () => {
expect(() => {
const recipient = Address.createFromRawAddress('SDBDG4IT43MPCW2W4CBBCSJJT42AYALQN7A4VVWL');
const secretLockTransaction = SecretLockTransaction.create(
Deadline.create(),
XEM.createAbsolute(10),
UInt64.fromUint(100),
HashType.Op_Hash_160,
'non valid hash',
recipient,
NetworkType.MIJIN_TEST,
);
}).to.throw(Error);
});
it('should be created with HashType: Op_Hash_256 secret', () => {
const proof = 'B778A39A3663719DFC5E48C9D78431B1E45C2AF9DF538782BF199C189DABEAC7';
const recipient = Address.createFromRawAddress('SDBDG4IT43MPCW2W4CBBCSJJT42AYALQN7A4VVWL');
const secretLockTransaction = SecretLockTransaction.create(
Deadline.create(),
XEM.createAbsolute(10),
UInt64.fromUint(100),
HashType.Op_Hash_256,
CryptoJS.SHA256(CryptoJS.SHA256(proof).toString(CryptoJS.enc.Hex)).toString(CryptoJS.enc.Hex),
recipient,
NetworkType.MIJIN_TEST,
);
expect(secretLockTransaction.mosaic.id).to.be.equal(XEM.MOSAIC_ID);
expect(secretLockTransaction.mosaic.amount.equals(UInt64.fromUint(10))).to.be.equal(true);
expect(secretLockTransaction.duration.equals(UInt64.fromUint(100))).to.be.equal(true);
expect(secretLockTransaction.hashType).to.be.equal(3);
expect(secretLockTransaction.secret).to.be.equal('c346f5ecf5bcfa54ab14fad815c8239bdeb051df8835d212dba2af59f688a00e');
expect(secretLockTransaction.recipient).to.be.equal(recipient);
});

it('should throw exception when the input is not related to HashTyp: Op_Hash_256', () => {
expect(() => {
const recipient = Address.createFromRawAddress('SDBDG4IT43MPCW2W4CBBCSJJT42AYALQN7A4VVWL');
const secretLockTransaction = SecretLockTransaction.create(
Deadline.create(),
XEM.createAbsolute(10),
UInt64.fromUint(100),
HashType.Op_Hash_256,
'non valid hash',
recipient,
NetworkType.MIJIN_TEST,
Expand Down
Loading