# Please use \`cardano-cli transaction build\` instead of \`cardano-cli transaction build-raw\`

**URL:** <https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919>\
**Category:** Misc Dev Talk\
**Created:** [6 February 2022 22:02 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919 "2022-02-06T22:02:15Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![HeptaSean](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.cardano.org/heptasean/32/82306_2.png) [@HeptaSean](https://forum.cardano.org/u/HeptaSean)\
**Post date:** [6 February 2022 22:02 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919/1 "2022-02-06T22:02:15Z")

</div>

Especially if you are writing a walk-through for beginners, please advise them to use `build` instead of `build-raw`. It’s a PITA debugging all those cases, where the balances don’t add up.

**The old way:**

```auto
$ cardano-cli query utxo --mainnet --address addr1vxlgahj760v86tzcpr5xd9u80kcmgm2gsl6ulhvxnya26pq3h39nq
                           TxHash TxIx Amount
--------------------------------------------------------------------------------------
82ad4e06c9a7319e765114aa15910a46391a1bc23900d808deeb86315c1ae158 0 13933006 lovelace + TxOutDatumNone
82ad4e06c9a7319e765114aa15910a46391a1bc23900d808deeb86315c1ae158 1 4000000 lovelace + 10000 a80398fd0dd6c71bbe067f6181274d0d9aff81d351d8c6749d6581dd.c39e6f7220436f696e + TxOutDatumNone
$ cardano-cli transaction build-raw \
> --tx-in 82ad4e06c9a7319e765114aa15910a46391a1bc23900d808deeb86315c1ae158#1 \
> --tx-out "addr1q89vv6r6e7040j7lm5m3s9c9cv7l0hdchwrwt62xm4v7h2df36408rhdrmchm7pxj8huuyz4jsgzqjllta5xfgrjysqsznluu4+2000000+3000 a80398fd0dd6c71bbe067f6181274d0d9aff81d351d8c6749d6581dd.c39e6f7220436f696e" \
> --tx-out "addr1vxlgahj760v86tzcpr5xd9u80kcmgm2gsl6ulhvxnya26pq3h39nq+2000000+7000 a80398fd0dd6c71bbe067f6181274d0d9aff81d351d8c6749d6581dd.c39e6f7220436f696e" \
> --fee 200000 \
> --out-file trans1-tx.raw
$ cardano-cli query protocol-parameters --mainnet --out-file protocol.json
$ cardano-cli transaction calculate-min-fee --mainnet \
> --tx-body-file trans1-tx.raw \
> --tx-in-count 1 --tx-out-count 2 --witness-count 1 \
> --protocol-params-file protocol.json
179845 Lovelace
$ cardano-cli transaction build-raw \
> --tx-in 82ad4e06c9a7319e765114aa15910a46391a1bc23900d808deeb86315c1ae158#1 \
> --tx-out "addr1q89vv6r6e7040j7lm5m3s9c9cv7l0hdchwrwt62xm4v7h2df36408rhdrmchm7pxj8huuyz4jsgzqjllta5xfgrjysqsznluu4+2000000+3000 a80398fd0dd6c71bbe067f6181274d0d9aff81d351d8c6749d6581dd.c39e6f7220436f696e" \
> --tx-out "addr1vxlgahj760v86tzcpr5xd9u80kcmgm2gsl6ulhvxnya26pq3h39nq+1820155+7000 a80398fd0dd6c71bbe067f6181274d0d9aff81d351d8c6749d6581dd.c39e6f7220436f696e" \
> --fee 179845 \
> --out-file trans1-tx.raw
$ cardano-cli transaction sign --mainnet \
> --tx-body-file trans1-tx.raw \
> --signing-key-file ../mint.skey \
> --out-file trans1-tx.signed
$ cardano-cli transaction submit --mainnet --tx-file trans1-tx.signed
Transaction successfully submitted.

```

We have to download protocol parameters, calculate the minimal fee by hand, adjust the outputs, …  
Especially if people use the army of shell variables used for some reason in a lot of guides, there are so many places, where something can go wrong.

**The “new” way:**  
(in fact, not so new at all)

```auto
$ cardano-cli query utxo --mainnet --address addr1vxlgahj760v86tzcpr5xd9u80kcmgm2gsl6ulhvxnya26pq3h39nq
                           TxHash TxIx Amount
--------------------------------------------------------------------------------------
38c6e56642afdbe796414271834c092f8481b68c3fd97d36348ccbda535f0176 1 1820155 lovelace + 7000 a80398fd0dd6c71bbe067f6181274d0d9aff81d351d8c6749d6581dd.c39e6f7220436f696e + TxOutDatumNone
82ad4e06c9a7319e765114aa15910a46391a1bc23900d808deeb86315c1ae158 0 13933006 lovelace + TxOutDatumNone
$ cardano-cli transaction build --mainnet \
> --tx-in 38c6e56642afdbe796414271834c092f8481b68c3fd97d36348ccbda535f0176#1 \
> --tx-in 82ad4e06c9a7319e765114aa15910a46391a1bc23900d808deeb86315c1ae158#0 \
> --tx-out "addr1q89vv6r6e7040j7lm5m3s9c9cv7l0hdchwrwt62xm4v7h2df36408rhdrmchm7pxj8huuyz4jsgzqjllta5xfgrjysqsznluu4+2000000+3000 a80398fd0dd6c71bbe067f6181274d0d9aff81d351d8c6749d6581dd.c39e6f7220436f696e" \
> --tx-out "addr1vxlgahj760v86tzcpr5xd9u80kcmgm2gsl6ulhvxnya26pq3h39nq+2000000+4000 a80398fd0dd6c71bbe067f6181274d0d9aff81d351d8c6749d6581dd.c39e6f7220436f696e" \
> --change-address addr1vxlgahj760v86tzcpr5xd9u80kcmgm2gsl6ulhvxnya26pq3h39nq \
> --out-file trans2-tx.raw
Estimated transaction fee: Lovelace 178657
$ cardano-cli transaction sign --mainnet \
> --tx-body-file trans2-tx.raw \
> --signing-key-file ../mint.skey \
> --out-file trans2-tx.signed
$ cardano-cli transaction submit --mainnet --tx-file trans2-tx.signed
Transaction successfully submitted.

```

No fee calculation by hand, no balancing of ADA by hand, no download of protocol parameters, the rest just flows into a UTxO at the given `--change-address`.

(Note: Unfortunately, non-ADA assets still have to be balanced by hand up to now. Otherwise we could have saved one `--tx-out` to the `--change-address` itself in this command.)

---

<div class="post-metadata">

**Author:** ![COSDpool](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.cardano.org/cosdpool/32/21482_2.png) [@COSDpool](https://forum.cardano.org/u/COSDpool)\
**Post date:** [6 February 2022 22:32 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919/2 "2022-02-06T22:32:32Z")

</div>

thanks @HeptaSean - that’s a good suggestion & I was happy to pursue it a while ago. Yet we ended up sticking with the original raw transaction building for a reason I didn’t anticipate… buildling a raw transaction to use complete UTxO’s always results in a single UTxO in the address used for your “change” while keeping the balance at the same address every time.

i.e. as time goes on, the same payment address (especially important for the pledge address of a stake pool) will always have a single UTxO in it with an easily human-readable Tx ID and balance, for further use in manual transactions… which is important if you feel more comfortable doing it that way.

The manual error can be reduced or removed by copy/pasting the CLI commands & keeping the parameters as variables, so users can retain the satisfaction and auditability of using the `cardano-cli` commands without relying on scripts to formulate the commands or total the UTxO’s at an address, e.g.:

> **[Withdraw stake pool rewards | COSD](https://cosd.com/frankenwallet/cardano/templates/withdraw-rewards)**
>
> Make a copy of the Data section somewhere in your host folder (low-security encrypted) where both your host computer & the Frankenwallet can access it.

Though we do this in the operations of our own pool, and invite others to do the same, we don’t claim that this is a better way of doing things… it’s just an argument that _both_ the “build” and “build-raw” approaches will have uses in scripts and tutorials 🤓

---

<div class="post-metadata">

**Author:** ![HeptaSean](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.cardano.org/heptasean/32/82306_2.png) [@HeptaSean](https://forum.cardano.org/u/HeptaSean)\
**Post date:** [6 February 2022 22:44 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919/3 "2022-02-06T22:44:27Z")

</div>

> [@COSDpool](#):
>
> buildling a raw transaction to use complete UTxO’s always results in a single UTxO in the address used for your “change” while keeping the balance at the same address every time.

If there are no other `--tx-out`s targeting the same address as `--change-address`, the `build` way should also consistently result in just a single UTxO at that address.

As soon as assets other than ADA are involved that doesn’t work anymore as my example already shows. It would be really good if future versions could also balance non-ADA assets to make it even more comfortable.

---

<div class="post-metadata">

**Author:** ![COSDpool](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.cardano.org/cosdpool/32/21482_2.png) [@COSDpool](https://forum.cardano.org/u/COSDpool)\
**Post date:** [6 February 2022 23:52 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919/4 "2022-02-06T23:52:48Z")

</div>

> [@HeptaSean](#):
>
> the `build` way should also consistently result in just a single UTxO at that address.

thanks; we’ve updated our template at the web page above accordingly 🕶

---

<div class="post-metadata">

**Author:** ![COSDpool](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.cardano.org/cosdpool/32/21482_2.png) [@COSDpool](https://forum.cardano.org/u/COSDpool)\
**Post date:** [14 April 2022 04:40 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919/5 "2022-04-14T04:40:25Z")

</div>

hey @HeptaSean (or anyone), I’m adapting some of our old scripts along these lines & noticed something I can’t figure out in our offline environment, running `cardano-cli transaction build` like so:

```auto
cardano-cli transaction build \
--mainnet \
--tx-in $(cat payment.utxo) \
--tx-out $(cat wallet.addr)+$(cat rbal) \
--change-address $(cat low/payment.addr) \
--withdrawal $(cat low/stake.addr)+$(cat rbal) \
--out-file tx.draft

```

It gets this error, as if we weren’t properly pointed to a live node to `submit` a transaction:

```auto
Command failed: transaction build Error: Error while looking up environment variable:
CARDANO_NODE_SOCKET_PATH Error: "CARDANO_NODE_SOCKET_PATH"

```

Why would any transaction building, designed to work offline, require a connection to a live Cardano node?

We didn’t notice this before since our automation was still using the old transaction model of building the dummy transaction first & are finally getting rid of that old stuff now.

If there was a memo about `cardano-cli transaction build` only working on a node machine, or with a connection to one, then I definitely missed it. Hopefully I’m making some dumb mistake regarding the syntax or context.

I was thinking it might need a timing reference from a live node if `--invalid-hereafter` were not specified, but it gets the same error even using that option. 🤔

---

<div class="post-metadata">

**Author:** ![HeptaSean](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.cardano.org/heptasean/32/82306_2.png) [@HeptaSean](https://forum.cardano.org/u/HeptaSean)\
**Post date:** [14 April 2022 05:31 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919/6 "2022-04-14T05:31:31Z")

</div>

I think, `build` only works with a synchronised node. There could be two reasons:

They integrated the minimum fee calculation. In the `build-raw` variant, you need to get the protocol parameters from a synchronised node (but can then copy around the file).

In order to calculate the transaction, it has to be known what assets are on the input UTxOs. I don’t know how `build-raw` does it. Maybe then transactions fail only on submission, while `build` tries to ensure that they will not fail.

Don’t know any way around it, other than building on the hot node and doing only the signing air-gapped. Sorry!

---

<div class="post-metadata">

**Author:** ![Triton-pool](https://avatars.discourse-cdn.com/v4/letter/t/f1d935/32.png) [@Triton-pool](https://forum.cardano.org/u/Triton-pool)\
**Post date:** [14 April 2022 05:32 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919/7 "2022-04-14T05:32:00Z")

</div>

I would first try to just define the variable and run the same command again.

---

<div class="post-metadata">

**Author:** ![COSDpool](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.cardano.org/cosdpool/32/21482_2.png) [@COSDpool](https://forum.cardano.org/u/COSDpool)\
**Post date:** [14 April 2022 15:45 UTC](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919/8 "2022-04-14T15:45:51Z")

</div>

> [@HeptaSean](#):
>
> Don’t know any way around it, other than building on the hot node and doing only the signing air-gapped. Sorry!

please don’t be sorry… this was just the confirmation I was looking for. I think they could have made `transaction build` work on a cold machine if the CLI gave the user the benefit of a doubt about the transaction amounts being correct, allowing the submitted transaction to fail if those preconditions were not met (just like it already does with `transaction build-raw`). I just needed to be sure about how it was implemented & that I wasn’t missing anything that could make it work cold.

It’s an adaptation to our workflow, rather than a real problem, since we’re already gathering parameters for our transaction on the relay, and just need to move 1 extra step to build the transaction there. Maybe someone would post here someday if `build` is ever detached from the requirement for a live node connection. 🕶
