Test zkSync with TestSTORJ token

I am currently testing zkSync in testnet. If you want to try it yourself here is what you should do.

Step 1: Go to https://rinkeby.zksync.io/ and open your wallet. I am using a trezor hardware wallet that can be connected via MetaMask.

Step 2: Most likely you will have 0 TestETH and also 0 TestSTORJ. Since I don’t have a social media account it is difficult to get TestETH. I managed to get a small amount from here: https://app.mycrypto.com/faucet

Step 3: Call mint on the TestSTORJ contract. If you don’t know how to do that I would recommend you just post your address here and let someone else call it for you.

Step 4: Now you should have TestETH and TestSTORJ. Time for the fun part. Open the wallet from step 1 again and press the deposit button. Select the TestStorj Token and execute.

Step 5: Find someone to send your TestSTORJ token to.

Step 6: Withdraw the balance back to another address outside zkSync. I assume that is what we would have to do in order to send the payout to an exchange.

Technically step 1-4 are just preparation and later the satellite would have to go through these steps in order to send you a balance. However, I would still recommend executing all of these steps. It will enable you to run the hole test even when nobody else is available to send you TestSTORJ token.

I guess now I have to wait for a second guinea pig so that we can send us TestSTORJ back and forth.

I already noticed one issue. MetaMask doesn’t support custom derivation paths. This means I have to change my payout address because otherwise I will be unable to access that wallet with MetaMask.

6 Likes

My test address is now in the state that it would have after receiving a payout https://rinkeby.zkscan.io/explorer/accounts/0x80a52B7F26426d2b16578FC5f376c349F54772A7

To withdraw my balance I also have to deposit TestETH. It is getting late over here. I will continue tomorrow.

Over night someone was sending me TestStorj. Time for me to send them back. In order to do anything I first have to publish my public key.

To start using your account you need to register your public key once. This operation costs 15000 gas on-chain. In the future, we will eliminate this step by verifying ETH signatures with zero-knowledge proofs. Please bear with us!

I can pay this fee with TestSTORJ (0.123 STORJ). I don’t need to deposit TestETH. The gas amount is low. I start to love this solution.

A transfer to another zkSync wallet seems to cost only 1/10 of that.

A withdraw is a bit more expensive:

Normal withdraw ( Fee: 0.484 STORJ ~$0.16 ).
Processing time: 50 minutes

Fast withdraw ( Fee: 4.68 STORJ ~$1.57 ).
Processing time: 20 seconds

The ability to pay all fees with tokens is awesome. I will opt in.

I noticed two other issue:
My trezor doesn’t show me the transaction details. A compromised system could let me sign a transaction that would steal all of my funds. Luckily the access is restricted to a single address. All other addresses on my hardware wallet are still safe.
I have no control or inside over the transaction fees. It is doing some magic and showing me a number. If it would show me gas costs and gas price I could estimate the fee for mainnet. It does look like the transaction fee would be acceptable especially if we take into account that I don’t need additional transactions to send ETH first.

4 Likes

Your withdraw fee is only what L2 is charging you on the Testnet to withdraw. It is missing the L1 gas fee component. You should really test a simple transaction on Mainnet and report back the total fee, Gwei, and gas amount that was needed to complete a L2 to L1 withdrawal on Mainnet.

5 Likes

This test is more for to be comfortable with tech. However, you do have to pay a fee but in testETH of course.

I started to withdraw my testSTORJ tokens. The normal fee is 0.495 testSTORJ ~$0.17, processing time: 50 minutes
The Fast withdraw Fee 4.79 testSTORJ ~$1.61, processing time: 20 seconds
I selected a Normal.
I also can select other tokens to pay a fee.

WOW. It’s processed almost instantly
Ah, no :smiley: It is submitted instantly, but still processing

Edit2:
And finally it’s confirmed


Gas used: 63,867 but I didn’t pay it. It seem was taken from the fee in tokens. Very interesting.
1 Like

