Sending Transactions
When calling a contract function on a Contract object, an incomplete Transaction object is returned. This transaction can be completed by providing a number of outputs using the to()
or withOpReturn()
functions. Other chained functions are included to set other transaction parameters.
Most of the available transaction options are only useful in very specific use cases, but the functions to()
, withOpReturn()
and send()
are commonly used. withHardcodedFee()
is also commonly used with covenant contracts.
Transaction options
to()
The to()
function allows you to add outputs to the transaction. Either a single pair to/amount
pair can be provided, or a list of them. This function can be called any number of times, and the provided outputs will be added to the list of earlier added outputs.
Example
withOpReturn()
The withOpReturn()
function allows you to add OP_RETURN
outputs to the transaction. The chunks
parameter can include regular UTF-8 encoded strings, or hex strings prefixed with 0x
. This function can be called any number of times, and the provided outputs will be added to the list of earlier added outputs.
Example
from()
The from()
function allows you to provide a hardcoded list of contract UTXOs to be used in the transaction. This overrides the regular UTXO selection performed by the CashScript SDK, so no further selection will be performed on the provided UTXOs. This function can be called any number of times, and the provided UTXOs will be added to the list of earlier added UTXOs.
tip
The built-in UTXO selection is generally sufficient. But there are specific use cases for which it makes sense to use a custom selection algorithm.
Example
withFeePerByte()
The withFeePerByte()
function allows you to specify the fee per per bytes for the transaction. By default the fee per bytes is set to 1.0 satoshis, which is nearly always enough to be included in the next block. So it's generally not necessary to change this.
Example
withHardcodedFee()
The withHardcodedFee()
function allows you to specify a hardcoded fee to the transaction. By default the transaction fee is automatically calculated by the CashScript SDK, but there are certain use cases where the smart contract relies on a hardcoded fee.
tip
If you're not building a covenant contract, you probably do not need a hardcoded transaction fee.
Example
withMinChange()
The withMinChange()
function allows you to set a threshold for including a change output. Any remaining amount under this threshold will be added to the transaction fee instead.
tip
This is generally only useful in specific covenant use cases.
Example
withoutChange()
The withoutChange()
function allows you to disable the change output. The remaining amount will be added to the transaction fee instead. This is equivalent to withMinChange(Number.MAX_VALUE)
.
caution
Be sure to check that the remaining amount (sum of inputs - sum of outputs) is not too high. The difference will be added to the transaction fee and cannot be reclaimed.
Example
withAge()
The withAge()
function allows you to specify the minimum age of the transaction inputs. This is necessary if you want to to use the tx.age
CashScript functionality, and the age
parameter passed into this function will be the value of tx.age
inside the smart contract. For more information, refer to BIP68.
Example
withTime()
The withTime()
function allows you to specify the minimum block number that the transaction can be included in. The time
parameter will be the value of tx.time
inside the smart contract.
tip
By default, the transaction's time
variable is set to the most recent block number, which is the most common use case. So you should only override this in specific use cases.
Example
Transaction building
send()
After completing a transaction, the send()
function can be used to send the transaction to the BCH network. An incomplete transaction cannot be sent.
tip
If the transaction fails, a meep command is automatically returned. This command can be used to debug the transaction using the meep debugger
Example
build()
After completing a transaction, the build()
function can be used to build the entire transaction and return the signed transaction hex string. This can then be imported into other libraries or applications as necessary.
Example
meep()
After completing a transaction, the meep()
function can be used to return the required debugging command for the meep debugger. This command string can then be used to debug the transaction.
Example
Transaction errors
Transactions can fail for a number of reasons. Most of these are related to the execution of the smart contract (e.g. wrong parameters or a bug in the contract code). But errors can also occur because of other reasons (e.g. a fee that's too low or the same transaction already exists in the mempool). To facilitate error handling in your applications, the CashScript SDK provides an enum of different reasons for a failure.
This Reason
enum only includes errors that are related to smart contract execution, so other reasons have to be caught separately. Besides the Reason
enum, there are also several error classes that can be caught and acted on:
FailedRequireError
, signifies a failed require statement. This includes the following reasons:Reason.EVAL_FALSE
Reason.VERIFY
Reason.EQUALVERIFY
Reason.CHECKMULTISIGVERIFY
Reason.CHECKSIGVERIFY
Reason.CHECKDATASIGVERIFY
Reason.NUMEQUALVERIFY
FailedTimeCheckError
, signifies a failed time check usingtx.time
ortx.age
. This includes the following reasons:Reason.NEGATIVE_LOCKTIME
Reason.UNSATISFIED_LOCKTIME
FailedSigCHeckError
, signifies a failed signature check. This includes the following reasons:Reason.SIG_COUNT
Reason.PUBKEY_COUNT
Reason.SIG_HASHTYPE
Reason.SIG_DER
Reason.SIG_HIGH_S
Reason.SIG_NULLFAIL
Reason.SIG_BADLENGTH
Reason.SIG_NONSCHNORR
FailedTransactionError
, signifies a general fallback error. This includes all remaining reasons listed in theReason
enum as well as any other reasons unrelated to the smart contract execution.