Diverse Updates

master
Harald Wolff 2017-10-17 21:43:06 +02:00
parent f10a75c82c
commit 9f2cd0fbb7
9 changed files with 356 additions and 45 deletions

44
Base58.cs 100644
View File

@ -0,0 +1,44 @@
using System;
using System.Text;
namespace sharp.cryptonote
{
public class Base58
{
private static string Base58Letters = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
public static string encode(UInt64 value){
StringBuilder sb = new StringBuilder();
do
{
sb.Append( Base58Letters[(int)(value % 58)] );
value /= 58;
} while (value != 0);
char[] encoded = sb.ToString().PadRight(11,'1').ToCharArray();
Array.Reverse(encoded);
return new string(encoded);
}
public static UInt64 decode(string encoded){
UInt64 value = 0;
char[] chars = encoded.ToCharArray();
//Array.Reverse(chars);
foreach (char ch in chars){
uint i = (uint)Base58Letters.IndexOf(ch);
if (i < 0){
throw new FormatException(String.Format("Illegal Character found in Base58 string: {0}",ch));
}
value *= 58;
value += i;
}
return value;
}
}
}

47
Block.cs 100644
View File

@ -0,0 +1,47 @@
using System;
using System.Text;
using System.IO;
using sharp.cryptonote.streams;
using sharp.extensions;
namespace sharp.cryptonote
{
public class Block
{
Int64 major_version, minor_version, timestamp;
byte[] hash;
UInt32 nonce;
public Block(byte[] buffer)
{
decode( new ExtendedStreamReader(new MemoryStream(buffer) ) );
}
private void decode(ExtendedStreamReader reader){
major_version = reader.readVarInt();
minor_version = reader.readVarInt();
timestamp = reader.readVarInt();
hash = reader.readBytes(32);
nonce = reader.readUInt32();
}
public byte[] toBytes(){
return null;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("[CryptoNote Block] Version: {0}.{1}, TS: {2} NONCE: {3}\n",major_version,minor_version,timestamp,nonce);
sb.AppendFormat("[CryptoNote Block] Last Blocks Hash: {0}\n",hash.toHexString());
return sb.ToString();
}
}
}

View File

