1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
// Copyright (C) 2019-2022 Aleo Systems Inc.
// This file is part of the snarkVM library.
// The snarkVM library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The snarkVM library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the snarkVM library. If not, see <https://www.gnu.org/licenses/>.
use super::*;
use crate::ProgramStorage;
impl<N: Network> Block<N> {
/// Initializes a new genesis block.
pub fn genesis<P: ProgramStorage<N>, R: Rng + CryptoRng>(
vm: &VM<N, P>,
private_key: &PrivateKey<N>,
rng: &mut R,
) -> Result<Self> {
// Prepare the caller.
let caller = Address::try_from(private_key)?;
// Prepare the program ID.
let program_id = FromStr::from_str("credits.aleo")?;
// Prepare the function name.
let function_name = FromStr::from_str("genesis")?;
// Prepare the function inputs.
let inputs = [Value::from_str(&caller.to_string())?, Value::from_str("1_100_000_000_000_000_u64")?];
// Authorize the call to start.
let authorization = vm.authorize(private_key, &program_id, function_name, &inputs, rng)?;
// Execute the genesis function.
let transaction = Transaction::execute_authorization(vm, authorization, rng)?;
// Prepare the transactions.
let transactions = Transactions::from(&[transaction]);
// Prepare the block header.
let header = Header::genesis(&transactions)?;
// Prepare the previous block hash.
let previous_hash = N::BlockHash::default();
// Construct the block.
let block = Self::new(private_key, previous_hash, header, transactions, rng)?;
// Ensure the block is valid genesis block.
match block.is_genesis() {
true => Ok(block),
false => bail!("Failed to initialize a genesis block"),
}
}
/// Returns `true` if the block is a genesis block.
pub fn is_genesis(&self) -> bool {
// Ensure the previous block hash is zero.
self.previous_hash == N::BlockHash::default()
// Ensure the header is a genesis block header.
&& self.header.is_genesis()
// Ensure there is 1 transaction in the genesis block.
&& self.transactions.len() == 1
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_genesis() {
let block = crate::ledger::test_helpers::sample_genesis_block();
// println!("{}", serde_json::to_string_pretty(&block).unwrap());
assert!(block.is_genesis());
}
}