public void RequestBalance(byte[] data) { SharpKeyPair skp = new SharpKeyPair(data); long balance = Core.Blockchain.Balance(skp); Log.NewLine($"Sending balance ({balance}) for address {skp.GetAddress()}."); Send(Opcodes["RequestBalanceResponse"], BitConverter.GetBytes(balance).Reverse().ToArray()); }
static void Main(string[] args) { Blockchain bc = new Blockchain(); SharpKeyPair skp = SharpKeyPair.Create(); while (true) { Block b = Miner.Solve(skp, bc); bc.AddBlock(b); } }
public void Start(SharpKeyPair skp = null) { SharpKeyPair resolvedSkp = skp ?? MiningKeyPair; if (!IsMining && resolvedSkp != null) { IsMining = true; MiningKeyPair = resolvedSkp; MineThread = new Thread(new ParameterizedThreadStart(Mine)); MineThread.Start(resolvedSkp); } }
public static Block Solve(SharpKeyPair skp, Blockchain bc) { Block LastBlock = bc.GetLastBlock(); Block Block = new Block { Index = LastBlock.Index + 1, PreviousHash = LastBlock.Hash }; Transaction RTx = new Transaction(new Output[] { new Output { Address = skp.GetAddress(), Amount = Config.BlockReward } }); RTx.Sign(skp); Block.AddTransaction(RTx); Block.Hash = Block.ToHash(); return(Solve(Block, bc)); }
// Creates a next block based on the chain given with a reward tx for the keypair. public static Block Create(SharpKeyPair skp, Blockchain bc) { Serializer s = new Serializer(); Transaction[] queued = bc.GetQueuedTransactions(); Block LastBlock = bc.GetLastBlock(); Block b = new Block { Index = LastBlock.Index + 1, PreviousHash = LastBlock.Hash }; b.TargetHash = b.Index % Config.SectionSize == 0 ? Config.CalculateDifficulty(bc.GetLastSection()).ToString("x") : LastBlock.TargetHash; b.AddTransaction(Builder.MakeReward(skp, Config.BlockReward)); int count = 0; do { try { Transaction tx = queued[count++]; // Only add verified, valid and non reward transactions to the block if (tx.Verify() && bc.IsValidTransaction(tx) && tx.IsDefaultTransaction()) { b.AddTransaction(tx); } } catch { break; } } while (s.Size(b) < Config.MaximumBlockSizeInBytes); b.Hash = b.ToHash(); return(b); }
public void Sign(SharpKeyPair Skp) { Signature = Skp.Sign(Hash.Sha1(ToString())); }
public long Balance(SharpKeyPair skp) { return(UnspentOutputs.Filter(output => output.Address == skp.GetAddress()).Map(output => output.Amount).Reduce(R.Total, 0)); }
public void RequestKeyPair(byte[] data) { Log.NewLine($"Sending keypair."); Send(Opcodes["RequestKeyPairResponse"], SharpKeyPair.Create().AsData()); }
// todo: one big clunky method that could be split up public void CreateTransaction(byte[] data) { int TotalKeySize = 96; int TransactionRecipientSize = 49; byte[] pubk = new byte[64]; byte[] seck = new byte[32]; Array.Copy(data, 0, pubk, 0, 64); Array.Copy(data, 64, seck, 0, 32); int TotalRecipients = (data.Length - TotalKeySize) / TransactionRecipientSize; TransactionRecipient[] txrs = new TransactionRecipient[TotalRecipients]; for (int i = 0; i < TotalRecipients; i++) { byte[] rawamount = new byte[8]; byte[] rawrecipient = new byte[41]; Array.Copy(data, 96 + (i * TransactionRecipientSize), rawamount, 0, 8); Array.Copy(data, 104 + (i * TransactionRecipientSize), rawrecipient, 0, 41); txrs[i] = new TransactionRecipient { RawAmount = rawamount, RawRecipient = rawrecipient }; } long TotalAmount = txrs.Map(rec => rec.Amount()).Reduce(R.Total, 0); SharpKeyPair skp = new SharpKeyPair(pubk, seck); Builder txb = new Builder(skp); // All queued inputs as meta outputs, so that we can compare them against all the keypair's unspent outputs in the index... We don't want // to use inputs that are already queued up in the blockchain. MetaOutput[] QueuedInputsAsOutputs = Core.Blockchain.GetQueuedTransactions().FlatMap(tx => tx.Inputs).Map(input => input.AsMetaOutput()).ToArray(); IEnumerator <Output> utxos = ((IEnumerable <Output>)Core.Blockchain.GetUnspentOutputs(skp.GetAddress())).GetEnumerator(); while (txb.InputAmount() < TotalAmount && utxos.MoveNext()) { // This expression somehow fails when put in the while test, so its an if here. if (!QueuedInputsAsOutputs.Any(output => output.Equals((MetaOutput)utxos.Current))) { MetaOutput output = (MetaOutput)utxos.Current; txb.AddInput(Core.Blockchain.GetTransaction(output.Transaction), output.Index); } } foreach (TransactionRecipient txr in txrs) { txb.AddOutput(txr.Recipient(), txr.Amount()); } try { Transaction newtx = txb.Make(); if (Core.Blockchain.QueueTransaction(newtx)) { Send(Opcodes["CreateTransactionResponse"], OK()); } else { Send(Opcodes["CreateTransactionResponse"], NOOP()); } } catch (Exception e) { Log.NewLine($"Failed to create a new transaction. {e.Message}"); Send(Opcodes["CreateTransactionResponse"], NOOP()); } }