Transactions

Transaction Tutorial

Creating transactions is a fundamental task for most BitcoinEvo applications. This section outlines how to use BitcoinEvo Core’s RPC interface to create transactions with various features.

While your application may use other tools besides BitcoinEvo Core to build transactions, you will need to provide similar data inputs to create transactions with the same characteristics as those described below.

To follow along with this tutorial, ensure that BitcoinEvo Core is properly set up and that you have a regression test mode environment with 50 BTCE in your test wallet.

Simple Spending

BitcoinEvo Core offers multiple RPCs that handle most of the transaction details, such as generating change outputs and applying appropriate fees. Even for experienced users, it is recommended to use these RPCs when possible to reduce the likelihood of accidentally losing satoshis.

bitcoinevo-cli -regtest getnewaddress
mvbnrCX3bg1cDRUu8pkecrvP6vQkSLDSou
NEW_ADDRESS=mvbnrCX3bg1cDRUu8pkecrvP6vQkSLDSou

Get a new BitcoinEvo address and store it in the shell variable $NEW_ADDRESS.

bitcoinevo-cli -regtest sendtoaddress $NEW_ADDRESS 10.00
263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0

Send 10 bitcoinevos to the specified address using the “sendtoaddress” RPC. The returned hexadecimal string represents the transaction identifier (txid).

The “sendtoaddress” RPC automatically selects an unspent transaction output (UTXO) to use for spending. In this example, it chose the satoshis from our only UTXO — the coinbase transaction for block #1, which became eligible for spending after block #101 was mined. If you want to target a specific UTXO, you could instead use the sendfrom RPC.

bitcoinevo-cli -regtest listunspent
[

]

Using the “listunspent” RPC will display the UTXOs for this wallet. The list is empty by default, as it only shows confirmed UTXOs, and we just spent our sole confirmed UTXO.

bitcoinevo-cli -regtest listunspent 0

[
{
"txid" : "263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0",
"vout" : 0,
"address" : "muhtvdmsnbQEPFuEmxcChX58fGvXaaUoVt",
"scriptPubKey" : "76a9149ba386253ea698158b6d34802bb9b550f5ce36dd88ac",
"amount" : 40.00000000,
"confirmations" : 0,
"spendable" : true,
"solvable" : true
},
{
"txid" : "263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0",
"vout" : 1,
"address" : "mvbnrCX3bg1cDRUu8pkecrvP6vQkSLDSou",
"account" : "",
"scriptPubKey" : "76a914a57414e5ffae9ef5074bacbe10a320bb2614e1f388ac",
"amount" : 10.00000000,
"confirmations" : 0,
"spendable" : true,
"solvable" : true
}
]

By re-running the “listunspent” RPC with the argument “0” to show unconfirmed UTXOs, we can see two UTXOs, both with the same txid. The first UTXO represents the change output created by the “sendtoaddress” command, assigned to a new address from the key pool. The second UTXO is the 10-bitcoinevo transaction sent to the specified address. If these satoshis had been sent to someone else, the second UTXO wouldn’t appear in our wallet’s list of UTXOs.

bitcoinevo-cli -regtest generate 1
unset NEW_ADDRESS

Create a new block to confirm the transaction (which only takes a moment) and clear the shell variable.

Simple Raw Transaction

The raw transaction RPCs allow users to craft custom transactions and delay their broadcasting. However, errors in raw transactions may not be caught by BitcoinEvo Core, and several users have lost significant amounts of satoshis because of mistakes, so it’s important to be cautious when dealing with raw transactions, especially on mainnet.

This section explains one of the simplest forms of a raw transaction.

bitcoinevo-cli -regtest listunspent

[
{
"txid": "263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0",
"vout": 0,
"address": "muhtvdmsnbQEPFuEmxcChX58fGvXaaUoVt",
"scriptPubKey": "76a9149ba386253ea698158b6d34802bb9b550f5ce36dd88ac",
"amount": 40.00000000,
"confirmations": 1,
"spendable": true,
"solvable": true
},
{
"txid": "263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0",
"vout": 1,
"address": "mvbnrCX3bg1cDRUu8pkecrvP6vQkSLDSou",
"scriptPubKey": "76a914a57414e5ffae9ef5074bacbe10a320bb2614e1f388ac",
"amount": 10.00000000,
"confirmations": 1,
"spendable": true,
"solvable": true
},
{
"txid": "3f4fa19803dec4d6a84fae3821da7ac7577080ef75451294e71f9b20e0ab1e7b",
"vout": 0,
"address": "mwJTL1dZG8BAP6X7Be3CNNcuVKi7Qqt7Gk",
"scriptPubKey": "210260a275cccf0f4b106220725be516adba2752db1bec8c5b7174c89c4c07891f88ac",
"amount": 50.00000000,
"confirmations": 101,
"spendable": true,
"solvable": true
}
]

UTXO_TXID=3f4fa19803dec4d6a84fae3821da7ac7577080ef75451294e71f[...]
UTXO_VOUT=0

listunspent Re-run “listunspent”. We now have three UTXOs: the two transactions created earlier and the coinbase transaction from block #2. Save the txid and output index number (vout) of the coinbase UTXO to shell variables.

