Hedera Technical Insights: Pricing Smart Contracts
Oct 18, 2019
by Paul Madsen
Technical Lead for Hedera Hashgraph

Hedera charges fees based on the burden a particular transaction or query places on the nodes of the network. Nodes analyze the particulars of a transaction (for instance, how long a file is to be stored, how many signatures are on a crypto transfer, etc.) or a query (for instance, how many records are returned, how large a file is, etc.) and multiply those specifics by coefficients within a published fee schedule to determine the appropriate fee for a given transaction or query.

For the Solidity smart contracts that Hedera supports, the unit by which we assess the burden of different smart contract operations on the network is gas – as used by Ethereum. The Ethereum yellow paper defines the amount of gas for each and every Solidity opcode operation as a way to differentiate between the computational burden of different operations.

While Hedera inherits Ethereum gas, there are critical differences in how we measure and price gas.

Gas contribution to fee

Clients pay fees to the network for the processing of transactions into consensus state. Those fees reflect the burden each transaction places on the nodes of the network – specifically how much of a number of scarce network resources a transaction consumes. The price for each of those scarce resources are distributed to the nodes in a fee schedule file that Hedera publishes.

To determine the fee for any transaction, nodes measure how much of each resource that transaction will consume (for instance, how much storage duration, file size , RAM storage, bandwidth, etc.) by the corresponding fee schedule coefficients.

Fee = Usage(disk, bandwidth, RAM, gas, ...) * Coefficients(disk, bandwidth, RAM, gas, ...) * (exchange rate)

Note: the units of the coefficient are USD/resource, the calculated fee in USD is multiplied by the current HBAR/USD exchange rate to convert to hbars before being charged to the client.

As the above formula indicates, Hedera gas is just one of a number of resources – the relative scarcity and usage of each that, in the aggregate, determine the total fee for a transaction or query.

For the majority of transactions and queries, no gas is used or charged – it is only the other terms in the above formula that are relevant. But for smart contract operations, the gas usage is non-zero and so gas is one of the resources that contribute to the total fee.

Measuring gas

The Ethereum yellow paper stipulates the amount of gas each opcode consumes. In processing a smart contract function, Ethereum nodes start at the amount of gas provided on the transaction and subtract the appropriate number of gas for each opcode. If there remains some leftover gas after the last OPCODE is dealt with, then the client is not charged for that remainder

Hedera treats most of the smart contract opcode in the exact same manner. The call is executed, the amount of gas consumed by the operations is added up, and the contribution of that gas consumption is determined to the total transaction fee (as explained below). And so the client is not charged for the remainder.

Critically however, Hedera treats differently the opcodes that imply a storage burden on the nodes. Ethereum has no concept of ‘rent’ and so does not price based on the duration of storage. As an example, the yellow paper stipulates that an SSTORE opcode consumes 20k gas – irrespective of any temporal duration.

Hedera does account for rent, and so measures gas consumption for opcodes like SSTORE and LOG differently. Specifically, rather than subtracting the fixed amount of gas for an SSTORE that the yellow paper defines, Hedera nodes subtract an amount of gas that reflects the duration of storage being imposed on the nodes. Rather than a static 20k gas for a SSTORE, Hedera nodes calculate how much gas is consumed by a smart contract operation using a gas/byte/hour term.

For a concrete example of how the above works, consider a smart contract that is set to expire in 30 days. If a client sends a transaction that causes the contract state to grow in size (perhaps a new account in an ERC-20), then the gas consumed by that transaction will reflect that 30 day duration. The very same contract call sent the day before the expiration date would consume less gas as the call itself would be paying for only a single day of storage. Of course, at the expiration time, the contract will need to pay for its ongoing storage.

Pricing gas

Gas measures resource usage, not price. In Ethereum, gas is multiplied by ‘gas price’ in units of eth/gas to convert an amount of gas into a price in ether.

In order to encourage miners to include a particular transaction in the block, Ethereum clients are recommended to use a higher gas price when calculating a fee. Those transactions with a higher fee for the same amount of gas will be more attractive to miners, and so more likely to be added to a block.

Hedera doesn’t believe that’s fair. Hedera also multiplies gas by a price/gas term to determine the equivalent price in hbars for a given amount of gas, but, critically, clients do not stipulate their own ‘gas price’ in order to bribe their way to the front of the line.

Instead, the above price/gas term is published in the fee schedule file, and so all Hedera clients pay the same gas price. This gives Hedera clients predictability in gas costs. There is no uncertainty due to bidding for the miner’s favor. There is no market uncertainty: the prices are clearly published.

Checks & balances

When submitting a transaction to the network, Hedera clients stipulate a maximum transaction fee they are willing to pay for the processing of that transaction into consensus and maintenance in consensus state. Logically, clients indicate that they are authorizing a transaction fee up to this maximum, but no more.

When processing any transaction or query, nodes will assess whether the fee that the client has authorized is sufficient. In other words, the node uses the published fee schedule to determine whether that authorized fee is enough to cover the fee calculated based on the specifics of the transaction or query. If a client authorizes 0.01 hbars, but the nodes determine that the transaction requires 0.015 hbars, according to the published fee schedule, then the transaction will be rejected. But if the client overpays, then they are not overcharged.

Similarly, when submitting a smart contract transaction to the network, Hedera clients also stipulate a maximum gas value they are willing to have used in the execution of the smart contract function.

When processing a smart contract transaction or query, nodes perform an additional check to the above validation of the transaction fee – whether or not the gas amount that the client has stipulated is sufficient. Specifically, does the provided amount of gas cover the required gas as determined by executing the transaction? If the client provides 100k gas, but the node, in actually running the call, determines it would use 125k gas, then they will not apply it to state.

Conclusion

Hedera uses the concept of gas for measuring smart contract computational complexity. As for other scarce resources on the network, clients pay fees proportional to how much gas their transactions consume. Critically, Hedera refines and extends gas as traditionally defined. Firstly, Hedera charges rent for smart contract operations that increase the size of the contract’s state, that is, require an amount of gas that reflects how long the data will be stored before it expires. Secondly, Hedera rejects the idea of clients using ‘gas price’ to gain preferential treatment for their transactions to be processed. On Hedera, a transaction receives fair access based on known fee schedules, and clients can’t bribe their way to the front of the line.