RSS Amplifier

Project 0 · Jun 5, 2023

The Single Gas Coin Conundrum

0
Sign in to vote or save

man0s · Project 0

Companion code: https://github.com/mrgnresearch/sui-cookbook/tree/main/single-gas-coin-transaction

Interacting on the blockchain comes with a price. It can be expensive or cheap, but there is always a gas/fee component to submitting a transaction on-chain.

In the case of Sui, this payment is done in the native SUI Coin. Each transaction packs a non-empty list of SUI coins used for gas payment, separate from the transaction’s arguments.

Say you just started developing on Sui and are eager to land your first PTB (check out this article if you are not familiar with the term). You decide to start simple, and code up the following transaction:

Rather simple: get the value of the coin object provided and divide it by 9.

The transaction in itself does not matter here, apart from noticing that we are using our only Sui coin as input to its first command (0x2::coin::value).

You then write the code to send it. In Rust it would look something like the following:

The code for the PTB itself (build_ptb_logic) can be found in the complete sample code.

After getting yourself airdropped some Sui to a fresh wallet, you run the program, and surprise:

While the code seems sane the error is rather explicit, pointing to a specific mutable object being used more than once in the transaction, which is forbidden. The client libraries normally prevent those errors from happening within the set of objects provided as call arguments, by inserting an object in the PTB inputs list only if this object is not already present. However in our case the issue is less obvious, as the duplication happens between primary_coin passed as (1) call argument, and (2) payment object.

Digging deeper, we can see that this happens specifically because gas payment objects are added to the list of input objects, before the check is performed.

The fix for the above is both obvious and slightly nuanced. The stages of grief go:

  1. Damn, it seems I cannot do anything when I only have one gas coin 😕

  2. Easy, I’ll split the coin first! 😀

  3. Wait this is the same problem, I’ll be splitting the coin I use for payment, so duplicate error again 😨

Enters: the GasCoin call argument type (next to Input/Result/NestedResult). The above reasoning is correct, the only nuance is that the argument provided to the opening coin split needs to be the special Argument::GasCoin, to avoid the duplicate issue.

The PTB then becomes:

And the code:

As usual, it is worth printing those PTBs to inspect what those changes do, and here observe that the inputs list does not include the primary coin explicitly anymore.

Getting a good understanding of these gas payment matters is important to avoid defaulting to weird coin management, which can in some cases lead to equivocation, depending on what you are attempting.

Companion code: https://github.com/mrgnresearch/sui-cookbook/tree/main/single-gas-coin-transaction

No posts

Read the original on 0dotxyz.substack.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.