Enable Canisters to Hold ICP

The sub-account based check is a workable solution which can work well/complement other solutions where one fetches and looks at blocks.

The fetch_blocks method won’t be available in two weeks but, and here I’m venturing a guess perhaps by the end of December. I’d expect it to be available before the sns & btc integration stuff.

We plan to remove notify completely (that’s why it’s not spec’ed out) The current thinking is that will have the user/canister notify the cycles minting canister about the transfer. The notify method will still be available (but not documented/added to the Candid interface) until we do this change. Can’t give an estimate for that though.

1 Like

My mistake, you are right, the sub-account feature is great and will work great. Thanks for those specifics and for the solution.

2 Likes

A couple high-level questions:

  • Can you explain why a user/canister would want to notify the cycles minting canister about a transfer? Why do cycles come into play when transferring ICP between accounts?
  • Just to confirm―if notify is removed, how would a recipient canister learn about that? In Ethereum, ether-receiving contracts typically implement a receive function, which is automatically executed. Will something like that be available?
  • Why does the ledger canister even have a hashed blockchain of transactions? Is it for additional security? I’m not sure why the underlying security guarantees of the IC aren’t enough here.

A couple low-level questions about the interface leaked by @kpeacock:

  • Why is the fee a field in the TransferArgs instead of being an implementation details?
  • Is Address the same as AccountIdentifier inside ledger.did? Why not make SubAccount a field inside one of those instead of making it an opaque blob?

Thanks! The ICP ledger canister interface is important because it also serves as inspiration for token canister interfaces. I hope they can learn from one another.

1 Like
  • The cycles minting canister is not notified of all transfers: it is only notified by transfers of ICP which should be converted to cycles. That is: if i want to get cycles (to either create a canister or top up a canister) I make a ledger transfer to a specific account of the CMC and then ask the ledger to notify the CMC. The CMC burns the ICPs mints cycles & either creates a canister or tops up a canister.

  • The sender of the ICPs would have to call the recipient directly to let it know about the incoming transfer. Above I outlined two ways in which the recipient can confirm the transfer was “as it should be”.

  • As you hint, the guarantees are sufficient for all replicated execution but not for unreplicated execution. For example, Rosetta nodes fetch the blocks of the ledger via query calls. Instead of (somehow) verifying that each individual block they got was correct (e.g. by making repeated queries to different replicas) one can get all blocks of the ledger, verify that chaining is correct and get a certificate (digital signature) on the hash of the last block in the chain.

  • The intention of the fee field is to indicate a max fee the caller is willing to pay for the transfer – this is in a world where the fee for transfer are dynamic (e.g. to throttle calls in case of overload). We’re not there yet, but it is part of the thinking.

  • They’re related but not the same: the Address is the AccountIdentifier prepended with a CRC32 checksum.

4 Likes
  • The sender of the ICPs would have to call the recipient directly to let it know about the incoming transfer. Above I outlined two ways in which the recipient can confirm the transfer was “as it should be”.

What about the use case where a user or canister wants to pay for a service using ICP, and the service should be performed in the same atomic transaction as the ICP transfer? I think this is a common use case in Ethereum, hence the receive callback.

  • As you hint, the guarantees are sufficient for all replicated execution but not for unreplicated execution. For example, Rosetta nodes fetch the blocks of the ledger via query calls. Instead of (somehow) verifying that each individual block they got was correct (e.g. by making repeated queries to different replicas) one can get all blocks of the ledger, verify that chaining is correct and get a certificate (digital signature) on the hash of the last block in the chain.

Interesting, this seems really important. It means that token canisters will also need to implement some kind of hashed blockchain, or only support update (not query) calls for all functions, if they want maximum security.

1 Like
  • It is difficult to ensure atomicity when multiple canisters are involved in a transaction: for example one of the canisters involved, say the service, may have its input queue full and calls may fail. So some retry logic would be needed, or some two-phase commit involving the ledger would have to be in place. We did have some discussions regarding two-phase commit protocols but are right now not on top of the agenda.
    i should highlight that having the ledger as part of a multi-canister call tree (e.g. what we get now using notify ) does not solve the problem since, to keep complexity low and state manageable we do not implement retry logic in the ledger for notify calls that failed and it’s up to the caller to “re-notify” the recipient.

  • Very good and important point! In general and data that is exposed via unreplicated query calls should be considered untrusted. What we use for the ledger is just an instace of using certified variables: the ledger is mantained as a hashed chain and we set the hash of the tip as a certified variable. The IC will then return (if asked) a certificate which can then be used to verify that whatever was hashed is genuine, i.e. comes from the IC. One can imagine other hashing schemes (e.g. a Merkle trees balanced one way or another) depending on the application.

