ICON Foundation recently announced open schedule notice for Fee 2.0, launching on ICON mainnet in June 2019. Fee 2.0 is the actual implementation of the buzzwords like Virtual Steps or SCORE staking that we heard a while back from the Transaction Fee Yellow Paper. Today we’ll take an early peek of Fee 2.0 features, as well as creating a SCORE to exercise fee sharing and SCORE deposits. We will also talk about what these features mean to the ICON Dapp ecosystem.

What was Fee 1.0?

Fee 1.0 was simply that users will pay for 100% of the transaction fees for SCORE (smart contract) execution, this is the case for most blockchain protocols and ICON was no different. Let’s review how transaction fees work in version 1,

Transaction fees

Transaction fees were solely paid for by transaction senders, there’s no concept of fee sharing in version 1. We covered transaction fee calculation in this article: ICON DAPP From A-Z part 2: SCORE under “Step Calculation” section if you want to look under the hood.

What are Steps

Recall that transaction fees are measured in “Steps”, which is simply a smaller unit of ICX (100,000,000 Steps = 1 ICX). This is conceptually similar to gas in Ethereum and what Gwei is to ETH. Users specify a max value they’re willing to spend for the transaction, exceeding the limit will effectively nullify the transaction.

What is Fee 2.0?

Transaction senders must pay the transaction fees to execute a smart contract on the blockchain. The result of this transaction fee system was that all DApp users were required to pay transaction fees to use the service. This has been a major hurdle in attracting more users into the DApp service. With the ICON Transaction Fee 2.0 (Fee Sharing and Virtual Step), DApp service operators can choose to pay the transaction fees on behalf of the service users.

By using Fee 2.0 feature, DApp providers can have service users to avoid paying fees or have them pay fees with Virtual Step, a system to mitigate the burden of transaction fees, generated through staking instead of the actual ICX.

Recall, Virtual Steps are transaction fee credits, they have 1:1 Step ratio but non-redeemable, non-transferable, and non-tradable. You can use these credits to deduct transaction fees only. Virtual Steps have expiration date, same as your deposit period.

When SCORE operator deposits ICX into the contract, Virtual Step is immediately created in proportion to the amount of ICX and the duration of the deposit. SCORE operators can pay for transaction fees with Virtual Steps.

Fee 2.0 has two main objectives

SCORE operators can share the transaction fees for their service users. SOCRE operators can earn Virtual Steps by staking ICX to the SCORE, to ease the burden of fee sharing.

In practice, fee 2.0 allows you to set_fee_sharing_proportion , which simply allows you to set a sharing proportion from 0 to 100%. This % is the transaction fee, you as the SCORE operator, will be paying for your users. Another key feature is the ability to make deposits into a SCORE, which will generate Virtual Steps that can be used to deduct transaction fees.

How to Deploy Fee 2.0 SCORE?

Fee 2.0 is pending to be deployed to the ICON network, so for this tutorial we’ll be using an early T-bears release candidate with Fee 2.0 features, you can pull the image from

$ docker pull iconloop/tbears:1.3.0-rc1

then run the container

$ docker run -it -p 9000:9000 iconloop/tbears:1.3.0-rc1

Let’s experiment by creating a new SCORE that implements fee sharing functionalities,

$ tbears init fee_sharing FeeSharing

IconScoreBase provides two APIs that can be invoked inside the SCORE's external methods, namely get_fee_sharing_proportion and set_fee_sharing_proportion . Proportion is between 0 to 100, if its set to 100, the SCORE will pay 100% of transaction fees on behalf of the transaction sender. We will also register wallets to a whitelist to prevent abusing, each wallet can have a different sharing proportion depending on the SCORE logic.

Now deploy this to your localhost,

# tbears_cli_config.json

{

"uri": "http://127.0.0.1:9000/api/v3",

"nid": "0x3",

"keyStore": null,

"from": "hxe7af5fcfd8dfc67530a01a0e403882687528dfcb",

"to": "cx0000000000000000000000000000000000000000",

"deploy": {

"stepLimit": "0x59682f00",

"mode": "install",

"scoreParams": {}

},

"txresult": {},

"transfer": {

"stepLimit": "0x200000"

}

}

We’ll use these default settings and keystore to deploy

$ tbears deploy fee_sharing

Check txresult as usual,

$ tbears txresult 0x4e570c0d4bbb99b670c5852655938cb1b4b91190d386fe814c6bd270f13b139e

Copy down the SCORE address.