bitcoinevo-cli -regtest getnewaddress
mz6KvC4aoUeo6wSxtiVQTo7FDwPnkp6URG

NEW_ADDRESS=mz6KvC4aoUeo6wSxtiVQTo7FDwPnkp6URG

Generate a new address to be used in the raw transaction.

## Outputs - Inputs = Transaction Fee, so double-check your math!
bitcoinevo-cli -regtest createrawtransaction '''
    [
      {
        "txid": "'$UTXO_TXID'",
        "vout": '$UTXO_VOUT'
      }
    ]
    ''' '''
    {
      "'$NEW_ADDRESS'": 49.9999
    }'''
01000000017b1eabe0209b1fe794124575ef807057c77ada2138ae4fa8d6c4de
0398a14f3f0000000000ffffffff01f0ca052a010000001976a914cbc20a7664
f2f69e5355aa427045bc15e7c6c77288ac00000000
RAW_TX=01000000017b1eabe0209b1fe794124575ef807057c77ada2138ae4[...]


By passing two arguments to the createrawtransaction RPC, we construct a new raw-format transaction. The first argument (a JSON array) refers to the txid of the coinbase transaction from block #2 and the output index (0) from that transaction we intend to spend. The second argument (a JSON object) specifies the output, including the recipient address (public key hash) and the amount of bitcoinevos we wish to transfer. The resulting raw transaction is saved to a shell variable.

Warning: The createrawtransaction RPC does not automatically generate change outputs, so you could accidentally pay a high transaction fee. In this example, the input had 50.0000 bitcoinevos, and we’re sending 49.9999 bitcoinevos to $NEW_ADDRESS, resulting in a transaction fee of 0.0001 bitcoinevos. If we had sent only 10 bitcoinevos without making other adjustments, the fee would have been an enormous 40 bitcoinevos. To handle change outputs, refer to the “Complex Raw Transaction” section below.

bitcoinevo-cli -regtest decoderawtransaction $RAW_TX

{
"txid": "c80b343d2ce2b5d829c2de9854c7c8d423c0e33bda264c40138d834aab4c0638",
"hash": "c80b343d2ce2b5d829c2de9854c7c8d423c0e33bda264c40138d834aab4c0638",
"size": 85,
"vsize": 85,
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "3f4fa19803dec4d6a84fae3821da7ac7577080ef75451294e71f9b20e0ab1e7b",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 49.99990000,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 cbc20a7664f2f69e5355aa427045bc15e7c6c772 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914cbc20a7664f2f69e5355aa427045bc15e7c6c77288ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"mz6KvC4aoUeo6wSxtiVQTo7FDwPnkp6URG"
]
}
}
]
}
The decoderawtransaction RPC allows you to inspect the contents of the transaction you just built.

bitcoinevo-cli -regtest signrawtransaction $RAW_TX

{
    "hex": "01000000017b1eabe0209b1fe794124575ef807057c77ada2138ae4fa8d6c4de0398a14f3f00000000494830450221008949f0
cb400094ad2b5eb399d59d01c14d73d8fe6e96df1a7150deb388ab8935022079656090d7f6bac4c9a94e0aad311a4268e082a72
5f8aeae0573fb12ff866a5f01ffffffff01f0ca052a010000001976a914cbc20a7664f2f69e5355aa427045bc15e7c6c77288ac
00000000",
    "complete": true
}

SIGNED_RAW_TX=01000000017b1eabe0209b1fe794124575ef807057c77ada[...]
Use the signrawtransaction RPC to sign the transaction created with createrawtransaction, and save the signed raw transaction to a shell variable.

Although the transaction is now signed and ready, the connected BitcoinEvo Core node remains unaware of it, as does the network. The transaction has been prepared but not yet broadcasted, and you could simply discard it by unsetting the $SIGNED_RAW_TX variable.

bitcoinevo-cli -regtest sendrawtransaction $SIGNED_RAW_TX
c7736a0a0046d5a8cc61c8c3c2821d4d7517f5de2bc66a966011aaa79965ffba

Broadcast the signed transaction to the connected node using the sendrawtransaction RPC. The node accepts the transaction and, under normal circumstances, would then propagate it to other peers. However, since we’re operating in regtest mode, there are no external peers.

bitcoinevo-cli -regtest generate 1

unset UTXO_TXID UTXO_VOUT NEW_ADDRESS RAW_TX SIGNED_RAW_TX

Finally, generate a new block to confirm the transaction and clear the shell variables.

Complex Raw Transaction

In this example, we’ll demonstrate how to create a raw transaction involving two inputs and two outputs. Each input will be signed individually, which may occur when the inputs belong to different participants agreeing to create a joint transaction (such as a CoinJoin transaction).

bitcoinevo-cli -regtest listunspent

