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 detail. 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 output 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 referred to as "utxo"s.

Let's take a look at some very simple transactions:

var transaction = new Transaction()
    .from(utxos)          // Feed information about what unspent 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

You can obtain the input and output total amounts of the transaction in satoshis by accessing the fields inputAmount and outputAmount.

Now, this could just be serialized to hexadecimal ASCII values (transaction.serialize()) and sent over to the bitcoind reference client.

bitcoin-cli sendrawtransaction <serialized transaction>

You can also override the fee estimation with another amount, specified in satoshis:

var transaction = new Transaction().fee(5430); // Minimum non-dust amount
var transaction = new Transaction().fee(1e8);  // Generous fee of 1 BTC

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.

var multiSigTx = new Transaction()
    .from(utxo, publicKeys, threshold)
    .change(address)
    .sign(myKeys);

var serialized = multiSigTx.toObject();

This can be serialized and sent to another party, to complete with the needed signatures:

var multiSigTx = new Transaction(serialized)
    .sign(anotherSetOfKeys);

assert(multiSigTx.isFullySigned());

Also, you can just send over the signature for your private key:

var multiSigTx = new Transaction()
    .from(utxo, publicKeys, threshold)
    .change(address);

var signature = multiSigTx.getSignatures(privateKey)[0];
console.log(JSON.stringify(signature));
console.log(signature.toObject());
console.log(signature.signature.toString()); // Outputs a DER signature
console.log(signature.sigtype);

Transfer that over the wire, and on the other side, apply it to a transaction:

assert(transaction.isValidSignature(receivedSig));
transaction.applySignature(receivedSig);

Adding inputs

Transaction inputs are instances of either Input or its subclasses. Input has some abstract methods, as there is no actual concept of a "signed input" in the bitcoin scripting system (just valid signatures for OP_CHECKSIG and similar opcodes). They are stored in the input property of Transaction instances.

Bitcore contains two implementations of Input, one for spending Pay to Public Key Hash outputs (called PublicKeyHashInput) and another to spend Pay to Script Hash outputs for which the redeem script is a Multisig script (called MultisigScriptHashInput).

All inputs have the following five properties:

  • prevTxId: a Buffer with the id of the transaction with the output this input is spending
  • outputIndex: a number the index of the output in the previous transaction
  • sequenceNumber: a number, the sequence number, see bitcoin's developer guide on nLockTime and the sequence number.
  • script: the Script instance for this input. Usually called scriptSig in the bitcoin community.
  • output: if available, a Output instance of the output associated with this input.

Both PublicKeyHashInput and MultisigScriptHashInput cache the information about signatures, even though this information could somehow be encoded in the script. Both need to have the output property set in order to calculate the sighash so signatures can be created.

Some methods related to adding inputs are:

  • from: A high level interface to add an input from a UTXO. It has a series of variants:

    • from(utxo): add an input from an Unspent Transaction Output. Currently, only P2PKH outputs are supported.
    • from(utxos): same as above, but passing in an array of Unspent Outputs.
    • from(utxo, publicKeys, threshold): add an input that spends a UTXO with a P2SH output for a Multisig script. The publicKeys argument is an array of public keys, and threshold is the number of required signatures in the Multisig script.
  • addInput: Performs a series of checks on an input and appends it to the end of the input vector and updates the amount of incoming bitcoins of the transaction.

  • uncheckedAddInput: adds an input to the end of the input vector and updates the inputAmount without performing any checks.

PublicKeyHashInput

This input uses the script property to mark the input as unsigned if the script is empty.

MultisigScriptHashInput

This input contains a set of signatures in a signatures property, and each time a signature is added, a potentially partial and/or invalid script is created. The isFullySigned method will only return true if all needed signatures are already added and valid. If addSignature is added after all need signatures are already set, an exception will be thrown.

Signing a Transaction

The following methods are used to manage signatures for a transaction:

  • getSignatures: takes an array of PrivateKey or strings from which a PrivateKey can be instantiated; the transaction to be signed; the kind of signature hash to use. Returns an array of objects with the following properties:

    • signature: an instance of Signature
    • prevTxId: this input's prevTxId,
    • outputIndex: this input's outputIndex,
    • inputIndex: this input's index in the transaction
    • sigtype: the "sighash", the type of transaction hash used to calculate the signature
    • publicKey: a PublicKey of the PrivateKey used to create the signature
  • addSignature: takes an element outputed by getSignatures and applies the signature to this input (modifies the script to include the new signature).

  • clearSignatures: removes all signatures for this input
  • isFullySigned: returns true if the input is fully signed

