UNPKG

bitcore-lib-cash

Version:

A pure and powerful JavaScript Bitcoin Cash library.

140 lines (135 loc) 8.39 kB
'use strict'; const bitcore = require('../..'); const Hash = bitcore.crypto.Hash; const Script = bitcore.Script; const PublicKey = bitcore.PublicKey; const Escrow = require('../../lib/script/escrow'); const checkScriptOperations = (operations, expectedScriptString) => { const script = new Script(); operations.forEach(operation => script.add(operation)); script.toString().should.equal(expectedScriptString); }; describe('Escrow', () => { const zeroHashed = Hash.sha256ripemd160(Buffer.alloc(0)); describe('#getMerkleRoot', () => { it('should properly hash a 2-level tree of zeros', () => { const merkleRoot = Escrow.getMerkleRoot([zeroHashed, zeroHashed, zeroHashed, zeroHashed]); merkleRoot.toString('hex').should.equal('bcd72713b594ea45d44512ca7912c625f7e69092'); }); }); describe('#generateMerkleRootFromPublicKeys', () => { it('should work for 3 public keys', () => { const publicKeyStrings = [ '03fb0ed01700a2e9303f76ec93c61114507d9ea9bb3704c873fa8c1c7f4fad0a49', '02cc0cbe9725cea57e475b8cf8fef5556df5c4a73a912a167ee3e170fa1172725a', '0312e866a0b1dd1221a79729907f45672ad0ee426f1234f5f44c447000daa42341' ]; const publicKeys = publicKeyStrings.map(publicKeyString => PublicKey.fromString(publicKeyString)); const merkleRoot = Escrow.generateMerkleRootFromPublicKeys(publicKeys); merkleRoot.toString('hex').should.equal('8001321ef1822edc229a5387b181d6f8d18515cc'); }); it('should fill empty slots with zeros', () => { const publicKeyStrings = [ '033c7364c06498e9d31ac5ba32c5071080a25c481ba3222df32a1839cdc57c1036', '034c6f4984b35e4260e441c6eccb90f382e02c497aa1d2dc20029887272a37d2c4', '0284f6810dc878d9fda1843f05404f22dbc1d1837bba80efb011ebca832bbe728a', '0379116c71638ad1264d1c54faebb6a1c00f1bd187faf32707d02ae2252d706971', '03e62689382e81452f0b95220fff4443521dc4248938168280d76b79984876e61d' ].sort(); const publicKeys = publicKeyStrings.map(publicKeyString => PublicKey.fromString(publicKeyString)); const publicKeyHashes = publicKeys.map(publicKey => Hash.sha256ripemd160(publicKey.toBuffer())); Escrow.getMerkleRoot([...publicKeyHashes, zeroHashed, zeroHashed, zeroHashed]).should.eql( Escrow.generateMerkleRootFromPublicKeys(publicKeys.map(buffer => new PublicKey(buffer))) ); }); }); describe('#generateInputPublicKeyValidationOperations', () => { it('should work for a single input public key', () => { const publicKey = PublicKey.fromString('03fb0ed01700a2e9303f76ec93c61114507d9ea9bb3704c873fa8c1c7f4fad0a49'); checkScriptOperations( Escrow.generateInputPublicKeyValidationOperations([publicKey]), `OP_DUP OP_HASH160 20 0x2a42558df3ea6f2a438251374d7bd61c81f09f96 OP_EQUALVERIFY` ); }); it('should work for two input public keys', () => { const publicKeyStrings = [ '02cc0cbe9725cea57e475b8cf8fef5556df5c4a73a912a167ee3e170fa1172725a', '0312e866a0b1dd1221a79729907f45672ad0ee426f1234f5f44c447000daa42341' ]; const publicKeys = publicKeyStrings.map(publicKeyString => PublicKey.fromString(publicKeyString)); checkScriptOperations( Escrow.generateInputPublicKeyValidationOperations(publicKeys), `OP_TOALTSTACK OP_1 OP_PICK OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 20 0x39a9d954ed1db3c2adbc413995f4e0589d39827e OP_EQUALVERIFY` ); }); it('should work for three input public keys', () => { const publicKeyStrings = [ '03fb0ed01700a2e9303f76ec93c61114507d9ea9bb3704c873fa8c1c7f4fad0a49', '02cc0cbe9725cea57e475b8cf8fef5556df5c4a73a912a167ee3e170fa1172725a', '0312e866a0b1dd1221a79729907f45672ad0ee426f1234f5f44c447000daa42341' ]; const publicKeys = publicKeyStrings.map(publicKeyString => PublicKey.fromString(publicKeyString)); checkScriptOperations( Escrow.generateInputPublicKeyValidationOperations(publicKeys), `OP_TOALTSTACK OP_TOALTSTACK OP_2 OP_PICK OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 20 0x8001321ef1822edc229a5387b181d6f8d18515cc OP_EQUALVERIFY` ); }); it('should work for four input public keys', () => { const publicKeyStrings = [ '02bc1d5f978c6147dc70db39d88e33026f8e2d5cdb99b925944a06a1cce1be87c0', '03ebc008265ae249a805f647bf9623d74071ce66dbb3a8674cd1f99e1dfa81f550', '0269419378d0a7e5860495e95038da9b02203cb772ab5618c29d82ec8eae6a0781', '02f50aa80526676b0c6058c0daed0b6bbacfac17cf7879cd45130dc8dc3a3be873' ]; const publicKeys = publicKeyStrings.map(publicKeyString => PublicKey.fromString(publicKeyString)); checkScriptOperations( Escrow.generateInputPublicKeyValidationOperations(publicKeys), `OP_TOALTSTACK OP_TOALTSTACK OP_2 OP_PICK OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 20 0x13b0df96f790ce4188d3d6c30e75518e646d9d23 OP_EQUALVERIFY` ); }); it('should work for five input public keys', () => { const publicKeyStrings = [ '033c7364c06498e9d31ac5ba32c5071080a25c481ba3222df32a1839cdc57c1036', '034c6f4984b35e4260e441c6eccb90f382e02c497aa1d2dc20029887272a37d2c4', '0284f6810dc878d9fda1843f05404f22dbc1d1837bba80efb011ebca832bbe728a', '0379116c71638ad1264d1c54faebb6a1c00f1bd187faf32707d02ae2252d706971', '03e62689382e81452f0b95220fff4443521dc4248938168280d76b79984876e61d' ]; const publicKeys = publicKeyStrings.map(publicKeyString => PublicKey.fromString(publicKeyString)); checkScriptOperations( Escrow.generateInputPublicKeyValidationOperations(publicKeys), `OP_TOALTSTACK OP_TOALTSTACK OP_TOALTSTACK OP_3 OP_PICK OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 20 0x82a74acda5701d011090ad0039f2aa25a8724c85 OP_EQUALVERIFY` ); }); it('should work for nine public keys', () => { const publicKeyStrings = [ '03e1d90a373b55b97fb633868698b2368b343a96b595fdb7ec270be2d3978c754a', '03907a5e9d51332a6f0c2b24b3bffff2ab099a3f332aa8f578d1ff64305b44c8de', '03fe269d30823cc4cc54c1e6b4366ecef3a51085de9a81c69baa1889dd8433883f', '0276ae3947cab8b51e9e80d93fd8339af04ccc1731c917e75887d958bbfd3b9af7', '02270f250ad4680e3c12846d50e87cd940a0a054bbb1e396d2791f29ea26547b19', '02ea05929efe64d41ce0b12d65525ca9b56e477d948c9a3580dfa9ec37b6af6cdc', '0360971cda4738b25af57b8a7b50536df280c9ed1336c294ea9d60b44b49d982c9', '025d273be791dcd72f5bc81d15599fb54bb107c8a784d96bb3d2751d70d12c5d5d', '0301ce14bcadae1c49beec6575c00969888351c3cd20d0e6cb7713668ce8cc37d9' ]; const publicKeys = publicKeyStrings.map(publicKeyString => PublicKey.fromString(publicKeyString)); checkScriptOperations( Escrow.generateInputPublicKeyValidationOperations(publicKeys), `OP_TOALTSTACK OP_TOALTSTACK OP_TOALTSTACK OP_TOALTSTACK OP_4 OP_PICK OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 OP_FROMALTSTACK OP_IF OP_SWAP OP_ENDIF OP_CAT OP_HASH160 20 0xa047442c13494553dbf18c98132605b0b708c71d OP_EQUALVERIFY` ); }); }); describe('#generateRedeemScriptOperations', () => { it('should work for a single input public key', () => { const inputPublicKey = PublicKey.fromString('03fb0ed01700a2e9303f76ec93c61114507d9ea9bb3704c873fa8c1c7f4fad0a49'); const redeemPublicKey = PublicKey.fromString( '03e1d90a373b55b97fb633868698b2368b343a96b595fdb7ec270be2d3978c754a' ); checkScriptOperations( Escrow.generateRedeemScriptOperations([inputPublicKey], redeemPublicKey), `OP_DUP OP_HASH160 20 0x98c24d8118bbb6b0baaa5926f441978fca0aea36 OP_EQUAL OP_IF OP_CHECKSIG OP_ELSE OP_DUP OP_HASH160 20 0x2a42558df3ea6f2a438251374d7bd61c81f09f96 OP_EQUALVERIFY OP_OVER OP_4 OP_PICK OP_EQUAL OP_NOT OP_VERIFY OP_DUP OP_TOALTSTACK OP_CHECKDATASIGVERIFY OP_FROMALTSTACK OP_CHECKDATASIG OP_ENDIF` ); }); }); });