@@ -5,7 +5,9 @@
using System.Security.Cryptography;
using System.Text;
using MemeIum.Misc;
using MemeIum.Misc.Transaction;
using MemeIum.Requests;
using MemeIum.Services.Blockchain;
using MemeIum.Services.Eventmanagger;
using Newtonsoft.Json;

@@ -17,21 +19,24 @@ class TransactionVerifier : ITransactionVerifier

private string _unspentDbFullPath;
private SQLiteConnection _unspentConnection;
private readonly IBlockChainService _blockChainService;

public TransactionVerifier()
{
_logger = Services.GetService<ILogger>();
_unspentDbFullPath = $"{Configurations.CurrentPath}\\BlockChain\\Data\\Unspent.sqlite";

var ev = Services.GetService<IEventManager>();
ev.RegisterEventListener(OnNewBlock,EventTypes.EventType.NewBlock);
ev.RegisterEventListener(OnNewBlock,EventTypes.EventType.NewVerifiedBlock);

_blockChainService = Services.GetService<IBlockChainService>();

TryConnectToUnspentDB();
}

public void CreateBaseDb()
{
string sql = @"CREATE TABLE unspent (id varchar(50) PRIMARY KEY,fromaddr varchar(50),toaddr varchar(50),amount varchar(70))";
string sql = @"CREATE TABLE unspent (id varchar(50) PRIMARY KEY,fromaddr varchar(50),toaddr varchar(50),amount varchar(70),inblock varchar(50));";
var cmd = _unspentConnection.CreateCommand();
cmd.CommandText = sql;

@@ -41,6 +46,21 @@ public void CreateBaseDb()
public void OnNewBlock(object obj)
{
var block = (Block) obj;
foreach (var transaction in block.Body.Tx)
{
foreach (var vout in transaction.Body.VOuts)
{
RegisterVout(vout);
}
}

}

public void RegisterVout(TransactionVOut vout)
{
var cmd = vout.CreateInsertCommand();
cmd.Connection = _unspentConnection;
cmd.ExecuteNonQuery();
}

public void TryConnectToUnspentDB()
@@ -66,8 +86,23 @@ public void TryConnectToUnspentDB()
}
}

public TransactionVOut GetUnspeTransactionVOut(string id)
{
var sql = "SELECT * FROM unspent WHERE id=$id";
var cmd = _unspentConnection.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("id", id);
var reader = cmd.ExecuteReader();
if (reader.FieldCount != 1)
{
return null;
}

reader.Read();
return TransactionVOut.GetVoutFromSqlReader(reader);
}

public bool Verify(TransactionRequest transaction)
public bool Verify(Transaction transaction)
{
var ss = JsonConvert.SerializeObject(transaction);

@@ -81,41 +116,58 @@ public bool Verify(TransactionRequest transaction)
return false;
}

if (!VerifyAddress(transaction))
{
return false;
}

if (!VerifyId(transaction))
{
return false;
}


foreach (var vin in transaction.Body.VInputs)
{
TransactionVOut vout;
if (!VerifyVInAsUnspent(vin, transaction, out vout))
{
return false;
}
}

return true;
}

public bool VerifyAddress(Transaction transaction)
{
var hash = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(transaction.Body.PubKey));
var hashString = Convert.ToBase64String(hash);
return hashString == transaction.Body.FromAddress;
}

public bool VerifyVoutAsUnspent(TransactionVOut vout,TransactionRequest transaction)
public bool VerifyVInAsUnspent(TransactionVIn vin, Transaction transaction,out TransactionVOut vout)
{
if (vout.ToAddress != transaction.Body.FromAddress)

vout = GetUnspeTransactionVOut(vin.OutputId);
if (vout == null)
{
return false;
}

var sql = "SELECT * FROM unspent WHERE id=$id";
var cmd = _unspentConnection.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("id", vout.Id);
var reader = cmd.ExecuteReader();
if (reader.FieldCount != 1)
if (vin.FromBlockId != vout.FromBlock)
{
return false;
}
reader.Read();
var samerecepients = vout.ToAddress == reader["toaddr"].ToString() &&
vout.FromAddress == reader["fromaddr"].ToString();

if (samerecepients &&reader[])
if (!_blockChainService.IsBlockInLongestChain(vout.FromBlock))
{

return false;
}

return true;
}