[
    {
        "txid": "263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0",
        "vout": 0,
        "address": "muhtvdmsnbQEPFuEmxcChX58fGvXaaUoVt",
        "scriptPubKey": "76a9149ba386253ea698158b6d34802bb9b550f5ce36dd88ac",
        "amount": 40.00000000,
        "confirmations": 2,
        "spendable": true,
        "solvable": true
    },
    {
        "txid": "263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0",
        "vout": 1,
        "address": "mvbnrCX3bg1cDRUu8pkecrvP6vQkSLDSou",
        "scriptPubKey": "76a914a57414e5ffae9ef5074bacbe10a320bb2614e1f388ac",
        "amount": 10.00000000,
        "confirmations": 2,
        "spendable": true,
        "solvable": true
    },
    {
        "txid": "78203a8f6b529693759e1917a1b9f05670d036fbb129110ed26be6a36de827f3",
        "vout": 0,
        "address": "n2KprMQm4z2vmZnPMENfbp2P1LLdAEFRjS",
        "scriptPubKey": "210229688a74abd0d5ad3b06ddff36fa9cd8edd181d97b9489a6adc40431fb56e1d8ac",
        "amount": 50.00000000,
        "confirmations": 101,
        "spendable": true,
        "solvable": true
    },
    {
        "txid": "c7736a0a0046d5a8cc61c8c3c2821d4d7517f5de2bc66a966011aaa79965ffba",
        "vout": 0,
        "address": "mz6KvC4aoUeo6wSxtiVQTo7FDwPnkp6URG",
        "amount": 49.99990000,
        "confirmations": 1,
        "spendable": true,
        "solvable": true
    }
]



UTXO1_TXID=78203a8f6b529693759e1917a1b9f05670d036fbb129110ed26[...]
UTXO1_VOUT=0
UTXO1_ADDRESS=n2KprMQm4z2vmZnPMENfbp2P1LLdAEFRjS

UTXO2_TXID=263c018582731ff54dc72c7d67e858c002ae298835501d80200[...]
UTXO2_VOUT=0
UTXO2_ADDRESS=muhtvdmsnbQEPFuEmxcChX58fGvXaaUoVt

For our two inputs, we select two UTXOs, storing the txid and vout (output index) in shell variables. We also store the corresponding addresses, which we’ll use to retrieve the private keys from the wallet.

bitcoinevo-cli -regtest dumpprivkey $UTXO1_ADDRESS
cSp57iWuu5APuzrPGyGc4PGUeCg23PjenZPBPoUs24HtJawccHPm


bitcoinevo-cli -regtest dumpprivkey $UTXO2_ADDRESS
cT26DX6Ctco7pxaUptJujRfbMS2PJvdqiSMaGaoSktHyon8kQUSg

UTXO1_PRIVATE_KEY=cSp57iWuu5APuzrPGyGc4PGUeCg23PjenZPBPoUs24Ht[...]

UTXO2_PRIVATE_KEY=cT26DX6Ctco7pxaUptJujRfbMS2PJvdqiSMaGaoSktHy[...]

Use the dumpprivkey RPC to retrieve the private keys associated with the addresses used in our selected UTXOs. We need these private keys to sign each input separately.

Warning: Users should never manually manage their private keys on the mainnet. As dangerous as raw transactions are (see warnings above), a private key error can be much worse – in the case of a cross-generational key compromise on an HD wallet. These examples are to help you learn and are not intended to be replicated on the mainnet.

bitcoinevo-cli -regtest getnewaddress
n4puhBEeEWD2VvjdRC9kQuX2abKxSCMNqN
bitcoinevo-cli -regtest getnewaddress
n4LWXU59yM5MzQev7Jx7VNeq1BqZ85ZbLj

NEW_ADDRESS1=n4puhBEeEWD2VvjdRC9kQuX2abKxSCMNqN
NEW_ADDRESS2=n4LWXU59yM5MzQev7Jx7VNeq1BqZ85ZbLj

For the two outputs, we generate two new addresses.
## Outputs – inputs = transaction fee, so always double-check your math!
bitcoinevo-cli -regtest createrawtransaction ”’
[
{
“txid”: “‘$UTXO1_TXID’”,
“vout”: ‘$UTXO1_VOUT’
},
{
“txid”: “‘$UTXO2_TXID’”,
“vout”: ‘$UTXO2_VOUT’
}
]
”’ ”’
{
“‘$NEW_ADDRESS1′”: 79.9999,
“‘$NEW_ADDRESS2′”: 10
}”’
0100000002f327e86da3e66bd20e1129b1fb36d07056f0b9a117199e759396526b8f3a20780000000000fffffffff0ede03d750
50f20801d50358829ae02c058e8677d2cc74df51f738285013c260000000000ffffffff02f028d6dc010000001976a914ffb035
781c3c69e076d48b60c3d38592e7ce06a788ac00ca9a3b000000001976a914fa5139067622fd7e1e722a05c17c2bb7d5fd6df08
8ac00000000

RAW_TX=0100000002f327e86da3e66bd20e1129b1fb36d07056f0b9a117199[...]

We create the raw transaction using createrawtransaction just like before, but this time we have two inputs and two outputs.

bitcoinevo-cli -regtest signrawtransaction $RAW_TX '[]' '''
[
"'$UTXO1_PRIVATE_KEY'"
]'''