6 Likes

I’m terribly sorry to disappoint and for having been too optimistic in my ETA. We hit roadblocks when testing the upgrade and will have to delay the proposal. I cannot give an ETA right now, we are treating it as a high priority but it may take a few weeks. I will keep you posted and give a progress update by the end of next week.

7 Likes

You are unbelievable, keep working. :smiley_cat:

1 Like

24 Likes

The canister can’t hold ICP just like Ethereum smart contract can’t hold ETH. This is unreasonable .
If you don’t finish it ASAP ,the whole ecosystem will continue to be insulated from financial applications.

4 Likes

While the inability to hold ICPs is a big disappointment, we should also recognize that the team is trying to do the best under the circumstances.

However because this feature was deemed to be ready to go in a few days and we are now pulling it back by several weeks, I would ask the obvious question.

How did we think that it was ready to go in a few days & what made us decide that there was a fairly severe issue that could not remediated in days but would take weeks?

This question is pretty important to be answered from a community standpoint; so that we minimize this kind of possibility in the future as well as provide surety to teams whose success absolutely depends on this feature.

I look forward to the update to be provided by @JensGroth this week & hopefully it will include the questions posed.

7 Likes

I feel like this problem (Canister unable to transfer ICP) has been blown out of proportion. ICP, after all, is just an application run by a canister on the NNS subnet. Anyone, I mean literally anyone, can build a canister to issue tokens, like the ICP. Developers don’t have to be held back by DFINITY foundation. For example, Wrapped ICP already exists, why don’t we see more utilization of that?

The only difference between a canister based token X and ICP, in my opinion, is that ICP is already traded on major exchanges and has a value in the market. So why aren’t we working on to bringing value to some token X?

  1. Build a bridge between IC and some other chain, and bring other chain’s token over. For example Wrapped ETH, or Wrapped ERC-20.
  2. Work on the adoption of Wrapped ICP.
  3. Create a new token X for every ICP burned (to cycles). This creates an exchange between X and cycles.

Any of these 3 options will work, and do not need the blessing from DFINITY foundation. The only native token to IC is cycle. ICP is only for NNS governance, and I’m feeling perfectly fine if we can ignore it. My question to the community is, can we?

2 Likes

Although we have a better way to wrap Ethereum token into ICP without bridge. But this is really a temporary good method. After all, the integration with bitcoin and Ethereum takes a lot of time .

If I read you correctly, Origyn has already tokens on IC. The issue is that community does not know what the actual issues were while testing this feature. Would it be applicable to other tokens (i.e. OGY) already on IC.

As you mentioned, ICP is already trading on the market. Certain use cases depend on the liquidity of the token and also it’s market cap.

Additionally it is much more important to learn from lessons; so that we try not to repeat them in the future (i.e. for Threshold Signatures, BTC and ETH integration etc)

2 Likes

Yeah I’d be curious what token standard they adopted, or whether they rolled with their own.

There are a lot of tricky issues with implementing a secure token canister… that’s why it’s probably safer for the community to agree on a token interface that everyone can then use and interoperate with, like how Ethereum did it.

Hopefully DFINITY can chime in at some point… see this.

2 Likes

We had trouble getting one of our testnests to work, and the vague “a few weeks” was due to not having a good estimate of the time involved to get it up and running. Based on my latest information I’m hoping it will be shorter.

4 Likes

We have made the preparatory proposal 30232. This proposal does not enable canisters to transfer ICP. The proposal tweaks the ledger to improve safety. In this proposal the ledger will be upgraded so that only whitelisted canisters (all residing on the NNS subnet) can receive transfer notifications from the ledger. This is to ensure the ledger will not get into a situation where it is waiting forever for a notify-reply from an outside canister. We are also updating the archiving mechanism to keep blocks in the ledger until the archiving canister has confirmed receipt. Finally, we are updating some dependencies in the ledger canister. The main proposal to enable canisters to transfer ICP will follow later.

16 Likes

Expect a new interpretation, icp will usher in a new beginning. For how whitelist containers are assigned, perhaps a big question is, who gets priority access to the test?

3 Likes

Is proposal 30232 means proposal 20588 invalid ?

1 Like

It’s the weekend now, how about the progress?