Taproot: делайте ваши ставки

Аннотация. В этой статье получатель гранта 100x Group Джереми Рубин описывает смарт-контракт, который можно использовать для подтверждения обязательства потерять монеты, если Taproot не активируется до определенной даты. Джереми объясняет новую интересную методику использования смарт-контрактов в сети биткоина для осуществления таких «ставок». Но, на наш взгляд, на практике эти ограниченные ставки вряд ли помогут решить очевидную проблему, связанную с методологией активации софтфорков в сети биткоина.

Сигнализирование о намерении активировать Taproot с помощью смартконтрактов

Если последние несколько месяцев вы не провели в танке, вы знаете, что Taproot это новый софтфорк в сети биткоина, который готовится к скорому выпуску. Подавляющее большинство членов сообщества согласны с тем, что Taproot отлично дополнит сеть биткоина, но существуют значительные разногласия по поводу того, как скоординировать активацию обновления. 1

Те из вас, кто знаком с моими предыдущими исследованиями вероятностных софтфорков, знают, что я поклонник механизмов активации, требующих личной заинтересованности пользователей. В этой короткой статье я расскажу, как в софтфорках, которые активируются пользователями, держатели биткоина могут взять на себя обязательство потерять монеты2 в том случае, если активация Taproot не состоится, что является честным сигналом об обязательстве признать только цепочку с Taproot.

У этой статьи две цели: во-первых, я хочу рассказать о Sapio, языке программирования смарт-контрактов в сети биткоина, который я разрабатываю. Sapio предназначен для BIP-119 CheckTemplateVerify (CTV), предлагаемого расширения сети биткоина, но для работы конкретно этого контракта не нужен CTV, так как он может использовать самоподписанные транзакции, и это не сильно влияет на обязательность контракта. Скоро я сделаю Sapio доступным для всеобщего использования, но если вы хотите получить доступ раньше, напишите мне личное сообщение в Twitter (@JeremyRubin).

Идея создания сигнала о личной финансовой заинтересованности со стороны пользователей родилась в разговоре с Мадарсом Вирзой, одним из создателей криптовалюты Zcash. В частности, Мадарс спросил меня, могу ли я разработать контракт, который позволит автоматически сделать серию ставок скажем, соотнесенных с периодами сигнализирования на уровне 2 016 блоков в BIP8/BIP9 на активацию Taproot (увеличивая «окно» ставки, можно хеджировать риск за весь период, если нет уверенности в точном времени активации; это также делает контракт более интересным…). На схеме ниже показано общее представление логики, которую мы хотим реализовать.

Примерно через 10 минут после разговора с Мадарсом у меня был готов функциональный прототип, который я доработал на следующий день.

Но хватит разговоров. Посмотрим на код:

/// Taproot Recurring Bet.
/// This data structure captures all the arguments required to build a contract.
#[derive(JsonSchema, Serialize, Deserialize, Clone)]
pub struct TapBet {
   /// How much Bitcoin to release per period
   #[schemars(with = "f64")]
   #[serde(with = "bitcoin::util::amount::serde::as_btc")]
   pub amount_per_time: Amount,
   /// How much in fees to pay per cycle.
   /// TODO: In theory, this could be zero, as miners could manually add such
   /// transactions (which they topet a reward out of) to their mempools.
   /// TODO: Optional, make cancellation path have a different feerate
   #[schemars(with = "f64")]
   #[serde(with = "bitcoin::util::amount::serde::as_btc")]
   pub fees_per_time: Amount,
   /// How frequently should we test to see if Taproot is active?
   pub period: AnyRelTimeLock,
   /// How long to wait to allow early-abort of the contract unfolding (should
   /// be > period)
   pub cancel_timeout: AnyRelTimeLock,
   /// An externally generated Taproot script (not address) to send the funds to
   pub taproot_script: Script,
   /// An arbitrary bitcoin address to send the funds to on cancellation
   pub cancel_to: bitcoin::Address,
}
 
/// This defines the interface for the TapBet Contract
impl Contract for TapBet {
   /// The "next steps" that can happen for an instance of a TapBet
   /// is either to:
   /// - stop_expansion: return the funds safely to the creator because Taproot is active
   /// - continue_expansion: take amount_per_time of the funds and send them to a taproot address.
   ///     > If taproot is active, the funds are safe in that key
   ///     > If taproot is not active, a miner may steal the funds
   declare! {then, Self::stop_expansion, Self::continue_expansion}
   /// you can ignore this line, it is only needed for an advanced Sapio feature
   /// and will be able to be removed when a specific rust feature stabilizes.
   declare! {non updatable}
}
 