public bool VerifyId(TransactionRequest transaction)
public bool VerifyId(Transaction transaction)
{
var id = transaction.Body.TransactionId;
transaction.Body.TransactionId = "42";
@@ -125,7 +177,7 @@ public bool VerifyId(TransactionRequest transaction)
return hash == id;
}

public bool VerifySignature(TransactionRequest transaction)
public bool VerifySignature(Transaction transaction)
{
var pTokens = transaction.Body.PubKey.Split(' ');
var pubKey = new RSAParameters();
@@ -5,6 +5,7 @@
using System.Net.Sockets;
using System.Text;
using MemeIum.Misc;
using MemeIum.Misc.Transaction;
using MemeIum.Requests;

namespace MemeIum.Services
@@ -95,9 +96,26 @@ public void ParseGetAddressesRequest(GetAddressesRequest request, Peer source)
_server.SendResponse(response,source);
}

public void Broadcast()
public void Broadcast(object data)
{
var invit = new InvitationRequest();
if (data.GetType() == typeof(Transaction))
{
invit.IsBlock = false;
}
else if (data.GetType() == typeof(Block))
{
invit.IsBlock = true;
}
else
{
return;
}

foreach (var peer in Peers)
{
_server.SendResponse(invit,peer);
}
}

}
@@ -5,6 +5,7 @@
using System.Reflection.Metadata;
using System.Text;
using MemeIum.Misc;
using MemeIum.Misc.Transaction;
using MemeIum.Requests;
using MemeIum.Services.Blockchain;
using MemeIum.Services.Wallet;
@@ -51,14 +52,13 @@ public void MockTest1()
var ww = Services.GetService<IWalletService>();

var genesis = new Block();
genesis.TimeOfCreation = DateTime.Now;
genesis.TimeOfCreation = DateTime.UtcNow;
genesis.Body = new BlockBody();
genesis.Body.Height = 0;
genesis.Body.LastBlockId = "0";
genesis.Body.MinedByAddress = ww.Address;
genesis.Body.Target = 0;
genesis.Body.Nounce = "42";
genesis.Body.Tx = new List<TransactionRequest>();
genesis.Body.Tx = new List<Transaction>();
Block.SetUniqueBlockId(genesis);
var bb1 = new TransactionBody(){FromAddress = "+Je/HCsw1/oOmTUP+OqzQSrgC/mJc+Pe1UyYLKvE4wU=",
Message = "Initial coin offer.",
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Text;
using MemeIum.Misc;
using MemeIum.Misc.Transaction;
using MemeIum.Requests;

namespace MemeIum.Services.Wallet
@@ -10,6 +11,6 @@ interface IWalletService
{
string Address { get;}
string PubKey { get; }
TransactionRequest MakeTransaction(TransactionBody body);
Transaction MakeTransaction(TransactionBody body);
}
}
@@ -4,6 +4,7 @@
using System.Security.Cryptography;
using System.Text;
using MemeIum.Misc;
using MemeIum.Misc.Transaction;
using MemeIum.Requests;
using Newtonsoft.Json;

@@ -118,14 +119,14 @@ public bool TryLoadSavedKeys()
return false;
}

public TransactionRequest MakeTransaction(TransactionBody body)
public Transaction MakeTransaction(TransactionBody body)
{
var bod = JsonConvert.SerializeObject(body);
var bbytes = Encoding.UTF8.GetBytes(bod);
var sign = _provider.SignData(bbytes, new SHA256CryptoServiceProvider());
var signString = Convert.ToBase64String(sign);

var req = new TransactionRequest()
var req = new Transaction()
{
Body = body,
Signature = signString