{
"hex" : "0100000002f327e86da3e66bd20e1129b1fb36d07056f0b9a117199e759396526b8f3a20780000000049483045022100fce442

ec52aa2792efc27fd3ad0eaf7fa69f097fdcefab017ea56d1799b10b2102207a6ae3eb61e11ffaba0453f173d1792f1b7bb8e74
22ea945101d68535c4b474801fffffffff0ede03d75050f20801d50358829ae02c058e8677d2cc74df51f738285013c26000000
0000ffffffff02f028d6dc010000001976a914ffb035781c3c69e076d48b60c3d38592e7ce06a788ac00ca9a3b000000001976a
914fa5139067622fd7e1e722a05c17c2bb7d5fd6df088ac00000000",
"complete" : false,
"errors": [
{
"txid": "c53f8f5ac0b6b10cdc77f543718eb3880fee6cf9b5e0cbf4edb2a59c0fae09a4",
"vout": 0,
"scriptSig": "",
"sequence": 4294967295,
"error": "Operation not valid with the current stack size"
}
]
}

PARTLY_SIGNED_RAW_TX=0100000002f327e86da3e66bd20e1129b1fb36d07[...]

To sign the raw transaction, the signrawtransaction command gets more intricate with three arguments:

  1. The unsigned raw transaction.
  2. An empty array. This positional argument is needed, even if it’s not used, to ensure access to the later arguments.
  3. The private key required to sign the first input.
The resulting raw transaction now has one input signed. The incomplete status is reflected in the complete field, so we store the partially signed transaction in a variable.
bitcoinevo-cli -regtest signrawtransaction $PARTLY_SIGNED_RAW_TX '[]' '''
[
"'$UTXO2_PRIVATE_KEY'"
]'''

{
"hex" : "0100000002f327e86da3e66bd20e1129b1fb36d07056f0b9a117199e759396526b8f3a20780000000049483045022100fce442

ec52aa2792efc27fd3ad0eaf7fa69f097fdcefab017ea56d1799b10b2102207a6ae3eb61e11ffaba0453f173d1792f1b7bb8e74
22ea945101d68535c4b474801fffffffff0ede03d75050f20801d50358829ae02c058e8677d2cc74df51f738285013c26000000
006b483045022100b77f935ff366a6f3c2fdeb83589c790265d43b3d2cf5e5f0047da56c36de75f40220707ceda75d8dcf2ccae
506f7293c3dcb910554560763d7659fb202f8ec324b012102240d7d3c7aad57b68aa0178f4c56f997d1bfab2ded3c2f94276860
17c603a6d6ffffffff02f028d6dc010000001976a914ffb035781c3c69e076d48b60c3d38592e7ce06a788ac00ca9a3b0000000
01976a914fa5139067622fd7e1e722a05c17c2bb7d5fd6df088ac00000000",
"complete" : true
}

The second input is signed in a similar manner by using the second private key. Now that both inputs are signed, the complete field shows that the transaction is fully signed.

unset PARTLY_SIGNED_RAW_TX RAW_TX NEW_ADDRESS1 [...]

Once complete, we clear out the shell variables used in the process. Unlike earlier examples, we won’t be broadcasting this transaction with sendrawtransaction. This lets us demonstrate, in the next section, how to work with a transaction that hasn’t yet been added to the blockchain or memory pool.

Offline Signing

We will now spend the transaction created in the Complex Raw Transaction section, but without broadcasting it to the local node first. This is the same general method used by wallets for offline signing — typically meaning that a transaction is signed without having access to the current UTXO set.

Offline signing is generally considered safe. However, in this example, we are also spending an output that has never been broadcast, meaning it isn’t yet part of the blockchain. This can introduce some risk:

Warning: Transactions that spend outputs from unconfirmed transactions are vulnerable to transaction malleability. It’s essential to understand transaction malleability and follow best practices before attempting to spend unconfirmed transactions on mainnet.

OLD_SIGNED_RAW_TX=0100000002f327e86da3e66bd20e1129b1fb36d07056f0b9a117199e759396526b8f3a207800000000494
83045022100fce442ec52aa2792efc27fd3ad0eaf7fa69f097fdcefab017ea56d1799b10b2102207a6ae3eb61e11ffaba0453f1
73d1792f1b7bb8e7422ea945101d68535c4b474801fffffffff0ede03d75050f20801d50358829ae02c058e8677d2cc74df51f7
38285013c26000000006b483045022100b77f935ff366a6f3c2fdeb83589c790265d43b3d2cf5e5f0047da56c36de75f4022070
7ceda75d8dcf2ccaebc506f7293c3dcb910554560763d7659fb202f8ec324b012102240d7d3c7aad57b68aa0178f4c56f997d1b
fab2ded3c2f9427686017c603a6d6ffffffff02f028d6dc010000001976a914ffb035781c3c69e076d48b60c3d38592e7ce06a7
88ac00ca9a3b000000001976a914fa5139067622fd7e1e722a05c17c2bb7d5fd6df088ac00000000

Save the previously signed, but unbroadcasted, raw transaction into a shell variable.

bitcoinevo-cli -regtest decoderawtransaction $OLD_SIGNED_RAW_TX

