-
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
Feature/create tx #160
Feature/create tx #160
Conversation
|
||
return answer; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. It might also be a good idea to be able to set the network. The way the version() function works is that you can either get or set the network. The same thing could work here. If arguments[0] is set, set the network to that network. Otherwise, just get the current network.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setting (changing) the network of an existing address seems strange to me :) Do you think that is a real use case?
I added the same to PrivateKey.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's exactly the same use case as setting the version. You probably wouldn't use it to set the network after, say, creating an address from an address string. But it would be a convenient way to set the network after creating an address from a hash.
For instance, rather than this:
var addr = new bitcore.Address(network.addressVersion, hash);
...which is confusing and has to be looked up every time, to this:
var addr = new bitcore.Address(hash);
addr.network('testnet');
This would require changing the constructor to detect that a buffer was being input as the first argument.
Another possible interface:
var addr = new bitcore.Address('testnet', hash);
Then self.network('testnet') would be called from within the constructor.
I'm not committed to doing this now, maybe this should be in a different PR. But it just occurred to me because the functionality of network() mirrors that of version(), but is more user-friendly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I usually create address which address string, in which the network info is embedded, i didn't think about initializing with a hash.
I like both:
var addr = new bitcore.Address(hash);
addr.network('testnet');
and
var addr = new bitcore.Address('testnet', hash);
both seems simple and straightforward to implement. Will create a new ticket for that, ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added here:
updated with signing capabilities. |
answer = testnet; | ||
|
||
return answer; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my above comment for Address, which is the same for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added here:
#162
Great work on this @matiu . Will continue code reviewing today. |
Updated:
|
Mostly sounds good. I thought it was agreed that signing was a separate operation from create? |
@jgarzik it an be done in 1 step:
Or in 2 (or more):
or
The 1 step creation seems to be a good idea for simpler use cases. |
Certainly for multisig you need to be able to sign it just once, and then pass the partially signed transaction onto others to continue signing. Seems like "signing" should be a separate event that follows creation of the transaction. |
The logic behind making signing a separate step is that it is security-sensitive. Technically signing is easy to incorporate, but making it a separate step forces people to think about what they are signing, IMO (or forces programmers to think about what they are designing). Making it a separate step is easier to test, and more in line with multisig workflow. (note: this is not "do it that way" message, just explaining the rationale) |
Good point. Would you say it shouldn't be possible to make it in one step? I like @matiu's idea of having two ways: the simplified one, with just 1 step:
and the separated one, with:
The other issue I see with this API is that it assumes ouput scripts are pubkeyhash (which is OK for a first simple API, but we should at least be thinking how we would incorporate other tx output types) |
Still code reviewing. I definitely think the .create function should not include the .sign function. Instead, .create should only create, but not sign, the transaction. The two could be combined into a .createAndSign function for convenience. |
How about making it so you can chain the calls, monad-style? All it takes is for the Transaction to keep a pointer to the utxos (it's already in memory, anyway). That way you could chain the calls and have "sign" only take the keys, which considering the above examples: vat tx = Transaction.create(utxos, outs).sign(keys); or vat tx = Transaction.create(utxos,outs)
.sign(key1)
.sign(key2); |
@jrpereira a similar schema was the original proposal, but was discarded to prevent Transaction storing the utxos silently. @ryanxcharles Do you think the most common use case will be to first create and the sign the tx? I like you idea, seems simple to understand, and friendly to new users. Will do that now. |
Since I think the bitcoin world is going to move to multisig, I think the most standard use-case will be to create the transaction first, and then sign it later. Signing it upon creation only makes sense if you have all the keys. |
updated with @ryanxcharles comments. Current constructors are:
related methods: (these needed to be updated to support p2sh)
Used Internally:
|
@ryanxcharles, that makes sense, but doesn't that mean you'll still need the utxos somewhere? Seeing as we're not copying the object (js is copy-on-write, so just storing a pointer to it), isn't the Transaction object an appropriate place to store a reference to this data, particularly if you'll be needing it for later sign operations? There could be something like a .finalize() call that "seals" the transaction and releases the utxos reference. |
@jrpereira I think the current PR address all all the comments: utxos are not stored on the Transaction object. Finally |
@matiu, ACK code changes. Unfortunately there is now a conflict, probably because I pulled in your other PR first. Can you fix the conflicts and update the PR so I can pull it in? |
no prob, working on it. On Tue, Mar 18, 2014 at 12:54 PM, Ryan X. Charles
Matías Alejo Garcia |
updated. |
This implements the method #create in Transactions. Its aims to provide a much simpler interface to create new transactions. Some auxiliary functions were added in Transaction and Address. The test were updated to cover the new code.
The raw output transaction from some given inputs are compared in the tests with the (hardcoded) output of createrawtransaction from bitcoind. The parameters to generate those outputs in bitcoind are included for validation.
In a future PR the transaction signing (#sign) will be implemented.sign
is provided to sign a transaction using a given key array.