Skip to main content

The Vault

Now we will try a far more interesting script than we have previously.

It is similar in principle to the multisig we played with earlier that had a cold and hot key for added security. But instead of trusting someone to be the co-signer, you use a smart contract to ensure funds are sent to an intermediary address before moving on..

Vault wallets are special. They use 'covenants' to ensure that funds are ALWAYS sent to a safe house first.

Vaults use 2 sets of keys. One that is HOT. These are kept online and are used to send funds from the vault to the safe house and eventually beyond. Another set is COLD. These are NEVER kept online and are only used in the event of a hack - or error in recipient. The HOT keys can be hacked.. and it's really no big deal.

What this means is that when you wish to send funds they MUST first be sent to a special address for a period of time - the Safe House. This is enforced by the smart contract. Even the owner of the vault must do this, and so therefore even the hacker who has pinched the keys.
Once the funds are at the safe house, you must wait a certain amount of time until you can send them to ONLY the pre-specified address. If they were sent by a hacker - you the owner can claim them back, within a certain amount of time, with your COLD key.

Hot wallet convenience with cold wallet security and all it takes is a little delay. An exchange, for instance, can keep large amounts online and available to send this way. Simple (yet secure).

Here's the script for the Vault:

/* You need 2 keys */
LET pkcold = 0xCOLD_KEY LET pkhot = 0xHOT_KEY

/* COLD key has root access*/
IF SIGNEDBY ( pkcold ) THEN RETURN TRUE ENDIF

/* The Amount and Recipient are specified in the State */
LET amt = STATE ( 20 ) LET recip = STATE ( 21 )

/* Now generate the Safe House Address */
LET safehouse =
[ LET pkcold = 0xCOLD_KEY LET pkhot = 0xHOT_KEY
IF SIGNEDBY ( pkcold ) THEN RETURN TRUE ENDIF
IF SIGNEDBY ( pkhot ) THEN IF @COINAGE GT 20 THEN
RETURN VERIFYOUT ( @INPUT PREVSTATE ( 21 ) @AMOUNT @TOKENID TRUE )
ENDIF
ENDIF ]

/* Make sure The Safe House Address is the opposite output */
ASSERT VERIFYOUT ( @INPUT ADDRESS(safehouse) amt @TOKENID TRUE )

/* Send the change back to the Vault */
LET chg = @AMOUNT - amt
IF chg GT 0 THEN
ASSERT VERIFYOUT ( INC(@INPUT) @ADDRESS ( @AMOUNT - amt ) @TOKENID TRUE )
ENDIF

/* Make sure is signed by the HOT key */
RETURN SIGNEDBY ( pkhot )

Here is the expanded safe house script - that is generated by the vault.

/* Same Keys as Vault */ 
LET pkcold = COLD_KEY LET pkhot = HOT_KEY

/* COLD key again has root access */
IF SIGNEDBY ( pkcold ) THEN RETURN TRUE ENDIF

/* ONLY spend after 20 blocks and ONLY to the pre-specified address for the whole amount */ IF SIGNEDBY ( pkhot ) THEN
IF @COINAGE GT 20 THEN
RETURN VERIFYOUT ( @INPUT PREVSTATE ( 21 ) @AMOUNT @TOKENID TRUE )
ENDIF ENDIF

Quite a lot going on there.

Basically the vault itself creates the address to send the funds to. You can see when someone spends funds from the vault. If it wasn't you, you have till the timeout expires to get the cold key and rescue the funds.