{
"txid": "682cad881df69cb9df8f0c996ce96ecad758357ded2da03bad40cf18ffbb8e09",
"hash": "682cad881df69cb9df8f0c996ce96ecad758357ded2da03bad40cf18ffbb8e09",
"size": 340,
"vsize": 340,
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "78203a8f6b529693759e1917a1b9f05670d036fbb129110ed26be6a36de827f3",
"vout": 0,
"scriptSig": {
"asm": "3045022100fce442ec52aa2792efc27fd3ad0eaf7fa69f097fdcefab017ea56d1799b10b2102207a6ae3eb61e11ffaba0453f1

73d1792f1b7bb8e7422ea945101d68535c4b474801",
"hex": "483045022100FCE442ec52aa2792efc27fd3ad0eaf7fa69f097fdcefab017ea56d1799b10b2102207a6ae3eb61e11ffaba0453

f173d1792f1b7bb8e7422ea945101d68535c4b474801"
},
"sequence": 4294967295
},
{
"txid": "263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0",
"vout": 0,
"scriptSig": {
"asm": "3045022100b77f935ff366a6f3c2fdeb83589c790265d43b3d2cf5e5f0047da56c36de75f40220707ceda75d8dcf2ccaebc506

f7293c3dcb910554560763d7659fb202f8ec324b012102240d7d3c7aad57b68aa0178f4c56f997d1bfab2ded3c2f9427686017c
603a6d6",
"hex": "483045022100b77f935ff366a6f3c2fdeb83589c790265d43b3d2cf5e5f0047da56c36de75f40220707ceda75d8dcf2ccaebc5

06f7293c3dcb910554560763d7659fb202f8ec324b012102240d7d3c7aad57b68aa0178f4c56f997d1bfab2ded3c2f942768601
7c603a6d6"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 79.99990000,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 ffb035781c3c69e076d48b60c3d38592e7ce06a7 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914ffb035781c3c69e076d48b60c3d38592e7ce06a788ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"n4puhBEeEWD2VvjdRC9kQuX2abKxSCMNqN"
]
}
},
{
"value": 10.00000000,
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 fa5139067622fd7e1e722a05c17c2bb7d5fd6df0 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914fa5139067622fd7e1e722a05c17c2bb7d5fd6df088ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"n4LWXU59yM5MzQev7Jx7VNeq1BqZ85ZbLj"
]
}
}
]
}

UTXO_TXID=682cad881df69cb9df8f0c996ce96ecad758357ded2da03bad40[...]
UTXO_VOUT=1
UTXO_VALUE=10.00000000
UTXO_OUTPUT_SCRIPT=76a914fa5139067622fd7e1e722a05c17c2bb7d5fd6[...]


Decode the signed raw transaction to obtain its txid. Then, select one of its UTXOs to spend and save the output index number (vout) and the public key script (scriptPubKey) as shell variables.

bitcoinevo-cli -regtest getnewaddress
mfdCHEFL2tW9eEUpizk7XLZJcnFM4hrp78

NEW_ADDRESS=mfdCHEFL2tW9eEUpizk7XLZJcnFM4hrp78

Get a new address to send the satoshis to.
## Outputs - Inputs = Transaction Fee (Always verify your calculations!)
bitcoinevo-cli -regtest createrawtransaction '''
    [
      {
        "txid": "'$UTXO_TXID'",
        "vout": '$UTXO_VOUT'
      }
    ]
    ''' '''
    {
      "'$NEW_ADDRESS'": 9.9999
    }'''
0100000001098ebbff18cf40ad3ba02ded7d3558d7ca6ee96c990c8fdfb99cf61d88ad2c680100000000ffffffff01f
0a29a3b000000001976a914012e2ba6a051c033b03d712ca2ea00a35eac1e7988ac00000000
RAW_TX=0100000001098ebbff18cf40ad3ba02ded7d3558d7ca6ee96c990c8[...]
Create the raw transaction just like we did in previous sections.

bitcoinevo-cli -regtest signrawtransaction $RAW_TX

{
"hex": "0100000001098ebbff18cf40ad3ba02ded7d3558d7ca6ee96c990c8fdfb99cf61d88ad2c680100000000ffffffff01f

0a29a3b000000001976a914012e2ba6a051c033b03d712ca2ea00a35eac1e7988ac00000000",
"complete": false
}


Attempt to sign the raw transaction without any special arguments, as we did in the Simple Raw Transaction section. However, this time the signing fails, leaving the raw transaction unchanged. If you’ve read the Transaction section of this guide, you may know why this signing attempt didn’t work.




Old Transaction Data Required To Be Signed

As demonstrated, the data that gets signed includes the txid and vout from the previous transaction, which are already part of the raw transaction created by createrawtransaction. However, the data being signed also includes the pubkey script from the prior transaction, even though it doesn’t explicitly appear in the raw transaction (either signed or unsigned).

In the other raw transaction examples discussed earlier, the previous output was part of the UTXO set recognized by the wallet. This allowed the wallet to automatically retrieve the pubkey script using the txid and output index.

In this instance, however, you’re spending an output unknown to the wallet, so it cannot automatically retrieve the previous pubkey script.