/// The actual logic for each TapBet
impl TapBet {
   /// The waiting period is over, sample if Taproot is active
   guard! {period_over |s, ctx| { s.period.into() }}
   then! {continue_expansion [Self::period_over] |s, ctx| {
       // creates a new transaction template for the next step
       // of this contract
       let mut builder = ctx.template().set_label("continue_expansion".into());
       // set the sequence validly
       builder = builder.set_sequence(0, s.period.into())?;
       // if we have sufficient funds, pay out to a taproot address now
       if builder.ctx().funds() >= s.amount_per_time {
           let mut range = AmountRange::new();
           range.update_range(s.amount_per_time);
           builder = builder.add_output(
               s.amount_per_time,
               &Compiled::from_script(s.taproot_script.clone(), Some(range), ctx.network)?,
               None
           )?;
       }
       // if we have funds remaining, make a recursive TapBet with the same
       // parameters.
       if builder.ctx().funds() >= s.fees_per_time {
           let amt =
               builder.ctx().funds() - s.fees_per_time;
           if amt > Amount::from_sat(0) {
               builder = builder.add_output(
                   amt,
                   s,
                   None
               )?;
           }
       }
       builder.into()
   }}
 
   /// The timeout period is over
   guard! {timeout |s, ctx| { s.cancel_timeout.into() }}
   then! {stop_expansion [Self::timeout] |s, ctx| {
       let mut builder  = ctx.template().set_label("stop_expansion".into());
       builder = builder.set_sequence(0, s.cancel_timeout.into())?;
       // Pay out to the original owner
       if builder.ctx().funds() >= s.fees_per_time {
           let amt = builder.ctx().funds() - s.fees_per_time;
           if amt > Amount::from_sat(0) {
               builder = builder.add_output(
                   amt,
                   &Compiled::from_address(s.cancel_to.clone(), None),
                   None
               )?;
           }
       }
       builder.into()
   }}
}
 
/// This registers our contract API with the module system.
REGISTER![TapBet];

Определение контракта TapBet компилируется в модуль WebAssembly, который можно загрузить и использовать для создания экземпляров контракта. Для удобства в Sapio предусмотрена библиотека Rust/CLI для взаимодействия со скомпилированными плагинами. Контракт можно создать3 следующим образом:

cargo run --bin cli -- contract create 0.09015
'{"amount_per_time": 0.03,
  "cancel_timeout": {"RH" : 2116}, 
  "cancel_to": "bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw",
  "fees_per_time": 0.00005,
  "period": {"RH": 2016},
  "taproot_script": "51200279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817"}'
--file="plugin-example/pkg/sapio_wasm_plugin_example_bg.wasm"

Обратите внимание, что переданной суммы биткоина (0,09015) достаточно для 3-х итераций ставок размером 0,03 с комиссией 0,00005 за ставку. Срок контракта истекает через каждые 2 016 блоков и может быть отменен через 100 блоков после того, как майнеру не удалось его продлить. В результате получается выход, указанный в конце статьи (см. Приложение 1). Нужно просто отправить 0,09015 биткоина на созданный адрес (bcrt1qgc803gks4d89362ql09ayycr2s7k6v4ze34pc4ndc0ggu4j24lgqewwf7y) и далее публиковать полученный выход с контрактом в формате JSON для подтверждения честного сигнала. Эти контракты можно привязать к конкретному выходу UTXO для создания списка PSBT (Partially Signed Transactions, частино подписанные транзакции) (см. Приложение 2) и выводить на экран помощью интерфейса Tux (см. рисунок выше). Выход команды содержит специфические для Sapio метаданные и сводки, которые помогают выполнять операции с контрактами и обрабатывать их, но по сути каждый контракт Sapio представляет собой простой список всех возможных транзакций.

В будущем гарантия добросовестного выполнения контракта будет заложена в CheckTemplateVerify. Это означает, что перевести средства можно, используя исключительно путь, обозначенный «then!» (тогда!), и никакой другой. В настоящее время, поскольку CheckTemplateVerify еще не доступен, мы можем симулировать функции CTV хотя модель обеспечения безопасности при этом будет хуже используя подписывающий сервер Оracle. В этом конкретном случае использование персонального подписывающего сервера не сильно повлияет на работу контракта, потому что рациональный майнер всегда выберет сделки, которые более выгодны, чем предлагаемые, что ограничивает возможности для обмана.

