/**
* Novacoin classes library
* Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
using SQLite.Net;
using SQLite.Net.Attributes;
using SQLite.Net.Interop;
using SQLite.Net.Platform.Generic;
using System.IO;
using System.Linq;
namespace Novacoin
{
///
/// Key storage item and structure
///
[Table("KeyStorage")]
class KeyStorageItem
{
///
/// Key item number
///
[PrimaryKey, AutoIncrement]
public int ItemId { get; set; }
///
/// Hash160 of pubkey
///
public byte[] KeyID { get; set; }
///
/// Public key
///
public byte[] PublicKey { get; set; }
///
/// Private key
///
public byte[] PrivateKey { get; set; }
///
/// Compressed key flag
///
public bool IsCompressed { get; set; }
///
/// Is this key a part of KeyPool?
///
[Indexed]
public bool IsUsed { get; set; }
///
/// Item creation time
///
[Indexed]
public int nTime { get; set; }
}
///
/// Script storage item and structure
///
[Table("ScriptStorage")]
class ScriptStorageItem
{
///
/// Script item number
///
[PrimaryKey, AutoIncrement]
public int ItemId { get; set; }
///
/// Hash160 of script
///
public byte[] ScriptID { get; set; }
///
/// Script code bytes
///
public byte[] ScriptCode { get; set; }
}
///
/// select count(...) as Count from ... where ...
///
class CountQuery
{
public int Count { get; set; }
}
public class CKeyStore
{
private object LockObj = new object();
private SQLiteConnection dbConn = null;
public CKeyStore(string strDatabasePath="KeyStore.db")
{
bool firstInit = File.Exists(strDatabasePath);
dbConn = new SQLiteConnection(new SQLitePlatformGeneric(), strDatabasePath);
if (!firstInit)
{
lock(LockObj)
{
dbConn.CreateTable(CreateFlags.AutoIncPK);
dbConn.CreateTable(CreateFlags.AutoIncPK);
dbConn.BeginTransaction();
// Generate keys
for (int i = 0; i < 1000; i++)
{
var keyPair = new CKeyPair();
var res = dbConn.Insert(new KeyStorageItem()
{
KeyID = keyPair.KeyID.hashBytes,
PublicKey = keyPair.PublicBytes,
PrivateKey = keyPair.SecretBytes,
IsCompressed = keyPair.IsCompressed,
IsUsed = false,
nTime = Interop.GetTime()
});
// TODO: Additional initialization
}
dbConn.Commit();
}
}
}
~CKeyStore()
{
if (dbConn != null)
{
dbConn.Close();
dbConn = null;
}
}
///
/// Insert key data into table
///
/// CKeyPair instance
/// Result
public bool AddKey(CKeyPair keyPair)
{
lock(LockObj)
{
var res = dbConn.Insert(new KeyStorageItem()
{
KeyID = keyPair.KeyID.hashBytes,
PublicKey = keyPair.PublicBytes,
PrivateKey = keyPair.SecretBytes,
IsCompressed = keyPair.IsCompressed,
IsUsed = true,
nTime = Interop.GetTime()
});
if (res == 0)
{
return false;
}
}
return true;
}
public bool HaveKey(CKeyID keyID)
{
var QueryCount = dbConn.Query("select count([ItemID]) as [Count] from [KeyStorage] where [KeyID] = ?", keyID.hashBytes);
return QueryCount.First().Count == 1;
}
///
/// Get the key pair object.
///
/// Hash of public key.
/// Instance of CKeyPair or null.
/// Result
public bool GetKey(CKeyID keyID, out CKeyPair keyPair)
{
var QueryGet = dbConn.Query("select * from [KeyStorage] where [KeyID] = ?", keyID.hashBytes);
if (QueryGet.Count() == 1)
{
keyPair = new CKeyPair(QueryGet.First().PrivateKey);
return true;
}
keyPair = null;
return false;
}
public bool AddScript(CScript script)
{
lock (LockObj)
{
var res = dbConn.Insert(new ScriptStorageItem()
{
ScriptID = script.ScriptID.hashBytes,
ScriptCode = script.Bytes
});
if (res == 0)
{
return false;
}
}
return true;
}
public bool HaveScript(CScriptID scriptID)
{
var QueryGet = dbConn.Query("select count([ItemID]) from [ScriptStorage] where [ScriptID] = ?", scriptID.hashBytes);
return QueryGet.First().Count == 1;
}
public bool GetScript(CScriptID scriptID, out CScript script)
{
var QueryGet = dbConn.Query("select * from [ScriptStorage] where [ScriptID] = ?", scriptID.hashBytes);
if (QueryGet.Count() == 1)
{
script = new CScript(QueryGet.First().ScriptCode);
return true;
}
script = null;
return false;
}
}
}