use std::default::Default;
use hashes::hex::FromHex;
use hashes::sha256d;
use blockdata::opcodes;
use blockdata::script;
use blockdata::transaction::{OutPoint, Transaction, TxOut, TxIn};
use blockdata::block::{Block, BlockHeader};
use network::constants::Network;
use util::uint::Uint256;
pub const MAX_SEQUENCE: u32 = 0xFFFFFFFF;
pub const COIN_VALUE: u64 = 100_000_000;
pub const TARGET_BLOCK_SPACING: u32 = 600;
pub const DIFFCHANGE_INTERVAL: u32 = 2016;
pub const DIFFCHANGE_TIMESPAN: u32 = 14 * 24 * 3600;
pub const MAX_BLOCK_WEIGHT: u32 = 4_000_000;
pub const MIN_TRANSACTION_WEIGHT: u32 = 4 * 60;
pub const WITNESS_SCALE_FACTOR: usize = 4;
pub fn max_target(_: Network) -> Uint256 {
Uint256::from_u64(0xFFFF).unwrap() << 208
}
pub fn max_money(_: Network) -> u64 {
105_120_000 * COIN_VALUE
}
fn bitcoin_genesis_tx() -> Transaction {
let mut ret = Transaction {
version: 1,
lock_time: 0,
input: vec![],
output: vec![],
};
let in_script = script::Builder::new().push_scriptint(486604799)
.push_scriptint(4)
.push_slice(b"Dec. 31th 2013 Japan, The winning numbers of the 2013 Year-End Jumbo Lottery:23-130916")
.into_script();
ret.input.push(TxIn {
previous_output: OutPoint::null(),
script_sig: in_script,
sequence: MAX_SEQUENCE,
witness: vec![],
});
let out_script = script::Builder::new()
.push_slice(&Vec::from_hex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9").unwrap())
.push_opcode(opcodes::all::OP_CHECKSIG)
.into_script();
ret.output.push(TxOut {
value: 50 * COIN_VALUE,
script_pubkey: out_script
});
ret
}
pub fn genesis_block(network: Network) -> Block {
let txdata = vec![bitcoin_genesis_tx()];
let hash: sha256d::Hash = txdata[0].txid().into();
let merkle_root = hash.into();
match network {
Network::Monacoin => {
Block {
header: BlockHeader {
version: 1,
prev_blockhash: Default::default(),
merkle_root,
time: 1388479472,
bits: 0x1e0ffff0,
nonce: 1234534
},
txdata: txdata
}
}
Network::MonacoinTestnet => {
Block {
header: BlockHeader {
version: 1,
prev_blockhash: Default::default(),
merkle_root,
time: 1488924140,
bits: 0x1e0ffff0,
nonce: 2122860
},
txdata: txdata
}
}
Network::MonacoinRegtest => {
Block {
header: BlockHeader {
version: 1,
prev_blockhash: Default::default(),
merkle_root,
time: 1296688602,
bits: 0x207fffff,
nonce: 1
},
txdata: txdata
}
}
}
}
#[cfg(test)]
mod test {
use std::default::Default;
use hashes::hex::FromHex;
use network::constants::Network;
use consensus::encode::serialize;
use blockdata::constants::{genesis_block, bitcoin_genesis_tx};
use blockdata::constants::{MAX_SEQUENCE, COIN_VALUE};
#[test]
fn bitcoin_genesis_first_transaction() {
let gen = bitcoin_genesis_tx();
assert_eq!(gen.version, 1);
assert_eq!(gen.input.len(), 1);
assert_eq!(gen.input[0].previous_output.txid, Default::default());
assert_eq!(gen.input[0].previous_output.vout, 0xFFFFFFFF);
assert_eq!(serialize(&gen.input[0].script_sig),
Vec::from_hex("5f04ffff001d01044c564465632e20333174682032303133204a6170616e2c205468652077696e6e696e67206e756d62657273206f6620746865203230313320596561722d456e64204a756d626f204c6f74746572793a32332d313330393136").unwrap());
assert_eq!(gen.input[0].sequence, MAX_SEQUENCE);
assert_eq!(gen.output.len(), 1);
assert_eq!(serialize(&gen.output[0].script_pubkey),
Vec::from_hex("4341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac").unwrap());
assert_eq!(gen.output[0].value, 50 * COIN_VALUE);
assert_eq!(gen.lock_time, 0);
assert_eq!(format!("{:x}", gen.wtxid()),
"35e405a8a46f4dbc1941727aaf338939323c3b955232d0317f8731fe07ac4ba6".to_string());
}
#[test]
fn bitcoin_genesis_full_block() {
let gen = genesis_block(Network::Monacoin);
assert_eq!(gen.header.version, 1);
assert_eq!(gen.header.prev_blockhash, Default::default());
assert_eq!(format!("{:x}", gen.header.merkle_root),
"35e405a8a46f4dbc1941727aaf338939323c3b955232d0317f8731fe07ac4ba6".to_string());
assert_eq!(gen.header.time, 1388479472);
assert_eq!(gen.header.bits, 0x1e0ffff0);
assert_eq!(gen.header.nonce, 1234534);
assert_eq!(format!("{:x}", gen.header.block_hash()),
"ff9f1c0116d19de7c9963845e129f9ed1bfc0b376eb54fd7afa42e0d418c8bb6".to_string());
}
#[test]
fn testnet_genesis_full_block() {
let gen = genesis_block(Network::MonacoinTestnet);
assert_eq!(gen.header.version, 1);
assert_eq!(gen.header.prev_blockhash, Default::default());
assert_eq!(format!("{:x}", gen.header.merkle_root),
"35e405a8a46f4dbc1941727aaf338939323c3b955232d0317f8731fe07ac4ba6".to_string());
assert_eq!(gen.header.time, 1488924140);
assert_eq!(gen.header.bits, 0x1e0ffff0);
assert_eq!(gen.header.nonce, 2122860);
assert_eq!(format!("{:x}", gen.header.block_hash()),
"a2b106ceba3be0c6d097b2a6a6aacf9d638ba8258ae478158f449c321061e0b2".to_string());
}
}