-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dogecoin integration #1990
Comments
Swapping out the network should work for most transactions, but unfortunately Doge has a maximum limit much higher than 53 bits, so some transactions will throw errors with number overflows. This especially happens often when trying to spend a utxo you received from an exchange withdrawal. Since the change can easily get larger than 53 bits and PSBT needs to parse the whole parent transaction. If BitcoinJS supported native JS BigInt, then we would be able to fully support Doge. |
Hi @junderw, |
PSBT is merely a transaction builder. It is network agnostic. You can use it with Dogecoin (and in fact I personally know of many implementations that do) When creating a new PSBT you can pass in an options argument which has a network key that you can replace with Doge network info. ie. const psbt = new Psbt({ network: doge }); Where the variable doge contains the network object format defined in network.ts |
As you can see here, using dogecoin network parameters will allow the test to work. const dogecoin = { // <-------- ADD THIS
messagePrefix: '\x19Dogecoin Signed Message:\n',
bech32: 'doge',
bip32: {
public: 0x02facafd,
private: 0x02fac398,
},
pubKeyHash: 0x1e,
scriptHash: 0x16,
wif: 0x9e,
}
const alice = ECPair.fromWIF(
// Changed the WIF key format to match Doge
'QUJJhNSzNZvb57bnACAp76p8rEd6vP4RnLTC7qwKRMEq3VG61eUB',
dogecoin, // <-------- ADD THIS
);
const psbt = new bitcoin.Psbt({ network: dogecoin }); // <-------- ADD THIS
psbt.setVersion(2); // These are defaults. This line is not needed.
psbt.setLocktime(0); // These are defaults. This line is not needed.
psbt.addInput({
// if hash is string, txid, if hash is Buffer, is reversed compared to txid
hash: '7d067b4a697a09d2c3cff7d4d9506c9955e93bff41bf82d439da7d030382bc3e',
index: 0,
sequence: 0xffffffff, // These are defaults. This line is not needed.
// non-segwit inputs now require passing the whole previous tx as Buffer
nonWitnessUtxo: Buffer.from(
'0200000001f9f34e95b9d5c8abcd20fc5bd4a825d1517be62f0f775e5f36da944d9' +
'452e550000000006b483045022100c86e9a111afc90f64b4904bd609e9eaed80d48' +
'ca17c162b1aca0a788ac3526f002207bb79b60d4fc6526329bf18a77135dc566020' +
'9e761da46e1c2f1152ec013215801210211755115eabf846720f5cb18f248666fec' +
'631e5e1e66009ce3710ceea5b1ad13ffffffff01' +
// value in satoshis (Int64LE) = 0x015f90 = 90000
'905f010000000000' +
// scriptPubkey length
'19' +
// scriptPubkey
'76a9148bbc95d2709c71607c60ee3f097c1217482f518d88ac' +
// locktime
'00000000',
'hex',
),
// // If this input was segwit, instead of nonWitnessUtxo, you would add
// // a witnessUtxo as follows. The scriptPubkey and the value only are needed.
// witnessUtxo: {
// script: Buffer.from(
// '76a9148bbc95d2709c71607c60ee3f097c1217482f518d88ac',
// 'hex',
// ),
// value: 90000,
// },
// Not featured here:
// redeemScript. A Buffer of the redeemScript for P2SH
// witnessScript. A Buffer of the witnessScript for P2WSH
});
psbt.addOutput({
// Changed the address to match dogecoin format
address: 'DPZSrvbCvBiAVAX6GpSBw8patJ7K6NaFa4',
value: 80000,
});
psbt.signInput(0, alice);
psbt.validateSignaturesOfInput(0, validator);
psbt.finalizeAllInputs();
assert.strictEqual(
psbt.extractTransaction().toHex(),
'02000000013ebc8203037dda39d482bf41ff3be955996c50d9d4f7cfc3d2097a694a7' +
'b067d000000006b483045022100931b6db94aed25d5486884d83fc37160f37f3368c0' +
'd7f48c757112abefec983802205fda64cff98c849577026eb2ce916a50ea70626a766' +
'9f8596dd89b720a26b4d501210365db9da3f8a260078a7e8f8b708a1161468fb2323f' +
'fda5ec16b261ec1056f455ffffffff0180380100000000001976a914ca0d36044e0dc' +
'08a22724efa6f6a07b0ec4c79aa88ac00000000',
); |
@junderw I am using my own |
That has nothing to do with the network parameters. It means that the Psbt couldn't find your signer's publickey (or its pubkeyhash) anywhere in the inputs. Please make sure you have all the information needed in your inputs and also that you are using the correct key. |
if I am building my transaction with segwit, where should i be adding my publickey in the inputs? |
If it's P2WPKH then the pubkey hash is inside witnessUtxo.script. You most likely are using the wrong key to sign. |
No. Both of them don't require any redeemScript or witnessScript, so the Psbt code will recognize either one. If you can post your pre-signed PSBT and also the hex of your public key, I can help you figure out what's wrong. |
is this the correct way to create a dogecoin address via p2wpkh? I am using your network configuration and getting invalid addresses |
@junderw |
Looks like the pubkey matches the input.
signInputAsync(0, {
publicKey: publicKey!,
sign: async (buffer: Buffer) => {
return (await signer(buffer)).slice(0, -1);
},
}) |
Your signer function might be throwing an exception. |
I am getting a |
Oh yeah. You need the full parent transaction, turn it into a Buffer and add it as nonWitnessUtxo instead of witnessUtxo. |
Also, you are spending 124 DOGE and only sending 1 DOGE, so the fee will be huge. Since it's testnet, you could just skip the fee checks on extractTransaction, but in prod you definitely don't want to skip the fee checks... or you can set a higher fee check threshold (PsbtOptions has an optional parameter) |
@junderw thanks for the heads up!
I am using your dogecoin network configuration and it creates an invalid wallet address |
In your original example for the
|
Just grab the full parent transaction from whatever API that you got your UTXO information from. It's just one big hex string. |
Since I am getting UTXO info from blockdaemon's API should I pass the whole object as a buffer, ie: |
Using the native endpoint: https://docs.blockdaemon.com/reference/how-to-access-dogecoin-api You can access The tx hash you would use to query is |
The native endpoint direction work! |
Try broadcasting it using native endpoint
|
I tried both blockdaemon's universal and native endpoints but got an invalid transaction hash: |
this is also my decoded transaction
|
Your transaction is valid, but the fees are too low. You paid 191 sats in fees, but the minimum fee for DOGE (and probably its testnet too) is much higher than that. Your transaction is 225 bytes and you're paying less than that. 0.85 sats/byte I think 100 sat/byte is the minimum fee to broadcast for doge. So maybe 22500 would work. Maybe a little more since signatures can vary by a byte or two in length. Try 23000 for fees. |
I'm running into a |
That error occurs when the mempool of the node you are trying to broadcast to has another transaction that already spends the same UTXO in one of its inputs. I'm not sure why that would happen. testnet is weird in Bitcoin, but I'm sure it would be even more weird for dogecoin testnet. Maybe ask blockdaemon support. I can't really help you from here. |
Hi, is there an example on how to use bitcoinjs-lib to create a transaction on the dogecoin network?
The text was updated successfully, but these errors were encountered: