#![allow(unused_imports)]
use k256::{
ecdsa::{signature::Signer, Signature, SigningKey}, elliptic_curve::sec1::ToEncodedPoint, PublicKey, SecretKey
};
use sha3::*;
use serde::*;
use std::{hash::Hash, io::Read};
pub type Txid = [u8; 32];
pub const EMPTY_TXID: Txid = [0; 32];
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct TxOutput {
pub spender: TxPredicate,
pub amount: u64,
pub recipient: PublicKey,
}
#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, Debug)]
pub struct Outpoint(pub Txid, pub u16);
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct TxInput {
pub signature: Signature,
pub prev_out: Outpoint,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct Tx {
pub inputs: Vec<TxInput>,
pub outputs: Vec<TxOutput>,
pub txid: Txid,
pub signature: Signature,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub enum TxPredicate {
Pubkey(PublicKey)
}
impl TxPredicate {
pub fn unwrap_key(&self) -> &PublicKey {
match &self {
TxPredicate::Pubkey(key) => &key,
}
}
}
impl TxInput {
pub fn as_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend_from_slice(&self.prev_out.0);
bytes.extend_from_slice(&self.prev_out.1.to_be_bytes());
bytes
}
}
impl TxOutput {
pub fn as_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
match &self.spender {
TxPredicate::Pubkey(key) => {
bytes.extend_from_slice(&key.to_encoded_point(false).as_bytes());
}
}
bytes.extend_from_slice(&self.amount.to_be_bytes());
bytes
}
}
impl Hash for TxOutput {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_bytes().hash(state);
}
}
impl Tx {
pub fn as_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
for input in &self.inputs {
bytes.extend_from_slice(&input.as_bytes());
}
for output in &self.outputs {
bytes.extend_from_slice(&output.as_bytes());
}
bytes.extend_from_slice(&self.signature.to_bytes());
bytes.extend_from_slice(&self.txid);
bytes
}
pub fn get_txid(&self) -> Txid {
let mut bytes = Vec::new();
for input in &self.inputs {
bytes.extend_from_slice(&input.as_bytes());
}
for output in &self.outputs {
bytes.extend_from_slice(&output.as_bytes());
}
let mut hasher = Sha3_256::new();
hasher.update(bytes);
hasher.finalize().into()
}
pub fn new() -> Self {
Self {
inputs: Vec::new(),
outputs: Vec::new(),
txid: EMPTY_TXID,
signature: Signature::from_slice(&[128u8; 64]).unwrap(),
}
}
}
impl Hash for Tx {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_bytes().hash(state);
}
}
impl Outpoint {
pub fn as_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend_from_slice(&self.0);
bytes.extend_from_slice(&self.1.to_be_bytes());
bytes
}
}