Multi-witness transactions
Overview#
note
This guide assumes that you have completed the Exploring Cardano Wallets guide. You will need one UTxO sitting at each of the wallets (payment1.addr and payment2.addr) to complete this guide.
This guide also assumes that you have cardano-node running in the background and connected to the testnet network.
Recap#
Let's recap what we did so far. Our goal in the previous guide was to draw 1000 tADA from the testnet faucet and send 250 tAda from payment1 to payment2.
Make sure we are in the correct folder.
$ pwd/home/user/cardano- Query UTxO
- Calculate fees
- Build Tx
- Sign & Submit Tx
- Verify Tx
We drew 1000 tAda from the Testnet Faucet into our payment1 wallet.
$ cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat keys/payment1.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------264c0aa805652e3607c5ea2b1e8a9f3bf9c3bc8d4d938e1a9035f352083ba703 0 1000000000 lovelaceWe used protocol-parameters to draft our transaction and calculated the expected fee.
$ cardano-cli query protocol-parameters \--testnet-magic 1097911063 \--out-file protocol.json$ cardano-cli transaction build-raw \--tx-in 264c0aa805652e3607c5ea2b1e8a9f3bf9c3bc8d4d938e1a9035f352083ba703#0 \--tx-out $(cat keys/payment2.addr)+0 \--tx-out $(cat keys/payment1.addr)+0 \--fee 0 \--out-file tx.draft$ cardano-cli transaction calculate-min-fee \--tx-body-file tx.draft \--tx-in-count 1 \--tx-out-count 2 \--witness-count 1 \--testnet-magic 1097911063 \--protocol-params-file protocol.json174169 LovelaceFrom the expected fee of 174169 Lovelace, we were able to calculate the outputs and build our transaction.
cardano-cli transaction build-raw \--tx-in 264c0aa805652e3607c5ea2b1e8a9f3bf9c3bc8d4d938e1a9035f352083ba703#0 \--tx-out $(cat keys/payment2.addr)+250000000 \--tx-out $(cat keys/payment1.addr)+749825831 \--fee 174169 \--out-file tx.draftnote
Your fees might have been different hence you would have different amounts.
We used payment1.skey to sign our transaction and submitted it to the blockchain.
cardano-cli transaction sign \--tx-body-file tx.draft \--signing-key-file keys/payment1.skey \--testnet-magic 1097911063 \--out-file tx.signed
cardano-cli transaction submit \--tx-file cardano/tx.signed \--testnet-magic 1097911063Transaction successfully submitted.Finally we verified the transaction by querying the payment1 and payment2 wallets.
$ cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat keys/payment1.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251 1 749825831 lovelace$ cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat payment2.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251 0 250000000 lovelaceWe currently have 749.825831 tAda in our payment1 wallet and 250 tAda in our payment2 wallet.
Let's see how we can spend it all at once!
Use case#
There are many possible reasons why you would want to have multiple wallets sending their ada in a single transaction. One is, you own two wallets (payment1 and payment2) and you want to spend it on something that...
- costs more than you have in any of your two wallets,
- but both amounts combined would cover the costs.
Let's say you are at the bike store and you see a nice bike with a price tag of 1100 tAda on it. You only have 999 tAda (plus change) left.
The bike store owner - a devious blockchain enthusiast - is willing to give you a 10% discount, if you manage to pay him in a single transaction
There has to be no change, buddy! --Bike Store Owner
So we need to make sure to spend all our tAda from our two wallets in a single transaction.
note
He can easily verify if we spent all our money by checking if the transaction has more than one output.
There are ways to optimize the amount you spend. We will leave this for you to figure out yourself.
Technical Flow#
This scenario is pretty straight forward and looks like this.