Чтобы обмануть, пользователь в конечном итоге будет вынужден предложить больше денег, чем уже могут получить майнеры по существующей сделке. Не исключено, что недобросовестный пользователь может подорвать честность сигнала и заплатить майнеру, скажем, 0,04 BTC, за досрочное прекращение действия контракта и возврата суммы, которая бы использовалась для сигнала в оставшееся время. Существует несколько способов преодоления этого ограничения:

  1. Финансировать только один период этого контракта (без повторения).
  2. Использовать группу сторонних подписантов (возможно, в дополнение к вашему собственному ключу); в этом случае вам придется заставлять нотариуса закрывать глаза на ваш обман.
  3. Активировать OP_CTV, что устраняет потребность в подписывающих серверах.

При наличии достаточных доказательств того, что внушительное количество экономически активных пользователей рассчитывает на активацию Taproot к определенному сроку, для сети было бы глупо и, возможно, экономически невыгодно не обеспечить выполнение

Итак, нужно ли бросаться подавать честный сигнал о том, что вы хотите получить Taproot к определенной дате? Что ж, я не могу вам в этом помешать! Но я бы посоветовал соблюдать осторожность — это новая концепция, а теория о том, чтобы дать майнеру возможность притвориться, что он никогда не слышал о «taproot» и украсть ваши деньги, может создать проблемы; это проверка на «слабо». Кроме того, активация по этому принципу потребует широкой поддержки экосистемы для контроля и измерения сумм, размещаемых в таких контрактах. На данном этапе автор склоняется к тому, что следует сформировать консенсус в отношении одного из существующих методов активации семейства BIP8/9, но призывает читателей не прекращать поиски и размышления на тему смарт-контрактов и консенсуса.

Хотите попробовать написать собственный смарт-контракт на языке Sapio? Следите за новостями! Официальный релиз состоится в ближайшее время

Примечания

1 – Я не стал углубляться во все потенциальные механизмы обновления сети, так как это выходит за рамки темы этого материала, но если вас интересуют все существующие предложения, прочитайте статью Аарона ван Вирдума в Bitcoin Magazine.

2 – С получением «призовых» монет дела обстоят чуточку сложнее — деньги легче тратить, чем зарабатывать! Правда ли, что найдутся люди, готовые заплатить вам, чтобы вы потеряли деньги, если Taproot не активируется? Один из способов реализовать премию сделать так, чтобы транзакция, для которой создается контракт, имела второй выход для премии и была не полностью профинансирована (используется SigHash AnyoneCanPay), чтобы в нее можно было добавить средства для премии.

3 – Может показаться, что параметр taproot_script творит чудеса, но это просто скрипт OP_1 PUSH32 <32 bytes pubkey> для создания выхода V1 Segwit Output, подробную информацию см. по адресу  https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki.

Приложения

Приложение 1. Контракт в формате JSON

 

