Introducing Bitlock

Burak
3 min readNov 16, 2022

Bitlock is a non-custodial vault service provider that allows distributed BTC custody without giving up the ownership of funds. The platform facilitates the distribution and management of bitcoin-native vault contracts, which immutably live on the Bitcoin network and enforce the trustless execution of vault policies. Each vault contract has custody of pooled assets, unlocks funds according to a preset quorum, and optionally degrades its quorum threshold over time. The degrading measure is taken to prevent potential loss of funds in case one or more signatories lose access to their keys.

Bitlock — Vault Setup

Bitlock vaults are powered by Bitcoin taproot multisig technology which supports up to 999 signatories per vault. Each signatory can be assigned a custom voting power in percentage in two decimal places. Signatories coordinate to meet the unlocking threshold to withdraw funds from their vault. To hit the unlocking threshold, each signatory vote on a withdrawal proposal by signing it off with their voting power, also known as the unlocking power. The party involved in deploying a Bitlock vault in the first place is called the vault initiator. The vault initiator determines the signatory members, their voting power, the unlocking threshold of the vault, and optional degrading parameters when setting up the vault.

Vault Script Template

The tapscript script template for the vault contract is below:

Witness:

<signatureN> //Signatory #N signature or empty push
.
.
<signature1> //Signatory #1 signature or empty push

<1> //Degrade period 1, or 2, or 3, or 4

Script:

OP_DUP OP_1 OP_EQUAL OP_IF //No degrading within the first period

OP_DROP OP_1 OP_CHECKSEQUENCEVERIFY <unlocking_threshold> OP_TOALTSTACK

OP_ELSE OP_DUP OP_2 OP_EQUAL OP_IF //Degrade after first period

OP_DROP <degrade_period_1> OP_CHECKSEQUENCEVERIFY <unlocking_threshold_1> OP_TOALTSTACK

OP_ELSE OP_DUP OP_3 OP_EQUAL OP_IF //Degrade again after second period

OP_DROP <degrade_period_2> OP_CHECKSEQUENCEVERIFY <unlocking_threshold_2> OP_TOALTSTACK

OP_ELSE OP_DUP OP_4 OP_EQUAL OP_IF //Degrade one more time after third period

OP_DROP <degrade_period_3> OP_CHECKSEQUENCEVERIFY <unlocking_threshold_3> OP_TOALTSTACK

OP_ELSE OP_RETURN //No other degrading period allowed

OP_ENDIF OP_ENDIF OP_ENDIF OP_ENDIF

OP_0 OP_TOALTSTACK //Accumulative vote begins with zero

- - - - - - - - - - - - - - - BEGIN Signatory #1 - - - - - - - - - - - - - - -

<signatory1_pubkey> OP_CHECKSIG:

OP_IF //If signatory #1 has signed off

<signatory1_unlocking_power> //Push signatory #1’s voting power as script number (i.e 1 for %0.01, 10 for %0.10)

OP_ELSE //If signatory #1 has not signed off

OP_0 //Push zero

OP_ENDIF

OP_FROMALTSTACK OP_ADD OP_TOALTSTACK //Update accumulative vote

- - - - - - - - - - - - - - - END Signatory #1 - - - - - - - - - - - - - - -
.
.
.
- - - - - - - - - - - - - - - BEGIN Signatory #N - - - - - - - - - - - - - - -
.
.
.
- - - - - - - - - - - - - - - END Signatory #N - - - - - - - - - - - - - - -

OP_FROMALTSTACK OP_FROMALTSTACK OP_GREATERTHANOREQUAL //Unlocking threshold met check

Output Structure

Vault addresses are P2TR outputs that commit to a single-leaf vault script, and tweaked by a point with an unknown discrete logarithm to eliminate a potential key path spend. The vault address can be funded by anyone, anytime, and in any amount; however, vault funds can only be spent by the rightful owner of signatories and only when complying with the vault’s unlocking policies determined by the vault initiator.

Bitlock — Output Structure

Spend Structure

Digital signatures are placed in witness in a row, followed by a one-byte degrading period flag. At the beginning of the script header, the target unlocking threshold based on the degrading period flag and the number zero as the initial accumulative vote is sent to the alternate stack as script numbers. Signatory pubkeys and their voting powers are hardcoded in the script body as 32-byte pushes and script numbers, respectively. Accumulative vote in alternate stack updated following signature checks. After comparing the unlocking threshold and the final cumulative vote at the script footer, funds are finally unlocked. The witness field is finalized with a 33-vByte control block push.

Bitlock — Spend Structure

--

--