Removed Hash struct, cleaned the code. Renamed Wyrd to wyrd_ns.
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "Wyrd"
|
||||
name = "wyrd_ns"
|
||||
version = "0.1.0"
|
||||
authors = ["Revertron <rev@revertron.com>"]
|
||||
edition = "2018"
|
||||
|
||||
+13
-13
@@ -4,14 +4,14 @@ extern crate num_bigint;
|
||||
extern crate num_traits;
|
||||
|
||||
use super::*;
|
||||
use rand::{thread_rng, Rng};
|
||||
use std::fmt::Debug;
|
||||
use chrono::{Utc, DateTime};
|
||||
use chrono::Utc;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use num_bigint::BigUint;
|
||||
use num_traits::One;
|
||||
use crypto::sha2::Sha512;
|
||||
use crypto::sha2::Sha256;
|
||||
use crypto::digest::Digest;
|
||||
use crate::keys::Key;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
|
||||
pub struct Block {
|
||||
@@ -24,13 +24,13 @@ pub struct Block {
|
||||
pub nonce: u64,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub transaction: Option<Transaction>,
|
||||
pub prev_block_hash: Hash,
|
||||
#[serde(skip_serializing_if = "Hash::is_default")]
|
||||
pub hash: Hash,
|
||||
pub prev_block_hash: Key,
|
||||
#[serde(default, skip_serializing_if = "Key::is_empty")]
|
||||
pub hash: Key,
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn new(index: u64, timestamp: i64, chain_id: u32, version: u32, prev_block_hash: Hash, transaction: Option<Transaction>) -> Self {
|
||||
pub fn new(index: u64, timestamp: i64, chain_id: u32, version: u32, prev_block_hash: Key, transaction: Option<Transaction>) -> Self {
|
||||
Block {
|
||||
index,
|
||||
timestamp,
|
||||
@@ -41,7 +41,7 @@ impl Block {
|
||||
nonce: 0,
|
||||
transaction,
|
||||
prev_block_hash,
|
||||
hash: Hash::default(),
|
||||
hash: Key::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,16 +60,16 @@ impl Block {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash(data: &[u8]) -> Hash {
|
||||
let mut buf: [u8; 64] = [0; 64];
|
||||
let mut digest = Sha512::new();
|
||||
pub fn hash(data: &[u8]) -> Key {
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let mut digest = Sha256::new();
|
||||
digest.input(data);
|
||||
digest.result(&mut buf);
|
||||
Hash::from_vec(&buf.to_vec())
|
||||
Key::new(buf.to_vec())
|
||||
}
|
||||
|
||||
pub fn is_genesis(&self) -> bool {
|
||||
self.index == 0 && self.transaction.is_none() && self.prev_block_hash == Hash::default()
|
||||
self.index == 0 && self.transaction.is_none() && self.prev_block_hash == Key::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
use crate::{Block, Transaction, Hash};
|
||||
use chrono::{Utc, DateTime};
|
||||
use crate::{Block, Transaction, Key};
|
||||
use chrono::Utc;
|
||||
|
||||
pub struct Blockchain {
|
||||
pub chain_id: u32,
|
||||
@@ -23,7 +23,7 @@ impl Blockchain {
|
||||
}
|
||||
|
||||
pub fn genesis(chain_id: u32, version: u32) -> Block {
|
||||
Block::new(0, Utc::now().timestamp(), chain_id, version, Hash::default(), None)
|
||||
Block::new(0, Utc::now().timestamp(), chain_id, version, Key::zero32(), None)
|
||||
}
|
||||
|
||||
pub fn add_block(&mut self, block: Block) {
|
||||
@@ -61,7 +61,7 @@ impl Blockchain {
|
||||
pub fn check_block_hash(block: &Block) -> bool {
|
||||
// We need to clear Hash value to rehash it without it for check :(
|
||||
let mut copy: Block = block.clone();
|
||||
copy.hash = Hash::default();
|
||||
copy.hash = Key::default();
|
||||
let data = serde_json::to_string(©).unwrap();
|
||||
Block::hash(data.as_bytes()) == block.hash
|
||||
}
|
||||
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
use crate::utils;
|
||||
use std::cmp::min;
|
||||
use serde::{Serialize, Deserialize, Serializer, Deserializer};
|
||||
use std::fmt;
|
||||
use serde::de::{Error as DeError, Visitor};
|
||||
use serde::ser::SerializeSeq;
|
||||
use serde::export::Formatter;
|
||||
use serde::export::fmt::Error;
|
||||
use std::ops::Deref;
|
||||
|
||||
/// A hash consisting of all zeroes, used as a constant
|
||||
pub const ZERO_HASH: Hash = Hash{ bytes: [0u8; 64]};
|
||||
|
||||
/// A hash struct
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Hash {
|
||||
bytes: [u8; 64]
|
||||
}
|
||||
|
||||
impl Hash {
|
||||
/// Size of a hash in bytes.
|
||||
const LEN: usize = 64;
|
||||
|
||||
pub fn new(bytes: [u8; 64]) -> Self {
|
||||
Hash{bytes}
|
||||
}
|
||||
|
||||
/// Builds a Hash from a byte vector. If the vector is too short, it will be
|
||||
/// completed by zeroes. If it's too long, it will be truncated.
|
||||
pub fn from_vec(v: &[u8]) -> Hash {
|
||||
let mut h = [0; Hash::LEN];
|
||||
let copy_size = min(v.len(), Hash::LEN);
|
||||
h[..copy_size].copy_from_slice(&v[..copy_size]);
|
||||
Hash::new(h)
|
||||
}
|
||||
|
||||
/// Converts the hash to a byte vector
|
||||
pub fn to_vec(&self) -> Vec<u8> {
|
||||
self.bytes.to_vec()
|
||||
}
|
||||
|
||||
/// Returns a byte slice of the hash contents.
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
&self.bytes
|
||||
}
|
||||
|
||||
/// Convert a hash to hex string format.
|
||||
pub fn to_hex(&self) -> String {
|
||||
utils::to_hex(self.to_vec().as_ref())
|
||||
}
|
||||
|
||||
pub fn is_default(&self) -> bool {
|
||||
utils::same_hash(&self.bytes, &Hash::default().bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Hash {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
|
||||
S: Serializer {
|
||||
serializer.serialize_str(&crate::utils::to_hex(&self.bytes))
|
||||
}
|
||||
}
|
||||
|
||||
struct HashVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for HashVisitor {
|
||||
type Value = Hash;
|
||||
|
||||
fn expecting(&self, formatter: &mut Formatter) -> Result<(), Error> {
|
||||
formatter.write_str("64 bytes")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> where E: DeError, {
|
||||
if v.len() == Hash::LEN {
|
||||
let mut h = [0; Hash::LEN];
|
||||
let copy_size = min(v.len(), Hash::LEN);
|
||||
h[..copy_size].copy_from_slice(&v[..copy_size]);
|
||||
Ok(Hash::new(h))
|
||||
} else {
|
||||
Err(E::custom("Hash must be 64 bytes!"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'dd> Deserialize<'dd> for Hash {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'dd>>::Error> where
|
||||
D: Deserializer<'dd> {
|
||||
deserializer.deserialize_bytes(HashVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Hash {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
utils::same_hash(&self.bytes, &other.bytes)
|
||||
}
|
||||
|
||||
fn ne(&self, other: &Self) -> bool {
|
||||
!utils::same_hash(&self.bytes, &other.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for Hash {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Hash {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let hash_hex = self.to_hex();
|
||||
const NUM_SHOW: usize = 8;
|
||||
|
||||
write!(f, "{}", &hash_hex[..NUM_SHOW])
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Hash {
|
||||
fn default() -> Hash {
|
||||
ZERO_HASH
|
||||
}
|
||||
}
|
||||
+66
-113
@@ -5,14 +5,16 @@ use rand::{thread_rng, Rng};
|
||||
use std::fs;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::io::Error as IoError;
|
||||
use serde::export::fmt::Error;
|
||||
use serde::{Serialize, Deserialize, Serializer, Deserializer};
|
||||
// For deserialization
|
||||
use serde::de::{Error as DeError, Visitor};
|
||||
use serde::export::Formatter;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Signature {
|
||||
private_key: KeyPrivate,
|
||||
public_key: KeyPublic,
|
||||
private_key: Key,
|
||||
public_key: Key,
|
||||
}
|
||||
|
||||
impl Signature {
|
||||
@@ -21,12 +23,12 @@ impl Signature {
|
||||
let mut rng = thread_rng();
|
||||
rng.fill(&mut buf);
|
||||
let (private, public) = keypair(&buf);
|
||||
Signature {private_key: KeyPrivate::new(&private), public_key: KeyPublic::new(&public)}
|
||||
Signature {private_key: Key::from_bytes(&private), public_key: Key::from_bytes(&public)}
|
||||
}
|
||||
|
||||
pub fn from_bytes(seed: &[u8]) -> Self {
|
||||
let (private, public) = keypair(&seed);
|
||||
Signature {private_key: KeyPrivate::new(&private), public_key: KeyPublic::new(&public)}
|
||||
Signature {private_key: Key::from_bytes(&private), public_key: Key::from_bytes(&public)}
|
||||
}
|
||||
|
||||
pub fn from_file(filename: &str, _password: &str) -> Option<Self> {
|
||||
@@ -40,11 +42,11 @@ impl Signature {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_public(&self) -> KeyPublic {
|
||||
pub fn get_public(&self) -> Key {
|
||||
self.public_key.clone()
|
||||
}
|
||||
|
||||
pub fn get_private(&self) -> KeyPrivate {
|
||||
pub fn get_private(&self) -> Key {
|
||||
self.private_key.clone()
|
||||
}
|
||||
|
||||
@@ -53,37 +55,53 @@ impl Signature {
|
||||
}
|
||||
|
||||
pub fn check(&self, message: &[u8], public_key: &[u8], signature: &[u8]) -> bool {
|
||||
verify(message, &self.public_key.data, signature)
|
||||
verify(message, public_key, signature)
|
||||
}
|
||||
}
|
||||
|
||||
/*impl fmt::Debug for Signature {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("Signature")
|
||||
.field("pub", &&self.public_key[..])
|
||||
.field("priv", &&self.private_key[..])
|
||||
.finish()
|
||||
}
|
||||
}*/
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct KeyPublic {
|
||||
data: [u8; 32]
|
||||
#[derive(Clone)]
|
||||
pub struct Key {
|
||||
data: Vec<u8>
|
||||
}
|
||||
|
||||
impl KeyPublic {
|
||||
pub fn new(data: &[u8]) -> Self {
|
||||
let mut buf = [0u8; 32];
|
||||
buf.copy_from_slice(data);
|
||||
KeyPublic{ data: buf }
|
||||
impl Key {
|
||||
pub fn new(data: Vec<u8>) -> Self {
|
||||
Key { data }
|
||||
}
|
||||
|
||||
pub fn from_bytes(data: &[u8]) -> Self {
|
||||
Key { data: Vec::from(data) }
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.data.is_empty()
|
||||
}
|
||||
|
||||
/// Returns a byte slice of the hash contents.
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
&self.data
|
||||
}
|
||||
|
||||
pub fn zero32() -> Self {
|
||||
Key { data: [0u8; 32].to_vec() }
|
||||
}
|
||||
|
||||
pub fn zero64() -> Self {
|
||||
Key { data: [0u8; 64].to_vec() }
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for KeyPublic {
|
||||
impl Default for Key {
|
||||
fn default() -> Key {
|
||||
Key { data: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Key {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
crate::utils::same_hash(&self.data, &other.data)
|
||||
}
|
||||
@@ -93,112 +111,47 @@ impl PartialEq for KeyPublic {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for KeyPublic {
|
||||
impl fmt::Debug for Key {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(&crate::utils::to_hex(&self.data))
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for KeyPublic {
|
||||
impl Serialize for Key {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
|
||||
S: Serializer {
|
||||
serializer.serialize_str(&crate::utils::to_hex(&self.data))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct KeyPrivate {
|
||||
data: [u8; 64]
|
||||
}
|
||||
struct KeyVisitor;
|
||||
|
||||
impl KeyPrivate {
|
||||
pub fn new(data: &[u8]) -> Self {
|
||||
let mut buf = [0u8; 64];
|
||||
buf.copy_from_slice(data);
|
||||
KeyPrivate{ data: buf }
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for KeyPrivate {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
crate::utils::same_hash(&self.data, &other.data)
|
||||
}
|
||||
|
||||
fn ne(&self, other: &Self) -> bool {
|
||||
!crate::utils::same_hash(&self.data, &other.data)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for KeyPrivate {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(&crate::utils::to_hex(&self.data))
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for KeyPrivate {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
|
||||
S: Serializer {
|
||||
serializer.serialize_str(&crate::utils::to_hex(&self.data))
|
||||
}
|
||||
}
|
||||
|
||||
use serde::de::{Error as DeError, Visitor};
|
||||
use serde::export::Formatter;
|
||||
|
||||
struct PublicVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for PublicVisitor {
|
||||
type Value = KeyPublic;
|
||||
impl<'de> Visitor<'de> for KeyVisitor {
|
||||
type Value = Key;
|
||||
|
||||
fn expecting(&self, formatter: &mut Formatter) -> Result<(), Error> {
|
||||
formatter.write_str("32 bytes")
|
||||
formatter.write_str("32 or 64 bytes")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> where E: DeError, {
|
||||
if v.len() == 32 {
|
||||
let mut h = [0; 32];
|
||||
h[..32].copy_from_slice(&v[..32]);
|
||||
Ok(KeyPublic::new(&h))
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: DeError, {
|
||||
if value.len() == 64 || value.len() == 128 {
|
||||
Ok(Key::new(crate::from_hex(value).unwrap()))
|
||||
} else {
|
||||
Err(E::custom("KeyPublic must be 32 bytes!"))
|
||||
Err(E::custom("Key must be 32 or 64 bytes!"))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> where E: DeError, {
|
||||
if value.len() == 32 || value.len() == 64 {
|
||||
Ok(Key::from_bytes(value))
|
||||
} else {
|
||||
Err(E::custom("Key must be 32 or 64 bytes!"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'dd> Deserialize<'dd> for KeyPublic {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'dd>>::Error> where
|
||||
D: Deserializer<'dd> {
|
||||
deserializer.deserialize_bytes(PublicVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
struct PrivateVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for PrivateVisitor {
|
||||
type Value = KeyPrivate;
|
||||
|
||||
fn expecting(&self, formatter: &mut Formatter) -> Result<(), Error> {
|
||||
formatter.write_str("32 bytes")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> where E: DeError, {
|
||||
if v.len() == 64 {
|
||||
let mut h = [0; 64];
|
||||
h[..64].copy_from_slice(&v[..64]);
|
||||
Ok(KeyPrivate::new(&h))
|
||||
} else {
|
||||
Err(E::custom("KeyPrivate must be 64 bytes!"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'dd> Deserialize<'dd> for KeyPrivate {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'dd>>::Error> where
|
||||
D: Deserializer<'dd> {
|
||||
deserializer.deserialize_bytes(PrivateVisitor)
|
||||
impl<'dd> Deserialize<'dd> for Key {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'dd>>::Error> where D: Deserializer<'dd> {
|
||||
deserializer.deserialize_str(KeyVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -3,10 +3,10 @@ pub use crate::block::Block;
|
||||
mod blockchain;
|
||||
pub use crate::blockchain::Blockchain;
|
||||
pub mod transaction;
|
||||
pub use crate::transaction::Action;
|
||||
pub use crate::transaction::Transaction;
|
||||
pub mod utils;
|
||||
pub use crate::utils::*;
|
||||
pub mod hash;
|
||||
pub use crate::hash::Hash;
|
||||
pub mod keys;
|
||||
pub use crate::keys::Signature;
|
||||
pub use crate::keys::Signature;
|
||||
pub use crate::keys::Key;
|
||||
+5
-3
@@ -1,5 +1,4 @@
|
||||
use Wyrd::{Blockchain, Block, Transaction, Signature, Hash};
|
||||
use Wyrd::transaction::Action;
|
||||
use wyrd_ns::{Blockchain, Block, Action, Transaction, Signature, Key};
|
||||
|
||||
fn main() {
|
||||
println!("Wyrd DNS 0.1.0");
|
||||
@@ -17,7 +16,7 @@ fn test_blockchain() -> () {
|
||||
|
||||
// Signing it with private key from Signature
|
||||
let sign_hash = signature.sign(&transaction.get_bytes());
|
||||
transaction.set_signature(Hash::new(sign_hash));
|
||||
transaction.set_signature(Key::from_bytes(&sign_hash));
|
||||
|
||||
// Creating a block with that signed transaction
|
||||
let mut block = blockchain.new_block(transaction);
|
||||
@@ -31,6 +30,9 @@ fn test_blockchain() -> () {
|
||||
blockchain.add_block(block);
|
||||
println!("Second block added");
|
||||
|
||||
let block2: Block = serde_json::from_str(&s).unwrap();
|
||||
println!("DeSerialized block:\n{:?}", block2);
|
||||
|
||||
// Let's check if the blockchain is valid
|
||||
if blockchain.check() {
|
||||
println!("Blockchain is correct");
|
||||
|
||||
+9
-10
@@ -1,4 +1,3 @@
|
||||
use super::*;
|
||||
use crate::transaction::Action::{MoveDomain, RenewDomain, ChangeDomain, NewDomain};
|
||||
use crate::keys::*;
|
||||
extern crate serde;
|
||||
@@ -7,15 +6,14 @@ extern crate serde_json;
|
||||
use serde::{Serialize, Deserialize, Serializer};
|
||||
use serde::ser::SerializeStruct;
|
||||
use std::fmt;
|
||||
use crypto::util::fixed_time_eq;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Action {
|
||||
NewDomain { name: String, owner: KeyPublic, #[serde(skip_serializing_if = "Vec::is_empty")] records: Vec<String>, #[serde(skip_serializing_if = "Vec::is_empty")] tags: Vec<String>, days: u16 },
|
||||
NewDomain { name: String, owner: Key, #[serde(default, skip_serializing_if = "Vec::is_empty")] records: Vec<String>, #[serde(default, skip_serializing_if = "Vec::is_empty")] tags: Vec<String>, days: u16 },
|
||||
ChangeDomain { name: String, records: Vec<String>, tags: Vec<String> },
|
||||
RenewDomain { name: String, days: u16 },
|
||||
MoveDomain { name: String, new_owner: KeyPublic },
|
||||
MoveDomain { name: String, new_owner: Key },
|
||||
}
|
||||
|
||||
impl Action {
|
||||
@@ -32,7 +30,7 @@ impl Action {
|
||||
}
|
||||
|
||||
pub fn move_domain(name: String, new_owner: [u8; 32]) -> Self {
|
||||
MoveDomain {name, new_owner: KeyPublic::new(&new_owner)}
|
||||
MoveDomain {name, new_owner: Key::from_bytes(&new_owner)}
|
||||
}
|
||||
|
||||
pub fn get_bytes(&self) -> Vec<u8> {
|
||||
@@ -84,16 +82,16 @@ impl fmt::Debug for Action {
|
||||
#[derive(Clone, Deserialize, PartialEq)]
|
||||
pub struct Transaction {
|
||||
pub action: Action,
|
||||
pub pub_key: KeyPublic,
|
||||
pub signature: Hash,
|
||||
pub pub_key: Key,
|
||||
pub signature: Key,
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
pub fn new(action: Action, pub_key: KeyPublic) -> Self {
|
||||
Transaction {action, pub_key, signature: Hash::new([0u8; 64])}
|
||||
pub fn new(action: Action, pub_key: Key) -> Self {
|
||||
Transaction {action, pub_key, signature: Key::zero64()}
|
||||
}
|
||||
|
||||
pub fn set_signature(&mut self, hash: Hash) {
|
||||
pub fn set_signature(&mut self, hash: Key) {
|
||||
self.signature = hash;
|
||||
}
|
||||
|
||||
@@ -106,6 +104,7 @@ impl Transaction {
|
||||
impl fmt::Debug for Transaction {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("Transaction")
|
||||
.field("action", &self.action)
|
||||
.field("pub", &&self.pub_key)
|
||||
.field("sign", &&self.signature)
|
||||
.finish()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::num;
|
||||
|
||||
/// Convert bytes array to HEX format
|
||||
pub fn to_hex(buf: &[u8]) -> String {
|
||||
@@ -8,6 +9,19 @@ pub fn to_hex(buf: &[u8]) -> String {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn from_hex(string: &str) -> Result<Vec<u8>, num::ParseIntError> {
|
||||
split_n(&string.trim()[..], 2)
|
||||
.iter()
|
||||
.map(|b| u8::from_str_radix(b, 16))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn split_n(s: &str, n: usize) -> Vec<&str> {
|
||||
(0..=(s.len() - n + 1) / 2)
|
||||
.map(|i| &s[2 * i..2 * i + n])
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// There is no default PartialEq implementation for arrays > 32 in size
|
||||
pub fn same_hash(left: &[u8], right: &[u8]) -> bool {
|
||||
for (x, y) in left.iter().zip(right) {
|
||||
|
||||
Reference in New Issue
Block a user