Difficulty in securing the seed phrases and the possibility of losing them might be the biggest obstacle for mass-adoption of cryptocurrency.
What if we only needed our 24 randomly generated words one time…
just to set up our wallets…
and then we could destroy the seed phrase if we wanted…
confidently knowing our accounts are secure…
and that we could never lose access to our funds?
Nothing to lose.
Nothing to get stolen.
Nothing to forget.
No one we need to trust.
Deploying a smart contract with the following properties should make this possible.
Contract can receive funds like any wallet.
Contract can disperse funds of a given amount to a given receiving address given the correct signature, just like any wallet.
Contract contains a variable called owners-public-key
This is used to verify that commands sent to the contract have been signed by the owner’s hardware wallet.
Contract contains a variable called global-epoch-trigger-point.
This is the epoch at which it becomes possible to send funds to the beneficiary.
Contract contains a variable called number of epochs-from-now.
This is a number used to update the global-epoch-trigger-point.
Contract contains as many variables as needed called beneficiary-address-01, beneficiary-address-02, …
These are the addresses where funds can go if the contract owner dies, or loses control of his/her hardware wallet which is used to sign messages that control the contract.
Contract contains as many variables as needed called extra-epochs-delayed-for-beneficiary-address-01, extra-epochs-delayed-for-beneficiary-address-02, …
These variables are used to specify how many epochs past the global-epoch-trigger-point each beneficiary address must wait before it becomes valid and able to receive funds.
Contract can disperse all funds to any beneficiary address after the global-epoch-trigger-point has been passed.
If the number of epochs specified in the extra-epochs-delayed-for-beneficiary-address-XX is greater than zero then that many epochs must also pass after global-epoch-trigger-point has been reached before funds can be sent to that address.
We notice there can be many preprogrammed beneficiary addresses, each associated with their own unique times in the future when it will be possible to send funds to those unique addresses.
One of these addresses serves as the primary beneficiary address.
The rest of these serve as backup addresses in case the first beneficiary loses control of their hardware wallet.
For the contract to disperse all funds to a preprogramed beneficiary address, the beneficiary must send 1 ADA to the contract from the hardware wallet controlling that address at any time after the address becomes valid. The contract will then immediately send all funds in the contract to the beneficiary’s address.
This method establishes that the beneficiary has control of the preprogrammed beneficiary address and so ensures that the funds will not be lost.
Contract can receive a message signed with a specific hardware wallet proving ownership of the contract.
The message may contain a command to change the value stored in the variable called number of epochs-from-now. This will set the global-epoch-trigger-point.
The message may contain a command to add, update, or deleted beneficiary addresses and their associated delays past the global-epoch-trigger-point.
Any spending, receiving, or message transaction by the contract’s owner will set the global-epoch-trigger-point with respect to the number of epochs-from-now.
This is how the owner tells the contract that he or she is still alive and in control of their hardware wallet.
This is also how the contract owner sets the time interval before beneficiaries can collect all the funds from the contract. If the owner does not message the contract again within the number of epochs-from-now then it is presumed that the owner has lost the control of their hardware wallet or is perhaps dead.
The contract works as follows:
The owner deploys the smart contract.
The owner transfers a small amount of funds to the contract.
The owner withdraws a small amount of funds from the contract to be certain the owner has control of funds in the contract.
The owner sends a message to the contract to set the beneficiary addresses and the delays on each address before they may receive funds.
This could be a friend or relative or just a wallet address controlled by the owner.
The owner sends a transaction to set the number of epochs-from-now for a short time into the future.
The owner waits for the global-epoch-trigger-point to pass.
The owner askes the beneficiary to send 1 ADA to the contract using the hardware wallet controlling the beneficiary address.
All funds should be dispersed to the beneficiary address when the 1 ADA is received.
If everything has been working correctly the owner loads the contract with significant funds and sets the number of epochs-from-now for perhaps one month into the future.
Every time the owner interacts with the contract the global-epoch-trigger-point will be set with respect the value contained in the variable called number of epochs-from-now.
The contract owner must spend, receive, or send a signed message to the contract before the new global-epoch-trigger-point is reached or all funds will become available for beneficiaries to collect.
In this way, the contract owner could set up a hardware wallet and then destroy the 24 words. If they lose the wallet it’s no big deal - any one of beneficiary wallets will be able to collect all the funds when the global-epoch-trigger-point has passed.
Funds are always safe.
There is nothing to lose.
There is nothing to get stolen.
There is nothing to forget.
There is no one we need to trust.
I need to know the following before starting this work:
Does a smart contract like this already exist?
Can anyone think of a reason this wouldn’t work or can’t be done?
You are just removing the need to backup the seed phrase, but there still has to be a private key somewhere in the hardware wallet and that can still in principle be extracted by a malicious firmware.
A malicious firmware can do nearly everything and that was clear before this event. What was new to many is that the secure enclave on a Ledger is not as isolated as thought. (BTW: Trezor does not even have a secure enclave.)
You have to (and always had to) trust the firmware to some extent. And if you do, there will be nothing extracted without you triggering it and consenting to it and Ledger’s defense of the functionality is quite correct. Their communication was horrendous, though.
But you still have to trust the firmware with your solution. That the user does not have to think about the secrets anymore and does not see them, does not mean that they are not there.
That’s not how contracts on Cardano work. They are not active. They cannot react to events.
Contracts are just instructions what nodes/block producers should do to validate if is okay to do a transaction. The transaction is always initiated from off-chain – either by a person or by some automated off-chain code on a server or such.
In this case that actually makes it easier. The “beneficiary” does not have to send a 1 ADA fake, trigger transaction. They just build a transaction transferring all the funds to wherever they want. And what the contract contains is that this is okay, because it is signed by the correct key.
You actually don’t even need Plutus contracts for that. Simple native contracts are enough.
Hmmm. There is this paper explaining how to defeat the firmware protection on STM32 even when the chip has readout protection enabled.
Altogether, these vulnerabilities completely break security for RDP Level 1 and alarmingly weaken security for RDP Level 2. Since only low-cost lab equipment is required, the impact increases. Especially the combination of vulnerabilities, e.g., downgrading security from RDP Level 2 and using the SWD exploit to read the firmware pushes the complexity of attacks down to the hobbyist level. Cold-Boot Stepping and the security downgrade might also work on other STM32 chip series, as they are
based on the same concept. Thus, the impact of this analysis is severe and might be expendable to more systems.
I guess that means you had better not let any well funded hackers obtain your physical device.
Are these “secure enclave” chips similarly vulnerable?
I’m honestly not sure if this secure enclave really is an advantage.
I’m now more interested in the question if it is – apart from the horrible communication – really that much of a disaster.
If both still only accept signed firmwares and only after the user has given consent (e.g., by PIN) then they are still both comparably secure.
Trezor does accept unsigned firmwares, but then it should extensively warn you:
As always: Open source is great for a lot of reasons, but security is only part of it in a very limited way. It could even give a false sense of security.
You typically do not get the firmware from the source you can read on Github, but from the Trezor Suite without a clear way to verify if the code you are running has anything to do with the code you can read.
You’d need a quite complicated reproducible build workflow to make it really more secure, doable, but not in place at all.
This is an amazing idea but I would prefer that the beneficiary initiate the transaction with their own wallet as a check that the beneficiary does indeed still have control of the receiving address. This is why I crowd sourced the problem here in this forum too. I finally accept that I need to think of smart contracts simply as information you check to see if a transaction has permission to proceed. But actual instructions to move funds must come from outside the blockchain in the form of a transaction written for the purpose. In fact, my IOG instructors prefer the term “validation script” over “smart contract”. Thanks for the much needed whack on the head.
In any case, your solution will work just fine.
The beneficiary needs to send a transaction to the blockchain with the instructions to move the funds. As long as the transaction is signed by his/her hardware wallet and we have past the global-epoch-trigger-point then the funds will be sent.
So when I make the smart contract then I can also make a simple UI that builds the transaction for the beneficiary and then sends it off to the blockchain.
Yes, the hardware wallet is vulnerable to attack by someone with a well equipped lab but I think thousands of seed phrases will be lost or stolen for every wallet cracked in a lab.
This method also addresses how funds are past on in the event of death.
Oddly, my work on Beemocracy has lead me to the study of zero knowledge proofs with the Mina community. There I met a man who has actually built a working commercial fund recovery service for the Ethereum community based on a smart contract much like the one described above. It is a fee based service where the vendor sends email warnings to the client as the global-epoch-trigger-point approaches. And when the global-epoch-trigger-point has past then the vendor sends the transaction which releases funds to the beneficiary.
So I would like to do this for the Cardano community but the service is free because the contract is managed by the owner and the beneficiary.
Thank you for your help
I am starting to see what you mean about malicious firmware. At any time, Ledger can force customers to download their latest firmware via Ledger Live and opt into their private key sharing scheme or deny us access to update our Ledger devices. I think that sooner or later, world governments (all controlled by the world’s central banking cartel) will force Ledger to collect our private keys via their firmware or deny us access to our Ledger devices.
Perhaps Frankenwallet or maybe tails is an alternative to hardware wallets. I use a raspberry pi with an encrypted SD card. So we can decentralize and open source our hardware wallet solutions to get past malicious firmware. But we still need to get past the issue of a lost or forgotten seed phrase. Perhaps a smart contract with a deadman switch is the way to go. I am going to give it a try.
Thanks again for helping me work this out.
My one concern is that smart contracts must always be able to tell the difference between a wallet and another smart contract. This is to prevent voting fraud. I am sure Sebastien has already considered this and is doing something to manage the issue.
In any case, we should be able to accomplish timed recovery for lost seed phrases by using smart contracts as wallets as opposed to blurring the distinction between the two. That said, there seems to be many good reasons for account abstraction.
What it sounds like you are proposing is a contract that acts like a trust/timed will. One thing you do need to be mindful of is that anything stored on the blockchain is publicly visible, so anyone can figure out what addresses you have stored in there, and when the payout is supposed to occur. You will never be able to destroy both your private key and seed phrase, because you will need a wallet in order to interact with the contract. Even with a timer for distribution, the contract will still require interaction in order to execute the transfer. This really makes it no different than a contract that performs time locked staking of funds. There is a solution on its way that will give you the security you are looking for. I am almost done programming it. The way your contract would operate would make it vulnerable if one of the control accounts were compromised. The attacker could use the compromised account, interact with the contract, and steal all the funds. you really need to know what you are doing with smart contracts, and how the blockchain operates in order to truly have a secure system.
Thank you @HeptaSean for bringing this up. I just learned of another way to manage this problem. Our smart contract could be multi-signature. So if we don’t completely trust Ledger then we could require a second signature from perhaps a Trezor or a Tangem for any spending transactions
Tangem is an interesting hardware wallet, by the way, because they never give you the seed phrase. Instead they give you backup hardware wallets. The problem with this, of course, is you have to trust the way they generate the private key.
So with a Ledger you can use your own method to generate the seed phrase and load this into the Ledger Nano. Believe it or not, I flip coins to get my seed phrases - I don’t let Ledger generate the seed phrase for me.
So Ledger could get your seed phrase by a firmware attack and Tangem could get it by generating a seed phase which is already know by the company. But it is extremely unlikely that both will attack at the very same time. So a multi-sig option is probably the way to go for this project.
I asked the following:
If the idea makes sense,
If the idea seems useful,
If Marlowe is the correct language for the job
What is the best tool stack to use
What is the best approach to accomplish the task
Any other thoughts on the project?
It would be wonderful if IOG Academy would use this project as an example in their next Marlowe or Plutus Cohort. I think knowledge of how to accomplish a Multi-sig smart wallet contract with a recovery timer would solve a serious problem with crypto and create wider adoption for Cardano.