@ -1,9 +1,10 @@
using System;
namespace cryptonote
namespace sharp.cryptonote
{
public class BlockTemplate
{
public BlockTemplate(byte[] blob, Int64 difficulty, Int64 height, string prev_hash, Int64 reserved_offset, Int64 reserve_size)
public BlockTemplate(byte[] blob, UInt64 difficulty, UInt64 height, string prev_hash, Int64 reserved_offset, Int64 reserve_size)
{
this.Blob = blob;
this.Height = height;
@ -11,16 +12,27 @@ namespace cryptonote
this.PreviousHash = prev_hash;
this.ReservedOffset = reserved_offset;
this.ReserveSize = reserve_size;
}
public byte[] Blob { get; private set; }
public Int64 Difficulty { get; private set; }
public Int64 Height { get; private set; }
public UInt64 Difficulty { get; private set; }
public UInt64 Height { get; private set; }
public Int64 ReservedOffset { get; private set; }
public Int64 ReserveSize { get; private set; }
public string PreviousHash { get; private set; }
public byte[] generateJobTemplate(byte[] jobbytes){
byte[] blob = new byte[this.Blob.Length];
if (jobbytes.Length > ReserveSize){
throw new ArgumentException("JobBytes bigger than reserved size!");
}
Array.Copy(this.Blob,blob,blob.Length);
Array.Copy(jobbytes, 0, blob, ReservedOffset, jobbytes.Length);
return blob;
}

View File

@ -0,0 +1,152 @@
using System;
using sharp.extensions;
using sharp.hashing;
using System.Text;
using System.Collections.Generic;
namespace sharp.cryptonote
{
public class CryptoNoteAddress
{
static IHash keccak256 = Hashes.createKECCAK_256();
static Dictionary<CryptoNoteCoin, CoinConfiguration> configurations = initializeConfigurations();
static Dictionary<CryptoNoteCoin, CoinConfiguration> initializeConfigurations(){
Dictionary<CryptoNoteCoin, CoinConfiguration> r = new Dictionary<CryptoNoteCoin, CoinConfiguration>();
r.Add(CryptoNoteCoin.XMR,new CoinConfiguration(95,4));
r.Add(CryptoNoteCoin.AEON,new CoinConfiguration(97,6));
return r;
}
byte[] address;
public CryptoNoteAddress(string address)
{
if (address.Length < 11){
throw new ArgumentException("Invalid Cryptonote Address, len(..) < 11");
}
byte[] prefix = new byte[8];
base58uint64decode2array(address.Substring(0, 11),prefix,0,8);
CryptoNoteCoin prefixCoin = (CryptoNoteCoin)prefix[0];
if (address.Length != configurations[prefixCoin].PublicAddressLen){
throw new ArgumentException(String.Format("Invalid Cryptonote Address, len(..) != {0}",configurations[prefixCoin].PublicAddressLen));
}
string[] parts = address.splitConstantWidth(11);
byte[] binary = new byte[69];
for (int n = 0; n< 8;n++){
base58uint64decode2array(parts[n], binary, n * 8);
}
base58uint64decode2array(parts[8], binary, 64, 5);
setup(binary);
}
public CryptoNoteAddress(byte[] address){
if (address.Length != 69){
throw new ArgumentException("Invalid Cryptonote Address, binary len(..) != 69");
}
setup(address);
}
public CryptoNoteAddress(CryptoNoteCoin coin){
this.address = new byte[59];
this.address[0] = (byte)coin;
updateChecksum();
}
private void setup(byte[] a){
this.address = a.Segment(0);
byte[] checksum = keccak256.compute(this.address.Segment(0, 65)).Segment(0,4);
if (!checksum.ArrayEquals(this.address.Segment(65,4))){
throw new ArgumentException("CheckSum failed for CryptoNote Address");
}
}
private void updateChecksum(){
byte[] checksum = keccak256.compute(this.address.Segment(0, 65));
Array.Copy(checksum,0,this.address,65,4);
}
public CryptoNoteCoin CryptoNoteCoin {
get { return (CryptoNoteCoin)this.address[0]; }
set { this.address[0] = (byte)value; updateChecksum(); }
}
public byte[] PublicSpendKey {
get { return this.address.Segment(1, 32); }
set {
if (value.Length != 32){
throw new ArgumentException("Invalid SpendKey, len != 32");
}
Array.Copy(value,0,this.address,1,32);
updateChecksum();
}
}
public byte[] PublicViewKey {
get { return this.address.Segment(33, 32); }
set {
if (value.Length != 32){
throw new ArgumentException("Invalid ViewKey, len != 32");
}
Array.Copy(value,0,this.address,33,32);
updateChecksum();
}
}
public byte[] CheckSum {
get { return this.address.Segment(65, 4); }
}
public byte[] toBytes() {
return this.address.Segment(0);
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int n = 0; n < 9;n++){
byte[] part = this.address.Segment(n * 8, n < 8 ? 8 : 5);
if (BitConverter.IsLittleEndian){
Array.Reverse(part);
}
UInt64 ui64 = BitConverter.ToUInt64(part.Extend(8),0);
if (n == 8){
sb.Append( Base58.encode(ui64).Substring(4) );
} else {
sb.Append( Base58.encode(ui64) );
}
}
return sb.ToString();
}
private static bool base58uint64decode2array(string b58, byte[] buffer, int pos, int length = 8)
{
byte[] t = BitConverter.GetBytes(Base58.decode(b58));
if (BitConverter.IsLittleEndian)
{
Array.Reverse(t);
}
Array.Copy(t, t.Length - length, buffer, pos, length);
return true;
}
struct CoinConfiguration {
public readonly int CheckSumSize,
PublicAddressLen;
public CoinConfiguration(int palen,int CheckSumSize){
this.PublicAddressLen = palen;
this.CheckSumSize = CheckSumSize;
}
}
}
}

12
CrytoNoteCoin.cs 100644
View File

@ -0,0 +1,12 @@
using System;
namespace sharp.cryptonote
{
public enum CryptoNoteCoin
{
XMR = 0x12,
AEON = 0xB2
};
}

View File

@ -1,14 +1,14 @@
using System;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using JSONRPC;
using cryptonote.tools;
using sharp.jsonrpc;
using sharp.extensions;
namespace cryptonote.rpc
namespace sharp.cryptonote.rpc
{
public class Daemon
{
@ -28,20 +28,20 @@ namespace cryptonote.rpc
return -1;
}
public BlockTemplate getBlockTemplate(string wallet,uint reserve_size){
public BlockTemplate getBlockTemplate(CryptoNoteAddress wallet,uint reserve_size){
BlockTemplate bt = null;
Response response = this.rpc.Call()
.method("getblocktemplate")
.parameter("wallet_address", wallet)
.parameter("reserve_size", 60)
.execute();
.method("getblocktemplate")
.parameter("wallet_address", wallet.ToString())
.parameter("reserve_size", reserve_size)
.execute();
if (response.Success()){
byte[] blob = HexString.toBytes(response.result["blocktemplate_blob"].ToString());
bt = new BlockTemplate(
blob,
response.result["difficulty"].ToObject<Int64>(),
response.result["height"].ToObject<Int64>(),
response.result["difficulty"].ToObject<UInt64>(),
response.result["height"].ToObject<UInt64>(),
response.result["prev_hash"].ToObject<string>(),
response.result["reserved_offset"].ToObject<Int64>(),
reserve_size

View File

@ -5,7 +5,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{52C68C13-2DC2-438A-9EC1-E8C4953B07DF}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>cryptonote</RootNamespace>
<RootNamespace>sharp.cryptonote</RootNamespace>
<AssemblyName>cryptonote</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
@ -32,26 +32,39 @@
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Security" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="BlockTemplate.cs" />
<Compile Include="rpc\Daemon.cs" />
<Compile Include="tools\HexString.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\JSONRPC\JSONRPC.csproj">
<Project>{DCE6066E-9709-4D12-8994-F7879C3557D6}</Project>
<Name>JSONRPC</Name>
</ProjectReference>
<Compile Include="CrytoNoteCoin.cs" />
<Compile Include="Base58.cs" />
<Compile Include="Block.cs" />
<Compile Include="CryptoNoteAddress.cs" />
<Compile Include="streams\ExtendedStreamReader.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="rpc\" />
<Folder Include="tools\" />
<Folder Include="streams\" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\sharp-jsonrpc\sharp.jsonrpc.csproj">
<Project>{DCE6066E-9709-4D12-8994-F7879C3557D6}</Project>
<Name>sharp.jsonrpc</Name>
</ProjectReference>
<ProjectReference Include="..\sharp-hashing\sharp.hashing.csproj">
<Project>{CCD7C196-B079-4AA7-98AF-5BECAD089CE4}</Project>
<Name>sharp.hashing</Name>
</ProjectReference>
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
<Name>sharp.extensions</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<MonoDevelop>

View File

@ -0,0 +1,51 @@
using System;
using System.IO;
namespace sharp.cryptonote.streams
{
public class ExtendedStreamReader
{
Stream stream;
public ExtendedStreamReader(Stream stream)
{
this.stream = stream;
}
public Int64 readVarInt(){
Int64 result = 0;
int t, s;
s = 0;
do
{
t = stream.ReadByte();
if (t == 0){
break;
}
//result *= 128;
//result += t & 0x7F;
result |= (t & 0x7F) << s;
s += 7;
} while (t >= 128);
return result;
}
public byte[] readBytes(int len){
byte[] buffer = new byte[len];
stream.Read(buffer,0,len);
return buffer;
}
public UInt32 readUInt32()
{
byte[] t = new byte[4];
stream.Read(t,0,4);
return BitConverter.ToUInt32(t, 0);
}
}
}

View File

@ -1,20 +0,0 @@
using System;
namespace cryptonote.tools
{
public class HexString
{
public static byte[] toBytes(string hexstring)
{
byte[] bytes = new byte[hexstring.Length >> 1];
for (int n = 0; n < hexstring.Length >> 1;n++){
bytes[n] = Convert.ToByte(hexstring.Substring(n << 1, 2), 16);
}
return bytes;
}
public static String toString(byte[] bytes){
return BitConverter.ToString(bytes).Replace("-", String.Empty);
}
}
}