ab_system_contract_block/
lib.rs

1#![no_std]
2
3use ab_contracts_common::ContractError;
4use ab_contracts_common::env::Env;
5use ab_contracts_macros::contract;
6use ab_core_primitives::address::Address;
7use ab_core_primitives::block::{BlockHash, BlockNumber};
8use ab_io_type::trivial_type::TrivialType;
9
10#[derive(Debug, Copy, Clone, TrivialType)]
11#[repr(C)]
12pub struct Block {
13    pub number: BlockNumber,
14    pub parent_hash: BlockHash,
15}
16
17// TODO: Probably maintain a history of recent block headers and allow to extract them
18#[contract]
19impl Block {
20    /// Initialize block state at genesis
21    #[init]
22    pub fn genesis() -> Self {
23        Self {
24            number: BlockNumber::ZERO,
25            parent_hash: BlockHash::default(),
26        }
27    }
28
29    /// Initialize new block
30    #[update]
31    pub fn initialize(
32        &mut self,
33        #[env] env: &mut Env<'_>,
34        #[input] &parent_hash: &BlockHash,
35    ) -> Result<(), ContractError> {
36        // Only execution environment can make a direct call here
37        if env.caller() != Address::NULL {
38            return Err(ContractError::Forbidden);
39        }
40
41        *self = Self {
42            number: self.number + BlockNumber::ONE,
43            parent_hash,
44        };
45
46        Ok(())
47    }
48
49    #[view]
50    pub fn get(&self) -> Self {
51        *self
52    }
53}