How to mine
Here’s a sample program written in C# that “mines” the asset, that is, generates transactions until the transaction satisfies all specified conditions, and then sends the transaction to the blockchain. If N was updated earlier than 15 blocks back, then the program sends a DataTransaction that updates N.
using System;
using System.Collections.Generic;
using WavesCS;
namespace Miner
{
class MainClass
{
static Node node = new Node(Node.MainNetChainId);
static Asset asset = node.GetAsset("BXSAEa9jm9Qrkmn2XPqqKBkukZoBkJ8YpQ9EZywjdnnx");
static byte[] senderPublicKey = node.GetTransactionById(asset.Id).SenderPublicKey;
static string sender = AddressEncoding.GetAddressFromPublicKey(senderPublicKey, node.ChainId);
static string recipient = ""; // put your address here
static long lastUpdateHeight = (long)node.GetAddressData(sender)["lastUpdateHeight"];
static long difficulty = (long)node.GetAddressData(sender)["difficulty"];
static int validityPeriod = 15;
static int transferAmount = 1;
static int miningRate = 100;
static int minDifficulty = 20;
static int maxDifficulty = 64;
public static void UpdateDifficulty()
{
try
{
var currentHeight = (long)node.GetHeight();
lastUpdateHeight = (long)node.GetAddressData(sender)["lastUpdateHeight"];
if (currentHeight - lastUpdateHeight >= validityPeriod)
{
var currentBalance = asset.AmountToLong(node.GetBalance(sender, asset));
var lastUpdateBalance = (long)node.GetAddressData(sender)["lastUpdateBalance"];
difficulty = (long)node.GetAddressData(sender)["difficulty"];
var delta = lastUpdateBalance - currentBalance > 0 ? lastUpdateBalance - currentBalance : 1;
var sgn = (delta < miningRate) ? -1 : 1;
var k = (delta < miningRate) ? miningRate / delta : delta / miningRate;
var log2 = Math.Min(10, (long)Math.Floor(Math.Log(k, 2)));
difficulty = difficulty + sgn * log2;
difficulty = Math.Max(minDifficulty, difficulty);
difficulty = Math.Min(maxDifficulty, difficulty);
var data = new Dictionary<string, object>
{
{ "difficulty", difficulty },
{ "lastUpdateHeight", currentHeight },
{ "lastUpdateBalance", currentBalance }
};
var tx = new DataTransaction(node.ChainId, senderPublicKey, data, 0.005m);
Http.Tracing = true;
node.Broadcast(tx.GetJsonWithSignature());
Console.WriteLine($"Mining difficulty was updated");
Console.WriteLine($"Current mining difficulty: {difficulty}");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Http.Tracing = false;
}
}
public static void Main(string[] args)
{
Http.Tracing = false;
Console.WriteLine($"Current mining difficulty: {difficulty}");
for (var iterations = 0; ; iterations++)
{
if (iterations % 1000000 == 0)
{
UpdateDifficulty();
}
var tx = new TransferTransaction
(
chainId: node.ChainId,
senderPublicKey: senderPublicKey,
recipient: recipient,
asset: asset,
amount: asset.LongToAmount(transferAmount),
fee: 0.005m
);
var id = tx.GenerateBinaryId();
var leadingZeros = 0;
for (int i = 0; i < 32; i++)
{
if (id[i] == 0)
leadingZeros += 8;
else
{
leadingZeros += 7 - (int)Math.Floor(Math.Log(id[i], 2));
break;
}
}
if (leadingZeros >= difficulty)
{
Console.Write("Generated transaction id: " + id.ToBase58());
try
{
Http.Tracing = true;
node.Broadcast(tx);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Http.Tracing = false;
}
}
}
}
}
}