|
16 | 16 |
|
17 | 17 | use std::io; |
18 | 18 | use std::str::FromStr; |
19 | | - |
20 | 19 | use crate::encode::{self, Encodable, Decodable}; |
21 | 20 | use crate::hashes::{self, hash_newtype, sha256, sha256d, Hash}; |
22 | 21 | use crate::fast_merkle_root::fast_merkle_root; |
23 | 22 | use secp256k1_zkp::Tag; |
| 23 | +use crate::genesis::{commit_to_custom_network_parameters, NetworkParams}; |
24 | 24 | use crate::transaction::OutPoint; |
| 25 | +use crate::Txid; |
25 | 26 |
|
26 | 27 | /// The zero hash. |
27 | 28 | const ZERO32: [u8; 32] = [ |
@@ -75,8 +76,16 @@ impl AssetId { |
75 | 76 | 0x3d, 0x1c, 0x04, 0xed, 0xe9, 0x79, 0x02, 0x6f, |
76 | 77 | ])); |
77 | 78 |
|
| 79 | + /// The asset ID for L-BTC, Bitcoin on the Liquidtestnet network. |
| 80 | + pub const LIQUIDTESTNET_BTC: AssetId = AssetId(sha256::Midstate([ |
| 81 | + 0x49, 0x9a, 0x81, 0x85, 0x45, 0xf6, 0xba, 0xe3, |
| 82 | + 0x9f, 0xc0, 0x3b, 0x63, 0x7f, 0x2a, 0x4e, 0x1e, |
| 83 | + 0x64, 0xe5, 0x90, 0xca, 0xc1, 0xbc, 0x3a, 0x6f, |
| 84 | + 0x6d, 0x71, 0xaa, 0x44, 0x43, 0x65, 0x4c, 0x14, |
| 85 | + ])); |
| 86 | + |
78 | 87 | /// Create an [`AssetId`] from its inner type. |
79 | | - pub const fn from_inner(midstate: sha256::Midstate) -> AssetId { |
| 88 | + pub fn from_inner(midstate: sha256::Midstate) -> AssetId { |
80 | 89 | AssetId(midstate) |
81 | 90 | } |
82 | 91 |
|
@@ -146,6 +155,31 @@ impl AssetId { |
146 | 155 | pub fn into_tag(self) -> Tag { |
147 | 156 | self.0.to_byte_array().into() |
148 | 157 | } |
| 158 | + |
| 159 | + /// Pegged asset id for given network parameters |
| 160 | + pub fn pegged_asset_id_for_network_params(params: &NetworkParams) -> Option<AssetId> { |
| 161 | + match params.network_id.as_str() { |
| 162 | + "liquidv1" => Some(Self::LIQUID_BTC), |
| 163 | + "liquidtestnet" => Some(Self::LIQUIDTESTNET_BTC), |
| 164 | + _ => { |
| 165 | + // Else calculate the asset_id |
| 166 | + let asset_id = Self::pegged_asset_id_for_params_and_parent_chain_hash( |
| 167 | + params, |
| 168 | + bitcoin::Network::Regtest.chain_hash(), |
| 169 | + ); |
| 170 | + Some(asset_id) |
| 171 | + } |
| 172 | + } |
| 173 | + } |
| 174 | + |
| 175 | + /// Calculate the `AssetId` for the pegged asset for a given set of network parameters assuming |
| 176 | + /// a Regtest parent network |
| 177 | + fn pegged_asset_id_for_params_and_parent_chain_hash(params: &NetworkParams, parent_chainhash: bitcoin::blockdata::constants::ChainHash) -> AssetId { |
| 178 | + let commit = commit_to_custom_network_parameters(params); |
| 179 | + let asset_outpoint = OutPoint::new(Txid::from_slice(commit.as_slice()).expect("txid"), 0); |
| 180 | + let asset_entropy = AssetId::generate_asset_entropy(asset_outpoint, ContractHash::from_slice(parent_chainhash.to_bytes().as_slice()).unwrap()); |
| 181 | + AssetId::from_entropy(asset_entropy) |
| 182 | + } |
149 | 183 | } |
150 | 184 |
|
151 | 185 | impl ::std::fmt::Display for AssetId { |
@@ -260,7 +294,7 @@ impl<'de> ::serde::Deserialize<'de> for AssetId { |
260 | 294 | mod test { |
261 | 295 | use super::*; |
262 | 296 | use std::str::FromStr; |
263 | | - |
| 297 | + use bitcoin::constants::ChainHash; |
264 | 298 | use crate::hashes::sha256; |
265 | 299 |
|
266 | 300 | #[test] |
@@ -366,4 +400,52 @@ mod test { |
366 | 400 | "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d", |
367 | 401 | ); |
368 | 402 | } |
| 403 | + |
| 404 | + #[test] |
| 405 | + fn liquid_asset_ids() { |
| 406 | + // Testing the two most common Regtest networks using in Liquid and CLN codebases |
| 407 | + let network_params = NetworkParams::custom_network("elementsregtest".to_string(), None, None, None); |
| 408 | + let asset_id = AssetId::pegged_asset_id_for_params_and_parent_chain_hash( |
| 409 | + &network_params, |
| 410 | + bitcoin::Network::Regtest.chain_hash(), |
| 411 | + ); |
| 412 | + |
| 413 | + let elementsregtest_asset_id = AssetId(sha256::Midstate([ |
| 414 | + 0x23, 0x0f, 0x4f, 0x5d, 0x4b, 0x7c, 0x6f, 0xa8, 0x45, 0x80, 0x6e, 0xe4, |
| 415 | + 0xf6, 0x77, 0x13, 0x45, 0x9e, 0x1b, 0x69, 0xe8, 0xe6, 0x0f, 0xce, 0xe2, |
| 416 | + 0xe4, 0x94, 0x0c, 0x7a, 0x0d, 0x5d, 0xe1, 0xb2, |
| 417 | + ])); |
| 418 | + |
| 419 | + assert_eq!(asset_id, elementsregtest_asset_id); |
| 420 | + |
| 421 | + let network_params = NetworkParams::custom_network("liquid-regtest".to_string(), None, None, None); |
| 422 | + let asset_id = AssetId::pegged_asset_id_for_params_and_parent_chain_hash( |
| 423 | + &network_params, |
| 424 | + bitcoin::Network::Regtest.chain_hash(), |
| 425 | + ); |
| 426 | + |
| 427 | + let liquid_regtest_assetid = AssetId(sha256::Midstate([ |
| 428 | + 0x5c, 0xe7, 0xb9, 0x63, 0xd3, 0x7f, 0x8f, 0x2d, 0x51, 0xca, 0xfb, 0xba, |
| 429 | + 0x92, 0x8a, 0xaa, 0x9e, 0x22, 0x0b, 0x8b, 0xbc, 0x66, 0x05, 0x71, 0x49, |
| 430 | + 0x9c, 0x03, 0x62, 0x8a, 0x38, 0x51, 0xb8, 0xce, |
| 431 | + ])); |
| 432 | + |
| 433 | + assert_eq!(asset_id, liquid_regtest_assetid); |
| 434 | + |
| 435 | + let liquidv1_params = NetworkParams::liquidv1(); |
| 436 | + let asset_id = AssetId::pegged_asset_id_for_params_and_parent_chain_hash( |
| 437 | + &liquidv1_params, |
| 438 | + bitcoin::Network::Bitcoin.chain_hash(), |
| 439 | + ); |
| 440 | + |
| 441 | + assert_eq!(asset_id, AssetId::LIQUID_BTC); |
| 442 | + |
| 443 | + let liquidtestnet_params = NetworkParams::liquidtestnet(); |
| 444 | + let asset_id = AssetId::pegged_asset_id_for_params_and_parent_chain_hash( |
| 445 | + &liquidtestnet_params, |
| 446 | + ChainHash::from([0u8; 32]), |
| 447 | + ); |
| 448 | + |
| 449 | + assert_eq!(asset_id, AssetId::LIQUIDTESTNET_BTC); |
| 450 | + } |
369 | 451 | } |
0 commit comments