├── LICENSE ├── Makefile ├── README.md ├── boarding.hack ├── forfeit.hack ├── miniscript ├── boarding.miniscript ├── unroll.miniscript └── vtxo.miniscript ├── redeem.hack ├── sweep.hack └── unroll.hack /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Ark Network Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | onboarding: 2 | miniscript-compiler descriptor "${shell cat ./miniscript/boarding.miniscript}" 3 | 4 | vtxo: 5 | miniscript-compiler descriptor "${shell cat ./miniscript/vtxo.miniscript}" 6 | 7 | unroll: 8 | miniscript-compiler descriptor "${shell cat ./miniscript/unroll.miniscript}" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ark Taproot Scripts 2 | 3 | ## Script tree 4 | 5 | Ark virtual transaction outputs (VTXO) are created by a shared output. This output is enforcing the value to be splitted into a binary tree of other taproot scripts. 6 | 7 | ```mermaid 8 | graph TD 9 | A[Shared Out ROOT] 10 | A --> B[Shared out 1] 11 | A --> C[Shared out 2] 12 | B --> D[Shared out 3] 13 | B --> E[Shared out 4] 14 | C --> F[Shared out 5] 15 | C --> G[Shared out 6] 16 | D --> H((VTXO 1)) 17 | E --> I((VTXO 2)) 18 | F --> J((VTXO 3)) 19 | G --> K((VTXO 4)) 20 | ``` 21 | 22 | _Each node of the diagram is a taproot script._ 23 | 24 | ### Shared output script 25 | 26 | A shared output is a bitcoin transaction output locked by a taproot script with 2 tapscript closures: 27 | 28 | * [Unroll](./unroll.hack) and [Boarding](./boarding.hack) scripts use [Elements introspections opcodes](https://github.com/ElementsProject/elements/blob/master/doc/tapscript_opcodes.md) to force the spending transaction format. The tx creates the next level of the script tree on-chain. Splitting the value into 2 outputs with the children taproot scripts. 29 | * [Sweep](./sweep.hack) lets the Ark Service Provider to spend the whole shared output after a timeout (CSV). 30 | 31 | ### VTXO script 32 | 33 | A VTXO taproot script is the last level of the script tree. It should appear on-chain only if the VTXO owner decided to unilaterally exit the Ark. It has 2 tapscript closures: 34 | 35 | * [Redeem](./redeem.hack) lets to spend the VTXO onchain after a CSV delay. the delay prevents the ASP to lost a VTXO spent off-chain. 36 | * [Forfeit](./forfeit.hack) expects both parties (owner and ASP) to sign the spending transaction. It is used to spend the VTXO **off-chain**. 37 | 38 | ### Miniscript 39 | 40 | The scripts are written using miniscript syntax. You can analyse them using the [Elements Miniscript compiler](https://github.com/louisinger/miniscript-compiler). 41 | 42 | install the miniscript-compiler: 43 | 44 | ```bash 45 | cargo install miniscript-compiler 46 | ``` 47 | 48 | Compile miniscript examples: 49 | 50 | ```bash 51 | make unroll 52 | make onboarding 53 | make vtxo 54 | ``` 55 | -------------------------------------------------------------------------------- /boarding.hack: -------------------------------------------------------------------------------- 1 | // constructorInputs: 2 | taproot_key: 3 | type: schnorr public key 4 | min_relay_fee_amount: 5 | type: little-endian uint64 6 | 7 | // witness (empty) 8 | 9 | // script: 10 | OP_0 11 | OP_INSPECTOUTPUTSCRIPTPUBKEY 12 | OP_1 13 | OP_EQUALVERIFY 14 | OP_DATA_32 15 | 16 | OP_EQUALVERIFY 17 | OP_0 18 | OP_INSPECTOUTPUTVALUE // stack: [out_value_version, out_value] 19 | OP_1 20 | OP_EQUALVERIFY // stack: [out_value] 21 | OP_PUSHCURRENTINPUTINDEX 22 | OP_INSPECTINPUTVALUE // stack: [input_value_version, input_value, out_value] 23 | OP_1 24 | OP_EQUALVERIFY // stack: [input_value, out_value] 25 | OP_DATA_8 26 | // stack: [min_relay_fee_amount, input_value, out_value] 27 | OP_SUB64 // stack: [overflow, input_value - min_relay_fee_amount, out_value] 28 | OP_1 // stack: [1, overflow, input_value - min_relay_fee_amount, out_value] 29 | OP_EQUALVERIFY // stack: [input_value - min_relay_fee_amount, out_value] 30 | OP_EQUAL 31 | 32 | // miniscript policy 33 | and_v( 34 | spk_eq(out_spk(0), "5120" + )), 35 | value_eq( 36 | value(sub(curr_inp_value, )), 37 | out_value(0) 38 | ) 39 | ) 40 | -------------------------------------------------------------------------------- /forfeit.hack: -------------------------------------------------------------------------------- 1 | // vtxo-forfeit-closure 2 | // constructorInputs: 3 | asp_pubkey: 4 | type: schnorr public key 5 | owner_pubkey: 6 | type: schnorr public key 7 | 8 | // witness 9 | 10 | 11 | 12 | // script: 13 | OP_DATA_32 14 | 15 | OP_CHECKSIGVERIFY 16 | OP_DATA_32 17 | 18 | OP_CHECKSIG 19 | 20 | // miniscript policy 21 | multi_a(2, asp_pubkey, owner_pubkey) 22 | -------------------------------------------------------------------------------- /miniscript/boarding.miniscript: -------------------------------------------------------------------------------- 1 | eltr( 2 | 02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e, 3 | { 4 | and_v( 5 | spk_eq(out_spk(0), 5120d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e), 6 | value_eq( 7 | sub(curr_inp_value, 010000000000000000), 8 | out_value(0) 9 | ) 10 | ), 11 | and_v( 12 | v:pk(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e), 13 | older(512) 14 | ) 15 | } 16 | ) -------------------------------------------------------------------------------- /miniscript/unroll.miniscript: -------------------------------------------------------------------------------- 1 | eltr( 2 | 02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e, 3 | { 4 | and_v( 5 | and_v( 6 | spk_eq(out_spk(0), 5120d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e), 7 | value_eq(out_value(0), 010000000000000000) 8 | ), 9 | and_v( 10 | spk_eq(out_spk(1), 5120d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e), 11 | value_eq(out_value(1), 010000000000000000) 12 | ) 13 | ), 14 | and_v( 15 | v:pk(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e), 16 | older(1024) 17 | ) 18 | } 19 | ) -------------------------------------------------------------------------------- /miniscript/vtxo.miniscript: -------------------------------------------------------------------------------- 1 | eltr( 2 | 02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e, 3 | { 4 | multi_a( 5 | 2, 6 | 02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e, 7 | 02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080f 8 | ), 9 | and_v( 10 | v:pk(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e), 11 | older(512) 12 | ) 13 | } 14 | ) -------------------------------------------------------------------------------- /redeem.hack: -------------------------------------------------------------------------------- 1 | // sweep-closure 2 | // constructorInputs 3 | owner_pubkey: 4 | type: schnorr public key 5 | redeem_delay: 6 | type: BIP68 sequence 7 | 8 | // witness 9 | 10 | 11 | // script 12 | OP_DATA_X # X depends on len() 13 | 14 | OP_CHECKSEQUENCEVERIFY 15 | OP_DROP 16 | OP_DATA_32 17 | 18 | OP_CHECKSIG 19 | 20 | // miniscript policy 21 | and_v(pk(), older(lifetime)) 22 | -------------------------------------------------------------------------------- /sweep.hack: -------------------------------------------------------------------------------- 1 | // sweep-closure 2 | // constructorInputs: 3 | asp_pubkey: 4 | type: schnorr public key 5 | lifetime: 6 | type: BIP68 sequence 7 | 8 | // witness 9 | 10 | 11 | // script 12 | OP_DATA_X # X depends on len() 13 | 14 | OP_CHECKSEQUENCEVERIFY 15 | OP_DROP 16 | OP_DATA_32 17 | 18 | OP_CHECKSIG 19 | 20 | // miniscript policy: 21 | and_v(pk(), older(lifetime)) 22 | -------------------------------------------------------------------------------- /unroll.hack: -------------------------------------------------------------------------------- 1 | // unroll-closure 2 | // constructorInputs: 3 | left_taproot_key: 4 | type: schnorr public key 5 | left_amount: 6 | type: little-endian uint64 7 | right_taproot_key: 8 | type: schnorr public key 9 | right_amount: 10 | type: little-endian uint64 11 | 12 | // witness (empty) 13 | 14 | // script: 15 | OP_0 16 | OP_INSPECTOUTPUTSCRIPTPUBKEY 17 | OP_1 18 | OP_EQUALVERIFY 19 | OP_DATA_32 20 | 21 | OP_EQUALVERIFY 22 | OP_0 23 | OP_INSPECTOUTPUTVALUE 24 | OP_1 25 | OP_EQUALVERIFY 26 | OP_DATA_8 27 | 28 | OP_EQUALVERIFY 29 | OP_1 30 | OP_INSPECTOUTPUTSCRIPTPUBKEY 31 | OP_1 32 | OP_EQUALVERIFY 33 | OP_DATA_32 34 | 35 | OP_EQUALVERIFY 36 | OP_1 37 | OP_INSPECTOUTPUTVALUE 38 | OP_1 39 | OP_EQUALVERIFY 40 | OP_DATA_8 41 | 42 | OP_EQUAL 43 | 44 | // miniscript policy 45 | and_v( 46 | and_v( 47 | spk_eq(out_spk(0), "5120" + ), 48 | value_eq(out_value(0), ) 49 | ), 50 | and_v( 51 | spk_eq(out_spk(1), "5120" + ), 52 | value_eq(out_value(1), ) 53 | ) 54 | ) 55 | --------------------------------------------------------------------------------