We are basically batching transactions. If we both initiate a withdraw at the same time they would get combined into one transaction and that way we have to pay fewer fees.

3 Likes

OK, so I also did some testing, earlier today.
I created 3 addresses with the following roles:

The process was relatively straight-forward using Metamask.
The first transaction (L2) is for 9 SOTRJ from the payout bot to the test SNO (L2). The fee was tiny (0.05 storj). In the mainnet, that could be higher but still be quite small.
Then the SNO wanted to withdraw to the final L1 address, which, just like @littleskunk mentioned needed a one-time fee of 15000 gas to publish pubkey. This was taken in tokens (0.123 storj). However, note that the testnet has a gas price of 1 gwei, so in the mainnet that would be (assuming a gas price of 40 gwei) around $$0.75 (15k gas * 40 gwei at 1250$$/ETH) or ~2 storj (at $0.38/storj). Not bad, this is one time only.
I don’t get how the 0.123 storj fee was calculated in the testnet, it should have been more like $0.02 (15k gas, 1 gwei) or 0.05 storj, or am I missing something?
The final transaction was the withdrawal from the SNO to the L1 address. This took a fee of 0.484 storj. Again, in the mainnet this would have been higher. It’s hard to say how much exactly, but similar withdrawals in the same block charge 0.0001309 paid in ETH. In the zksync mainnet, at the same time, the block height was 10241 and contained withdrawals with a fee of 0.00476 eth. From that, we could estimate that the ratio of mainnet over testnet fees is around 36x. So in the mainnet, the SNO would pay a fee of 17.4 storj (~$6.60). For comparison, a direct L1 transfer of storj would be around $1.75 (35k gas, 40 gwei).

I also did some more withdrawal transaction tests (in the testnet, in eth), in the same block, and the fee doesn’t seem to change depending on the number of transactions (the first transaction and the last made had the same fee). (it’s easy to spot them, they were sent to addresses beginning with 0xaaaaa)

All in all: L2->L2 has very small fees, but L2->L1 is more expensive than L1->L1.

5 Likes

In my case it is cheaper. My wallet has no ETH yet. If we take these additional transactions into account it is cheaper.

The next question would also be if there is an exchange connected to zkSync. If so that would mean we can send the token directly to the exchange with minimal fee.

1 Like

I thought that too, but I was then reminded, in the thread concerning the minimum threshold announcement, that as an SNO you could add the address of your preferred exchange directly instead, thus from your point of view, you wouldn’t need to pay any fees of have any ether. I guess this is the appealing option that was removed with the threshold.
But, I agree that having an exchange supporting zkSync would be a very good solution.

The problem with testing on testnet is that the gwei on L1’s side is 1gwei. Which makes it seam really cheap to perform any L2 to L1 transactions. This is why it may seem great on testnet, the numbers will not reflect mainnet zksync transactions.

It turns out there is an API that we can query to estimate the transaction fee.

Query Transfer Fee

First a transfer in rinkeby so that we can double check how this API works:

curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Transfer", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "STORJ"]
    }'   https://rinkeby-api.zksync.io/jsrpc | jq
{
  "jsonrpc": "2.0",
  "result": {
    "feeType": "Transfer",
    "gasTxAmount": "2334",
    "gasPriceWei": "1000000000",
    "gasFee": "1133892",
    "zkpFee": "587642",
    "totalFee": "1721000"
  },
  "id": 1
}

Looks like totalFee / 8 decimals. I have paid 0.01718 which is close enough. The STORJ fee will differ depending on the current STORJ price.

Now lets try the same on mainnet:

curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Transfer", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "STORJ"]
    }'   https://api.zksync.io/jsrpc | jq
{
  "jsonrpc": "2.0",
  "error": {
    "code": 105,
    "message": "Chosen token is not suitable for paying fees."
  },
  "id": 1
}

Ok that means I have to raise a question to the team and ask if this is intensional or if the zkSync team can just enable it. For the moment we can’t use this directy.

