I'm attempting to make a transaction on the testnet with an OP_RETURN and a change address in it, and then make a second OP_RETURN transaction from first transaction's change address in the same block. The way my code is currently written the second transaction shouldn't rely on the first transaction being processed (it gets coins from a faucet).
Here is a simplified version of my code that maintains the problem (my "write" function is a modified version of this bitcoinjs-lib example):
var assert = require('assert'),
bitcoin = require('bitcoinjs-lib'),
blockchain = new (require('cb-helloblock'))('testnet'),
dynamicKey,
dynamicChangeKey;
connect = function (callback) {
dynamicKey = bitcoin.ECKey.makeRandom();
dynamicChangeKey = bitcoin.ECKey.makeRandom();
write("Connecting to blockchain!", callback);
};
message = function (callback) {
dynamicKey = dynamicChangeKey;
dynamicChangeKey = bitcoin.ECKey.makeRandom();
write("Posting to blockchain!", callback);
};
write = function (arbitraryData, callback) {
var address = dynamicKey.pub.getAddress(bitcoin.networks.testnet).
toString();
blockchain.addresses.__faucetWithdraw(address, 2e4, function (err) {
if (err) return callback(err);
blockchain.addresses.unspents(address, function (err, unspents) {
var tx,
data,
dataScript,
unspent,
txBuilt;
if (err) return callback(err);
tx = new bitcoin.TransactionBuilder();
data = new Buffer(arbitraryData.toString());
dataScript = bitcoin.scripts.nullDataOutput(data);
unspent = unspents.pop();
tx.addInput(unspent.txId, unspent.vout);
tx.addOutput(dataScript, 1000);
tx.addOutput(dynamicChangeKey.pub.getAddress(bitcoin.networks.
testnet).toString(), 1000);
tx.sign(0, dynamicKey);
txBuilt = tx.build();
blockchain.transactions.propagate(txBuilt.toHex(), function (err) {
if (err) return callback(err);
// check that the message was propagated
blockchain.transactions.get(txBuilt.getId(), function (err,
transaction) {
var actual,
dataScript2,
data2;
if (err) return callback(err);
actual = bitcoin.Transaction.fromHex(transaction.txHex);
dataScript2 = actual.outs[0].script;
data2 = dataScript2.chunks[1];
assert.deepEqual(dataScript, dataScript2);
assert.deepEqual(data, data2);
callback();
});
});
});
});
};
log = function (value) {
console.log(value);
};
connect(message.bind(undefined, log));
When running this code the first transaction processes correctly, but the second one returns this error:
{ [AssertionError: Invalid JSend Response {"status":"fail","message":"Propagation unsuccessful","details":"TX rejected"}]
name: 'AssertionError',
actual: false,
expected: true,
operator: '==',
message: 'Invalid JSend Response {"status":"fail","message":"Propagation unsuccessful","details":"TX rejected"}' }
If I change line 15 to read
dynamicKey = bitcoin.ECKey.makeRandom();
instead of
dynamicKey = dynamicChangeKey;
both transactions process correctly, so the problem is definitely in my use of the change key as the next transaction key.
Does anybody know where I'm messing up?