As you can see in the diagram above, we will build and submit a multi-witness transaction, having two inputs and one output.
note
We can't do this with cardano-wallet, or any other wallet like Daedalus or Yoroi because we will need both signing-keys from payment1 and payment2 to sign the transaction.
Time to code#
note
As mentioned above, this guide assumes you completed the Exploring Cardano Wallets guide.
We also assume you paid 174169 Lovelace in transaction fees and that your current balances are:
- payment1:
749825831 Lovelace - payment2:
250000000 Lovelace
Create a store-owner wallet#
If you don't already have a third wallet to use for this guide, let's create one where we can transfer all our funds to.
Make sure you are inside the keys directory like so: cd /home/user/cardano/keys
Generate a payment key-pair using cardano-cli:
cardano-cli address key-gen \--verification-key-file /home/user/cardano/keys/store-owner.vkey \--signing-key-file /home/user/cardano/keys/store-owner.skeyThen generate a wallet address for the testnet network:
cardano-cli address build \--payment-verification-key-file /home/user/cardano/keys/store-owner.vkey \--out-file /home/user/cardano/keys/store-owner.addr \--testnet-magic 1097911063Check your keys directory. It should look something like this:
/home/user/cardano/keys/โโโ payment1.addrโโโ payment1.skeyโโโ payment1.vkeyโโโ payment2.addrโโโ payment2.skeyโโโ payment2.vkeyโโโ store-owner.addrโโโ store-owner.skeyโโโ store-owner.vkey
0 directories, 9 filesCalculate the transaction fee#
Lets create a directory to store our transactions for this guide and enter it:
mkdir -p /home/user/cardano/multi-witness-sample && cd $_;We want to send all our tAda sitting at the two UTxO we verified before and send it to the store-owner.addr. That means we will have two inputs.
What about the outputs? Well, the devious store-owner wants us to spend it all, so there will be one output to the store-owner and zero outputs to us. Remember? "...no change, buddy!"
Lets build that transaction.
cardano-cli transaction build-raw \--tx-in b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251#0 \--tx-in b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251#1 \--tx-out $(cat ../keys/store-owner.addr)+0 \--fee 0 \--out-file tx2.draftThe last thing we need to do is to calculate the fees for tx2.draft. Notice the --tx-in-count and --witness-count.
cardano-cli transaction calculate-min-fee \--tx-body-file tx2.draft \--tx-in-count 2 \--tx-out-count 1 \--witness-count 2 \--testnet-magic 1097911063 \--protocol-params-file ../protocol.json 179581 LovelaceWe can calculate the amount the store-owner will receive, if both UTxO are spent during the transaction:
749825831 (payment1)+ 250000000 (payment2) --------- 999825831- 179581 (fee) --------- 999646250 (store-owner) =========Build, sign and submit transaction#
We know the output amount as well as the fee. We can finally build, sign and submit our tx2.draft transaction.
We have to use payment1.skey and payment2.skey to sign our transaction.
cardano-cli transaction build-raw \--tx-in b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251#0 \--tx-in b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251#1 \--tx-out $(cat ../keys/store-owner.addr)+999646250 \--fee 179581 \--out-file tx2.draft
cardano-cli transaction sign \--tx-body-file tx2.draft \--signing-key-file ../keys/payment1.skey \--signing-key-file ../keys/payment2.skey \--testnet-magic 1097911063 \--out-file tx2.signed
cardano-cli transaction submit \--tx-file tx2.signed \--testnet-magic 1097911063Transaction successfully submittedVerify multi-witness transactions#
The devious store-owner will now verify that everything went according to his plan.
cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat /home/user/cardano/keys/store-owner.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------258abd628eef7d6ff0f7b4e6866b4f7c21065f4d6b5e49b51e2ac4ff035ad06f 0 999646250 lovelaceVerify 258abd628eef7d6ff0f7b4e6866b4f7c21065f4d6b5e49b51e2ac4ff035ad06f on the cardano testnet explorer
Success!
He can see that the transaction has one output to his wallet. No other outputs, hence you must have spent all of your tAda.
Congratulations, you are now able to submit multi-witness transactions on Cardano. This should help you bring integrations to your existing or new upcoming applications. ๐๐๐