bitcoinevo-cli -regtest signrawtransaction $RAW_TX '''
[
{
"txid": "'$UTXO_TXID'",
"vout": '$UTXO_VOUT',
"scriptPubKey": "'$UTXO_OUTPUT_SCRIPT'",
"value": '$UTXO_VALUE'
}
]'''

{
"hex": "0100000001098ebbff18cf40ad3ba02ded7d3558d7ca6ee96c990c8fdfb99cf61d88ad2c68010000006b483045022100c3f92f

b74bfa687d76ebe75a654510bb291b8aab6f89ded4fe26777c2eb233ad02207f779ce2a181cc4055cb0362aba7fd7a6f72d5dbb
9bd863f4faaf47d8d6c4b500121028e4e62d25760709806131b014e2572f7590e70be01f0ef16bfbd51ea5f389d4dffffffff01
f0a29a3b000000001976a914012e2ba6a051c033b03d712ca2ea00a35eac1e7988ac00000000",
"complete": true
}

SIGNED_RAW_TX=0100000001098ebbff18cf40ad3ba02ded7d3558d7ca6ee9[...]

Here, the transaction is successfully signed by providing the previous pubkey script along with other necessary input data.

This is a typical operation for offline signing wallets. The online wallet creates the raw transaction and fetches the previous pubkey scripts for all the inputs. The user then takes this information to an offline wallet. After reviewing the transaction details, the offline wallet signs the transaction, just as we did in the above steps. The user then returns the signed transaction to the online wallet, which broadcasts it.

bitcoinevo-cli -regtest sendrawtransaction $SIGNED_RAW_TX

{"error": {"code":-22,"message":"TX rejected"}}

Attempting to broadcast the second transaction before broadcasting the first fails because the second transaction attempts to spend an output that the node doesn’t recognize as a valid UTXO yet.

bitcoinevo-cli -regtest sendrawtransaction $OLD_SIGNED_RAW_TX
682cad881df69cb9df8f0c996ce96ecad758357ded2da03bad40cf18ffbb8e09
bitcoinevo-cli -regtest sendrawtransaction $SIGNED_RAW_TX
67d53afa1a8167ca093d30be7fb9dcb8a64a5fdecacec9d93396330c47052c57

First, broadcast the original transaction, which is accepted. Afterward, broadcast the second transaction — it now succeeds because the node sees the UTXO from the first transaction.

bitcoinevo-cli -regtest getrawmempool

[
"67d53afa1a8167ca093d30be7fb9dcb8a64a5fdecacec9d93396330c47052c57",
"682cad881df69cb9df8f0c996ce96ecad758357ded2da03bad40cf18ffbb8e09"
]

Although we haven’t generated a new block, both transactions are now part of the local node’s memory pool (mempool). They haven’t yet been included in the regtest blockchain, but they are awaiting confirmation.

unset OLD_SIGNED_RAW_TX SIGNED_RAW_TX RAW_TX [...]

Remove the old shell variables.

P2SH Multisig

In this section, we will create a P2SH multisig address, send satoshis to it, and then spend those satoshis from the multisig address to another address.

Creating a multisig address is straightforward. A multisig output requires two key parameters: the minimum number of signatures required (m) and the number of public keys used to validate those signatures (n). This is known as an m-of-n multisig, and in this example, we’ll create a 2-of-3 multisig setup.

bitcoinevo-cli -regtest getnewaddress
mhAXF4Eq7iRyvbYk1mpDVBiGdLP3YbY6Dm
bitcoinevo-cli -regtest getnewaddress
moaCrnRfP5zzyhW8k65f6Rf2z5QpvJzSKe
bitcoinevo-cli -regtest getnewaddress
mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP

NEW_ADDRESS1=mhAXF4Eq7iRyvbYk1mpDVBiGdLP3YbY6Dm
NEW_ADDRESS2=moaCrnRfP5zzyhW8k65f6Rf2z5QpvJzSKe
NEW_ADDRESS3=mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP


Generate three new P2PKH addresses. These types of addresses can’t be directly used in the multisig redeem script below (since hashing the public keys is unnecessary). However, BitcoinEvo Core uses these addresses to reference the full, unhashed public keys, so we generate these addresses to retrieve the corresponding public keys for the multisig setup.
Keep in mind that hashed public keys, used in addresses, obscure the full public key. To create a multisig output or P2SH multisig redeem script, you must use full public keys, not addresses.

bitcoinevo-cli -regtest validateaddress $NEW_ADDRESS3

{
"isvalid": true,
"address": "mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP",
"scriptPubKey": "76a9143172b5654f6683c8fb146959d347ce303cae4ca788ac",
"ismine": true,
"iswatchonly": false,
"isscript": false,
"pubkey": "029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255",
"iscompressed": true,
"account": ""
}

NEW_ADDRESS3_PUBLIC_KEY=029e03a901b85534ff1e92c43c74431f7ce720[...]

Use the validateaddress RPC to retrieve the full public key associated with one of the generated addresses. This is the information that will be included in the multisig redeem script.

If you were setting up a multisig with another person or device, this is the public key you’d share.