Let’s try the same with ETH then. This should allow us to get close enough with our calculation:

curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Transfer", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "STORJ"]
    }'   https://a^C.zksync.io/jsrpc | jq
root@datengrab:~# curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Transfer", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "ETH"]
    }'   https://rinkeby-api.zksync.io/jsrpc | jq
{
  "jsonrpc": "2.0",
  "result": {
    "feeType": "Transfer",
    "gasTxAmount": "2334",
    "gasPriceWei": "1000000000",
    "gasFee": "3034200000000",
    "zkpFee": "1572479852163",
    "totalFee": "4600000000000"
  },
  "id": 1
}

curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Transfer", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "ETH"]
    }'   https://api.zksync.io/jsrpc | jq
{
  "jsonrpc": "2.0",
  "result": {
    "feeType": "TransferToNew",
    "gasTxAmount": "6862",
    "gasPriceWei": "38960000000",
    "gasFee": "347546576000000",
    "zkpFee": "4717439556487",
    "totalFee": "352000000000000"
  },
  "id": 1
}

Transfer Fee
Factor Testnet to Mainnet fee: 76.5
Testnet Fee: 0.01718 STORJ
Estimated Mainnet Fee: 1.31427 STORJ

Query Withdraw Fee

This also allowes us to caculate the fee for a withdraw in mainnet:

curl -X POST -H 'Content-type: application/json' \
    -d '{
      "jsonrpc":"2.0",
      "id":1, "method": "get_tx_fee",
      "params": ["Withdraw", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "STORJ"]
      }' \
    https://rinkeby-api.zksync.io/jsrpc | jq
{
  "jsonrpc": "2.0",
  "result": {
    "feeType": "Withdraw",
    "gasTxAmount": "96991",
    "gasPriceWei": "1000000000",
    "gasFee": "47119641",
    "zkpFee": "1762924",
    "totalFee": "48800000"
  },
  "id": 1
}

curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Withdraw", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "ETH"]
    }'   https://rinkeby-api.zksync.io/jsrpc | jq
{
  "jsonrpc": "2.0",
  "result": {
    "feeType": "Withdraw",
    "gasTxAmount": "96991",
    "gasPriceWei": "1000000000",
    "gasFee": "126088300000000",
    "zkpFee": "4717439556487",
    "totalFee": "130800000000000"
  },
  "id": 1
}

curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Withdraw", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "ETH"]
    }'   https://api.zksync.io/jsrpc | jq
{
  "jsonrpc": "2.0",
  "result": {
    "feeType": "Withdraw",
    "gasTxAmount": "96991",
    "gasPriceWei": "36000000000",
    "gasFee": "4539178800000000",
    "zkpFee": "4717439556487",
    "totalFee": "4540000000000000"
  },
  "id": 1
}

Withdraw Fee
Factor Testnet to Mainnet fee: 34.7
Testnet Fee: 0.488 STORJ
Estimated Mainnet Fee: 16.9336 STORJ

6 Likes

Hi!
I would like to help you test this zkSync technology.
Could you send me some testSTORJ on that address please?

0xa58BF03404ec40F717Eb5ccDF21Dab075766e4ca