{
 "template_hash_to_template_map": {
   "a6dbda05299a7225d6422e8a0d163b9e5c734143eb1a507a5772e65edb4898dd": {
     "precomputed_template_hash": "a6dbda05299a7225d6422e8a0d163b9e5c734143eb1a507a5772e65edb4898dd",
     "precomputed_template_hash_idx": 0,
     "max_amount_sats": 9010000,
     "metadata_map_s2s": {
       "label": "stop_expansion"
     },
     "transaction_literal": {
       "version": 2,
       "lock_time": 0,
       "input": [
         {
           "previous_output": "0000000000000000000000000000000000000000000000000000000000000000:4294967295",
           "script_sig": "",
           "sequence": 2116,
           "witness": []
         }
       ],
       "output": [
         {
           "value": 9010000,
           "script_pubkey": "001487a87e0e17a80a2d2bd65c421a1090df8ed6cc9a"
         }
       ]
     },
     "outputs_info": [
       {
         "sending_amount_sats": 9010000,
         "receiving_contract": {
           "address": "bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw",
           "amount_range": {
             "max_btc": 21000000
           }
         }
       }
     ]
   },
   "2a5a2eecaf8090ffc6668ae60f70722d8d4791f9c282c6da0ecc5e8838c38175": {
     "precomputed_template_hash": "2a5a2eecaf8090ffc6668ae60f70722d8d4791f9c282c6da0ecc5e8838c38175",
     "precomputed_template_hash_idx": 0,
     "max_amount_sats": 9010000,
     "metadata_map_s2s": {
       "label": "continue_expansion"
     },
     "transaction_literal": {
       "version": 2,
       "lock_time": 0,
       "input": [
         {
           "previous_output": "0000000000000000000000000000000000000000000000000000000000000000:4294967295",
           "script_sig": "",
           "sequence": 2016,
           "witness": []
         }
       ],
       "output": [
         {
           "value": 3000000,
           "script_pubkey": "51200279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817"
         },
         {
           "value": 6010000,
           "script_pubkey": "00206709d4f25ab69955961cc8538e5d58343ae3aa3709a3fd9c7c0fa33f4af63887"
         }
       ]
     },
     "outputs_info": [
       {
         "sending_amount_sats": 3000000,
         "receiving_contract": {
           "address": "bcrt1pqfumuen7l8wthtz45p3ftn58pvrs9xlumvkuu2xet8egzkcklqtscyvky6",
           "amount_range": {
             "max_btc": 0.03
           }
         }
       },
       {
         "sending_amount_sats": 6010000,
         "receiving_contract": {
           "template_hash_to_template_map": {
             "d61ac7b03b54f0ad0ab9e9e69ad966e4faa325375577cb259e7891a7b493dc82": {
               "precomputed_template_hash": "d61ac7b03b54f0ad0ab9e9e69ad966e4faa325375577cb259e7891a7b493dc82",
               "precomputed_template_hash_idx": 0,
               "max_amount_sats": 6005000,
               "metadata_map_s2s": {
                 "label": "stop_expansion"
               },
               "transaction_literal": {
                 "version": 2,
                 "lock_time": 0,
                 "input": [
                   {
                     "previous_output": "0000000000000000000000000000000000000000000000000000000000000000:4294967295",
                     "script_sig": "",
                     "sequence": 2116,
                     "witness": []
                   }
                 ],
                 "output": [
                   {
                     "value": 6005000,
                     "script_pubkey": "001487a87e0e17a80a2d2bd65c421a1090df8ed6cc9a"
                   }
                 ]
               },
               "outputs_info": [
                 {
                   "sending_amount_sats": 6005000,
                   "receiving_contract": {
                     "address": "bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw",
                     "amount_range": {
                       "max_btc": 21000000
                     }
                   }
                 }
               ]
             },
             "ebcea40f3558db070bf30445c208b329e2386080662dd5d6fe29da8f0c301ffb": {
               "precomputed_template_hash": "ebcea40f3558db070bf30445c208b329e2386080662dd5d6fe29da8f0c301ffb",
               "precomputed_template_hash_idx": 0,
               "max_amount_sats": 6005000,
               "metadata_map_s2s": {
                 "label": "continue_expansion"
               },
               "transaction_literal": {
                 "version": 2,
                 "lock_time": 0,
                 "input": [
                   {
                     "previous_output": "0000000000000000000000000000000000000000000000000000000000000000:4294967295",
                     "script_sig": "",
                     "sequence": 2016,
                     "witness": []
                   }
                 ],
                 "output": [
                   {
                     "value": 3000000,
                     "script_pubkey": "51200279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817"
                   },
                   {
                     "value": 3005000,
                     "script_pubkey": "0020d023b8ffc5162902a1902e12d0282957fb4726a0f83efc2cb7efc4a6d4247483"
                   }
                 ]
               },
               "outputs_info": [
                 {
                   "sending_amount_sats": 3000000,
                   "receiving_contract": {
                     "address": "bcrt1pqfumuen7l8wthtz45p3ftn58pvrs9xlumvkuu2xet8egzkcklqtscyvky6",
                     "amount_range": {
                       "max_btc": 0.03
                     }
                   }
                 },
                 {
                   "sending_amount_sats": 3005000,
                   "receiving_contract": {
                     "template_hash_to_template_map": {
                       "64ca1a03d428ce2bb3413080cfa303dcdc841ba30900c2d72cd3615593bf294b": {
                         "precomputed_template_hash": "64ca1a03d428ce2bb3413080cfa303dcdc841ba30900c2d72cd3615593bf294b",
                         "precomputed_template_hash_idx": 0,
                         "max_amount_sats": 3000000,
                         "metadata_map_s2s": {
                           "label": "continue_expansion"
                         },
                         "transaction_literal": {
                           "version": 2,
                           "lock_time": 0,
                           "input": [
                             {
                               "previous_output": "0000000000000000000000000000000000000000000000000000000000000000:4294967295",
                               "script_sig": "",
                               "sequence": 2016,
                               "witness": []
                             }
                           ],
                           "output": [
                             {
                               "value": 3000000,
                               "script_pubkey": "51200279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817"
                             }
                           ]
                         },
                         "outputs_info": [
                           {
                             "sending_amount_sats": 3000000,
                             "receiving_contract": {
                               "address": "bcrt1pqfumuen7l8wthtz45p3ftn58pvrs9xlumvkuu2xet8egzkcklqtscyvky6",
                               "amount_range": {
                                 "max_btc": 0.03
                               }
                             }
                           }
                         ]
                       },
                       "037164a6bc5e23333ccd750972927c4de669face404841ce476b867eb08a5d1e": {
                         "precomputed_template_hash": "037164a6bc5e23333ccd750972927c4de669face404841ce476b867eb08a5d1e",
                         "precomputed_template_hash_idx": 0,
                         "max_amount_sats": 3000000,
                         "metadata_map_s2s": {
                           "label": "stop_expansion"
                         },
                         "transaction_literal": {
                           "version": 2,
                           "lock_time": 0,
                           "input": [
                             {
                               "previous_output": "0000000000000000000000000000000000000000000000000000000000000000:4294967295",
                               "script_sig": "",
                               "sequence": 2116,
                               "witness": []
                             }
                           ],
                           "output": [
                             {
                               "value": 3000000,
                               "script_pubkey": "001487a87e0e17a80a2d2bd65c421a1090df8ed6cc9a"
                             }
                           ]
                         },
                         "outputs_info": [
                           {
                             "sending_amount_sats": 3000000,
                             "receiving_contract": {
                               "address": "bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw",
                               "amount_range": {
                                 "max_btc": 21000000
                               }
                             }
                           }
                         ]
                       }
                     },
                     "known_policy": "thresh(1,and(older(2116),pk(02d9259ccb8d82d21b80155926dc8dd840f22a862792eba28c935b5221bda7f696)),and(older(2016),pk(037a7ffbdac37874b
4128c484318f3a9c0f0f2088628181d2ed83add9e4ab291c1)))",                                                                                                                       
                     "address": "bcrt1q6q3m3l79zc5s9gvs9cfdq2pf2la5wf4qlql0ct9halz2d4pywjpsa25fsl",
                     "known_descriptor": "wsh(thresh(1,nj:and_v(v:pk(02d9259ccb8d82d21b80155926dc8dd840f22a862792eba28c935b5221bda7f696),older(2116)),snj:and_v(v:pk(037a7f
fbdac37874b4128c484318f3a9c0f0f2088628181d2ed83add9e4ab291c1),older(2016))))#fcpsm54r",                                                                                      
                     "amount_range": {
                       "max_btc": 0.03
                     }
                   }
                 }
               ]
             }
           },
           "known_policy": "thresh(1,and(older(2116),pk(03bac00d55195f4822f0d6660b43e2a0c20bb162542fe7656400024c499edb21a1)),and(older(2016),pk(03ea94374570b77c401224ffe33
