rgbcore/operation/
layer1.rs

1// RGB Consensus Library: consensus layer for RGB smart contracts.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Written in 2019-2024 by
6//     Dr Maxim Orlovsky <orlovsky@lnp-bp.org>
7//
8// Copyright (C) 2019-2024 LNP/BP Standards Association. All rights reserved.
9// Copyright (C) 2019-2024 Dr Maxim Orlovsky. All rights reserved.
10//
11// Licensed under the Apache License, Version 2.0 (the "License");
12// you may not use this file except in compliance with the License.
13// You may obtain a copy of the License at
14//
15//     http://www.apache.org/licenses/LICENSE-2.0
16//
17// Unless required by applicable law or agreed to in writing, software
18// distributed under the License is distributed on an "AS IS" BASIS,
19// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20// See the License for the specific language governing permissions and
21// limitations under the License.
22
23use std::str::FromStr;
24
25use bp::BlockHash;
26use strict_encoding::{StrictDecode, StrictEncode, StrictType};
27
28use crate::{LIB_NAME_RGB_COMMIT, LIB_NAME_RGB_LOGIC};
29
30#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
31#[display(lowercase)]
32#[derive(StrictType, StrictEncode, StrictDecode)]
33#[strict_type(lib = LIB_NAME_RGB_LOGIC, tags = repr, into_u8, try_from_u8)]
34#[cfg_attr(
35    feature = "serde",
36    derive(Serialize, Deserialize),
37    serde(crate = "serde_crate", rename_all = "camelCase")
38)]
39#[repr(u8)]
40#[derive(Default)]
41pub enum Layer1 {
42    #[default]
43    Bitcoin = 0,
44    Liquid = 1,
45}
46
47#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
48#[display(inner)]
49#[derive(StrictType, StrictEncode, StrictDecode)]
50#[strict_type(lib = LIB_NAME_RGB_COMMIT, tags = repr, into_u8, try_from_u8)]
51#[cfg_attr(
52    feature = "serde",
53    derive(Serialize, Deserialize),
54    serde(crate = "serde_crate", rename_all = "camelCase")
55)]
56#[repr(u8)]
57#[derive(Default)]
58pub enum ChainNet {
59    BitcoinMainnet = 0,
60    BitcoinTestnet3 = 1,
61    #[default]
62    BitcoinTestnet4 = 2,
63    BitcoinSignet = 3,
64    BitcoinRegtest = 4,
65    LiquidMainnet = 5,
66    LiquidTestnet = 6,
67}
68
69impl ChainNet {
70    pub fn prefix(&self) -> &str {
71        match self {
72            ChainNet::BitcoinMainnet => "bc",
73            ChainNet::BitcoinTestnet3 => "tb3",
74            ChainNet::BitcoinTestnet4 => "tb4",
75            ChainNet::BitcoinRegtest => "bcrt",
76            ChainNet::BitcoinSignet => "sb",
77            ChainNet::LiquidMainnet => "lq",
78            ChainNet::LiquidTestnet => "tl",
79        }
80    }
81
82    pub fn layer1(&self) -> Layer1 {
83        match self {
84            ChainNet::BitcoinMainnet
85            | ChainNet::BitcoinTestnet3
86            | ChainNet::BitcoinTestnet4
87            | ChainNet::BitcoinSignet
88            | ChainNet::BitcoinRegtest => Layer1::Bitcoin,
89            ChainNet::LiquidMainnet | ChainNet::LiquidTestnet => Layer1::Liquid,
90        }
91    }
92
93    pub fn genesis_block_hash(&self) -> BlockHash {
94        BlockHash::from_str(match self {
95            ChainNet::BitcoinMainnet => {
96                "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
97            }
98            ChainNet::BitcoinTestnet3 => {
99                "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
100            }
101            ChainNet::BitcoinTestnet4 => {
102                "00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043"
103            }
104            ChainNet::BitcoinSignet => {
105                "00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6"
106            }
107            ChainNet::BitcoinRegtest => {
108                "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"
109            }
110            ChainNet::LiquidMainnet => {
111                "4f4eac81e5f9f04f5d2a17b03e6726e6a1af69d9c3f00d820f1c82fcb6000000"
112            }
113            ChainNet::LiquidTestnet => {
114                "f9f21a7636b35c12f080ff73fc8bb16bb7c3ceafdc2eb1b673f0ea7a40c00000"
115            }
116        })
117        .unwrap()
118    }
119}
120
121#[derive(Debug, Display, Error, From)]
122#[display(doc_comments)]
123pub enum ChainNetParseError {
124    /// invalid chain-network pair {0}.
125    Invalid(String),
126}
127
128impl FromStr for ChainNet {
129    type Err = ChainNetParseError;
130
131    fn from_str(s: &str) -> Result<Self, Self::Err> {
132        match s.to_lowercase() {
133            x if ChainNet::BitcoinMainnet.prefix() == x => Ok(ChainNet::BitcoinMainnet),
134            x if ChainNet::BitcoinRegtest.prefix() == x => Ok(ChainNet::BitcoinRegtest),
135            x if ChainNet::BitcoinSignet.prefix() == x => Ok(ChainNet::BitcoinSignet),
136            x if ChainNet::BitcoinTestnet3.prefix() == x => Ok(ChainNet::BitcoinTestnet3),
137            x if ChainNet::BitcoinTestnet4.prefix() == x => Ok(ChainNet::BitcoinTestnet4),
138            x if ChainNet::LiquidMainnet.prefix() == x => Ok(ChainNet::LiquidMainnet),
139            x if ChainNet::LiquidTestnet.prefix() == x => Ok(ChainNet::LiquidTestnet),
140            _ => Err(ChainNetParseError::Invalid(s.to_owned())),
141        }
142    }
143}