-
Notifications
You must be signed in to change notification settings - Fork 347
CIP-1856 | Collateral Key derivation #104
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,11 +50,12 @@ Example: `m / 1852' / 1815' / 0' / 0 / 0` | |
|
||
Here, `chain` can be the following | ||
|
||
| Name | Value | Description | ||
|----------------|-------|------------- | ||
| External chain | `0` | Same as defined in [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) | ||
| Internal chain | `1` | Same as defined in [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) | ||
| Staking Key | `2` | See [CIP11](../CIP-0011) | ||
| Name | Value | Description | ||
|--------------------|-------|------------- | ||
| External chain | `0` | Same as defined in [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) | ||
| Internal chain | `1` | Same as defined in [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) | ||
| Staking Key | `2` | See [CIP11](../CIP-0011) | ||
| Collateral Account | `3` | See [CIP11](../CIP-???) | ||
|
||
Wallets **MUST** implement this new scheme using the master node derivation algorithm from Icarus with sequential addressing (see [CIP3](../CIP-0003) for more information) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this requirement isn't currently feasible for Ledger (without the Ledger devs updating the firmware which is closed source) as the Cardano app doesn't have control over the master node derivation (and that's why it wasn't compliant with Icarus so far), or is this paragraph just meant to clarify that the collateral account key has to be derived in the same way as the standard account key was derived so far by given wallet type (Ledger/Trezor/Icarus wallets)? The latter would require significantly less effort given it would be consistent with the current status of key derivations There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this way of treating collateral is relevant any longer. Babbage will come with collateral outputs |
||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,109 @@ | ||||||
--- | ||||||
CIP: ? | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tentatively CIP-1856 |
||||||
Title: Collateral Key for HD Wallets | ||||||
Authors: Sebastien Guillemot <seba@dcspark.io> | ||||||
Comments-URI: https://forum.cardano.org/t/collateral-account-derivation/65879 | ||||||
Status: Draft | ||||||
Type: Standards | ||||||
Created: 2021-06-29 | ||||||
License: CC-BY-4.0 | ||||||
--- | ||||||
|
||||||
# Abstract | ||||||
|
||||||
This document describes using a separate derivation path to ensure there is always sufficient collateral to execute UTXO smart contracts | ||||||
|
||||||
# Motivation | ||||||
|
||||||
Collateral input | As of Alonzo, transactions that call Plutus smart contracts are required to put up collateral to cover the potential cost of smart contract execution failure. Inputs used as collateral has the following properties: | ||||||
|
||||||
- Cannot contain any tokens (only ADA) | ||||||
- Cannot be a script address | ||||||
- Must be a UTXO input | ||||||
- Must be at least some percentage of the fee in the tx (concrete percentage decided by a protocol parameter) | ||||||
- Can be the same UTXO entry as used in non-collateral tx input | ||||||
- Is consumed entirely (no change) if the contract execution fails during phase 2 validation | ||||||
SebastienGllmt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
- Is not consumed if phase phase 2 validation succeeds | ||||||
|
||||||
Additionally, there cannot be more than *maxColInputs* (protocol parameter) inputs and the inputs have to cover a percentage of the fee defined by *collateralPercent* (protocol parameter) | ||||||
|
||||||
We therefore need a way for the wallet to handle picking which inputs to use for collateral | ||||||
SebastienGllmt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
## Naive solution | ||||||
|
||||||
The naive solution would do the following steps | ||||||
1. Add any non-collateral input that satisfies the constraints as collateral as well | ||||||
1. If collateral is still insufficient, look at the wallet UTXO for any other entry that can be added as collateral | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Later in this CIP, if I understood correctly, it is implied that light wallets have no way to know how much of collateral is actually needed so they have to select all utxo in collateral account and at best provide some guesses of how much of collateral would be needed - which then means here in the naive solution the step of accessing whether the selected collateral is sufficient or not is impossible at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the specs collateral is a function of the tx fee, so it can be computed beforehand. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Collateral is not an explicit field in transactions -- it's calculated based on the tx fee which depends on the amount you include as part of the witness for each redeemer script. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, but the problem then is that the correct fee would depend on the execution units then as well, so if I'm getting it right, rather than knowing the correct collateral from knowing the correct fee, a wallet that has no access to a local personal full-node would not be able to correctly get neither the fee, nor the collateral 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's correct. That's why there is talk about trying to get the PAB to run in the browser so it can be included as part of light wallets. Otherwise the best you can do is trust some 3rd party to tell the truth about the cost of running the contract and risk losing collateral if they lied. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two independent issues:
The only way to arrange to have your collateral taken is to calculate the execution units incorrectly, but to include the correct protocol parameters into the transaction body. That is you cannot get this wrong by 3rd parties lying to you about current protocol parameters. You have to do something really wrong.
Yes.
A wallet needs some information from the chain like the wallet's UTxO, and the values of some of the current protocol parameters. If you're thinking about a light wallet and a compromised server lying to you, then there's no problem: because the hash of the relevant protocol parameters is included in the tx body and checked by the ledger rules in phase 1, you will not loose collateral if you were given the wrong protocol parameter values, or if the values changed before the tx is submitted.
No. Unless there's a design mistke here that I am not aware of then I don't think you can lose collateral if the server lies. Provided that your local wallet can run the scripts locally then the only reason to loose collateral is bugs in the wallet. You do not need the whole PAB to be able to run scripts. There are more lightweight libraries that can do that. For example the CLI will do this using the Cardano API library. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dcoutts what other lightweight libraries can do that? by "Cardano API" you mean
I must be missing something but I'm not sure how a pure JS wallet like Yoroi will be able to do this. If a light wallet needs to rely on a remote node every time it needs to recompute the fees and re-validate a smart-contract tx, this doesn't translates into a great UX. I'm also confused because you mention that the wallet only needs to know its UTXO set and some protocol parameters in order to compute the execution units, but then you mention that the wallet needs to run the scripts locally, which sound like a big additional requirement. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@dcoutts , yes, but the main point is specifically about whether it is 100% guaranteed already that all wallets will be able to run scripts locally to validate their execution and calculate the execution points?
Is this planned to be compatible with light wallets, e.g. allowing to run any script from any user, without having an instance of a wallet created locally? |
||||||
1. If there are not enough UTXO entries that can be used as collateral, check if we can rearrange the wallet UTXO to create enough UTXO entries that match the requirement | ||||||
1. If rearranging can unblock the wallet, prompt the user to send a transaction to rearrange their UTXO (and pay the tx fee associated with it) before sending their transaction. If rearranging can't unblock the wallet, tell the user they will need more ADA to call this smart contract | ||||||
|
||||||
This however, causes the following problems: | ||||||
1. This may cause users to risk more collateral than they are comfortable with. In general, software should run smart contracts locally to detect if a transaction would fail before sending and alert the user to avoid consuming the collateral, but relying on this is not ideal. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When we were discussing collateral inputs, we were thinking that there might indeed be only one collateral UTxO, and that most transactions would be over-collateralised. I don't think relying on this is particularly risky. Firstly, we expect that most transactions spending from script-locked addresses will be submitted by the PAB, and hence already verified. Secondly, with IntersectMBO/ouroboros-network#3230 we expect the local node to reject submitted transactions that fail phase-2 validation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless you are running your own node, there is no guarantee anybody is setting this flag. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't follow. It's quite simple: if your wallet is working correctly then you will never ever have any collateral taken. The local node that you submit your transaction two is just an extra double-check on this. So it should be really very safe indeed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would put this much more strongly: Wallets must run scripts locally to determine that they do not fail and how many execution units they need. This is a crucial part of the function of a wallet supporting scripts. They should not construct or submit invalid transactions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would make sense, have to describe the best practices like you're mentioning about running your own node? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no reason why a good-faith user should ever end up submitting a transaction with failing scripts. So the only people who are ever at risk of losing their collateral are malicious users or people who've inexplicably decided to go to some trouble to not check their transactions before sending them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about light wallets or hosted APIs, where the operator of the service does not want to consume its computational resources but instead wants to delegate this responsibility to the user? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we really categorically rule out that wallets and PAB will never send transactions with failing scripts? Should the user pay with an overly large collateral utxo in case of a wallet/PAB bug? I've lost my fair share of collateral on the Alonzo Blue testnet (using Cardano CLI) :) Currently, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The testnet node currently accepts transactions with failing scripts and posts them to the network as failures. That will be fixed before mainnet. |
||||||
1. Although the rearrange transaction can be created under the hood for in-software wallet, it will confused users when it shows up on their transaction history. For hardware wallets, it will require explicit approval from the user which is also possibly confusing. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
1. Altough wallets can try and always pick UTXOs to make sure there is always a valid UTXO entry for collateral, it can't be guaranteed because the wallet state can always be changed by any dApp or other wallet that doesn't use the same logic to guarantee the presence of satisfactory collateral input | ||||||
1. Multisig wallets don't have any non-script addresses in general and so would need some separate solution | ||||||
|
||||||
So with this, we can see the naive solution is complicated while still having issues and an unintuitive user experience. | ||||||
|
||||||
|
||||||
|
||||||
# Specification | ||||||
|
||||||
Recall that [CIP1852](../CIP-1852) specifies the following derivation path | ||||||
|
||||||
``` | ||||||
m / purpose' / coin_type' / account' / chain / address_index | ||||||
``` | ||||||
|
||||||
We set `chain=3` to indicate the *collateral chain*. | ||||||
|
||||||
## *address_index* value | ||||||
|
||||||
Wallets MUST only use `address_index=0` for this specification. Since a single address can contain multiple UTXO entries, there is no need to derive other addresses (using more addresses would not provide any privacy benefit and would complicate address discovery). | ||||||
|
||||||
We will call this specific derivation the *collateral key*. Any address created with this payment key is called a *collateral address*. | ||||||
|
||||||
## New solution for managing collateral | ||||||
|
||||||
Wallets SHOULD only use UTXO entries of the collateral key as collateral in the transaction. If the collateral is insufficient, the wallet SHOULD tell the user to send more ADA to their collateral key. | ||||||
|
||||||
The benefits of this solution are as follows: | ||||||
1. Transactions in the history to add collateral can be clearly marked as such by wallet software. | ||||||
1. Prompting the user to add ADA to their collateral address doesn't require explaining users about how UTXO works under the hood compared to the rearranging option. | ||||||
1. No change required to input selection algorithms | ||||||
1. Multisig (or other script-based wallets) are handled the same way as regular wallets | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you should elaborate on how this proposal interacts with multi-sig wallets since it is not clear. Do the collateral addresses just belong to one party? So this is equivalent of the submitting party having a second personal account (which is of course the primary alternative solution). |
||||||
1. User only risks as much collateral as their are comfortable with | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have one general concern regarding hw wallets - hw wallets don't have the context to safely assure the user what is the collateral amount of the input(s) included as it isn't part of the collateral field when serialized in the transaction and the hw wallet inherently can't trust the software wallet to not include a collateral input too big or from a non-collateral address. hw wallets neither have the capacity to be able to reasonably validate the script to assure that the collateral wouldn't be spent. The only possible way I can think of to assure the user that the input they are including as collateral is of a certain amount would be letting the hw wallet parse the transaction from which the collateral input came which would be a significant complication as hw wallets would have to be able to parse all possible tx bodies with forward compatibility in mind |
||||||
|
||||||
However, this solution also comes with downsides: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should mention the UX downside that this means users have to be aware of a whole new concept: a collateral address, and need to manually move funds into it which are not normally spendable. Are those collateral funds part of your balance or not? Whereas with the "naive" solution, there are no new concepts for users. There are already rare corner cases where wallets have to rearrange the UTxO to be able to perform certain transactions, and this is visible in the transaction history and for hardware wallet users. Such rearranging transactions are (in principle) already easily identifiable by both software and hardware wallets because all the input and output addresses are within the wallet. So this is already in the UX, but is fortunately rare. There's no clear reason to think that the new corner cases here would be any more problematic. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we decide we don't want to explicitly tell the users about the collateral address existence, that's fine. It can be like how we have external & internal addresses without the user really knowing about their existence.
I don't think this is that rare. When I was working at EMURGO we usually had a few support tickets about this topic per day due to NFTs and the presence of tokens will only increase going forward -- especially with Alonzo |
||||||
|
||||||
1. Reusing the same collateral address for all your smart contract calls gets rid of any privacy. However, wallets using base addresses in Cardano already usually forgo privacy and so users who want to call smart contracts with privacy will already need to handle things differently. | ||||||
1. The blockchain can't stop people from sending tokens to somebody's collateral address. This doesn't harm the user (since other UTXO entries can still be used) and wallets will already need to implement a way for the user to withdraw from their collateral address so the impact should be minimal. | ||||||
1. It's possible for the collateral key to be contained in mangled addresses (same as regular base addresses for the wallet), but empirically mangled addresses are rare and people should not be sending to collateral addresses directly anyway so this is of minimal concern | ||||||
1. Support for a collateral key needs to be added to hardware wallets | ||||||
1. If the user doesn't reduce the ADA in their collateral address when calling cheaper smart contracts, they are still be putting up more collateral than necessary | ||||||
|
||||||
## Test vectors | ||||||
|
||||||
recovery phrase | ||||||
``` | ||||||
prevent company field green slot measure chief hero apple task eagle sunset endorse dress seed | ||||||
``` | ||||||
|
||||||
collateral private key (including chaincode) for `m / 1852' / 1815' / 0' / 3 / 0` | ||||||
``` | ||||||
40c7f7d3c03c3711e6c03ef828ba244f40f81ec915899483eda006bac0e5974480b77fe9816eb518cb190214b7368e76e3462a0caecfb1d3add8315bfe2e5616647312b7b6d29e0e577b9923594a12be4ded5f5e3a8f7d5249f33c97ecafa620 | ||||||
``` | ||||||
|
||||||
staking private key (including chaincode) for `m / 1852' / 1815' / 0' / 2 / 0` | ||||||
``` | ||||||
b8ab42f1aacbcdb3ae858e3a3df88142b3ed27a2d3f432024e0d943fc1e597442d57545d84c8db2820b11509d944093bc605350e60c533b8886a405bd59eed6dcf356648fe9e9219d83e989c8ff5b5b337e2897b6554c1ab4e636de791fe5427 | ||||||
``` | ||||||
|
||||||
base address (with `network_id=1`) | ||||||
``` | ||||||
addr1qy85lw87w0q6xns59y806v37xh6dafnf3w6kkn6x3p4pzsqwfdvw69hjqdklg9x94f8wxwlkldzsd8ycmxsj06904p9skhtxnm | ||||||
``` | ||||||
|
||||||
## Copyright | ||||||
|
||||||
This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tentatively CIP-0027