Now let’s create a new JSON-RPC call to make deposit to the SCORE, replace “to” address with what you just copied from the last step.

# deposit.json {

"jsonrpc": "2.0",

"method": "icx_sendTransaction",

"id": 1,

"params": {

"version": "0x3",

"nid": "0x3",

"from": "hxe7af5fcfd8dfc67530a01a0e403882687528dfcb",

"to": " cxff74e566e30e9ccd2ba6291183876e3350d47942 ",

"value": "0x10f0cf064dd59200000",

"stepLimit": "0x3000000",

"timestamp": "0x58a1be6dac367",

"nonce": "0x1",

"signature": "Z+sc78SjGGsdch5kalcNqaK8+7ZX8M6SwaRYjrFopOoepLBok/sJ9EPulGxrDN4OodTqqYRA6KnuwGrNStomwAA=",

"dataType": "deposit",

"data": {

"action": "add"

}

}

}

Execute it, for icx_sendTransaction we should use tbears sendtx

$ tbears sendtx deposit.json

Check the transaction result

$ tbears txresult 0x9c74f320e8415c4abd341e8b1ee38d1451b83e9d1e6e7c8110b6119930ad8164

Now the transaction result is something we’ve not seen before, if our deposit was successful in the last step, you should see an eventlog in our transaction result DepositAdded .

Transaction result: {

"jsonrpc": "2.0",

"result": {

"txHash": "0x9c74f320e8415c4abd341e8b1ee38d1451b83e9d1e6e7c8110b6119930ad8164",

"blockHeight": "0x33d",

"blockHash": "0xf0bfacc8873947333a3f7fd26ec006b2cdc88a20dc4c4677bf2554d22d522133",

"txIndex": "0x0",

"to": "cxff74e566e30e9ccd2ba6291183876e3350d47942",

"stepUsed": "0x1ba94",

"stepPrice": "0x2540be400",

"cumulativeStepUsed": "0x1ba94",

"eventLogs": [

{

"scoreAddress": "cxff74e566e30e9ccd2ba6291183876e3350d47942",

"indexed": [

"DepositAdded(bytes,Address,int,int)",

"0x9c74f320e8415c4abd341e8b1ee38d1451b83e9d1e6e7c8110b6119930ad8164",

"hxe7af5fcfd8dfc67530a01a0e403882687528dfcb"

],

"data": [

"0x10f0cf064dd59200000",

"0x13c680"

]

}

],

"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000800000000000000000000000000001000000000004000000000004000000000001000000000000000000000000010000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000",

"status": "0x1"

},

"id": 1

}

DespositAdded is defined as follows,

@eventlog(indexed=2)

def DepositAdded(self, id: bytes, from_: Address, amount: int, term: int):

pass

where id is the deposit id (i.e., the transaction hash), from_ is the transaction sender, amount is the amount of deposited ICX, and term is the deposit period in blocks, which is currently fixed to 1 month (1,296,000 blocks in 30 days).

In our example, our transaction hash 0x9c74f320e8415c4abd341e8b1ee38d1451b83e9d1e6e7c8110b6119930ad8164

from the transaction sender

hxe7af5fcfd8dfc67530a01a0e403882687528dfcb

deposit amount

0x10f0cf064dd59200000 (5000 ICX, unit converter)

and term

0x13c680 (1296000 blocks or 30-day deposit period)

We will demonstrate more features once Fee 2.0 gets deployed to the ICON testnet. We will show you how to add wallets to the whitelist using different proportions (variable sharing fees), and illustrate how this can fit into actual use cases. We will also cover how to check SCORE deposit status using getScoreStatus API and withdrawal operations, as well as early withdrawal penalties.

For more information please visit the official document: Set the policy for the transaction fee

Also check out development branch of Java SDK for more examples on fee 2.0.

ICON — A Dapp Friendly Blockchain

ICON is a Dapp friendly blockchain for a number of reasons. It is based in Python, which is the preferred language for many developers and has a large existing community. ICON Dapps can benefit directly from DAPP Booster Program (DBP) where DApps on the network will receive a portion of the block rewards based on their ranking. ICON Dapps can also benefit indirectly from Ecosystem Expansion Projects (EEP), Dapp incentive programs like the tx challenge, ICONgress initiatives and more. ICON also has VC arms such as Deblock and ICX Station that can support ICON Dapp teams from incubation to acceleration and funding support. With the implementation of Fee 2.0, ICON continues to add more reasons for devs to come develop their next Dapp on top of the ICON Network.