5b4dd4a640e5cd7d52c3d2f9e5fe3a5b02e481e)))",                                                                                                                                 
           "address": "bcrt1qvuyafuj6k6v4t9suepfcuh2cxsaw823hpx3lm8rup73n7jhk8zrsmkaflr",
           "known_descriptor": "wsh(thresh(1,nj:and_v(v:pk(03bac00d55195f4822f0d6660b43e2a0c20bb162542fe7656400024c499edb21a1),older(2116)),snj:and_v(v:pk(03ea94374570b77c
401224ffe335b4dd4a640e5cd7d52c3d2f9e5fe3a5b02e481e),older(2016))))#wc87daeg",                                                                                                
           "amount_range": {
             "max_btc": 0.06005
           }
         }
       }
     ]
   }
 },
 "known_policy": "thresh(1,and(older(2116),pk(02d3c32217f7bc3d43f1b8cfd7425379a3bf07074f1a3b4d243546e80e69b0c172)),and(older(2016),pk(02214f6ce3917541ca51705ea29e592dd4e39
cfffcf8f46d43e26011e331e6f5bd)))",                                                                                                                                           
 "address": "bcrt1qgc803gks4d89362ql09ayycr2s7k6v4ze34pc4ndc0ggu4j24lgqewwf7y",
 "known_descriptor": "wsh(thresh(1,nj:and_v(v:pk(02d3c32217f7bc3d43f1b8cfd7425379a3bf07074f1a3b4d243546e80e69b0c172),older(2116)),snj:and_v(v:pk(02214f6ce3917541ca51705ea2
9e592dd4e39cfffcf8f46d43e26011e331e6f5bd),older(2016))))#nu55ucem",                                                                                                          
 "amount_range": {
   "max_btc": 0.0901
 }
}

Приложение 2. Данные PSBT и метаданные контракта

