From 43ffce4e2017d553bf7ce89e3e54e1a89cc71edc Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Fri, 14 Nov 2014 16:22:16 -0300 Subject: [PATCH] Address and Transaction docs --- docs/Address.md | 30 +++++++++ docs/Transaction.md | 146 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 docs/Address.md create mode 100644 docs/Transaction.md diff --git a/docs/Address.md b/docs/Address.md new file mode 100644 index 000000000..c5f140993 --- /dev/null +++ b/docs/Address.md @@ -0,0 +1,30 @@ +# Address + +Represents a bitcoin Address. Addresses became the most popular way to make +bitcoin transactions. See [the official Bitcoin +Wiki](https://en.bitcoin.it/wiki/Address) for more information. + +The main use that we expect you'll have for the `Address` class in bitcore is +validating that an address is a valid one, what type of address it is (you may +be interested on knowning if the address is a simple "pay to public key hash" +address or a "pay to script hash" address) and what network does the address +belong to. + +The code to do these validations looks like this: + +```javascript +var address = new bitcore.Address('1BitcoinAddress...'); +assert(address.network === bitcore.network.livenet); +// Detect the kind of the address... +assert(address.type === bitcore.Address.Pay2PubKeyHash); +``` + +There are also static methods for this that work very similarly: + +```javascript +var address = new bitcore.Address(); +assert(bitcore.Address.isValid('1BitcoinAddress...')); +assert(bitcore.Address.network('1BitcoinAddress...') === bitcore.network.livenet); +assert(bitcore.Address.type('1BitcoinAddress...') !== bitcore.Address.Pay2ScriptHash); +assert(bitcore.Address.type('3MultisigP2SH...') === bitcore.Address.Pay2ScriptHash); +``` diff --git a/docs/Transaction.md b/docs/Transaction.md new file mode 100644 index 000000000..bb91bce93 --- /dev/null +++ b/docs/Transaction.md @@ -0,0 +1,146 @@ +# Transaction + +Bitcore provides a very simple API for creating transactions. We expect this +API to be accessible for developers without knowing the working internals of +bitcoin in deep. What follows is a small introduction to transactions with some +basic knowledge required to use this API. + +A Transaction contains a set of inputs and a set of outputs. Each input +contains a reference to another transaction's output, and a signature +that allows the value referenced in that ouput to be used in this transaction. + +Note also that an output can be used only once. That's why there's a concept of +"change address" in the bitcoin ecosystem: if an output of 10 BTC is available +for me to spend, but I only need to transmit 1 BTC, I'll create a transaction +with two outputs, one with 1 BTC that I want to spend, and the other with 9 BTC +to a change address, so I can spend this 9 BTC with another private key that I +own. + +So, in order to transmit a valid transaction, you must know what other transactions +on the network store outputs that have not been spent and that are available +for you to spend (meaning that you have the set of keys that can validate you +own those funds). The unspent outputs are usually refered to as "utxo"s. + +Let's take a look at some very simple transactions: + +```javascript +var transaction = new Transaction() + .from(utxos) // Feed information about what unspend outputs one can use + .to(address, amount) // Add an output with the given amount of satoshis + .change(address) // Sets up a change address where the rest of the funds will go + .sign(privkeySet) // Signs all the inputs it can + +var transaction2 = new Transaction() + .from(utxos) // Feed information about what unspend outputs one can use + .spendAllTo(address) // Spends all outputs into one address + .sign(privkeySet) // Signs all the inputs it can +``` + +Now, one could just serialize this transaction in hexadecimal ASCII values +(`transaction.serialize()`) and send it over to the bitcoind reference client. + +```bash +bitcoin-cli sendrawtransaction +``` + +## Transaction API + +You can take a look at the javadocs for the [Transaction class here](link +missing). This document will go over the expected high level use cases. + +* from(utxo) +* change(address) +* fee(amount) +* usingStrategy(strategy) +* to(address, amount) +* to(pubKeySet, amount) +* addData(opReturnValue) +* sign(privKey) +* sign(privKeySet) +* applySignature(signature) +* missingSignatures() +* isValidSignature(signature) +* getSignatures(privKey) +* getSignatures(privKeySet) +* isFullySigned() +* toBuffer() +* toJSON() + +## Multisig Transactions + +To send a transaction to a multisig address, the API is the same as in the +above example. To spend outputs that require multiple signatures, the process +needs extra information: the public keys of the signers that can unlock that +output. + +```javascript + var multiSigTx = new Transaction() + .fromMultisig(utxo, publicKeys) + .spendAllTo(address, amount) + .sign(myKeys); + + var serialized = multiSigTx.serialize(); +``` + +This can be serialized and sent to another party, to complete with the needed +signatures: + +```javascript + var multiSigTx = new Transaction(serialized) + .sign(anotherSetOfKeys); + + assert(multiSigTx.isFullySigned()); +``` + +## Advanced topics + +### Unspent Output Selection + +If you have a larger set of unspent outputs, only some of them will be selected +to fulfill the amount. This is done by storing a cache of unspent outputs in a +protected member called `_utxos`. When the `to()` method is called, some of +these outputs will be selected to pay the requested amount to the appropiate +address. + +There are some nits that you should have in mind when using this API: + + * When a signature is added, the corresponding utxo is removed from the cache. + * When the transaction is serialized, this cache is not included in the + serialized form. + +#### Spending Strategies + +We have implemented partially Merge Avoidance for the change +addresses of a transaction with a simple API: + +``` + var mergeAvoidance = new Transaction.Strategy.MergeAvoidance({ + change: ['1bitcoinChange...', '3bitcoinChange...'] + }); + var transaction = new Transaction() + .usingStrategy(mergeAvoidance) + .to(['1target...', '3anaddress...'], amount) +``` + +Note that this will not create multiple transactions, which would increase +privacy. The `MergeAvoidance` API will take care that the target and change +addresses provided will receive as equally distributed outputs as possible, +using a simple algorithm. + +In the future, if a Stealth Address is provided to the `to` method and the +strategy being used is `MergeAvoidance`, it will derive as many addresses as +needed according to the utxos received. In a similar fashion, we are discussing +how to provide an API for using an extended public key to derive change +addresses, but as the user of the library should be in control of the policy +for deriving keys (so no transaction outputs gets unnoticed), it's proving to +be a hard problem to solve and it may end up being the user's responsability. + +## Upcoming changes + +We're debating an API for full Merge Avoidance, CoinJoin, Smart contracts, +CoinSwap, and Stealth Addresses. We're expecting to have all of them by some +time in 2015. + +A first draft of a Payment Channel smart contract modular extension to this +library is being implemented independently +(https://github.com/eordano/bitcore-channel).