diff --git a/gui/EasyDEX-GUI b/gui/EasyDEX-GUI index 0092ac5..ba9ec3a 160000 --- a/gui/EasyDEX-GUI +++ b/gui/EasyDEX-GUI @@ -1 +1 @@ -Subproject commit 0092ac50871b6964e6462f3ba68ac7d1cd8c1421 +Subproject commit ba9ec3ad4d56a9454648b7396afcd16aadc61456 diff --git a/package.json b/package.json index 2c76e0e..5041db4 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "agama", "SuperNET", "komodo", - "pax" + "multicoin", + "wallet", + "spv" ], "author": "SuperNET", "license": "MIT", @@ -33,6 +35,7 @@ "bitcoinforksjs-lib": "git://github.com/bitcoinjs/bitcoinjs-lib#opt-in-bitcoincash-sighash", "bitcoinjs-lib": "^3.2.0", "bitcoinjs-lib-zcash": "git://github.com/karel-3d/bitcoinjs-lib#zcash", + "bitcoinjs-lib-pos": "git://github.com/KomodoPlatform/bitcoinjs-lib-pos", "bluebird": "^3.4.7", "body-parser": "^1.15.2", "buffer-reverse": "^1.0.1", diff --git a/routes/electrumjs/electrumjs.networks.js b/routes/electrumjs/electrumjs.networks.js index e82295c..fcb3848 100644 --- a/routes/electrumjs/electrumjs.networks.js +++ b/routes/electrumjs/electrumjs.networks.js @@ -226,6 +226,7 @@ networks.blk = { scriptHash: 0x55, wif: 0x99, dustThreshold: 1000, + isPoS: true, }; networks.sib = { diff --git a/routes/electrumjs/electrumjs.txdecoder-pos.js b/routes/electrumjs/electrumjs.txdecoder-pos.js new file mode 100644 index 0000000..849a1ad --- /dev/null +++ b/routes/electrumjs/electrumjs.txdecoder-pos.js @@ -0,0 +1,124 @@ +/* +MIT License + +Copyright (c) 2017 Yuki Akiyama, SuperNET + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +var bitcoin = require('bitcoinjs-lib-pos'); +var script = require('bitcoinjs-lib-pos/src/script'); +var address = require('bitcoinjs-lib-pos/src/address'); +var bitcoinJS = require('bitcoinjs-lib'); + +var decodeFormat = function(tx) { + var result = { + txid: tx.getId(), + version: tx.version, + locktime: tx.locktime, + }; + + return result; +} + +var decodeInput = function(tx) { + var result = []; + + tx.ins.forEach(function(input, n) { + var vin = { + txid: input.hash.reverse().toString('hex'), + n: input.index, + script: script.fromHex(input.hash), + sequence: input.sequence, + }; + + result.push(vin); + }); + + return result; +} + +var decodeOutput = function(tx, network) { + var format = function(out, n, network) { + var vout = { + satoshi: out.value, + value: (1e-8 * out.value).toFixed(8), + n: n, + scriptPubKey: { + asm: bitcoinJS.script.toASM(out.script.chunks), + hex: out.script.toHex(), + type: bitcoin.scripts.classifyOutput(out.script), + addresses: [], + }, + }; + + switch(vout.scriptPubKey.type) { + case 'pubkeyhash': + vout.scriptPubKey.addresses.push(address.fromOutputScript(out.script, network)); + break; + case 'pubkey': + const pubKeyBuffer = new Buffer(vout.scriptPubKey.asm.split(' ')[0], 'hex'); + vout.scriptPubKey.addresses.push(bitcoin.ECPair.fromPublicKeyBuffer(pubKeyBuffer, network).getAddress()); + break; + case 'scripthash': + vout.scriptPubKey.addresses.push(address.fromOutputScript(out.script, network)); + break; + } + +console.log(vout); + return vout; + } + + var result = []; + + tx.outs.forEach(function(out, n) { + result.push(format(out, n, network)); + }); + + return result; +} + +var TxDecoder = module.exports = function(rawtx, network) { + try { + const _tx = bitcoin.Transaction.fromHex(rawtx, network); + + return { + tx: _tx, + network: network, + format: decodeFormat(_tx), + inputs: decodeInput(_tx), + outputs: decodeOutput(_tx, network), + }; + } catch (e) { + return false; + } +} + +TxDecoder.prototype.decode = function() { + var result = {}; + var self = this; + + Object.keys(self.format).forEach(function(key) { + result[key] = self.format[key]; + }); + + result.outputs = self.outputs; + + return result; +} \ No newline at end of file diff --git a/routes/shepherd.js b/routes/shepherd.js index fa38930..9d5c26b 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -61,8 +61,6 @@ shepherd.electrumKeys = {}; shepherd.electrumJSCore = require('./electrumjs/electrumjs.core.js'); shepherd.electrumJSNetworks = require('./electrumjs/electrumjs.networks.js'); -shepherd.electrumJSTxDecoder = require('./electrumjs/electrumjs.txdecoder.js'); -shepherd.electrumJSTxDecoderZ = require('./electrumjs/electrumjs.txdecoder-2bytes.js'); shepherd.electrumServers = require('./electrumjs/electrumServers.js'); shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA = 'connection error or incomplete data'; diff --git a/routes/shepherd/electrum/balance.js b/routes/shepherd/electrum/balance.js index 5f9b099..f77bd60 100644 --- a/routes/shepherd/electrum/balance.js +++ b/routes/shepherd/electrum/balance.js @@ -45,7 +45,7 @@ module.exports = (shepherd) => { // decode tx const _network = shepherd.getNetworkData(network); - const decodedTx = shepherd.isZcash(network) ? shepherd.electrumJSTxDecoderZ(_rawtxJSON, _network) : shepherd.electrumJSTxDecoder(_rawtxJSON, _network); + const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, network, _network); if (decodedTx && decodedTx.format && diff --git a/routes/shepherd/electrum/createtx.js b/routes/shepherd/electrum/createtx.js index f109f84..376248f 100644 --- a/routes/shepherd/electrum/createtx.js +++ b/routes/shepherd/electrum/createtx.js @@ -1,11 +1,13 @@ const bitcoinJSForks = require('bitcoinforksjs-lib'); const bitcoinZcash = require('bitcoinjs-lib-zcash'); +const bitcoinPos = require('bitcoinjs-lib-pos'); module.exports = (shepherd) => { // unsigned tx shepherd.buildUnsignedTx = (sendTo, changeAddress, network, utxo, changeValue, spendValue) => { let tx; + // TODO: finish unsigned for zcash, btc forks and pos coins if (network === 'btg') { shepherd.log('enable btg'); tx = new bitcoinJSForks.TransactionBuilder(shepherd.getNetworkData(network)); @@ -54,7 +56,15 @@ module.exports = (shepherd) => { // single sig shepherd.buildSignedTx = (sendTo, changeAddress, wif, network, utxo, changeValue, spendValue) => { let key = shepherd.isZcash(network) ? bitcoinZcash.ECPair.fromWIF(wif, shepherd.getNetworkData(network)) : shepherd.bitcoinJS.ECPair.fromWIF(wif, shepherd.getNetworkData(network)); - let tx = shepherd.isZcash(network) ? new bitcoinZcash.TransactionBuilder(shepherd.getNetworkData(network)) : new shepherd.bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network)); + let tx; + + if (shepherd.isZcash(network)) { + tx = new bitcoinZcash.TransactionBuilder(shepherd.getNetworkData(network)); + } else if (shepherd.isPos(network)) { + tx = new bitcoinPos.TransactionBuilder(shepherd.getNetworkData(network)); + } else { + tx = new shepherd.bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network)); + } shepherd.log('buildSignedTx'); // console.log(`buildSignedTx priv key ${wif}`); @@ -65,10 +75,18 @@ module.exports = (shepherd) => { tx.addInput(utxo[i].txid, utxo[i].vout); } - tx.addOutput(sendTo, Number(spendValue)); + if (shepherd.isPos(network)) { + tx.addOutput(sendTo, Number(spendValue), shepherd.getNetworkData(network)); + } else { + tx.addOutput(sendTo, Number(spendValue)); + } if (changeValue > 0) { - tx.addOutput(changeAddress, Number(changeValue)); + if (shepherd.isPos(network)) { + tx.addOutput(changeAddress, Number(changeValue), shepherd.getNetworkData(network)); + } else { + tx.addOutput(changeAddress, Number(changeValue)); + } } if (network === 'komodo' || @@ -86,7 +104,11 @@ module.exports = (shepherd) => { shepherd.log(tx, true); for (let i = 0; i < utxo.length; i++) { - tx.sign(i, key); + if (shepherd.isPos(network)) { + tx.sign(shepherd.getNetworkData(network), i, key); + } else { + tx.sign(i, key); + } } const rawtx = tx.build().toHex(); diff --git a/routes/shepherd/electrum/interest.js b/routes/shepherd/electrum/interest.js index 8a954e7..aaeef34 100644 --- a/routes/shepherd/electrum/interest.js +++ b/routes/shepherd/electrum/interest.js @@ -19,7 +19,7 @@ module.exports = (shepherd) => { } timestampDiffMinutes -= 59; - shepherd.log(`minutes if statement ${timestampDiffMinutes}`, true); + // shepherd.log(`minutes if statement ${timestampDiffMinutes}`, true); // TODO: check if interest is > 5% yr // calc ytd and 5% for 1 yr diff --git a/routes/shepherd/electrum/listunspent.js b/routes/shepherd/electrum/listunspent.js index b3262e0..180135f 100644 --- a/routes/shepherd/electrum/listunspent.js +++ b/routes/shepherd/electrum/listunspent.js @@ -36,7 +36,7 @@ module.exports = (shepherd) => { // decode tx const _network = shepherd.getNetworkData(network); - const decodedTx = shepherd.isZcash(network) ? shepherd.electrumJSTxDecoderZ(_rawtxJSON, _network) : shepherd.electrumJSTxDecoder(_rawtxJSON, _network); + const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, network, _network); shepherd.log('decoded tx =>', true); shepherd.log(decodedTx, true); diff --git a/routes/shepherd/electrum/network.js b/routes/shepherd/electrum/network.js index 0937079..e201cfa 100644 --- a/routes/shepherd/electrum/network.js +++ b/routes/shepherd/electrum/network.js @@ -1,3 +1,9 @@ +const txDecoder = { + default: require('../../electrumjs/electrumjs.txdecoder.js'), + zcash: require('../../electrumjs/electrumjs.txdecoder-2bytes.js'), + pos: require('../../electrumjs/electrumjs.txdecoder-pos.js'), +}; + module.exports = (shepherd) => { shepherd.isZcash = (network) => { if (network === 'ZEC' || @@ -5,13 +11,28 @@ module.exports = (shepherd) => { network === 'zcash' || network === 'ZCASH' || network === 'HUSH' || - network === 'hush' || - network === 'blk' || - network === 'BLK') { + network === 'hush') { + return true; + } + }; + + shepherd.isPos = (network) => { + if (network === 'BLK' || + network === 'blk') { return true; } }; + shepherd.electrumJSTxDecoder = (rawtx, networkName, network) => { + if (shepherd.isZcash(networkName)) { + return txDecoder.zcash(rawtx, network); + } else if (shepherd.isPos(networkName)) { + return txDecoder.pos(rawtx, network); + } else { + return txDecoder.default(rawtx, network); + } + }; + shepherd.getNetworkData = (network) => { const coin = shepherd.findNetworkObj(network) || shepherd.findNetworkObj(network.toUpperCase()) || shepherd.findNetworkObj(network.toLowerCase()); const coinUC = coin ? coin.toUpperCase() : null; diff --git a/routes/shepherd/electrum/transactions.js b/routes/shepherd/electrum/transactions.js index 8142f0f..a309d7d 100644 --- a/routes/shepherd/electrum/transactions.js +++ b/routes/shepherd/electrum/transactions.js @@ -69,7 +69,7 @@ module.exports = (shepherd) => { // decode tx const _network = shepherd.getNetworkData(network); - const decodedTx = shepherd.isZcash(network) ? shepherd.electrumJSTxDecoderZ(_rawtxJSON, _network) : shepherd.electrumJSTxDecoder(_rawtxJSON, _network); + const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, network, _network); let txInputs = []; shepherd.log(`decodedtx network ${network}`, true); @@ -84,7 +84,7 @@ module.exports = (shepherd) => { if (_decodedInput.txid !== '0000000000000000000000000000000000000000000000000000000000000000') { ecl.blockchainTransactionGet(_decodedInput.txid) .then((rawInput) => { - const decodedVinVout = shepherd.isZcash(network) ? shepherd.electrumJSTxDecoderZ(rawInput, _network) : shepherd.electrumJSTxDecoder(rawInput, _network); + const decodedVinVout = shepherd.electrumJSTxDecoder(rawInput, network, _network); shepherd.log('electrum raw input tx ==>', true); @@ -348,12 +348,12 @@ module.exports = (shepherd) => { shepherd.get('/electrum/decoderawtx', (req, res, next) => { const _network = shepherd.getNetworkData(req.query.network); const _rawtx = req.query.rawtx; - // const _rawtx = '0100000001dd6d064f5665f8454293ecaa9dbb55accf4f7e443d35f3b5ab7760f54b6c15fe000000006a473044022056355585a4a501ec9afc96aa5df124cf29ad3ac6454b47cd07cd7d89ec95ec2b022074c4604ee349d30e5336f210598e4dc576bf16ebeb67eeac3f4e82f56e930fee012103b90ba01af308757054e0484bb578765d5df59c4a57adbb94e2419df5e7232a63feffffff0289fc923b000000001976a91424af38fcb13bbc171b0b42bb017244a53b6bb2fa88ac20a10700000000001976a9142f4c0f91fc06ac228c120aee41741d0d3909683288ac49258b58'; - const decodedTx = shepherd.electrumJSTxDecoder(_rawtx, _network); + console.log(_network); + //const _rawtx = '010000006f2c395a02d81487fc7f9d1be3ea900316730133c044af70cd76d21e988e71de0e9e85918f010000006a47304402202097acd391e1d0eaaf91844bd596e918fb71320e3e0c51554acb71a39e4ee98b0220548fd61d4ae77a08d70b01bf5340983a1ba63f6b71ad71d478af77011f96fd510121031ffc010d8abc4180b4c1a13962bf9153a78082e7f2ac18f7d14cb6a6634ca218feffffff2b31f6c9a7916f7cf128cae94b3fc10e4c74ca3a740e1a7a6fd6624e4e9a5c8b010000006a473044022063f014c5fbaa7614732e0ae486179a854215fc32c02230e13f69b7e81fa000e50220236a2ba6373b1854aafc59c5391ab7505062067f3d293c016cbb5d252b35a56a012102f307f17d282fc0eabf99227c2e0f3122ae9ecd7da0de099f0c6007d4c941b57bfeffffff021b797ad7120000001976a914c7a7142d743b3e6eebe76923f43bae477d3ce31a88acff086d66000000001976a91463800ff36b9c52b2ffe5564af1c2a38df4f0126788ac16381d00'; + const decodedTx = shepherd.electrumJSTxDecoder(_rawtx, req.query.network, _network); shepherd.log('electrum decoderawtx input tx ==>', true); - if (req.query.parseonly || decodedTx.inputs[0].txid === '0000000000000000000000000000000000000000000000000000000000000000') { const successObj = { @@ -373,12 +373,14 @@ module.exports = (shepherd) => { const ecl = new shepherd.electrumJSCore(shepherd.electrumServers[req.query.network].port, shepherd.electrumServers[req.query.network].address, shepherd.electrumServers[req.query.network].proto); // tcp or tls ecl.connect(); + shepherd.log(decodedTx.inputs[0]); + shepherd.log(decodedTx.inputs[0].txid); ecl.blockchainTransactionGet(decodedTx.inputs[0].txid) .then((json) => { ecl.close(); shepherd.log(json, true); - const decodedVin = shepherd.electrumJSTxDecoder(json, _network); + const decodedVin = shepherd.electrumJSTxDecoder(json, req.query.network, _network); const successObj = { msg: 'success', diff --git a/version b/version index 2ded27d..ef2859a 100644 --- a/version +++ b/version @@ -1,3 +1,3 @@ -version=0.2.0.25h -type=h-beta +version=0.2.0.25i +type=i-beta minversion=0.2.0.2 \ No newline at end of file diff --git a/version_build b/version_build index 227e03f..abb893b 100644 --- a/version_build +++ b/version_build @@ -1 +1 @@ -0.2.0.25h-beta \ No newline at end of file +0.2.0.25i-beta \ No newline at end of file