Handling Outputs

Outputs can be added by:

  • The addOutput(output) method, which pushes an Output to the end of the outputs property and updates the outputAmount field. It also clears signatures (as the hash of the transaction may have changed) and updates the change output.
  • The to(address, amount) method, that adds an output with the script that corresponds to the given address. Builds an output and calls the addOutput method.
  • Specifying a change address

To remove all outputs, you can use clearOutputs(), which preserves change output configuration.

Serialization

There are a series of methods used for serialization:

  • toObject: Returns a plain JavaScript object with no methods and enough information to fully restore the state of this transaction. Using other serialization methods (except for toJSON) will cause a some information to be lost.
  • toJSON: Will be called when using JSON.stringify to return JSON-encoded string using the output from toObject.
  • toString or uncheckedSerialize: Returns an hexadecimal serialization of the transaction, in the serialization format for bitcoin.
  • serialize: Does a series of checks before serializing the transaction
  • inspect: Returns a string with some information about the transaction (currently a string formatted as <Transaction 000...000>, that only shows the serialized value of the transaction.
  • toBuffer: Serializes the transaction for sending over the wire in the bitcoin network
  • toBufferWriter: Uses an already existing BufferWriter to copy over the serialized transaction

Serialization Checks

When serializing, the bitcore library performs a series of checks. These can be disabled by providing an object to the serialize method with the checks that you'll like to skip.

  • disableLargeFees avoids checking that the fee is no more than Transaction.FEE_PER_KB * Transaction.FEE_SECURITY_MARGIN * size_in_kb.
  • disableSmallFees avoids checking that the fee is less than Transaction.FEE_PER_KB * size_in_kb / Transaction.FEE_SECURITY_MARGIN.
  • disableIsFullySigned does not check if all inputs are fully signed
  • disableDustOutputs does not check for dust outputs being generated
  • disableMoreOutputThanInput avoids checking that the sum of the output amounts is less than or equal to the sum of the amounts for the outputs being spent in the transaction

These are the current default values in the bitcore library involved on these checks:

  • Transaction.FEE_PER_KB: 10000 (satoshis per kilobyte)
  • Transaction.FEE_SECURITY_MARGIN: 15
  • Transaction.DUST_AMOUNT: 546 (satoshis)

Fee calculation

When outputs' value don't sum up to the same amount that inputs, the difference in bitcoins goes to the miner of the block that includes this transaction. The concept of a "change address" usually is associated with this: an output with an address that can be spent by the creator of the transaction.

For this reason, some methods in the Transaction class are provided:

  • change(address): Set up the change address. This will set an internal _changeScript property that will store the change script associated with that address.
  • fee(amount): Sets up the exact amount of fee to pay. If no change address is provided, this will raise an exception.
  • getFee(): returns the estimated fee amount to be paid, based on the size of the transaction, but disregarding the priority of the outputs.

Internally, a _changeIndex property stores the index of the change output (so it can get updated when a new input or output is added).

Time-Locking transaction

All bitcoin transactions contain a locktime field. The locktime indicates the earliest time a transaction can be added to the blockchain. Locktime allows signers to create time-locked transactions which will only become valid in the future, giving the signers a chance to change their minds. Locktime can be set in the form of a bitcoin block height (the transaction can only be included in a block with a higher height than specified) or a linux timestamp (transaction can only be confirmed after that time). For more information see bitcoin's development guide section on locktime.

In bitcore, you can set a Transaction's locktime by using the methods Transaction#lockUntilDate and Transaction#lockUntilBlockHeight. You can also get a friendly version of the locktime field via Transaction#getLockTime;

For example:

var future = new Date(2025,10,30); // Sun Nov 30 2025
var transaction = new Transaction()
  .lockUntilDate(future);
console.log(transaction.getLockTime());
// output similar to: Sun Nov 30 2025 00:00:00 GMT-0300 (ART)

Upcoming changes

We're debating an API for Merge Avoidance, CoinJoin, Smart contracts, CoinSwap, and Stealth Addresses. We're expecting to have all of them by some time in 2015. Payment channel creation is available in the bitcore-channel module.

MultiSigScriptHashInput

Kind: global class

PublicKeyInput

Kind: global class

new PublicKeyInput()

Represents a special kind of input of PayToPublicKey kind.

publicKeyInput.getSignatures(transaction, privateKey, index, [sigtype]) ⇒ Array

Kind: instance method of PublicKeyInput
Returns: Array - of objects that can be

Param Type Description
transaction Transaction the transaction to be signed
privateKey PrivateKey the private key with which to sign the transaction
index number the index of the input in the transaction input vector
[sigtype] number the type of signature, defaults to Signature.SIGHASH_ALL

publicKeyInput.addSignature(signature) ⇒ PublicKeyInput

Add the provided signature

Kind: instance method of PublicKeyInput
Returns: PublicKeyInput - this, for chaining

Param Type
signature Object
signature.publicKey PublicKey
signature.signature Signature
[signature.sigtype] number

publicKeyInput.clearSignatures() ⇒ PublicKeyHashInput

Clear the input's signature

Kind: instance method of PublicKeyInput
Returns: PublicKeyHashInput - this, for chaining

publicKeyInput.isFullySigned() ⇒ boolean

Query whether the input is signed

Kind: instance method of PublicKeyInput

PublicKeyHashInput

Kind: global class

new PublicKeyHashInput()

Represents a special kind of input of PayToPublicKeyHash kind.

publicKeyHashInput.getSignatures(transaction, privateKey, index, [sigtype], [hashData]) ⇒ Array

Kind: instance method of PublicKeyHashInput
Returns: Array - of objects that can be

Param Type Description
transaction Transaction the transaction to be signed
privateKey PrivateKey the private key with which to sign the transaction
index number the index of the input in the transaction input vector
[sigtype] number the type of signature, defaults to Signature.SIGHASH_ALL
[hashData] Buffer the precalculated hash of the public key associated with the privateKey provided

publicKeyHashInput.addSignature(signature) ⇒ PublicKeyHashInput

Add the provided signature

Kind: instance method of PublicKeyHashInput
Returns: PublicKeyHashInput - this, for chaining

Param Type
signature Object
signature.publicKey PublicKey
signature.signature Signature
[signature.sigtype] number

publicKeyHashInput.clearSignatures() ⇒ PublicKeyHashInput

Clear the input's signature

Kind: instance method of PublicKeyHashInput
Returns: PublicKeyHashInput - this, for chaining

publicKeyHashInput.isFullySigned() ⇒ boolean

Query whether the input is signed

Kind: instance method of PublicKeyHashInput

Signing : object

Kind: global namespace

Signing.sighash

Returns a buffer of length 32 bytes with the hash that needs to be signed for OP_CHECKSIG.

Kind: static property of Signing

Param Type Description
transaction Transaction the transaction to sign
sighashType number the type of the hash
inputNumber number the input index for the signature
subscript Script the script that will be signed

Signing.sign ⇒ Signature

Create a signature

Kind: static property of Signing

Param Type
transaction Transaction
privateKey PrivateKey
sighash number
inputIndex number
subscript Script

Signing.verify ⇒ boolean

Verify a signature

Kind: static property of Signing

Param Type
transaction Transaction
signature Signature
publicKey PublicKey
inputIndex number
subscript Script

TransactionSignature

Kind: global class

new TransactionSignature(arg)

Wrapper around Signature with fields related to signing a transaction specifically

Param Type
arg Object | string | TransactionSignature

transactionSignature.toObject ⇒ Object

Serializes a transaction to a plain JS object

Kind: instance property of TransactionSignature

TransactionSignature.fromObject(object) ⇒ TransactionSignature

Builds a TransactionSignature from an object

Kind: static method of TransactionSignature

Param Type
object Object

Transaction

Kind: global class

new Transaction(serialized)

Represents a transaction, a set of inputs and outputs to change ownership of tokens

Param Type
serialized *

transaction._getHash() ⇒ Buffer

Retrieve the little endian hash of the transaction (used for serialization)

Kind: instance method of Transaction

transaction.serialize(unsafe) ⇒ string

Retrieve a hexa string that can be used with bitcoind's CLI interface (decoderawtransaction, sendrawtransaction)

Kind: instance method of Transaction

Param Type Description
unsafe Object | boolean if true, skip all tests. if it's an object, it's expected to contain a set of flags to skip certain tests: disableAll: disable all checks disableSmallFees: disable checking for fees that are too small disableLargeFees: disable checking for fees that are too large disableIsFullySigned: disable checking if all inputs are fully signed disableDustOutputs: disable checking if there are no outputs that are dust amounts disableMoreOutputThanInput: disable checking if the transaction spends more bitcoins than the sum of the input amounts

transaction.checkedSerialize(opts) ⇒ string

Retrieve a hexa string that can be used with bitcoind's CLI interface (decoderawtransaction, sendrawtransaction)

Kind: instance method of Transaction

Param Type Description
opts Object allows to skip certain tests. {@see Transaction#serialize}

transaction.getSerializationError(opts) ⇒ bitcore.Error

Retrieve a possible error that could appear when trying to serialize and broadcast this transaction.

Kind: instance method of Transaction

Param Type Description
opts Object allows to skip certain tests. {@see Transaction#serialize}

transaction.lockUntilDate(time) ⇒ Transaction

Sets nLockTime so that transaction is not valid until the desired date(a timestamp in seconds since UNIX epoch is also accepted)

Kind: instance method of Transaction
Returns: Transaction - this

Param Type
time Date | Number

transaction.lockUntilBlockHeight(height) ⇒ Transaction

Sets nLockTime so that transaction is not valid until the desired block height.

Kind: instance method of Transaction
Returns: Transaction - this

Param Type
height Number

transaction.getLockTime() ⇒ Number | Date

Returns a semantic version of the transaction's nLockTime.

Kind: instance method of Transaction
Returns: Number | Date - If nLockTime is 0, it returns null, if it is < 500000000, it returns a block height (number) else it returns a Date object.

transaction.from(utxo, [pubkeys], [threshold])

Add an input to this transaction. This is a high level interface to add an input, for more control, use @{link Transaction#addInput}.

Can receive, as output information, the output of bitcoind's listunspent command, and a slightly fancier format recognized by bitcore:

{
 address: 'mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1',
 txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
 outputIndex: 0,
 script: Script.empty(),
 satoshis: 1020000
}

Where address can be either a string or a bitcore Address object. The same is true for script, which can be a string or a bitcore Script.

Beware that this resets all the signatures for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).

Kind: instance method of Transaction

Param Type
utxo Array.<fromObject> | fromObject
[pubkeys] Array
[threshold] number

Example

var transaction = new Transaction();

// From a pay to public key hash output from bitcoind's listunspent
transaction.from({'txid': '0000...', vout: 0, amount: 0.1, scriptPubKey: 'OP_DUP ...'});

// From a pay to public key hash output
transaction.from({'txId': '0000...', outputIndex: 0, satoshis: 1000, script: 'OP_DUP ...'});

// From a multisig P2SH output
transaction.from({'txId': '0000...', inputIndex: 0, satoshis: 1000, script: '... OP_HASH'},
                 ['03000...', '02000...'], 2);

transaction.addInput(input, outputScript, satoshis) ⇒

Add an input to this transaction. The input must be an instance of the Input class. It should have information about the Output that it's spending, but if it's not already set, two additional parameters, outputScript and satoshis can be provided.

Kind: instance method of Transaction
Returns: Transaction this, for chaining

Param Type
input Input
outputScript String | Script
satoshis number

transaction.uncheckedAddInput(input) ⇒

Add an input to this transaction, without checking that the input has information about the output that it's spending.

Kind: instance method of Transaction
Returns: Transaction this, for chaining

Param Type
input Input

transaction.hasAllUtxoInfo() ⇒ boolean

Returns true if the transaction has enough info on all inputs to be correctly validated

Kind: instance method of Transaction

transaction.fee(amount) ⇒ Transaction

Manually set the fee for this transaction. Beware that this resets all the signatures for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

Param Type Description
amount number satoshis to be sent

transaction.feePerKb(amount) ⇒ Transaction

Manually set the fee per KB for this transaction. Beware that this resets all the signatures for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

Param Type Description
amount number satoshis per KB to be sent

transaction.change(address) ⇒ Transaction

Set the change address for this transaction

Beware that this resets all the signatures for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

Param Type Description
address Address An address for change to be sent to.

transaction.getChangeOutput() ⇒ Output

Kind: instance method of Transaction
Returns: Output - change output, if it exists

transaction.to(address, amount) ⇒ Transaction

Add an output to the transaction.

Beware that this resets all the signatures for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

Param Type Description
address string | Address | Array.<toObject>
amount number in satoshis

transaction.addData(value) ⇒ Transaction

Add an OP_RETURN output to the transaction.

Beware that this resets all the signatures for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

Param Type Description
value Buffer | string the data to be stored in the OP_RETURN output. In case of a string, the UTF-8 representation will be stored

transaction.addOutput(output) ⇒ Transaction

Add an output to the transaction.

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

Param Type Description
output Output the output to add.

transaction.clearOutputs() ⇒ Transaction

Remove all outputs from the transaction.

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

transaction._getOutputAmount() ⇒ Number

Calculates or gets the total output amount in satoshis

Kind: instance method of Transaction
Returns: Number - the transaction total output amount

transaction._getInputAmount() ⇒ Number

Calculates or gets the total input amount in satoshis

Kind: instance method of Transaction
Returns: Number - the transaction total input amount

transaction.getFee() ⇒ Number

Calculates the fee of the transaction.

If there's a fixed fee set, return that.

If there is no change output set, the fee is the total value of the outputs minus inputs. Note that a serialized transaction only specifies the value of its outputs. (The value of inputs are recorded in the previous transaction outputs being spent.) This method therefore raises a "MissingPreviousOutput" error when called on a serialized transaction.

If there's no fee set and no change address, estimate the fee based on size.

Kind: instance method of Transaction
Returns: Number - fee of this transaction in satoshis

transaction._estimateFee()

Estimates fee from serialized transaction size in bytes.

Kind: instance method of Transaction

transaction.sort() ⇒ Transaction

Sort a transaction's inputs and outputs according to BIP69

Kind: instance method of Transaction
Returns: Transaction - this
See: {https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki}

transaction.shuffleOutputs() ⇒ Transaction

Randomize this transaction's outputs ordering. The shuffling algorithm is a version of the Fisher-Yates shuffle, provided by lodash's _.shuffle().

Kind: instance method of Transaction
Returns: Transaction - this

transaction.sortOutputs(sortingFunction) ⇒ Transaction

Sort this transaction's outputs, according to a given sorting function that takes an array as argument and returns a new array, with the same elements but with a different order. The argument function MUST NOT modify the order of the original array

Kind: instance method of Transaction
Returns: Transaction - this

Param Type
sortingFunction function

transaction.sortInputs(sortingFunction) ⇒ Transaction

Sort this transaction's inputs, according to a given sorting function that takes an array as argument and returns a new array, with the same elements but with a different order.

Kind: instance method of Transaction
Returns: Transaction - this

Param Type
sortingFunction function

transaction.sign(privateKey, sigtype) ⇒ Transaction

Sign the transaction using one or more private keys.

It tries to sign each input, verifying that the signature will be valid (matches a public key).

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

Param Type
privateKey Array | String | PrivateKey
sigtype number

transaction.applySignature(signature) ⇒ Transaction

Add a signature to the transaction

Kind: instance method of Transaction
Returns: Transaction - this, for chaining

Param Type
signature Object
signature.inputIndex number
signature.sigtype number
signature.publicKey PublicKey
signature.signature Signature

transaction.verifySignature() ⇒ bool

Kind: instance method of Transaction
Returns: bool - whether the signature is valid for this transaction input

transaction.verify()

Check that a transaction passes basic sanity tests. If not, return a string describing the error. This function contains the same logic as CheckTransaction in bitcoin core.

Kind: instance method of Transaction

transaction.isCoinbase()

Analogous to bitcoind's IsCoinBase function in transaction.h

Kind: instance method of Transaction

transaction.isRBF()

Determines if this transaction can be replaced in the mempool with another transaction that provides a sufficiently higher fee (RBF).

Kind: instance method of Transaction

transaction.enableRBF()

Enable this transaction to be replaced in the mempool (RBF) if a transaction includes a sufficiently higher fee. It will set the sequenceNumber to DEFAULT_RBF_SEQNUMBER for all inputs if the sequence number does not already enable RBF.

Kind: instance method of Transaction

Transaction.shallowCopy(transaction) ⇒ Transaction

Create a 'shallow' copy of the transaction, by serializing and deserializing it dropping any additional information that inputs and outputs may have hold

Kind: static method of Transaction

Param Type
transaction Transaction

Transaction~fromObject : Object

Kind: inner typedef of Transaction
Properties

Name Type
prevTxId string
outputIndex number
script Buffer | string | Script
satoshis number

Transaction~toObject : Object

Kind: inner typedef of Transaction
Properties

Name Type
address string | Address
satoshis number