bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.68k stars 2.1k forks source link

What changes need to be done for LTC, ZCASH, DOGE, DASH + Their TESTNET #1696

Closed vipertechofficial closed 3 years ago

vipertechofficial commented 3 years ago

This code is actually working great without managing error, yet I've asked myself if it was possible to do the same for the crypto in the issues' title...

function _get_btc_account_by_seed(seed) {

    const seeed = bip39.mnemonicToSeedSync(seed);
    const root = bip32.fromSeed(seeed, bitcoin.networks.testnet);

    const path = "m/49'/1'/0'/0/0";
    const child = root.derivePath(path);

    const _wif = child.toWIF();
    const key_pair = bitcoin.ECPair.fromWIF(_wif.toString(), bitcoin.networks.testnet);

    return {key_pair: key_pair, child: child};
}

function get_btc_address_by_seed(seed) {

    let { child } = _get_btc_account_by_seed(seed);
    return bitcoin.payments.p2pkh({ pubkey: child.publicKey, network: bitcoin.networks.testnet }).address;
}

function send_btc_transaction(seed, address, amount, memo, callback_function) {

    const my_address = get_btc_address_by_seed(seed);
    const { key_pair } = _get_btc_account_by_seed(seed);

    function add_unspent_output(error, response) {

        const amount_satoshis = Math.floor(amount * 100000000);
        let tx = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
        const txfeemin = 1000;
        let balance = 0;
        let input_count = 0;

        /*const data = new Buffer(memo); // Message is inserted
        const data_script = bitcoin.script.nullDataOutput(data);
        tx.addOutput(data_script, 0);*/

        if(!error) {

            if(response.data) {
                if(response.data.txs) {

                    response.data.txs.forEach(function(uo) {

                        tx.addInput(uo.txid, uo.output_no, uo.output_no, uo.script);
                        balance += Math.round(uo.value * 100000000);
                        input_count++;

                    });

                    let txfee = txfeemin;
                    //Estimate transaction size in bytes
                    const txSize = input_count * 180 + 2 * 34 + 10 + input_count;
                    //Blockchain: Minimum fee is 1.5 satoshi / Byte
                    if (txSize * 2 > txfeemin){
                        txfee = txSize * 2;
                    }

                    tx.addOutput(address, amount_satoshis);
                    tx.addOutput(my_address, balance - (amount_satoshis + txfee));

                    for (let i = 0; i < input_count; i++){

                        tx.sign(i, key_pair);
                    }

                    let tx_hex = tx.build().toHex();

                    function send_transaction_callback(error, response) {

                        callback_function(error, response);
                    }

                    postDATA("https://chain.so/api/v2/send_tx/BTCTEST", "tx_hex=" + tx_hex, send_transaction_callback);
                }
            }

        }

    }

    loadJSON('https://chain.so/api/v2/get_tx_unspent/BTCTEST/' + my_address, add_unspent_output);

}

In the documentation it seems to be said that the network parameter object need to be configured as such, yet 1) we're talking about not the testnet and some issues refer to use https://github.com/cryptocoinjs/coininfo to generate this network object for testnet and other currency.

const LITECOIN = {
      messagePrefix: '\x19Litecoin Signed Message:\n',
      bech32: 'ltc',
      bip32: {
        public: 0x019da462,
        private: 0x019d9cfe,
      },
      pubKeyHash: 0x30,
      scriptHash: 0x32,
      wif: 0xb0,
    };

Hacking a bit the way (we) can use issues, I will prefer to post my solutions in comments until everything will work, so if someone find a better way or solutions before me, please, write it down, I am pretty sure this issue will help a lot of developer.

As soon as all the solutions are found and tested, this issue should be closed.

PS: I use sochain.com api.

junderw commented 3 years ago

We only officially support Bitcoin.

Other coins similar to bitcoin are easy to use with this library due to all network-specific parameters being contained in the network object. So if you know all the parameters needed for your coin, it should work.

However, that being said some coins change a lot of things from bitcoin. Especially if the transaction format changes or the address format changes beyond a version number change (ie. byte length of version grows etc.).

For those types of coins, this library will not work for those areas where bitcoin and that coin differ.


Whether or not those coins are compatible or not is something the developer must look into.

I am fairly certain LTC will work with only a network object change.

vipertechofficial commented 3 years ago

Ok I'll get myself to get ok with theses other coins {{maybe}} using this library.

Anderson-Juhasc commented 3 years ago

@vipertechofficial try to use my libraries, I think it will solve your problems: https://www.npmjs.com/~andersonjuhasc

Anderson-Juhasc commented 3 years ago

@vipertechofficial for Dogecoin I did this: https://gist.github.com/Anderson-Juhasc/e6975cc51116742b650d1d9cefffa4af

vipertechofficial commented 3 years ago

@Anderson-Juhasc Thanks

vipertechofficial commented 3 years ago

@Anderson-Juhasc "https://github.com/cryptocoinjs/coininfo " is very useful but wrong for zcash and doge.

Work with my example using coininfo and your gist for doge and by the way your bip84 lib looks cool!

`

I can't find the right zcash network param, can you?

junderw commented 3 years ago

zcash address version bytes are 2 bytes long.

bitcoinjs-lib only supports 1 byte versions.

Anderson-Juhasc commented 3 years ago

@vipertechofficial you can try here https://iancoleman.io/bip39/

vipertechofficial commented 3 years ago

Useful for those who want to estimate fees without hard parameters. [OT but relevant]

function get_btc_fee_per_byte(callback_function) {

    function extract_value(error, result) {

        if(!error) {

            const satoshi = result.data.suggested_transaction_fee_per_byte_sat;
            callback_function(null, satoshi);
        }else {

            callback_function(error, null);
        }
    }

    loadJSON("https://api.blockchair.com/bitcoin/stats", extract_value)
}
vipertechofficial commented 3 years ago

Okay for those who want to be able to use any coins mentioned in the issue's title, just put the piece together with https://github.com/bitcoinjs/bitcoinjs-lib/pull/1351/commits/38e0f833504e68bff32ddf80e23b969111a01e0a too and that's it.

Thanks to all.

ghost commented 2 years ago

@vipertechofficial Hi, I try create zcash wallet from mnemonic but get some errors. I use "bitcoinjs-lib": "5.1.1" & "coininfo": "^5.2.1". Can you guide me?