[
 [
   {
     "global": {
       "unsigned_tx": {
         "version": 2,
         "lock_time": 0,
         "input": [
           {
             "previous_output": "4fac5f4526a712ad202029cb713469f15c65925be29ac52f89cb637d03b3b678:0",
             "script_sig": "",
             "sequence": 2016,
             "witness": []
           }
         ],
         "output": [
           {
             "value": 3000000,
             "script_pubkey": "51200279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817"
           },
           {
             "value": 6010000,
             "script_pubkey": "00206709d4f25ab69955961cc8538e5d58343ae3aa3709a3fd9c7c0fa33f4af63887"
           }
         ]
       },
       "version": 0,
       "xpub": {},
       "proprietary": [],
       "unknown": []
     },
     "inputs": [
       {
         "non_witness_utxo": null,
         "witness_utxo": {
           "value": 9010000,
           "script_pubkey": "0020460ef8a2d0ab4e58e940fbcbd21303543d6d32a2cc6a1c566dc3d08e564aafd0"
         },
         "partial_sigs": {
           "02214f6ce3917541ca51705ea29e592dd4e39cfffcf8f46d43e26011e331e6f5bd": "1ce7a3360f44340211df12a3fa98ef29b577cd2f4b228c0e2ff3
bc90f7659395711913e17c7ce033a60a3c7f957f64cc399f6d574767ca5206c3b8e6755ef7d001"                                                         
         },
         "sighash_type": "SIGHASH_ALL",
         "redeem_script": null,
         "witness_script": "8292632102d3c32217f7bc3d43f1b8cfd7425379a3bf07074f1a3b4d243546e80e69b0c172ad024408b268927c8292632102214f6c
e3917541ca51705ea29e592dd4e39cfffcf8f46d43e26011e331e6f5bdad02e007b26892935187",                                                        
         "bip32_derivation": [],
         "final_script_sig": null,
         "final_script_witness": null,
         "ripemd160_preimages": {},
         "sha256_preimages": {},
         "hash160_preimages": {},
         "hash256_preimages": {},
         "proprietary": [],
         "unknown": []
       }
     ],
     "outputs": [
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       },
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       }
     ]
   },
   {
     "global": {
       "unsigned_tx": {
         "version": 2,
         "lock_time": 0,
         "input": [
           {
             "previous_output": "4fac5f4526a712ad202029cb713469f15c65925be29ac52f89cb637d03b3b678:0",
             "script_sig": "",
             "sequence": 2116,
             "witness": []
           }
         ],
         "output": [
           {
             "value": 9010000,
             "script_pubkey": "001487a87e0e17a80a2d2bd65c421a1090df8ed6cc9a"
           }
         ]
       },
       "version": 0,
       "xpub": {},
       "proprietary": [],
       "unknown": []
     },
     "inputs": [
       {
         "non_witness_utxo": null,
         "witness_utxo": {
           "value": 9010000,
           "script_pubkey": "0020460ef8a2d0ab4e58e940fbcbd21303543d6d32a2cc6a1c566dc3d08e564aafd0"
         },
         "partial_sigs": {
           "02d3c32217f7bc3d43f1b8cfd7425379a3bf07074f1a3b4d243546e80e69b0c172": "e95b534aecc4325ade5c3241d06c4606de2244a990d01879b4d8
9370e31a3b9b2fe7f242505eb76915931de3a23b6f06d59a7f437c98cf083b84296859a5755b01"                                                         
         },
         "sighash_type": "SIGHASH_ALL",
         "redeem_script": null,
         "witness_script": "8292632102d3c32217f7bc3d43f1b8cfd7425379a3bf07074f1a3b4d243546e80e69b0c172ad024408b268927c8292632102214f6c
e3917541ca51705ea29e592dd4e39cfffcf8f46d43e26011e331e6f5bdad02e007b26892935187",                                                        
         "bip32_derivation": [],
         "final_script_sig": null,
         "final_script_witness": null,
         "ripemd160_preimages": {},
         "sha256_preimages": {},
         "hash160_preimages": {},
         "hash256_preimages": {},
         "proprietary": [],
         "unknown": []
       }
     ],
     "outputs": [
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       }
     ]
   },
   {
     "global": {
       "unsigned_tx": {
         "version": 2,
         "lock_time": 0,
         "input": [
           {
             "previous_output": "d9b7e135a0265e77b7cab8c9254cbe2638bca168c00120dde56e41fb74e36d5a:1",
             "script_sig": "",
             "sequence": 2116,
             "witness": []
           }
         ],
         "output": [
           {
             "value": 6005000,
             "script_pubkey": "001487a87e0e17a80a2d2bd65c421a1090df8ed6cc9a"
           }
         ]
       },
       "version": 0,
       "xpub": {},
       "proprietary": [],
       "unknown": []
     },
     "inputs": [
       {
         "non_witness_utxo": null,
         "witness_utxo": {
           "value": 6010000,
           "script_pubkey": "00206709d4f25ab69955961cc8538e5d58343ae3aa3709a3fd9c7c0fa33f4af63887"
         },
         "partial_sigs": {
           "03bac00d55195f4822f0d6660b43e2a0c20bb162542fe7656400024c499edb21a1": "0f24413cf9e4a0d53ff24496969d357b5c0a95f25b61f98d9fda
de8a2c8c612a5dcc211242ff81fd3836c7adaa8a9c1988a5f48719d87b2fe1c34afb666c198601"                                                         
         },
         "sighash_type": "SIGHASH_ALL",
         "redeem_script": null,
         "witness_script": "8292632103bac00d55195f4822f0d6660b43e2a0c20bb162542fe7656400024c499edb21a1ad024408b268927c8292632103ea9437
4570b77c401224ffe335b4dd4a640e5cd7d52c3d2f9e5fe3a5b02e481ead02e007b26892935187",                                                        
         "bip32_derivation": [],
         "final_script_sig": null,
         "final_script_witness": null,
         "ripemd160_preimages": {},
         "sha256_preimages": {},
         "hash160_preimages": {},
         "hash256_preimages": {},
         "proprietary": [],
         "unknown": []
       }
     ],
     "outputs": [
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       }
     ]
   },
   {
     "global": {
       "unsigned_tx": {
         "version": 2,
         "lock_time": 0,
         "input": [
           {
             "previous_output": "d9b7e135a0265e77b7cab8c9254cbe2638bca168c00120dde56e41fb74e36d5a:1",
             "script_sig": "",
             "sequence": 2016,
             "witness": []
           }
         ],
         "output": [
           {
             "value": 3000000,
             "script_pubkey": "51200279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817"
           },
           {
             "value": 3005000,
             "script_pubkey": "0020d023b8ffc5162902a1902e12d0282957fb4726a0f83efc2cb7efc4a6d4247483"
           }
         ]
       },
       "version": 0,
       "xpub": {},
       "proprietary": [],
       "unknown": []
     },
     "inputs": [
       {
         "non_witness_utxo": null,
         "witness_utxo": {
           "value": 6010000,
           "script_pubkey": "00206709d4f25ab69955961cc8538e5d58343ae3aa3709a3fd9c7c0fa33f4af63887"
         },
         "partial_sigs": {
           "03ea94374570b77c401224ffe335b4dd4a640e5cd7d52c3d2f9e5fe3a5b02e481e": "7fef952d3488420612e2ff5bb422606112357085b7dcb745534e
59c31db9795076f54f9173448a0ffd7f93f98139ce0f155583427356b77f5da8be69393a67f301"                                                         
         },
         "sighash_type": "SIGHASH_ALL",
         "redeem_script": null,
         "witness_script": "8292632103bac00d55195f4822f0d6660b43e2a0c20bb162542fe7656400024c499edb21a1ad024408b268927c8292632103ea9437
4570b77c401224ffe335b4dd4a640e5cd7d52c3d2f9e5fe3a5b02e481ead02e007b26892935187",                                                        
         "bip32_derivation": [],
         "final_script_sig": null,
         "final_script_witness": null,
         "ripemd160_preimages": {},
         "sha256_preimages": {},
         "hash160_preimages": {},
         "hash256_preimages": {},
         "proprietary": [],
         "unknown": []
       }
     ],
     "outputs": [
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       },
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       }
     ]
   },
   {
     "global": {
       "unsigned_tx": {
         "version": 2,
         "lock_time": 0,
         "input": [
           {
             "previous_output": "e3b104521048350140ffb52914cc780fe45a44c733e2524a25ec1a79c235639b:1",
             "script_sig": "",
             "sequence": 2116,
             "witness": []
           }
         ],
         "output": [
           {
             "value": 3000000,
             "script_pubkey": "001487a87e0e17a80a2d2bd65c421a1090df8ed6cc9a"
           }
         ]
       },
       "version": 0,
       "xpub": {},
       "proprietary": [],
       "unknown": []
     },
     "inputs": [
       {
         "non_witness_utxo": null,
         "witness_utxo": {
           "value": 3005000,
           "script_pubkey": "0020d023b8ffc5162902a1902e12d0282957fb4726a0f83efc2cb7efc4a6d4247483"
         },
         "partial_sigs": {
           "02d9259ccb8d82d21b80155926dc8dd840f22a862792eba28c935b5221bda7f696": "58848a5e8abb37ac1c395ec5934e984bd25496488a0ca718ce28
2ce742686a247156f7c42a84b07db71f1d265ef9ee3dcab34491ee62cac6d6d064cb3abf87a201"                                                         
         },
         "sighash_type": "SIGHASH_ALL",
         "redeem_script": null,
         "witness_script": "8292632102d9259ccb8d82d21b80155926dc8dd840f22a862792eba28c935b5221bda7f696ad024408b268927c82926321037a7ffb
dac37874b4128c484318f3a9c0f0f2088628181d2ed83add9e4ab291c1ad02e007b26892935187",                                                        
         "bip32_derivation": [],
         "final_script_sig": null,
         "final_script_witness": null,
         "ripemd160_preimages": {},
         "sha256_preimages": {},
         "hash160_preimages": {},
         "hash256_preimages": {},
         "proprietary": [],
         "unknown": []
       }
     ],
     "outputs": [
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       }
     ]
   },
   {
     "global": {
       "unsigned_tx": {
         "version": 2,
         "lock_time": 0,
         "input": [
           {
             "previous_output": "e3b104521048350140ffb52914cc780fe45a44c733e2524a25ec1a79c235639b:1",
             "script_sig": "",
             "sequence": 2016,
             "witness": []
           }
         ],
         "output": [
           {
             "value": 3000000,
             "script_pubkey": "51200279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817"
           }
         ]
       },
       "version": 0,
       "xpub": {},
       "proprietary": [],
       "unknown": []
     },
     "inputs": [
       {
         "non_witness_utxo": null,
         "witness_utxo": {
           "value": 3005000,
           "script_pubkey": "0020d023b8ffc5162902a1902e12d0282957fb4726a0f83efc2cb7efc4a6d4247483"
         },
         "partial_sigs": {
           "037a7ffbdac37874b4128c484318f3a9c0f0f2088628181d2ed83add9e4ab291c1": "ad0cb6da9994d8b1ae6aea2e158c728887d5f3c9a57bfbc0346d
85ffdf30769e370fb72b1067fc7cb62e7350a5624b2a07e376baa8ec0e769b0187d08663ec9c01"                                                         
         },
         "sighash_type": "SIGHASH_ALL",
         "redeem_script": null,
         "witness_script": "8292632102d9259ccb8d82d21b80155926dc8dd840f22a862792eba28c935b5221bda7f696ad024408b268927c82926321037a7ffb
dac37874b4128c484318f3a9c0f0f2088628181d2ed83add9e4ab291c1ad02e007b26892935187",                                                        
         "bip32_derivation": [],
         "final_script_sig": null,
         "final_script_witness": null,
         "ripemd160_preimages": {},
         "sha256_preimages": {},
         "hash160_preimages": {},
         "hash256_preimages": {},
         "proprietary": [],
         "unknown": []
       }
     ],
     "outputs": [
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       }
     ]
   },
   {
     "global": {
       "unsigned_tx": {
         "version": 2,
         "lock_time": 0,
         "input": [
           {
             "previous_output": "0a9038bbb488729f23c0c1d7c6cfa98ea8464f204fcd9f8d5d90ab91a995d2ba:0",
             "script_sig": "",
             "sequence": 4294967294,
             "witness": []
           }
         ],
         "output": [
           {
             "value": 9010000,
             "script_pubkey": "0020460ef8a2d0ab4e58e940fbcbd21303543d6d32a2cc6a1c566dc3d08e564aafd0"
           },
           {
             "value": 190986940,
             "script_pubkey": "0014b423d53997e1607cf64e31a5a107360fa69db3bd"
           }
         ]
       },
       "version": 0,
       "xpub": {},
       "proprietary": [],
       "unknown": []
     },
     "inputs": [
       {
         "non_witness_utxo": null,
         "witness_utxo": null,
         "partial_sigs": {},
         "sighash_type": null,
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "final_script_sig": null,
         "final_script_witness": null,
         "ripemd160_preimages": {},
         "sha256_preimages": {},
         "hash160_preimages": {},
         "hash256_preimages": {},
         "proprietary": [],
         "unknown": []
       }
     ],
     "outputs": [
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       },
       {
         "redeem_script": null,
         "witness_script": null,
         "bip32_derivation": [],
         "proprietary": [],
         "unknown": []
       }
     ]
   }
 ],
 [
   {
     "color": "green",
     "metadata": {
       "label": "continue_expansion"
     },
     "utxo_metadata": [
       {},
       {}
     ]
   },
   {
     "color": "green",
     "metadata": {
       "label": "stop_expansion"
     },
     "utxo_metadata": [
       {}
     ]
   },
   {
     "color": "green",
     "metadata": {
       "label": "stop_expansion"
     },
     "utxo_metadata": [
       {}
     ]
   },
   {
     "color": "green",
     "metadata": {
       "label": "continue_expansion"
     },
     "utxo_metadata": [
       {},
       {}
     ]
   },
   {
     "color": "green",
     "metadata": {
       "label": "stop_expansion"
     },
     "utxo_metadata": [
       {}
     ]
   },
   {
     "color": "green",
     "metadata": {
       "label": "continue_expansion"
     },
     "utxo_metadata": [
       {}
     ]
   },
   {
     "color": "black",
     "metadata": {
       "label": "funding"
     },
     "utxo_metadata": {}
   }
 ]
]