bitcoinevo-cli -regtest createmultisig 2 '''
[
"'$NEW_ADDRESS1'",
"'$NEW_ADDRESS2'",
"'$NEW_ADDRESS3_PUBLIC_KEY'"
]'''

{
"address": "2N7NaqSKYQUeM8VNgBy8D9xQQbiA8yiJayk",
"redeemScript": "522103310188e911026cf18c3ce274e0ebb5f95b007f230d8cb7d09879d96dbeab1aff210243930746e6ed6552e03359db521b

088134652905bd2d1541fa9124303a41e95621029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c7725553ae"
}

P2SH_ADDRESS=2N7NaqSKYQUeM8VNgBy8D9xQQbiA8yiJayk
P2SH_REDEEM_SCRIPT=522103310188e911026cf18c3ce274e0ebb5f95b007[...]

Now, use the createmultisig RPC to generate a multisig address that requires two signatures (2-of-3). You can provide a mix of public keys and addresses as arguments, but only the corresponding public keys will be included in the final redeem script.
The command returns a P2SH address along with the corresponding redeem script, which will need to be provided whenever you spend satoshis sent to this P2SH address.


Warning: You must be careful not to lose the redeem script, especially if you don’t keep a record of the public keys used to create the P2SH multisig address. The redeem script is essential to spend any bitcoinevos sent to the P2SH address. If you lose the redeem script, you can recreate it by running the same createmultisig command as before, ensuring that the public keys are listed in the exact same order. However, if you lose both the redeem script and even one of the public keys, you will no longer be able to spend the funds at that P2SH address.

The address and redeem script are not automatically stored in the wallet when using the createmultisig command. If you wish to store them, you should use the addmultisigaddress RPC instead. Once added, ensure you create a new wallet backup to store this information safely.


bitcoinevo-cli -regtest sendtoaddress $P2SH_ADDRESS 10.00
7278d7d030f042ebe633732b512bcb31fff14a697675a1fe1884db139876e175

UTXO_TXID=7278d7d030f042ebe633732b512bcb31fff14a697675a1fe1884[...]

Paying the P2SH multisig address is just as simple as sending satoshis to a standard P2PKH address. Here, we use the sendtoaddress command, which automatically selects an unspent transaction output (UTXO), creates a change output if necessary, and deducts a transaction fee if applicable.

We store the returned txid in a shell variable for the UTXO we plan to spend next.

bitcoinevo-cli -regtest getrawtransaction $UTXO_TXID 1

{
"hex": "0100000001f0ede03d75050f20801d50358829ae02c058e8677d2cc74df51f738285013c26010000006a47304402203c375959

2bf608ab79c01596c4a417f3110dd6eb776270337e575cdafc699af20220317ef140d596cc255a4067df8125db7f349ad945212
e9264a87fa8d777151937012102a92913b70f9fb15a7ea5c42df44637f0de26e2dad97d6d54957690b94cf2cd05ffffffff0100
ca9a3b0000000017a9149af61346ce0aa2dffcf697352b4b704c84dcbaff8700000000",
"txid": "7278d7d030f042ebe633732b512bcb31fff14a697675a1fe1884db139876e175",
"size": 189,
"vsize": 189,
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "263c018582731ff54dc72c7d67e858c002ae298835501d80200f05753de0edf0",
"vout": 1,
"scriptSig": {
"asm": "304402203c3759592bf608ab79c01596c4a417f3110dd6eb776270337e575cdafc699af20220317ef140d596cc255a4067df81

25db7f349ad945212e9264a87fa8d777151937012102a92913b70f9fb15a7ea5c42df44637f0de26e2dad97d6d54957690b94cf2cd05",
"hex": "47304402203c3759592bf608ab79c01596c4a417f3110dd6eb776270337e575cdafc699af20220317ef140d596cc255a4067df

8125db7f349ad945212e9264a87fa8d777151937012102a92913b70f9fb15a7ea5c42df44637f0de26e2dad97d6d54957690b94cf2cd05"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 10.00000000,
"n": 0,
"scriptPubKey": {
"asm": "OP_HASH160 9af61346ce0aa2dffcf697352b4b704c84dcbaff OP_EQUAL",
"hex": "a9149af61346ce0aa2dffcf697352b4b704c84dcbaff87",
"reqSigs": 1,
"type": "scripthash",
"addresses": [
"2N7NaqSKYQUeM8VNgBy8D9xQQbiA8yiJayk"
]
}
}
]
}

UTXO_VOUT=0
UTXO_OUTPUT_SCRIPT=a9149af61346ce0aa2dffcf697352b4b704c84dcbaff87

Next, we use the getrawtransaction command to decode the transaction and examine its details. We select one of the outputs to use as the UTXO for the next step, retrieving both the output index (vout) and the public key script (scriptPubKey).

bitcoinevo-cli -regtest getnewaddress
mxCNLtKxzgjg8yyNHeuFSXvxCvagkWdfGU

NEW_ADDRESS4=mxCNLtKxzgjg8yyNHeuFSXvxCvagkWdfGU

Finally, we generate a new P2PKH address to use as the output for the next transaction.

