How to deploy and use gas stations

Thanos
KadenaCoin
Published in
5 min readMay 24, 2021

--

Gas stations are a very neat way of offloading the gas cost from the user to the deployer. There is a multitude of ways to configure them and limit what they will pay for. You can find more information about gas stations here.

General information

Gas stations are almost the same as the account you hold your coins in. The main difference is its controlled by guards (rules) instead of a keyset. They can store any asset that a normal account would including tokens and NFTs. Think of it as a public account that anyone can use IF the transaction is within the rules set by the deployer. Lets take a look at the 2 types of stations.

“Gas guard” type gas stations

This type of gas station can be called by anyone and for any contract as long as it fits within the defined rules. There is quite a few of those rules you can set to you station so it only pay the transactions you want it to. You first choose a guard that fits your needs. Its name describes how to enforce the rules. It can be

  • guard-all
    “Create a guard that only succeeds if every guard in GUARDS is successfully enforced.”
  • guard-any
    “Create a guard that succeeds if at least one guard in GUARDS is successfully enforced.”
  • guard-and
    “Guard to enforce both A and B.”
  • guard-or
    “Guard to enforce A or B.”

Once you chose one of those you can then select what those rules you want to be enforced are.

  • max-gas-notional
    “Guard to enforce gas price * gas limit is smaller than or equal to GAS”
  • max-gas-price
    “Guard to enforce gas price is smaller than or equal to GAS PRICE”
  • max-gas-limit
    “Gas Limit must be smaller than or equal to {}”
  • at-before-date
    “Guard to enforce chain time is at or before DATE.”
  • at-after-date
    “Guard to enforce chain time is at or after DATE.”

Examples

  • Will only pay for gas if the price is under 0.00000001 and the amount used is under 400
(use util.guards)
(use util.guards1)
(coin.create-account "NAME-OF-THE-ACCOUNT" (guard-all [
(create-user-guard (coin.gas-only))
(max-gas-price 0.00000001)
(max-gas-limit 400)
])
)
  • Will only pay until November 1 2021
(use util.guards)
(use util.guards1)
(coin.create-account "NAME-OF-THE-ACCOUNT" (guard-all [
(create-user-guard (coin.gas-only))
(max-gas-price 0.00000001)
(max-gas-limit 400)
(util.guards.before-date (time "2021-11-01T00:00:00Z"))
])
)

“Gas payer” type gas stations

Those gas stations are a lot more advanced and allow more fine tuning of who can use it. You can use the same rules as the other type of station but also add any pact code to it. This allow the station to be infinitely customizable for anything you would need. It can leverage everything in pact.

(namespace 'free)

(module anedak-gas-station GOVERNANCE
(defcap GOVERNANCE ()
"makes sure only admin account can update the smart contract"
(enforce-guard (at 'guard (coin.details "admin-anedak")))
; true
)

(implements gas-payer-v1)
(use coin)

(defschema gas
balance:decimal
guard:guard)

(deftable ledger:{gas})

(defcap GAS_PAYER:bool
( user:string
limit:integer
price:decimal
)
(enforce (= "exec" (at "tx-type" (read-msg))) "Inside an exec")
(enforce (= 1 (length (at "exec-code" (read-msg)))) "Tx of only one pact function")
(enforce (= "(free.anedak." (take 13 (at 0 (at "exec-code" (read-msg))))) "only free.anedak smart contract")

(compose-capability (ALLOW_GAS))
)

(defcap ALLOW_GAS () true)

(defun create-gas-payer-guard:guard ()
(create-user-guard (gas-payer-guard))
)

(defun gas-payer-guard ()
(require-capability (GAS))
(require-capability (ALLOW_GAS))
)
)
(coin.transfer-create "8ff29d31d954cbd55ea3173f47455810f4835e8e5de85834a55a1ad296cf9e61" "anedak-gas-payer" (free.anedak-gas-station.create-gas-payer-guard) 2.0)

This contract creates a gas station that has 3 rules. Enforce the transaction is an exec so it’s not wasted. Enforce the transaction is a simple one with only one function, and enforce that it will only pay if the code starts with free.anedak.

(namespace 'free)

(module anon-chat-gas-stationV2 GOVERNANCE
(defcap GOVERNANCE ()
"makes sure only admin account can update the smart contract"
(enforce-guard (at 'guard (coin.details "chat-keyset")))
; true
)

(implements gas-payer-v1)
(use coin)
(use util.guards1)

(defschema gas
balance:decimal
guard:guard)

(deftable ledger:{gas})

(defcap GAS_PAYER:bool
( user:string
limit:integer
price:decimal
)
(enforce (= "exec" (at "tx-type" (read-msg))) "Inside an exec")
(enforce (= 1 (length (at "exec-code" (read-msg)))) "Tx of only one pact function")
(enforce (= "(free.anon-chat." (take 16 (at 0 (at "exec-code" (read-msg))))) "only anon-chat token smart contract")
(enforce-below-or-at-gas-price 0.000000000001)
(enforce-below-or-at-gas-limit 800)

(compose-capability (ALLOW_GAS))
)

(defcap ALLOW_GAS () true)

(defun create-gas-payer-guard:guard ()
(create-user-guard (gas-payer-guard))
)

(defun gas-payer-guard ()
(require-capability (GAS))
(require-capability (ALLOW_GAS))
)
)
(coin.transfer-create "(. Y .)" "chat-gas-payerV2" (free.anon-chat-gas-stationV2.create-gas-payer-guard) 2.0)

This one is similar but with a limit to the price and amount of gas it will pay for. 0.000000000001 for price and 800 units

Front-end integration

Force the transfer to be executed by the station you created instead of a user account. You might need to add capabilities depending on your type of station and its level of customization.

“Gas Guard” type don't need any special capability. Simply set the account as the sender of a transaction.

Example capability for the “Gas Payer” type

clist: [
//capability to use gas station
{name: `free.anon-chat-gas-stationV2.GAS_PAYER`,
args: ["hi", {int: 1}, 1.0]
}]

Deployment

The process of deploying a station is the same as demonstrated in a previous article on how to deploy tokens here. Load the contract in Chainweaver and press deploy.

Conclusion

Gas station are an extremely powerful tool that allow developers to pay gas fee for their users, allow anonymous interaction or even completely hide that the user is on a blockchain.

Here’s a list of some gas-stations currently deployed

https://explorer.chainweb.com/mainnet/txsearch?q=gas-station
https://explorer.chainweb.com/mainnet/txsearch?q=x-chain
https://explorer.chainweb.com/mainnet/txsearch?q=free-october-gas

Most useful gas station commands can be found in those 2 contracts

https://balance.chainweb.com/modules.html?server=api.chainweb.com&module=util.guards&chain=0

https://balance.chainweb.com/modules.html?server=api.chainweb.com&module=util.guards1&chain=0

Useful Links:

--

--