bitcoin/blockdata/
constants.rs

1// Rust Bitcoin Library
2// Written in 2014 by
3//     Andrew Poelstra <apoelstra@wpsoftware.net>
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! Blockdata constants
16//!
17//! This module provides various constants relating to the blockchain and
18//! consensus code. In particular, it defines the genesis block and its
19//! single transaction
20//!
21
22use std::default::Default;
23
24use blockdata::opcodes;
25use blockdata::script;
26use blockdata::transaction::{OutPoint, Transaction, TxOut, TxIn};
27use blockdata::block::{GenesisBlock, BlockHeader};
28use network::constants::Network;
29use util::misc::hex_bytes;
30use util::hash::MerkleRoot;
31use util::uint::Uint256;
32
33/// The maximum allowable sequence number
34pub static MAX_SEQUENCE: u32 = 0xFFFFFFFF;
35/// How many satoshis are in "one bitcoin"
36pub static COIN_VALUE: u64 = 100_000_000;
37/// How many seconds between blocks we expect on average
38pub static TARGET_BLOCK_SPACING: u32 = 60;
39/// How many blocks between diffchanges
40pub static DIFFCHANGE_INTERVAL: u32 = 360;
41/// How much time on average should occur between diffchanges
42pub static DIFFCHANGE_TIMESPAN: u32 = 6 * 60 * 60;
43
44/// In Bitcoind this is insanely described as ~((u256)0 >> 32)
45pub fn max_target(_: Network) -> Uint256 {
46    Uint256::from_u64(0xFFFF).unwrap() << 208
47}
48
49/// The maximum value allowed in an output (useful for sanity checking,
50/// since keeping everything below this value should prevent overflows
51/// if you are doing anything remotely sane with monetary values).
52pub fn max_money(_: Network) -> u64 {
53    888_000_000 * COIN_VALUE
54}
55
56/// Constructs and returns the coinbase (and only) transaction of the Bitcoin genesis block
57fn bitcoin_genesis_tx() -> Transaction {
58    // Base
59    let mut ret = Transaction {
60        version: 1,
61        lock_time: 0,
62        input: vec![],
63        output: vec![],
64    };
65
66    // Inputs
67    let in_script = script::Builder::new().push_scriptint(486604799)
68                                          .push_scriptint(4)
69                                          .push_slice(b"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks")
70                                          .into_script();
71    ret.input.push(TxIn {
72        previous_output: OutPoint::null(),
73        script_sig: in_script,
74        sequence: MAX_SEQUENCE,
75        witness: vec![],
76    });
77
78    // Outputs
79    let out_script = script::Builder::new()
80        .push_slice(&hex_bytes("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f").unwrap())
81        .push_opcode(opcodes::all::OP_CHECKSIG)
82        .into_script();
83    ret.output.push(TxOut {
84        value: 50 * COIN_VALUE,
85        script_pubkey: out_script
86    });
87
88    // end
89    ret
90}
91
92/// Constructs and returns the genesis block
93pub fn genesis_block(network: Network) -> GenesisBlock {
94    match network {
95        Network::Bitcoin => {
96            let txdata = vec![bitcoin_genesis_tx()];
97            GenesisBlock {
98                header: BlockHeader {
99                    version: 1,
100                    prev_blockhash: Default::default(),
101                    merkle_root: txdata.merkle_root(),
102                    time: 1549246364,
103                    bits: 0x1e0ffff0,
104                    nonce: 204673
105                },
106                txdata: txdata
107            }
108        }
109        Network::Testnet => {
110            let txdata = vec![bitcoin_genesis_tx()];
111            GenesisBlock {
112                header: BlockHeader {
113                    version: 1,
114                    prev_blockhash: Default::default(),
115                    merkle_root: txdata.merkle_root(),
116                    time: 1544509441,
117                    bits: 0x1e0ffff0,
118                    nonce: 167093
119                },
120                txdata: txdata
121            }
122        }
123        Network::Regtest => {
124            let txdata = vec![bitcoin_genesis_tx()];
125            GenesisBlock {
126                header: BlockHeader {
127                    version: 1,
128                    prev_blockhash: Default::default(),
129                    merkle_root: txdata.merkle_root(),
130                    time: 1544509441,
131                    bits: 0x207fffff,
132                    nonce: 1
133                },
134                txdata: txdata
135            }
136        }
137    }
138}
139
140#[cfg(test)]
141mod test {
142    use std::default::Default;
143    use hex::decode as hex_decode;
144
145    use network::constants::Network;
146    use consensus::encode::serialize;
147    use blockdata::constants::{genesis_block, bitcoin_genesis_tx};
148    use blockdata::constants::{MAX_SEQUENCE, COIN_VALUE};
149    use util::hash::BitcoinHash;
150
151    #[test]
152    fn bitcoin_genesis_first_transaction() {
153        let gen = bitcoin_genesis_tx();
154
155        assert_eq!(gen.version, 1);
156        assert_eq!(gen.input.len(), 1);
157        assert_eq!(gen.input[0].previous_output.txid, Default::default());
158        assert_eq!(gen.input[0].previous_output.vout, 0xFFFFFFFF);
159        assert_eq!(serialize(&gen.input[0].script_sig),
160                   hex_decode("4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73").unwrap());
161
162        assert_eq!(gen.input[0].sequence, MAX_SEQUENCE);
163        assert_eq!(gen.output.len(), 1);
164        assert_eq!(serialize(&gen.output[0].script_pubkey),
165                   hex_decode("434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac").unwrap());
166        assert_eq!(gen.output[0].value, 50 * COIN_VALUE);
167        assert_eq!(gen.lock_time, 0);
168
169        assert_eq!(format!("{:x}", gen.bitcoin_hash()),
170                   "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b".to_string());
171    }
172
173    #[test]
174    fn bitcoin_genesis_full_block() {
175        let gen = genesis_block(Network::Bitcoin);
176
177        assert_eq!(gen.header.version, 1);
178        assert_eq!(gen.header.prev_blockhash, Default::default());
179        assert_eq!(format!("{:x}", gen.header.merkle_root),
180                   "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b".to_string());
181        assert_eq!(gen.header.time, 1549246364);
182        assert_eq!(gen.header.bits, 0x1e0ffff0);
183        assert_eq!(gen.header.nonce, 204673);
184        assert_eq!(format!("{:x}", gen.header.bitcoin_hash()),
185                   "0000052c0f76a21b6313429a74fbc75a409833b6e501ab7c09c463db32adab41".to_string());
186    }
187
188    #[test]
189    fn testnet_genesis_full_block() {
190        let gen = genesis_block(Network::Testnet);
191        assert_eq!(gen.header.version, 1);
192        assert_eq!(gen.header.prev_blockhash, Default::default());
193        assert_eq!(format!("{:x}", gen.header.merkle_root),
194                  "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b".to_string());
195        assert_eq!(gen.header.time, 1544509441);
196        assert_eq!(gen.header.bits, 0x1e0ffff0);
197        assert_eq!(gen.header.nonce, 167093);
198        assert_eq!(format!("{:x}", gen.header.bitcoin_hash()),
199                   "00000199b49877c0e552f25462a80ef421fd2a15c7f5978683adc2b6b5c5ea02".to_string());
200    }
201}
202