## Outputs - Inputs = Transaction Fee (Always double-check your math!)
bitcoinevo-cli -regtest createrawtransaction '''
[
{
"txid": "'$UTXO_TXID'",
"vout": '$UTXO_VOUT'
}
]
''' '''
{
"'$NEW_ADDRESS4'": 9.998
}'''

010000000175e1769813db8418fea17576694af1ff31cb2b512b7333e6eb42f030d0d778720000000000ffffffff01c0bc973b0
00000001976a914b6f64f5bf3e38f25ead28817df7929c06fe847ee88ac00000000

RAW_TX=010000000175e1769813db8418fea17576694af1ff31cb2b512b733[...]

We generate the raw transaction, just like we did in the Simple Raw Transaction section.

bitcoinevo-cli -regtest dumpprivkey $NEW_ADDRESS1
cVinshabsALz5Wg4tGDiBuqEGq4i6WCKWXRQdM8RFxLbALvNSHw7
bitcoinevo-cli -regtest dumpprivkey $NEW_ADDRESS3
cNmbnwwGzEghMMe1vBwH34DFHShEj5bcXD1QpFRPHgG9Mj1xc5hq

NEW_ADDRESS1_PRIVATE_KEY=cVinshabsALz5Wg4tGDiBuqEGq4i6WCKWXRQd[...]
NEW_ADDRESS3_PRIVATE_KEY=cNmbnwwGzEghMMe1vBwH34DFHShEj5bcXD1Qp[...]


We retrieve the private keys for two of the public keys used to create the multisig transaction. Since we set up a 2-of-3 multisig, we need signatures from two private keys.

Reminder: Users should never manually handle private keys on mainnet. Refer to the warning in the Complex Raw Transaction section.

bitcoinevo-cli -regtest signrawtransaction $RAW_TX '''
[
{
"txid": "'$UTXO_TXID'",
"vout": '$UTXO_VOUT',
"scriptPubKey": "'$UTXO_OUTPUT_SCRIPT'",
"redeemScript": "'$P2SH_REDEEM_SCRIPT'"
}
]
''' '''
[
"'$NEW_ADDRESS1_PRIVATE_KEY'"
]'''

{
"hex" : "010000000175e1769813db8418fea17576694af1ff31cb2b512b7333e6eb42f030d0d7787200000000b5004830450221008d5e

c57d362ff6ef6602e4e756ef1bdeee12bd5c5c72697ef1455b379c90531002202ef3ea04dfbeda043395e5bc701e4878c15baab
9c6ba5808eb3d04c91f641a0c014c69522103310188e911026cf18c3ce274e0ebb5f95b007f230d8cb7d09879d96dbeab1aff21
0243930746e6ed6552e03359db521b088134652905bd2d1541fa9124303a41e95621029e03a901b85534ff1e92c43c74431f7ce
72046060fcf7a95c37e148f78c7725553aeffffffff01c0bc973b000000001976a914b6f64f5bf3e38f25ead28817df7929c06f
e847ee88ac00000000",
"complete" : false
}


PARTLY_SIGNED_RAW_TX=010000000175e1769813db8418fea17576694af1f[...]

We provide the first signature. The input JSON object takes an additional redeemScript parameter, which is used to append the redeem script to the signature script after both signatures are provided.

bitcoinevo-cli -regtest signrawtransaction $PARTLY_SIGNED_RAW_TX '''
[
{
"txid": "'$UTXO_TXID'",
"vout": '$UTXO_VOUT',
"scriptPubKey": "'$UTXO_OUTPUT_SCRIPT'",
"redeemScript": "'$P2SH_REDEEM_SCRIPT'"
}
]
''' '''
[
"'$NEW_ADDRESS3_PRIVATE_KEY'"
]'''

{
"hex" : "010000000175e1769813db8418fea17576694af1ff31cb2b512b7333e6eb42f030d0d7787200000000fdfd0000483045022100

8d5ec57d362ff6ef6602e4e756ef1bdeee12bd5c5c72697ef1455b379c90531002202ef3ea04dfbeda043395e5bc701e4878c15
baab9c6ba5808eb3d04c91f641a0c0147304402200bd8c62b938e02094021e481b149fd5e366a212cb823187149799a68cfa765
2002203b52120c5cf25ceab5f0a6b5cdb8eca0fd2f386316c9721177b75ddca82a4ae8014c69522103310188e911026cf18c3ce
274e0ebb5f95b007f230d8cb7d09879d96dbeab1aff210243930746e6ed6552e03359db521b088134652905bd2d1541fa912430
3a41e95621029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c7725553aeffffffff01c0bc973b00000
0001976a914b6f64f5bf3e38f25ead28817df7929c06fe847ee88ac00000000",
"complete" : true
}

SIGNED_RAW_TX=010000000175e1769813db8418fea17576694af1ff31cb2b[...]

For the second signature, we follow the same process as above, but using the second private key. With both required signatures in place, the transaction is now marked as complete.

bitcoinevo-cli -regtest sendrawtransaction $SIGNED_RAW_TX
430a4cee3a55efb04cbb8718713cab18dea7f2521039aa660ffb5aae14ff3f50

Finally, we send the fully signed transaction to the local node, which accepts and processes it.