compressed_transactions 1.0.0

A crate that exposes a command-line interface for compressing bitcoin transactions, and a library that exposes a CompressedTransaction structure and its required subclasses.
Documentation
use bitcoin::consensus::{Encodable, Decodable};
use bitcoincore_rpc::{Auth, Client};
use bitcoin::Transaction;
use std::env;

mod error;
use crate::error::{Error};

mod util;

mod compressed_transaction;
use crate::compressed_transaction::{CompressedTransaction};

mod compress_outpoints;
use crate::compress_outpoints::{compress_outpoints, decompress_outpoints};


fn main() -> Result<(), Error> {
    let args: Vec<String> = env::args().collect();

    let mut rpc_username = "";
    let mut rpc_password = "";
    let mut rpc_port = "8332";

    let mut parameters = vec![];

    for arg in &args[1..args.len()] {
        if &arg[0..2] == "--" {
            let split = arg[2..].split('=').collect::<Vec<&str>>();
            if split.len() != 2 { return Err(Error::UnknownArgument(arg.to_string())); }
            match split[0] {
                "rpcuser" => rpc_username = split[1],
                "rpcpassword" => rpc_password = split[1],
                "rpcport" => rpc_port = split[1],
                _ => { return Err(Error::UnknownArgument(arg.to_string())); }
            }
        } else {
            parameters.push(arg);
        }
    }

    let rpc = Client::new(&("http://localhost:".to_owned()+rpc_port), Auth::UserPass(rpc_username.to_string(), rpc_password.to_string()))?;

    if parameters.len() != 2 { return Err(Error::HelpMessage()); }

    match parameters[0].as_str() {
        "compressrawtransaction" => {
            let hex_bytes: Vec<u8> = hex::decode(parameters[1]).or(Err(Error::InvalidHex(parameters[1].to_string())))?;
            let transaction: Transaction = Transaction::consensus_decode(&mut hex_bytes.as_slice()).or(Err(Error::InvalidHex(parameters[1].to_string())))?;
            let (minimum_height, compressed_inputs) = compress_outpoints(&rpc, &transaction, true)?;
            let ctx: CompressedTransaction = CompressedTransaction::compress(&transaction, minimum_height, &compressed_inputs)?;
            let mut stream: Vec<u8> = vec![];
            _ = ctx.consensus_encode(&mut stream)?;
            println!("{}", hex::encode(stream));
            Ok(())
        },
        "decompressrawtransaction" => {
            let hex_bytes: Vec<u8> = hex::decode(parameters[1]).or(Err(Error::InvalidHex(parameters[1].to_string())))?;
            let ctx: CompressedTransaction = CompressedTransaction::consensus_decode(&mut hex_bytes.as_slice()).or(Err(Error::InvalidHex(parameters[1].to_string())))?;
            let out_tup = decompress_outpoints(&rpc, ctx.minimum_height(), ctx.input())?;
            let utx: Transaction = ctx.decompress(&out_tup)?;
            let mut stream: Vec<u8> = vec![];
            _ = utx.consensus_encode(&mut stream)?;
            println!("{}", hex::encode(stream));
            Ok(())
        },
        m => Err(Error::UnknownMethod(m.to_string()))
    }
}