Closed dskloet closed 9 years ago
Looking at the JSON for the transaction before and after de/serializing, it seems to have lost the changeScript
field, and the input has lost the output
field. Passing the unsafe
parameter to serialize
doesn't seem to make a difference.
The unsigned transaction can be converted to JSON and back. The signed transaction can be serialized and deserialzed. But: The unsigned transaction can NOT correctly be serialized and deserialzed, and the signed transaction can NOT correctly be converted to JSON and back.
Hi there! Can you try with the latest version, v0.10.3
and see if you still have this issue? Let me know if you run into further issues. If possible, send the UTXOs and private keys (you can modify them for random values).
Remember that the fee
needs to be set up in satoshis.
I can correctly run this:
var Transaction = require('bitcore').Transaction;
var t = new Transaction()
.from({"address":"3BazTqvkvEBcWk7J4sbgRnxUw6rjYrogf9","txid":"dc2e197ab72f71912c39bc23a42d823a3aa8d469fe65eb591c086e60d14c64a0","vout":0,"ts":1418878014,"scriptPubKey":"a9146c8d8b04c6a1e664b1ec20ec932760760c97688e87","amount":0.00300299,"confirmationsFromCache":false}, ["020483ebb834d91d494a3b649cf0e8f5c9c4fcec5f194ab94341cc99bb440007f2", "0271ebaeef1c2bf0c1a4772d1391eab03e4d96a6e9b48551ab4e4b0d2983eb452b", "03a659828aabe443e2dedabb1db5a22335c5ace5b5b7126998a288d63c99516dd8"], 2)
.to("38nw4sTs3fCH1YiBjYeQAX1t9eWMxpek8Z", 150000)
.change("3BazTqvkvEBcWk7J4sbgRnxUw6rjYrogf9")
.sign("L2U9m5My3cdyN5qX1PH4B7XstGDZFWwyukdX8gj8vsJ3fkrqArQo") // Also tested without this step
.fee(13400);
console.log(t.toJSON());
I used http://bitcore.io/playground/bower_components/bitcore/bitcore.min.js Where can I get the latest version? I've tried installing npm multiple times but it never works so building it myself is not an option.
Your code doesn't try to sign after serializing.
My full code is below. Again, swapping the lines marked // this line
makes it work.
<html>
<head>
<script src="bitcore.min.js"></script>
<script src="bitcore-explorers.min.js"></script>
<head>
<body>
<script>
var bitcore = require('bitcore');
var explorers = require('bitcore-explorers');
var insight = new explorers.Insight('https://test-insight.bitpay.com','testnet');
var fromAddress = 'muPSeU5Zhqt3QGWyxM9RyvcMHKAgacrn91';
var privateKey = 'cQ6XLpaC8PfQeoewDvDjhBLpXdDtWs3C48jjguTrXzJPfsb3iTaG';
var toAddress = 'n2egRNcYDguKApkyK3QT5GtGkeLFZTFq7F';
var amount = 150000;
var fee = 1000;
function main() {
insight.getUnspentUtxos(fromAddress, handleOutputs);
}
function handleOutputs(err, outputs) {
var change = fromAddress;
var tx = new bitcore.Transaction().
from(outputs).
to(toAddress, amount).
change(change).
fee(fee);
tx = new bitcore.Transaction(tx.serialize(true)); // this line
tx = tx.sign(privateKey); // this line
broadcast(tx);
}
function broadcast(tx) {
insight.broadcast(tx, function(err, txid) {
if (err != null) {
window.console.log('Broadcast Error:', err);
} else {
window.console.log('txid:', txid);
}
});
}
window.addEventListener('load', main);
</script>
</body>
</html>
Hi @dskloet,
I'll mark this as a "won't fix at the moment". Please use toJSON
, as serialize
loses information about the outputs that you are trying to spend. If you take a look at toJSON
, you'll see that it contains information about the script from the previous output. We have some ideas to fix this on a further version, I'll keep you posted.
toJSON()
works for the unsigned transaction.
For for the signed transaction toJSON()
doesn't work and only serialize()
works.
By this I mean that if I do
tx = new bitcore.Transaction(tx.toJSON());
before broadcasting the transaction, the broadcast fails.
Tested on both node and the browser:
var bitcore = require('bitcore');
var explorer = require('bitcore-explorers');
var Transaction = bitcore.Transaction;
var insight = new explorer.Insight('https://test-insight.bitpay.com','testnet');
var fromAddress = 'muPSeU5Zhqt3QGWyxM9RyvcMHKAgacrn91';
var privateKey = 'cQ6XLpaC8PfQeoewDvDjhBLpXdDtWs3C48jjguTrXzJPfsb3iTaG';
var toAddress = 'n2egRNcYDguKApkyK3QT5GtGkeLFZTFq7F';
var amount = 150000;
var fee = 1000;
function handleOutputs(err, outputs) {
var change = fromAddress;
var tx = new bitcore.Transaction().
from(outputs).
to(toAddress, amount).
change(change).
fee(fee);
tx1 = new bitcore.Transaction(tx.toJSON());
tx2 = tx1.sign(privateKey);
tx3 = new bitcore.Transaction(tx2.toJSON());
tx4 = tx3.sign(privateKey);
tx5 = new bitcore.Transaction(tx4.toJSON());
tx6 = tx5.sign(privateKey);
console.log(tx6.serialize() === tx2.serialize());
console.log(tx6.toJSON() === tx2.toJSON()); // This may be false because of different serialization orders, but I tried and it turned out to be the same
insight.broadcast(tx6);
}
insight.getUnspentUtxos(fromAddress, handleOutputs);
You can check your bitcore version with require('bitcore').version
! I tested with 0.10.2
. Let me know if you have any further doubts
Does it work if you remove this line tx6 = tx5.sign(privateKey);
?
Why are you signing the transaction 3 times?
My version is 0.10.2. Is 0.10.3 served somewhere or is the only way to get it to build it myself?
And since I have your attention, if you don't mind. I suddenly started getting SyntaxError: Unexpected token T
when doing
var tx = new bitcore.Transaction(json);
while earlier today this was working fine.
Any idea how I can debug this? Which T is unexpected?
The json is
'{"version":1,"inputs":[{"prevTxId":"ab0e7f158ff4801f0d95759c0a35f06f1d0fcb943a64654da0ed061560225f18","outputIndex":0,"sequenceNumber":4294967295,"script":"","output":{"satoshis":1000000,"script":"OP_DUP OP_HASH160 20 0x689eea5c9eb3c296af083cb1c7dbdfce0386d113 OP_EQUALVERIFY OP_CHECKSIG"}},{"prevTxId":"faac3caa6131e5ab873b670039c03eed76faf1962a7aed8d40842e133bbd149a","outputIndex":0,"sequenceNumber":4294967295,"script":"","output":{"satoshis":7200000,"script":"OP_DUP OP_HASH160 20 0x689eea5c9eb3c296af083cb1c7dbdfce0386d113 OP_EQUALVERIFY OP_CHECKSIG"}},{"prevTxId":"e7927380272468a9551204c4f7707cc9d43aafa707874cfb0722901e9bd12869","outputIndex":1,"sequenceNumber":4294967295,"script":"","output":{"satoshis":2199000,"script":"OP_DUP OP_HASH160 20 0x689eea5c9eb3c296af083cb1c7dbdfce0386d113 OP_EQUALVERIFY OP_CHECKSIG"}}],"outputs":[{"satoshis":5000000,"script":"OP_DUP OP_HASH160 20 0x2f1b6a429396647d29cfc7254422e0e167408107 OP_EQUALVERIFY OP_CHECKSIG"},{"satoshis":5398000,"script":"OP_DUP OP_HASH160 20 0x689eea5c9eb3c296af083cb1c7dbdfce0386d113 OP_EQUALVERIFY OP_CHECKSIG"}],"nLockTime":0,"changeScript":"OP_DUP OP_HASH160 20 0x689eea5c9eb3c296af083cb1c7dbdfce0386d113 OP_EQUALVERIFY OP_CHECKSIG","changeIndex":1,"fee":1000}'
Sorry, the error seems to happen while broadcasting. Is something going on with insight at the moment?
Sorry, to pollute this issue. I'll create a new issue.
tx4 = tx3.sign(privateKey);
This line shouldn't be necessary because tx3 was already signed before it was converted to JSON. Mind if I look into fixing this at some point?
I have the following code working:
But if I swap the two lines marked as
// this line
, I get the following error when broadcasting the transaction:Uncaught bitcore.ErrorInvalidState: Invalid state: undefined