Sending Multiple Payments in a Single Transaction

At SteemSports, we do hundreds of payouts weekly. Currently, each payout is done as a standalone transaction.

I was wondering if its possible to be more efficient, and send multiple payouts at once. It turns out, its not only possible, but very easy to do.

I've borrowed some code from piston to hack together these two helper functions:

def broadcast_multi(steem, wifs, ops, write_mode=False):
    tx = sign_multi_tx(steem, ops, wifs)
    if not write_mode:
        return tx
    return steem.broadcast(tx)


def sign_multi_tx(steem, ops, wifs):
    """Construct a transaction that contains multiple operations."""
    if not isinstance(wifs, list):
        wifs = [wifs]

    if not any(wifs) and not steem.unsigned:
        raise MissingKeyError

    ops = [transactions.Operation(x) for x in ops]
    expiration = transactions.formatTimeFromNow(steem.expiration)
    ref_block_num, ref_block_prefix = transactions.getBlockParams(steem.rpc)
    tx = transactions.Signed_Transaction(
        ref_block_num=ref_block_num,
        ref_block_prefix=ref_block_prefix,
        expiration=expiration,
        operations=ops
    )
    if not steem.unsigned:
        tx = tx.sign(wifs)

    return tx.json()

To send multiple payments at once, we need to create a list of operations. I am going to do this manually here for sake of simplicity and ease of understanding:

ops = [
        transactions.Transfer(
            **{"from": "fnait",
               "to": "furion",
               "amount": '{:.{prec}f} {asset}'.format(
                   float(0.1),
                   prec=3,
                   asset="SBD"
               ),
               "memo": "TEST MULTI"
               }
        ),
        transactions.Transfer(
            **{"from": "fnait",
               "to": "furion",
               "amount": '{:.{prec}f} {asset}'.format(
                   float(0.1),
                   prec=3,
                   asset="SBD"
               ),
               "memo": "TEST MULTI 2"
               }
        )
    ]

Now we can construct, sign and broadcast the transfers with a single line of code:

tx = broadcast_multi(steem, wifs, ops, write_mode=True)

Where do steem and wifs come from?
steem is just a piston Steem instance: steem = Steem() and wifs is a list of private keys (in this case, we just need the active private key).

If we set write_mode to False, it will run in simulation mode, without actually broadcasting the transaction to the network.

tx

Steemit

Note
Beware that the transaction has a hardcoded limit of 64k, so don't cram too many operations in one.



Don't miss out on the next post - follow me.
SteemSports | steemtools | steem.li | witness


H2
H3
H4
Upload from PC
Video gallery
3 columns
2 columns
1 column
16 Comments