-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
contract checking tx inclusion in block
- Loading branch information
1 parent
1542a05
commit d25ede2
Showing
6 changed files
with
163 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
mod escrow; | ||
mod orderbook; | ||
mod utils; | ||
mod relay; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
mod relay; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use utils::hash::Digest; | ||
use utu_relay::bitcoin::block::BlockHeader; | ||
|
||
#[starknet::interface] | ||
pub trait IBitcoinDepositor<TContractState> { | ||
fn prove_inclusion( | ||
ref self: TContractState, | ||
tx_id: Digest, | ||
block_height: u64, | ||
block_header: BlockHeader, | ||
tx_inclusion: Array<(Digest, bool)> | ||
); | ||
} | ||
|
||
#[starknet::contract] | ||
mod BitcoinDepositor { | ||
use onchain::utils::utils::compute_merkle_root; | ||
use utu_relay::bitcoin::block::BlockHashTrait; | ||
use starknet::{ContractAddress, get_block_timestamp}; | ||
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; | ||
use utils::{hash::Digest, numeric::u32_byte_reverse}; | ||
use utu_relay::{ | ||
interfaces::{IUtuRelayDispatcher, IUtuRelayDispatcherTrait}, bitcoin::block::BlockHeader | ||
}; | ||
|
||
#[storage] | ||
struct Storage { | ||
depositor: ContractAddress, | ||
utu_address: ContractAddress, | ||
} | ||
|
||
#[constructor] | ||
fn constructor(ref self: ContractState, utu_address: ContractAddress) { | ||
self.utu_address.write(utu_address); | ||
} | ||
|
||
#[abi(embed_v0)] | ||
impl BitcoinDepositorImpl of super::IBitcoinDepositor<ContractState> { | ||
fn prove_inclusion( | ||
ref self: ContractState, | ||
tx_id: Digest, | ||
block_height: u64, | ||
block_header: BlockHeader, | ||
tx_inclusion: Array<(Digest, bool)> | ||
) { | ||
// we verify this tx is included in the provided block | ||
let merkle_root = compute_merkle_root(tx_id, tx_inclusion); | ||
assert( | ||
block_header.merkle_root_hash.value == merkle_root.value, 'Invalid inclusion proof.' | ||
); | ||
|
||
// we verify this block is safe to use (part of the canonical chain & sufficient pow) | ||
// sufficient pow for our usecase: 100 sextillion expected hashes | ||
let utu = IUtuRelayDispatcher { contract_address: self.utu_address.read() }; | ||
utu.assert_safe(block_height, block_header.hash(), 100_000_000_000_000_000_000_000, 0); | ||
// we ensure this block was not premined | ||
let block_time = u32_byte_reverse(block_header.time).into(); | ||
assert(block_time <= get_block_timestamp(), 'Block comes from the future.'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,37 @@ | ||
use utils::hash::Digest; | ||
use utils::double_sha256::double_sha256_parent; | ||
|
||
/// Computes the Merkle root from a transaction hash and its siblings. | ||
/// | ||
/// Arguments: | ||
/// - `tx_hash: Digest`: The transaction hash as a Digest | ||
/// - `siblings: Array<(Digest, bool)>`: An array of tuples (Digest, bool), where the bool indicates if the sibling is on | ||
/// the right | ||
/// | ||
/// Returns: | ||
/// - `Digest`: The computed Merkle root as a Digest | ||
pub fn compute_merkle_root(tx_hash: Digest, siblings: Array<(Digest, bool)>) -> Digest { | ||
let mut current_hash = tx_hash; | ||
|
||
// Iterate through all siblings | ||
let mut i = 0; | ||
loop { | ||
if i == siblings.len() { | ||
break; | ||
} | ||
|
||
let (sibling, is_left) = *siblings.at(i); | ||
|
||
// Concatenate current_hash and sibling based on the order | ||
current_hash = | ||
if is_left { | ||
double_sha256_parent(@sibling, @current_hash) | ||
} else { | ||
double_sha256_parent(@current_hash, @sibling) | ||
}; | ||
|
||
i += 1; | ||
}; | ||
|
||
current_hash | ||
} |