Пример #1
0
        static void Main()
        {
            string fileName;

            do
            {
                Console.Write("Enter whitelist file name or NEO address: ");
                fileName = Console.ReadLine();

                if (!fileName.Contains("."))
                {
                    break;
                }

                if (File.Exists(fileName))
                {
                    break;
                }
            } while (true);

            List <string> lines;

            if (fileName.Contains("."))
            {
                lines = File.ReadAllLines(fileName).ToList();
            }
            else
            {
                lines = new List <string>()
                {
                    fileName
                };
            }

            if (File.Exists(result_fileName))
            {
                var finishedLines     = File.ReadAllLines(result_fileName);
                var finishedAddresses = new HashSet <string>();
                foreach (var entry in finishedLines)
                {
                    var temp = entry.Split(',');
                    finishedAddresses.Add(temp[0]);
                }

                var previousTotal = lines.Count;

                lines = lines.Where(x => !finishedAddresses.Contains(x)).ToList();

                var skippedTotal = previousTotal - lines.Count;

                Console.WriteLine($"Skipping {skippedTotal} addresses...");
            }

            var api = new LocalRPCNode(10332, "http://neoscan.io");

            api.SetLogger(x =>
            {
                ColorPrint(ConsoleColor.DarkGray, x);
            });

            string privateKey;

            byte[] scriptHash = null;

            do
            {
                Console.Write("Enter WIF private key: ");
                privateKey = Console.ReadLine();

                if (privateKey.Length == 52)
                {
                    break;
                }
            } while (true);

            var keys = KeyPair.FromWIF(privateKey);

            Console.WriteLine("Public address: " + keys.address);

            do
            {
                Console.Write("Enter contract script hash or token symbol: ");
                var temp = Console.ReadLine();

                scriptHash = NeoAPI.GetScriptHashFromSymbol(temp);

                if (scriptHash == null && temp.Length == 40)
                {
                    scriptHash = NeoAPI.GetScriptHashFromString(temp);
                }
            } while (scriptHash == null);


            var token = new NEP5(api, scriptHash);

            decimal amount;

            Console.WriteLine($"Write amount of {token.Symbol} to distribute to each address:");
            do
            {
                if (decimal.TryParse(Console.ReadLine(), out amount) && amount > 0)
                {
                    break;
                }
            } while (true);

            int skip = 0;
            int done = 0;

            Console.WriteLine($"Initializing {token.Name} airdrop...");

            var srcBalance = token.BalanceOf(keys);

            Console.WriteLine($"Balance of {keys.address} is {srcBalance} {token.Symbol}");

            var minimum = lines.Count * amount;

            if (srcBalance < minimum)
            {
                ColorPrint(ConsoleColor.Red, $"Error: For this Airdrop you need at least {minimum} {token.Symbol} at {keys.address}");
                Console.ReadLine();
                return;
            }

            foreach (var temp in lines)
            {
                var address = temp.Trim();
                if (!address.IsValidAddress())
                {
                    skip++;
                    ColorPrint(ConsoleColor.Yellow, "Invalid address: " + address);
                    continue;
                }

                var hash    = address.GetScriptHashFromAddress();
                var balance = token.BalanceOf(hash);

                Console.WriteLine($"Found {address}: {balance} {token.Symbol}");

                Console.WriteLine($"Sending {token.Symbol} to  {address}");
                Transaction tx = null;

                int failCount = 0;
                int failLimit = 20;
                do
                {
                    int tryCount = 0;
                    int tryLimit = 3;
                    do
                    {
                        tx = token.Transfer(keys, address, amount);
                        Thread.Sleep(1000);

                        if (tx != null)
                        {
                            break;
                        }

                        Console.WriteLine("Tx failed, retrying...");

                        tryCount++;
                    } while (tryCount < tryLimit);


                    if (tx != null)
                    {
                        break;
                    }
                    else
                    {
                        Console.WriteLine("Changing RPC server...");
                        Thread.Sleep(2000);
                        api.rpcEndpoint = null;
                        failCount++;
                    }
                } while (failCount < failLimit);

                if (failCount >= failLimit || tx == null)
                {
                    ColorPrint(ConsoleColor.Red, "Try limit reached, internal problem maybe?");
                    break;
                }

                Console.WriteLine("Unconfirmed transaction: " + tx.Hash);

                api.WaitForTransaction(keys, tx);

                ColorPrint(ConsoleColor.Green, "Confirmed transaction: " + tx.Hash);

                File.AppendAllText(result_fileName, $"{address},{tx.Hash}\n");

                done++;
            }

            Console.WriteLine($"Skipped {skip} invalid addresses.");
            Console.WriteLine($"Airdropped {amount} {token.Symbol} to {done} addresses.");

            Console.WriteLine("Finished.");
            Console.ReadLine();
        }
Пример #2
0
 /// <summary>
 /// Returns the balance of TTL for a specified address
 /// </summary>
 /// <param name="address">Address to get the balance of</param>
 /// <returns>Balance of tokens for the specified address</returns>
 public decimal GetTokenBalance()
 {
     return(_token.BalanceOf(_contextWallet.Address));
 }