Hunting for the lost blockchain treasures.

Hunting for the lost blockchain treasures.

Or how to claim what's yours

Of the existing 18.5 million Bitcoin, around 20 percent — currently worth around $140 billion — appear to be in lost or otherwise stranded wallets, according to the cryptocurrency data firm Chainalysis. Decentralized nature of most blockchains means there is no central authority that can be contacted to recover the funds. Normally it's a good thing and is one of the security promises, but since "to err is human" the internet is full of stories about people losing millions of dollars. So is there a way to recover lost funds without compromising security? My colleagues from Facebook proposed a very interesting solution based on smart contracts. In simple words, user makes a claim that contains addresses of the lost account, address_c, and the account which should receive the funds, address_r in case they are successfully reclaimed. In case no transaction from address_c is signed in a reasonable time-frame, say a year, the claim is successful and funds are transferred from address_c to address_r. But if someone sings a transaction from address_c, it's treated as a challenge and an evidence that the key was not lost. In such case, claimer is punished by losing all fees paid for the claim and address_c receives them as a payment for inconveniences.

claim_blockchain_funds.png There are numerous possible modifications:

  • limit addresses from which claims are allowed
  • time-limit

and many other. This mechanism has been successfully implemented as a proof of concept smart contract in the Diem (formerly known as Libra) blockchain:

module KELP {
...
  /// Finalize a claim on a KELP account
  public fun claim(account_r: &signer, new_key: vector<u8>, address_c: address): Diem<XUS> acquires Reveal, KELP {
    let address_r = Signer::address_of(account_r);
    let Reveal { reveal_time, reveal_seq } = move_from<Reveal>(address_r);
    let kelp = borrow_global_mut<KELP>(address_c);
    let claim_time = DiemTimestamp::now_seconds();
    // ensure the reveal was not invalidated by a subsequent "challenge" (i.e., a transaction sent from address_c)
    assert(reveal_seq <DiemAccount::sequence_number(address_c),Errors::limit_exceeded(EBAD_CLAIM));
    // ensure the reveal happened after the conclusion of the challenge period
    assert(claim_time - reveal_time > kelp.t2, Errors::limit_exceeded(ECLAIM_TOO_SOON));
    // successful claim. allow claimer to reclaim account by rotating key
    DiemAccount::rotate_authentication_key(&kelp.rotate_cap, new_key);
    // return fees to the claimer
    Diem::withdraw_all(&mut kelp.fees)
  }
...
}

Hopefully similar ideas will find their way into more mainstream blockchains.