[EDIT] Actually, I managed to mint STORJ by my own.
For anyone would be interested to know how to do it (it was the first time for me, didn’t know it would be that easy), just follow these steps:

  1. Go to the Rinkeby Etherscan smartcontract page of StorjToken (test token) (https://rinkeby.etherscan.io/token/0x8098165d982765097e4aa17138816e5b95f9fdb5#writeContract)
  2. Expand “4. mint”
  3. Fill in the field “_to address” with your own address on Rinkeby network and then the amont of STORJ token you want (to be set with ^8).
3 Likes

I did a bit more of research to understand who I need to trust with my L2 balance. The L2 transfers are instand. Every 10 minutes the transactions are getting combined into one L1 transaction. You can actually see these L1 transactions in the testnet. Once the L2 transaction is finalized there seems to be no additional risk. I like that.

2 issues remaining.
On mainnet we can’t pay the withdraw fee with STORJ tokens. Someone has to enable that feature.
The first approval has an unlimited amount. There is an open issue for that: https://github.com/matter-labs/zksync/issues/265 This is more an issue for storj labs and not so much for the storage node side.

4 Likes

There was an update: https://twitter.com/zksync/status/1359190015671164930

With this update the deposit and withdraw fees should be lower now. Let’s give it a new try and see how expensive it would be now.

We are also in contact with their developer team in order to enable paying fees in STORJ. In the meantime the implementation is comming quickly. The first part will be included in the next storage node release. I would say it is also time to calculate the worst case fee just in case they will not enable paying fees in STORJ. Let’s see how expensive that might get. If the SNOs are still fine with that worst case fee they can opt in early or wait for an update from our side about resolving that potential critical issue. It concerns me a bit that we move forward with zkSync quickly and expect a decision from storage nodes without giving them all information needed.

9 Likes

So true. Thanks for these information and concerns! Reflects my thoughts very well.
I’d be interested in those worst case fees and having all information before opting in.

Preferably I’d also like to have a L2 exchange but guess that’s a big out of your hands :rofl:

As an employee I am unable to work in that direction because we are a utility token and that comes with some legal restrictions.

As a storage node I will simply use that new opt in feature for a voting. Let’s say the withdraw fee is too expensive and I would like to avoid that. Maybe loopring would be a better ecosystem inclusive a L2 exchange? I could signal that I am willing to accept my payout via loopring. Sure storj labs doesn’t support that and might never support it in the future. At least they would see my vote and could think about it.

Transaction Fees for zkSync Withdraw
As you know the transaction fee depends on the current gas price. The following numbers are culculated in gas and you can multiply them with the current gas price.

Worst Case
Currently zkSync doesn’t allow us to pay transctions fees in STORJ. We are working on resolving that issues but we also want to be as transparent as possible. If zkSync disables or never enables fee payment in STORJ you would have to deposit ETH first. You will need a bunch of additional transactions to get started:

  1. Withdraw ETH from an exchange. You can’t Deposit directly. You have to send it to an address that you have the private keys for. Exchanges will work with a flat ETH fee of around 0.005 ETH. So lets calculate with around 50K gas here.
  2. Deposit ETH into zkSync. The transaction comes with a gas limit of 200K. Blockexplorer is showing that around 60K will be consumed.
  3. Activate zkSync account. 15K gas
  4. Withdraw STORJ to an exchange. You can send it directly to the deposit address of the exchange. I am unable to estimate the fee because it doesn’t scale with the gas price. So the best thing you can do is run this command (enter your address because that makes a difference):
curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Withdraw", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "ETH"]
    }'   https://api.zksync.io/jsrpc | jq

Best Case

  1. Activate zkSync account. 15K gas
  2. Withdraw STORJ to an exchange. Same deal. You can send it directly to the deposit address. You have to run this script to estimate the fee (enter your address because that makes a difference):
curl -X POST -H 'Content-type: application/json'   -d '{
    "jsonrpc":"2.0",
    "id":1, "method": "get_tx_fee",
    "params": ["Withdraw", "0x80a52B7F26426d2b16578FC5f376c349F54772A7", "STORJ"]
    }'   https://api.zksync.io/jsrpc | jq

Update
STORJ fees have been enabled in production. Now we can count on the best case fees.

6 Likes

I went through a bunch of random addresses from the latest payout and it shows that withdrawal is 52700 gas which is quite a bit more than normal 36508 and a bit above 51508 which is also common. On top of that I don’t see a way to set your own gas price, so you can’t save on that too.
Final amount was about 3 times more than I paid to move my tokens earlier this week and 1.5-2 times more compared to erc20 transfer from etherscan gas tracker.

1 Like

hi there, anyone to send me testSTORJ to my wallet 0x58E15bD276d391FD0BA20Ced16E4071D5A52F76D on test net? thank you