예제 #1
0
        public void TestTransferToAlias()
        {
            var node = new Node(Node.TestNetHost);

            var seed    = PrivateKeyAccount.GenerateSeed();
            var account = PrivateKeyAccount.CreateFromSeed(seed, 'T');

            node.Transfer(Accounts.Alice, account.Address, Assets.WAVES, 0.001m);
            Thread.Sleep(10000);

            var alias = GenerateRandomAlias();

            node.CreateAlias(account, alias, 'T');
            Thread.Sleep(10000);

            var amount        = 0.0001m;
            var balanceBefore = node.GetBalance(account.Address);

            node.Transfer(Accounts.Alice, "alias:T:" + alias, Assets.WAVES, amount);
            Thread.Sleep(15000);

            var balanceAfter = node.GetBalance(account.Address);

            Assert.AreEqual(balanceBefore + amount, balanceAfter);
        }
예제 #2
0
 public void Init()
 {
     Seed             = PrivateKeyAccount.GenerateSeed();
     Account          = PrivateKeyAccount.CreateFromSeed(seed, AddressEncoding.TestNet);
     Base58PrivateKey = Account.PrivateKey.ToBase58();
     Base58PublicKey  = Account.PublicKey.ToBase58();
 }
예제 #3
0
        public void TestTransferToAlias()
        {
            var node = new Node(Node.TestNetChainId);

            var seed    = PrivateKeyAccount.GenerateSeed();
            var account = PrivateKeyAccount.CreateFromSeed(seed, 'T');

            var response = node.Transfer(Accounts.Alice, account.Address, Assets.BCT, 0.001m);

            node.WaitTransactionConfirmationByResponse(response);

            var alias = GenerateRandomAlias();

            response = node.CreateAlias(account, alias, 'T');
            node.WaitTransactionConfirmationByResponse(response);

            var amount        = 0.0001m;
            var balanceBefore = node.GetBalance(account.Address);

            response = node.Transfer(Accounts.Alice, "alias:T:" + alias, Assets.BCT, amount);
            node.WaitTransactionConfirmationByResponse(response);

            var balanceAfter = node.GetBalance(account.Address);

            Assert.AreEqual(balanceBefore + amount, balanceAfter);
        }
예제 #4
0
 public void Load()
 {
     using (StreamReader sr = new StreamReader("account.dat"))
     {
         Seed    = sr.ReadLine();
         Account = PrivateKeyAccount.CreateFromSeed(Seed, AddressEncoding.TestNet);
     }
 }
예제 #5
0
        private static async Task Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                                .SetBasePath(Directory.GetCurrentDirectory())
#if DEBUG
                                .AddJsonFile("appsettings.development.json", optional: true, reloadOnChange: true)
#elif RELEASE
                                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#endif
                                .AddCommandLine(args)
                                .Build();

            var settings = configuration.Get <Settings>();
            var seed     = args[0];

            var wavesHelper = new WavesHelper(settings.NodeUrl, settings.ChainId);
            var account     = PrivateKeyAccount.CreateFromSeed(seed, settings.ChainId);
            var node        = new Node(settings.NodeUrl, settings.ChainId);

            var commands = new List <Command>()
            {
                Command.Withdraw,
                Command.TransferToAuction,
                Command.ExecuteOrderLiquidation,
                Command.ExecuteOrderAuction,
                Command.RebalanceLeasing
            };

            var pacemakerService = new PacemakerService(wavesHelper, node, account, settings.NeutrinoSettings, settings.Leasing, settings.DeficitOffset);

            while (true)
            {
                foreach (var command in commands)
                {
                    Logger.Info($"Run command:{command}");
                    var sw = new Stopwatch();
                    sw.Start();

                    try
                    {
                        await RunCommand(pacemakerService, command);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                    }

                    sw.Stop();
                    Logger.Info($"Commands completed in {sw.ElapsedMilliseconds/1000} seconds");
                }

                Logger.Info($"Wait {TimeSpan.FromSeconds(settings.TimeoutSec)} seconds");
                await Task.Delay(TimeSpan.FromSeconds(settings.TimeoutSec));
            }
        }
예제 #6
0
        public void TestInvokeScript()
        {
            Http.Tracing = true;
            var node = new Node(Node.TestNetChainId);

            var Alice = PrivateKeyAccount.CreateFromSeed("seedAlice123", node.ChainId);
            var Bob   = PrivateKeyAccount.CreateFromSeed("seedBob123", node.ChainId);

            var script         = @"{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}

@Callable(inv)
func foo (a:ByteVector) = {
    WriteSet([DataEntry(""a"", a),
    DataEntry(""sender"", inv.caller.bytes)])
}";
            var compiledScript = node.CompileScript(script);

            var response = node.SetScript(Alice, compiledScript);

            node.WaitForTransactionBroadcastResponseConfirmation(response);

            response = node.InvokeScript(Bob, Alice.Address, "foo", new List <object> {
                42L
            }, null);
            node.WaitForTransactionBroadcastResponseConfirmation(response);

            Assert.AreEqual((long)node.GetAddressData(Alice.Address)["a"], 42L);
            Assert.AreEqual(((byte[])node.GetAddressData(Alice.Address)["sender"]).ToBase58(), Bob.Address);

            var dataTx = new DataTransaction(
                chainId: node.ChainId,
                senderPublicKey: Alice.PublicKey,
                entries: new Dictionary <string, object> {
                { "a", "OOO" }
            },
                fee: 0.005m
                ).Sign(Alice);

            node.BroadcastAndWait(dataTx);

            Assert.AreEqual(node.GetAddressData(Alice.Address)["a"], "OOO");

            response = node.SetScript(Alice, null);
            node.WaitForTransactionBroadcastResponseConfirmation(response);

            var scriptInfo = node.GetObject("addresses/scriptInfo/{0}", Alice.Address);

            Assert.IsFalse(scriptInfo.ContainsKey("scriptText"));
        }
예제 #7
0
        static PrivateKeyAccount GetAccount(string seed, bool base58)
        {
            //var seed = Base58.Decode("2PLzSeA7TSYAehA5y1Qj1U5GZw9nQaHVLy2MbBwM6cCtqSS26hL6PrNNDg6k25kaWygaeEcX6KfzwPkNc9G1zLbF");
            //var recipient = "3Mr2S13RUQzn2peQMZjf7bTrjkkUqtJaYEa";

            // create account
            var seedBytes = Encoding.UTF8.GetBytes(seed);

            if (base58)
            {
                seedBytes = Base58.Decode(seed);
            }
            return(PrivateKeyAccount.CreateFromSeed(seedBytes, AddressEncoding.TestNet));
        }
예제 #8
0
        public void TestAccountCreation()
        {
            var seed    = "health lazy lens fix dwarf salad breeze myself silly december endless rent faculty report beyond";
            var account = PrivateKeyAccount.CreateFromSeed(seed, AddressEncoding.TestNet);

            byte[] seed2    = Encoding.UTF8.GetBytes(seed);
            var    account2 = PrivateKeyAccount.CreateFromSeed(seed2, AddressEncoding.TestNet);

            Assert.AreEqual("CMLwxbMZJMztyTJ6Zkos66cgU7DybfFJfyJtTVpme54t", account.PrivateKey.ToBase58());
            Assert.AreEqual("8LbAU5BSrGkpk5wbjLMNjrbc9VzN9KBBYv9X8wGpmAJT", account.PublicKey.ToBase58());
            Assert.AreEqual("3MzZCGFyuxgC4ZmtKRS7vpJTs75ZXdkbp1K", account.Address);

            Assert.AreEqual("CMLwxbMZJMztyTJ6Zkos66cgU7DybfFJfyJtTVpme54t", account2.PrivateKey.ToBase58());
            Assert.AreEqual("8LbAU5BSrGkpk5wbjLMNjrbc9VzN9KBBYv9X8wGpmAJT", account2.PublicKey.ToBase58());
            Assert.AreEqual("3MzZCGFyuxgC4ZmtKRS7vpJTs75ZXdkbp1K", account2.Address);
        }
예제 #9
0
        static void Main(string[] args)
        {
            var node = new Node();

            var data = new DictionaryObject
            {
                { "test string", "Hello, 0bsNetwork!" }
            };

            PrivateKeyAccount Alice = PrivateKeyAccount.CreateFromSeed("test", AddressEncoding.TestNet);

            var tx = new DataTransaction(node.ChainId, Alice.PublicKey, data).Sign(Alice);

            Console.WriteLine("Tx size: " + tx.GetBody().Length);
            Console.WriteLine("Response tx id: " + node.BroadcastAndWait(tx.GetJsonWithSignature()));

            Console.ReadLine();
        }
예제 #10
0
        public void TestMultisig()
        {
            // This test works with tranfer transactions of version 2 only
            var node = new Node();

            var script = $@"                
                let aliceSigned = sigVerify(tx.bodyBytes, tx.proofs[0], base58'{Accounts.Alice.PublicKey.ToBase58()}')
                let bobSigned   = sigVerify(tx.bodyBytes, tx.proofs[1], base58'{Accounts.Bob.PublicKey.ToBase58()}')
                aliceSigned && bobSigned";

            Console.WriteLine($"Script: {script}");

            var compiledScript = node.CompileScript(script);

            var multiAccount = PrivateKeyAccount.CreateFromSeed(PrivateKeyAccount.GenerateSeed(), AddressEncoding.TestNet);

            Console.WriteLine("Account generated: {0}", multiAccount.Address);
            node.Transfer(Accounts.Alice, multiAccount.Address, Assets.WAVES, 0.1m);

            Thread.Sleep(10000);

            Assert.IsTrue(node.GetBalance(multiAccount.Address) == 0.1m);

            var setScriptTx = new SetScriptTransaction(multiAccount.PublicKey, compiledScript, 'T');

            setScriptTx.Sign(multiAccount);
            node.Broadcast(setScriptTx.GetJsonWithSignature());

            Thread.Sleep(10000);

            var tx = new TransferTransaction(multiAccount.PublicKey, Accounts.Alice.Address, Assets.WAVES, 0.07m, 0.005m)
            {
                Version = 2
            };

            tx.Sign(Accounts.Alice, 0);
            tx.Sign(Accounts.Bob, 1);

            node.Broadcast(tx);

            Thread.Sleep(10000);

            Assert.IsTrue(node.GetBalance(multiAccount.Address) < 0.02m);
        }
예제 #11
0
        public void TestCreateAssetScript()
        {
            var node = new Node();
            var tokenomicaAccount = PrivateKeyAccount.CreateFromSeed("aim property attract warfare stamp sample holiday input invest rather potato novel produce car arctic", 'T');
            var script            = $@"
            let tokenomicaAccount = base58'{tokenomicaAccount.Address}'
            let matcherAccount = tokenomicaAccount
             match tx {{
                case tx: BurnTransaction => tx.sender.bytes == tokenomicaAccount
                case tx: ExchangeTransaction =>
                    tx.sender.bytes == matcherAccount
                    && extract(getBoolean(Address(tokenomicaAccount), toBase58String(tx.buyOrder.sender.bytes))) # whitelist
                    && extract(getBoolean(Address(tokenomicaAccount), toBase58String(tx.sellOrder.sender.bytes)))
                case tx: TransferTransaction => tx.sender.bytes == tokenomicaAccount || addressFromRecipient(tx.recipient).bytes == tokenomicaAccount
                case tx: MassTransferTransaction => false
                case tx: ReissueTransaction => true
                case _ => true # SetAssetScriptTransaction
            }}";

            var compiledScript = node.CompileScript(script);
            var asset          = node.IssueAsset(tokenomicaAccount, "ttoken", "ttoken", 1000000m, 8, true, compiledScript);
        }
예제 #12
0
        public void TestMultisig()
        {
            // This test works with transfer transactions of version 2 only
            var node = new Node();

            var script = $@"                
                let aliceSigned = sigVerify(tx.bodyBytes, tx.proofs[0], base58'{Accounts.Alice.PublicKey.ToBase58()}')
                let bobSigned   = sigVerify(tx.bodyBytes, tx.proofs[1], base58'{Accounts.Bob.PublicKey.ToBase58()}')
                aliceSigned && bobSigned";

            Console.WriteLine($"Script: {script}");

            var compiledScript = node.CompileScript(script);

            var multiAccount = PrivateKeyAccount.CreateFromSeed(PrivateKeyAccount.GenerateSeed(), AddressEncoding.TestNet);

            Console.WriteLine("Account generated: {0}", multiAccount.Address);

            var response = node.Transfer(Accounts.Alice, multiAccount.Address, Assets.ZBS, 0.1m);

            node.WaitForTransactionBroadcastResponseConfirmation(response);

            Assert.IsTrue(node.GetBalance(multiAccount.Address) == 0.1m);

            response = node.SetScript(multiAccount, compiledScript, node.ChainId);
            node.WaitForTransactionBroadcastResponseConfirmation(response);

            var tx = new TransferTransaction(node.ChainId, multiAccount.PublicKey, Accounts.Alice.Address, Assets.ZBS, 0.07m, 0.005m)
            {
                Version = 2
            };

            tx.Sign(Accounts.Alice, 0);
            tx.Sign(Accounts.Bob, 1);

            node.BroadcastAndWait(tx);

            Assert.IsTrue(node.GetBalance(multiAccount.Address) < 0.02m);
        }
예제 #13
0
        public void TestMassTransferToAlias()
        {
            var node = new Node(Node.TestNetHost);

            var seed    = PrivateKeyAccount.GenerateSeed();
            var account = PrivateKeyAccount.CreateFromSeed(seed, 'T');

            node.Transfer(Accounts.Alice, account.Address, Assets.WAVES, 0.001m);
            Thread.Sleep(10000);

            var alias = GenerateRandomAlias();

            node.CreateAlias(account, alias, 'T');
            Thread.Sleep(10000);

            var amount        = 0.0001m;
            var balanceBefore = node.GetBalance(account.Address);

            var recipients = new List <MassTransferItem>
            {
                new MassTransferItem(account.Address, amount),
                new MassTransferItem("alias:T:" + alias, amount),
                new MassTransferItem(account.Address, amount),
                new MassTransferItem(account.Address, amount),
                new MassTransferItem("alias:T:" + alias, amount)
            };

            var tx = new MassTransferTransaction(Accounts.Alice.PublicKey, Assets.WAVES, recipients);

            tx.Sign(Accounts.Alice);
            node.Broadcast(tx.GetJsonWithSignature());

            Thread.Sleep(20000);

            var balanceAfter = node.GetBalance(account.Address);

            Assert.AreEqual(balanceBefore + amount * recipients.Count, balanceAfter);
        }
예제 #14
0
        public void TestWavesSpendingUserAccountScript()
        {
            var node = new Node();



            var tokenomicaSeed    = "aim property attract warfare stamp sample holiday input invest rather potato novel produce car arctic"; //3N6GrCERRyWw9k9siP9iPbqNV9q86jnbrYY
            var tokenomicaAccount = PrivateKeyAccount.CreateFromSeed(tokenomicaSeed, AddressEncoding.TestNet);

            var data = new DictionaryObject
            {
                { "limit", 200000001L }
            };

            var dataTx = new DataTransaction(userAccount.PublicKey, data, 0.005m).Sign(tokenomicaAccount);

            node.Broadcast(dataTx.GetJsonWithSignature());

            var wavesTransferTx = new TransferTransaction(userAccount.PublicKey, Alice.Address, Assets.WAVES, 0.01m, 0.005m).Sign(userAccount);

            wavesTransferTx.Version = 2;
            node.Broadcast(wavesTransferTx.GetJsonWithSignature());
        }
예제 #15
0
        public void TestMassTransferToAlias()
        {
            var node = new Node(Node.TestNetChainId);

            var seed    = PrivateKeyAccount.GenerateSeed();
            var account = PrivateKeyAccount.CreateFromSeed(seed, 'T');

            var response = node.Transfer(Accounts.Alice, account.Address, Assets.BCT, 0.001m);

            node.WaitTransactionConfirmationByResponse(response);

            var alias = GenerateRandomAlias();

            response = node.CreateAlias(account, alias, 'T');
            node.WaitTransactionConfirmationByResponse(response);

            var amount        = 0.0001m;
            var balanceBefore = node.GetBalance(account.Address);

            var recipients = new List <MassTransferItem>
            {
                new MassTransferItem(account.Address, amount),
                new MassTransferItem("alias:T:" + alias, amount),
                new MassTransferItem(account.Address, amount),
                new MassTransferItem(account.Address, amount),
                new MassTransferItem("alias:T:" + alias, amount)
            };

            var tx = new MassTransferTransaction(node.ChainId, Accounts.Alice.PublicKey, Assets.BCT, recipients);

            tx.Sign(Accounts.Alice);
            node.BroadcastAndWait(tx.GetJsonWithSignature());

            var balanceAfter = node.GetBalance(account.Address);

            Assert.AreEqual(balanceBefore + amount * recipients.Count, balanceAfter);
        }
예제 #16
0
        public void TestErrorMessage()
        {
            var node    = new Node(Node.TestNetChainId);
            var account = PrivateKeyAccount.CreateFromSeed(PrivateKeyAccount.GenerateSeed(), node.ChainId);

            var transferTxResponse = node.Transfer(Accounts.Alice, account.Address, Assets.WAVES, 0.02m);

            node.WaitTransactionConfirmationByResponse(transferTxResponse);

            var script = @"{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}

@Verifier(tx)
func verify() = {
    match tx {
        case d: SetScriptTransaction | DataTransaction => true
        case _ => false
    }
}";

            var compiledScript = node.CompileCode(script);

            var setScriptTxResponse = node.SetScript(account, compiledScript);

            node.WaitTransactionConfirmationByResponse(setScriptTxResponse);

            try
            {
                node.Transfer(account, account.Address, Assets.WAVES, 0.00000001m, 0.005m);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error: {e.Message}");
                Assert.AreEqual(e.Message, "Transaction is not allowed by account-script");
            }
        }
예제 #17
0
        public static (string, bool, List <string>) SendWavesFunds(bool mainnet, string privKey, string addr1, string addr2, string assetId = null)
        {
            var sentTxIds = new List <string>();
            var chainId   = Node.TestNetChainId;
            var nodeAddr  = "https://testnodes.wavesnodes.com";

            if (mainnet)
            {
                chainId  = Node.MainNetChainId;
                nodeAddr = "https://nodes.wavesnodes.com/";
            }
            var node  = new Node(nodeAddr, chainId);
            var asset = Assets.WAVES;

            if (assetId != null)
            {
                asset = node.GetAsset(assetId);
            }
            Console.WriteLine($"::send {asset.Name} funds");
            var seed = xchwallet.Utils.ParseHexString(privKey);
            var key  = PrivateKeyAccount.CreateFromSeed(seed, chainId, 0);
            var addr = key.Address;

            Console.WriteLine($"  ::privkey: {privKey}");
            Console.WriteLine($"  ::addr:    {addr}");
            var balance = node.GetBalance(addr, asset);

            Console.WriteLine($"  ::balance:        {balance} {asset.Name}");
            if (balance > 0)
            {
                var numTxs           = 6;
                var txFee            = 0.001M;
                var massTxFee        = txFee + 0.0005M * 2;
                var feeTotal         = txFee * (numTxs - 2) + massTxFee;
                var balanceAfterFees = balance - feeTotal;
                if (!asset.Equals(Assets.WAVES)) // if the asset is not waves then we ignore the fees because we are paying fees in WAVES
                {
                    balanceAfterFees = balance;
                }
                Console.WriteLine($"  ::fees:           {feeTotal} {asset.Name}");
                Console.WriteLine($"  ::balance - fees: {balanceAfterFees} {asset.Name}");
                var amount = balanceAfterFees / numTxs;
                amount = Math.Round(amount, asset.Decimals);
                var remainder = balanceAfterFees - amount * numTxs;
                Console.WriteLine($"  ::amount per tx:  {amount} (x {numTxs} = {amount * numTxs}, remainder: {remainder})");
                var txs = new List <TransferTransaction>();
                for (var i = 0; i < numTxs - 2; i++)
                {
                    var tx = new TransferTransaction(chainId, key.PublicKey, addr1, asset, amount, txFee);
                    tx.Sign(key);
                    txs.Add(tx);
                    System.Threading.Thread.Sleep(100); // sleep to ensure new timestamp
                }
                var transfers = new List <MassTransferItem>
                {
                    new MassTransferItem(addr1, amount + remainder),
                    new MassTransferItem(addr2, amount),
                };
                var massTx = new MassTransferTransaction(chainId, key.PublicKey, asset, transfers, "Shut up & take my money");
                System.Diagnostics.Debug.Assert(massTx.Fee == massTxFee);
                massTx.Sign(key);
                // send the raw signed transactions and get the txids
                try
                {
                    string output = null;
                    foreach (var tx in txs)
                    {
                        output = node.BroadcastAndWait(tx);
                        Console.WriteLine($"  {output}");
                        sentTxIds.Add(tx.GenerateId());
                    }
                    output = node.BroadcastAndWait(massTx);
                    Console.WriteLine($"  {output}");
                    sentTxIds.Add(massTx.GenerateId());
                }
                catch (System.Net.WebException ex)
                {
                    var     resp = new System.IO.StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
                    dynamic obj  = JsonConvert.DeserializeObject(resp);
                    if (obj != null)
                    {
                        Console.WriteLine($"  ERROR: {obj.message}");
                    }
                    else
                    {
                        Console.WriteLine($"  ERROR: {ex}");
                    }
                    return(addr, false, sentTxIds);
                }
            }
            return(addr, true, sentTxIds);
        }
        public void TestTransactionSerialize()
        {
            var node = new Node("http://*****:*****@"{-# STDLIB_VERSION 4 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}

@Callable(i)
func parseTxBytes(txBytes : ByteVector) = {
    let tx = transactionFromBytes(txBytes)

    let key = match(tx) {
        case t : IssueTransaction => ""3""
        case t : TransferTransaction => ""4""
        case t : ReissueTransaction => ""5""
        case t : BurnTransaction => ""6""
        case t : ExchangeTransaction => ""7""
        case t : LeaseTransaction => ""8""
        case t : LeaseCancelTransaction => ""9""
        case t : CreateAliasTransaction => ""10""
        case t : MassTransferTransaction => ""11""
        case t : DataTransaction => ""12""
        case t : SetScriptTransaction => ""13""
        case t : SponsorFeeTransaction => ""14""
        case t : SetAssetScriptTransaction => ""15""
        # case t : InvokeScriptTransaction => ""16""
        case _ => throw(""incorrect tx"")
    }

    WriteSet([
        DataEntry(key + ""_V"" + toString(extract(tx).version), toBase58String(extract(tx).id))
    ])
}";
            var compiledScript = node.CompileCode(script);
            var account        = PrivateKeyAccount.CreateFromSeed("seedddd1234", node.ChainId);

            node.SetScript(account, compiledScript);

            var txList = new List <Transaction>
            {
                new IssueTransaction(account.PublicKey, "1234", "dcvbh54tre", 123m, 3, false, node.ChainId, 2m, node.CompileCode("false"))
                {
                    Version = 1
                }.Sign(account),
                new TransferTransaction(node.ChainId, account.PublicKey, account.Address, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1234m, "1234567o")
                {
                    Version = 1
                }.Sign(account),
                new ReissueTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1234m, true, 2m)
                {
                    Version = 1
                }.Sign(account),
                new BurnTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1m)
                {
                    Version = 1
                }.Sign(account),
                new ExchangeTransaction(node.ChainId, account.PublicKey, 1m, 1m, 1m, Assets.BCT, Assets.BTC, new Order(OrderSide.Buy, 1m, 100m, 12345L.ToDate(), Assets.BCT, Assets.BTC, account.PublicKey, account.PublicKey, 123445455L.ToDate(), 124m, account.Address), new Order(OrderSide.Sell, 1m, 100m, 12345L.ToDate(), Assets.BCT, Assets.BTC, account.PublicKey, account.PublicKey, 1234454L.ToDate(), 124m, account.Address), 100m, 43m, 123456L.ToDate())
                {
                    Version = 1
                }.Sign(account),
                new LeaseTransaction(node.ChainId, account.PublicKey, account.Address, 100m)
                {
                    Version = 1
                }.Sign(account),
                new CancelLeasingTransaction(node.ChainId, account.PublicKey, "FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti")
                {
                    Version = 1
                }.Sign(account),
                new AliasTransaction(account.PublicKey, "buba", node.ChainId)
                {
                    Version = 1
                }.Sign(account),

                // without proofs
                new IssueTransaction(account.PublicKey, "1234", "dcvbh54tre", 123m, 3, false, node.ChainId, 2m, node.CompileCode("false")),
                new TransferTransaction(node.ChainId, account.PublicKey, account.Address, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1234m, "1234567o"),
                new ReissueTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1234m, true, 2m),
                new BurnTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1m),
                new ExchangeTransaction(node.ChainId, account.PublicKey, 1m, 1m, 1m, Assets.BCT, Assets.BTC, new Order(OrderSide.Buy, 1m, 100m, 12345L.ToDate(), Assets.BCT, Assets.BTC, account.PublicKey, account.PublicKey, 123445455L.ToDate(), 124m, account.Address), new Order(OrderSide.Sell, 1m, 100m, 12345L.ToDate(), Assets.BCT, Assets.BTC, account.PublicKey, account.PublicKey, 1234454L.ToDate(), 124m, account.Address), 100m, 43m, 123456L.ToDate()),
                new LeaseTransaction(node.ChainId, account.PublicKey, account.Address, 100m),
                new CancelLeasingTransaction(node.ChainId, account.PublicKey, "FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti"),
                new AliasTransaction(account.PublicKey, "buba", node.ChainId),
                new MassTransferTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), new List <MassTransferItem> {
                    new MassTransferItem(account.Address, 1m)
                }, "hello"),
                new DataTransaction(node.ChainId, account.PublicKey, new Dictionary <string, object>()),
                new SetScriptTransaction(account.PublicKey, node.CompileCode("true"), node.ChainId),
                new SponsoredFeeTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1m),
                new SetAssetScriptTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), node.CompileCode("true")),
                new InvokeScriptTransaction(node.ChainId, account.PublicKey, account.Address, "wertyu", new List <object> {
                    42L
                }, null, 0.005m, Assets.BCT),

                // with proofs
                new IssueTransaction(account.PublicKey, "1234", "dcvbh54tre", 123m, 3, false, node.ChainId, 2m, node.CompileCode("false")).Sign(account).Sign(account, 1),
                new TransferTransaction(node.ChainId, account.PublicKey, account.Address, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1234m, "1234567o").Sign(account),
                new ReissueTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1234m, true, 2m).Sign(account),
                new BurnTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1m).Sign(account),
                new ExchangeTransaction(node.ChainId, account.PublicKey, 1m, 1m, 1m, Assets.BCT, Assets.BTC, new Order(OrderSide.Buy, 1m, 100m, 12345L.ToDate(), Assets.BCT, Assets.BTC, account.PublicKey, account.PublicKey, 123445455L.ToDate(), 124m, account.Address), new Order(OrderSide.Sell, 1m, 100m, 12345L.ToDate(), Assets.BCT, Assets.BTC, account.PublicKey, account.PublicKey, 1234454L.ToDate(), 124m, account.Address), 100m, 43m, 123456L.ToDate()).Sign(account),
                new LeaseTransaction(node.ChainId, account.PublicKey, account.Address, 100m).Sign(account),
                new CancelLeasingTransaction(node.ChainId, account.PublicKey, "FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti").Sign(account),
                new AliasTransaction(account.PublicKey, "buba", node.ChainId).Sign(account),
                new MassTransferTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), new List <MassTransferItem> {
                    new MassTransferItem(account.Address, 1m)
                }, "hello").Sign(account),
                new DataTransaction(node.ChainId, account.PublicKey, new Dictionary <string, object>()).Sign(account),
                new SetScriptTransaction(account.PublicKey, node.CompileCode("true"), node.ChainId).Sign(account),
                new SponsoredFeeTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), 1m).Sign(account),
                new SetAssetScriptTransaction(node.ChainId, account.PublicKey, new Asset("FTQvw9zdYirRksUFCKDvor3hiu2NiUjXEPTDEcircqti", "", 4), node.CompileCode("true")).Sign(account),
                new InvokeScriptTransaction(node.ChainId, account.PublicKey, account.Address, "wertyu", new List <object> {
                    42L
                }, null, 0.005m, Assets.BCT).Sign(account)
            };

            foreach (var tx in txList)
            {
                var bytes    = tx.GetBytes();
                var response = node.InvokeScript(account, account.Address, "parseTxBytes", new List <object> {
                    bytes
                }, null, 0.009m, Assets.BCT);

                node.WaitTransactionConfirmation(response);
                var type = tx.GetJson().GetByte("type").ToString();
                Assert.AreEqual(node.GetAddressData(account.Address)[type], tx.GenerateId());
            }
        }
예제 #19
0
        private static async Task Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                                .SetBasePath(Directory.GetCurrentDirectory())
#if DEBUG
                                .AddJsonFile("appsettings.development.json", optional: true, reloadOnChange: true)
#elif RELEASE
                                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#endif
                                .AddCommandLine(args)
                                .Build();

            var seed     = args[0];
            var settings = configuration.Get <Settings>();

            var nodeApi     = new Node(settings.NodeUrl, settings.ChainId);
            var account     = PrivateKeyAccount.CreateFromSeed(seed, settings.ChainId);
            var wavesHelper = new WavesHelper(settings.NodeUrl, settings.ChainId);

            Logger.Info("Start price oracle");
            while (true)
            {
                try
                {
                    var height = await wavesHelper.GetHeight();

                    Logger.Info($"Height:{height}");
                    var controlContractData = AccountDataConverter.ToControlAccountData(await wavesHelper.GetDataByAddress(settings.ContractAddress));

                    var newPrice = await GetPrice();

                    var oracleData = AccountDataConverter.ToOracleAccountData(await wavesHelper.GetDataByAddress(account.Address));
                    if (!oracleData.PriceByHeight?.ContainsKey(Convert.ToString(height)) ?? true)
                    {
                        var tx = nodeApi.PutData(account, new Dictionary <string, object>()
                        {
                            { "price_" + height, newPrice }
                        });
                        Logger.Info($"Tx set current price ({newPrice}): {(string) JObject.Parse(tx)["id"]}");
                        Logger.Debug(tx);
                    }

                    var oraclePriceCount = 0;
                    foreach (var oracle in controlContractData.Oracles.Split(","))
                    {
                        var anyOracleData = AccountDataConverter.ToOracleAccountData(await wavesHelper.GetDataByAddress(oracle));
                        if (anyOracleData.PriceByHeight?.ContainsKey(Convert.ToString(height)) ?? false)
                        {
                            oraclePriceCount++;
                        }
                    }

                    Logger.Debug("Oracle price count:" + oraclePriceCount);
                    if (oraclePriceCount >= controlContractData.BftCoefficientOracle && (!controlContractData.PriceByHeight?.ContainsKey(Convert.ToString(height)) ?? true))
                    {
                        var tx = nodeApi.InvokeScript(account, settings.ContractAddress, "finalizeCurrentPrice", null);
                        Logger.Info($"Tx finalize current price: {(string) JObject.Parse(tx)["id"]}");
                        Logger.Debug(tx);
                    }

                    Logger.Info($"Сurrent price:{controlContractData.Price}");
                    Logger.Info($"New price:{newPrice}");
                }
                catch (Exception ex)
                {
                    Logger.Error(ex);
                }

                Logger.Info($"Sleep");
                await Task.Delay(TimeSpan.FromSeconds(settings.TimeoutSec));
            }
        }
예제 #20
0
        private static async Task Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                                .SetBasePath(Directory.GetCurrentDirectory())
#if DEBUG
                                .AddJsonFile("appsettings.development.json", optional: true, reloadOnChange: true)
#elif RELEASE
                                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#endif
                                .AddCommandLine(args)
                                .Build();

            var settings = configuration.Get <Settings>();
            var seed     = args[0];

            var wavesHelper     = new WavesHelper(settings.NodeUrl, settings.ChainId);
            var account         = PrivateKeyAccount.CreateFromSeed(seed, settings.ChainId);
            var node            = new Node(settings.NodeUrl, settings.ChainId);
            var contractPubKey  = Base58.Decode((settings.ContractPubKey));
            var contractAddress = AddressEncoding.GetAddressFromPublicKey(contractPubKey, settings.ChainId);

            while (true)
            {
                try
                {
                    var height = await wavesHelper.GetHeight();

                    Logger.Info("New height: " + height);
                    Logger.Info("Init");

                    var neutrinoContractData = AccountDataConverter.ToNeutrinoAccountData(
                        await wavesHelper.GetDataByAddress(contractAddress));
                    var controlContractData = AccountDataConverter.ToControlAccountData(
                        await wavesHelper.GetDataByAddress(neutrinoContractData.ControlContractAddress));
                    var auctionControlData = AccountDataConverter.ToAuctionAccountData(
                        await wavesHelper.GetDataByAddress(neutrinoContractData.AuctionContractAddress));
                    var liquidationControlData = AccountDataConverter.ToLiquidationAccountData(
                        await wavesHelper.GetDataByAddress(neutrinoContractData.LiquidationContractAddress));

                    var totalNeutrinoSupply = await wavesHelper.GetTotalSupply(neutrinoContractData.NeutrinoAssetId);

                    var neutrinoBalance = await wavesHelper.GetBalance(contractAddress, neutrinoContractData.NeutrinoAssetId);

                    var wavesBalance = await wavesHelper.GetBalance(contractAddress);

                    Logger.Info($"Price:{controlContractData.Price}");

                    var neutrinoContractBalance = await wavesHelper.GetDetailsBalance(contractAddress);

                    var addresses = new List <string>();
                    if (neutrinoContractData.BalanceLockNeutrinoByUser != null)
                    {
                        addresses.AddRange(neutrinoContractData.BalanceLockNeutrinoByUser.Where(x => x.Value > 0).Select(x => x.Key));
                    }
                    if (neutrinoContractData.BalanceLockWavesByUser != null)
                    {
                        addresses.AddRange(neutrinoContractData.BalanceLockWavesByUser?.Where(x => x.Value > 0).Select(x => x.Key));
                    }

                    long totalWithdraw = 0;
                    foreach (var address in addresses)
                    {
                        var withdrawBlock = neutrinoContractData.BalanceUnlockBlockByAddress.GetValueOrDefault(address);
                        if (height < withdrawBlock)
                        {
                            continue;
                        }

                        var indexes = controlContractData.PriceHeightByIndex.Where(x => x.Value >= withdrawBlock).ToList();

                        if (!indexes.Any())
                        {
                            continue;
                        }

                        var indexString            = indexes.Min(x => x.Key);
                        var index                  = Convert.ToInt64(indexString);
                        var heightByIndex          = controlContractData.PriceHeightByIndex[indexString];
                        var priceByHeight          = controlContractData.PriceByHeight[Convert.ToString(heightByIndex)];
                        var withdrawNeutrinoAmount = neutrinoContractData.BalanceLockNeutrinoByUser.GetValueOrDefault(address);

                        if (withdrawNeutrinoAmount > 0)
                        {
                            var availableBalance = neutrinoContractBalance.Available - totalWithdraw;
                            var wavesAmount      = CurrencyConvert.NeutrinoToWaves(withdrawNeutrinoAmount, priceByHeight);

                            if (wavesAmount > availableBalance)
                            {
                                if (!settings.Leasing.IsLeasingProvider)
                                {
                                    continue;
                                }

                                var totalLeasingCancelAmount = 0L;
                                var activeLeaseTxs           = await wavesHelper.GetActiveLease(settings.Leasing.NodeAddress);

                                foreach (var leasingTx in activeLeaseTxs.OrderBy(x => x.Amount))
                                {
                                    if (totalLeasingCancelAmount >= wavesAmount)
                                    {
                                        break;
                                    }

                                    totalLeasingCancelAmount += leasingTx.Amount;
                                    var cancelLease = new CancelLeasingTransaction(settings.ChainId, contractPubKey, leasingTx.Id, 0.005m);
                                    cancelLease.Sign(account);
                                    // shit code. Bug in wavesCs
                                    var json = JObject.Parse(cancelLease.GetJsonWithSignature().ToJson());
                                    json.Add("proofs", new JArray {
                                        cancelLease.Proofs.Take(Array.FindLastIndex(cancelLease.Proofs, p => p != null && p.Length > 0) + 1)
                                        .Select(p => p == null ? "" : p.ToBase58())
                                        .ToArray()
                                    });
                                    json.Add("version", 2);
                                    json.Add("chainId", settings.ChainId);
                                    var id = await wavesHelper.WaitTxAndGetId(await wavesHelper.Broadcast(json.ToString()));

                                    Logger.Info($"Cancel lease tx:{id} (LeaseId:{cancelLease.LeaseId})");
                                }
                            }

                            totalWithdraw += wavesAmount;
                        }

                        var withdrawTx = node.InvokeScript(account, contractAddress, "withdraw",
                                                           new List <object>()
                        {
                            address, index
                        });
                        var txId = await wavesHelper.WaitTxAndGetId(withdrawTx);

                        Logger.Info($"Withdraw tx id:{txId} (Address:{address})");
                    }

                    if (settings.Leasing.IsLeasingProvider)
                    {
                        var leasingAmountForOneTxInWavelet = settings.Leasing.LeasingAmountForOneTx * CurrencyConvert.Wavelet;

                        var minWaves         = Convert.ToInt64((neutrinoContractBalance.Regular - totalWithdraw) / 100 * (100 - settings.Leasing.LeasingSharePercent));
                        var availableBalance = neutrinoContractBalance.Available - totalWithdraw;
                        var neededAmount     = minWaves - availableBalance;
                        var activeLeaseTxs   = await wavesHelper.GetActiveLease(settings.Leasing.NodeAddress);

                        var totalLeasingCancelAmount = 0L;
                        if (neededAmount > leasingAmountForOneTxInWavelet)
                        {
                            foreach (var leasingTx in activeLeaseTxs.OrderBy(x => x.Amount).Where(x => x.Sender == contractAddress))
                            {
                                if (totalLeasingCancelAmount >= neededAmount)
                                {
                                    break;
                                }

                                totalLeasingCancelAmount += leasingTx.Amount;
                                var cancelLease = new CancelLeasingTransaction(settings.ChainId, contractPubKey,
                                                                               leasingTx.Id, 0.005m);
                                cancelLease.Sign(account);
                                // shit code. Bug in wavesCs
                                var json = JObject.Parse(cancelLease.GetJsonWithSignature().ToJson());
                                json.Add("proofs", new JArray
                                {
                                    cancelLease.Proofs
                                    .Take(Array.FindLastIndex(cancelLease.Proofs, p => p != null && p.Length > 0) +
                                          1)
                                    .Select(p => p == null ? "" : p.ToBase58())
                                    .ToArray()
                                });
                                json.Add("version", 2);
                                json.Add("chainId", settings.ChainId);
                                var id = await wavesHelper.WaitTxAndGetId(await wavesHelper.Broadcast(json.ToString()));

                                Logger.Info($"Cancel lease tx:{id} (LeaseId:{cancelLease.LeaseId})");
                            }
                        }

                        var expectedLeasingBalance = Convert.ToInt64((neutrinoContractBalance.Regular - totalWithdraw) / 100 * settings.Leasing.LeasingSharePercent);
                        var leasingBalance         = neutrinoContractBalance.Regular - neutrinoContractBalance.Available;
                        var neededLeaseTx          = expectedLeasingBalance - leasingBalance;


                        while (neededLeaseTx >= leasingAmountForOneTxInWavelet)
                        {
                            neededLeaseTx -= leasingAmountForOneTxInWavelet;
                            var leaseTx = new LeaseTransaction(settings.ChainId, contractPubKey, settings.Leasing.NodeAddress, settings.Leasing.LeasingAmountForOneTx, 0.005m);
                            leaseTx.Sign(account);
                            // shit code. Bug in wavesCs
                            var json = JObject.Parse(leaseTx.GetJsonWithSignature().ToJson());
                            json.Add("proofs", new JArray {
                                leaseTx.Proofs.Take(Array.FindLastIndex(leaseTx.Proofs, p => p != null && p.Length > 0) + 1)
                                .Select(p => p == null ? "" : p.ToBase58())
                                .ToArray()
                            });
                            json.Add("version", 2);
                            var id = await wavesHelper.WaitTxAndGetId(await wavesHelper.Broadcast(json.ToString()));

                            Logger.Info($"Lease tx:{id}");
                        }
                    }

                    var supply  = totalNeutrinoSupply - neutrinoBalance + neutrinoContractData.BalanceLockNeutrino;
                    var reserve = wavesBalance - neutrinoContractData.BalanceLockWaves;

                    Logger.Info($"Supply:{supply}");
                    Logger.Info($"Reserve:{reserve}");

                    var bondAuctionBalance = await wavesHelper.GetBalance(neutrinoContractData.AuctionContractAddress,
                                                                          neutrinoContractData.BondAssetId);

                    var deficit = CurrencyConvert.NeutrinoToBond(supply - CurrencyConvert.WavesToNeutrino(reserve, controlContractData.Price));
                    var liquidationContractBalance = CurrencyConvert.NeutrinoToBond(await wavesHelper.GetBalance(neutrinoContractData.LiquidationContractAddress, neutrinoContractData.NeutrinoAssetId));

                    Logger.Info($"Deficit:{deficit}");
                    Logger.Info($"BondBalance:{bondAuctionBalance}");

                    if ((deficit > 0 && deficit - bondAuctionBalance >= CurrencyConvert.NeutrinoToBond(supply) * DeficitOffset / 100) || (deficit * -1) - liquidationContractBalance > 0)
                    {
                        Logger.Info("Transfer to auction");
                        var generateBondTx = node.InvokeScript(account, contractAddress,
                                                               "transferToAuction", null);
                        var txId = await wavesHelper.WaitTxAndGetId(generateBondTx);

                        Logger.Info($"Transfer to auction tx id:{txId}");
                    }
                    var surplusWithoutLiquidation = CurrencyConvert.NeutrinoToBond(CurrencyConvert.WavesToNeutrino(reserve, controlContractData.Price) - supply - CurrencyConvert.BondToNeutrino(liquidationContractBalance));
                    if (surplusWithoutLiquidation > 0 && liquidationContractBalance > 0 && !string.IsNullOrEmpty(liquidationControlData.Orderbook))
                    {
                        Logger.Info("Execute order for liquidation");

                        var  orders       = liquidationControlData.Orderbook.Split("_");
                        long totalExecute = 0;
                        var  surplus      = Math.Abs(deficit);
                        foreach (var order in orders.Where(x => !string.IsNullOrEmpty(x)))
                        {
                            var total       = liquidationControlData.TotalByOrder[order];
                            var totalFilled = liquidationControlData.FilledTotalByOrder?.GetValueOrDefault(order) ?? 0;
                            var amount      = total - totalFilled;
                            if (totalExecute >= surplus)
                            {
                                break;
                            }

                            totalExecute += amount;

                            var exTx = node.InvokeScript(account, neutrinoContractData.LiquidationContractAddress, "liquidateBond",
                                                         null);
                            var txId = await wavesHelper.WaitTxAndGetId(exTx);

                            Logger.Info($"Execute order tx id:{txId}");
                        }
                    }
                    else if (surplusWithoutLiquidation <= 0 && liquidationContractBalance > 0)
                    {
                        var exTx = node.InvokeScript(account, neutrinoContractData.LiquidationContractAddress,
                                                     "liquidateBond",
                                                     null);
                        var txId = await wavesHelper.WaitTxAndGetId(exTx);

                        Logger.Info($"Execute order tx id:{txId}");
                    }
                    else if (deficit > 0 && bondAuctionBalance > 0 && !string.IsNullOrEmpty(auctionControlData.Orderbook))
                    {
                        Logger.Info("Execute order for auction");

                        var  orders       = auctionControlData.Orderbook.Split("_");
                        long totalExecute = 0;
                        foreach (var order in orders.Where(x => !string.IsNullOrEmpty(x)))
                        {
                            var total       = auctionControlData.TotalByOrder[order];
                            var totalFilled = auctionControlData.FilledTotalByOrder?.GetValueOrDefault(order) ?? 0;
                            var amount      = CurrencyConvert.NeutrinoToBond(total - totalFilled) * 100 / auctionControlData.PriceByOrder[order];

                            if (totalExecute >= deficit)
                            {
                                break;
                            }

                            totalExecute += amount;

                            var exTx = node.InvokeScript(account, neutrinoContractData.AuctionContractAddress,
                                                         "sellBond", null);
                            var exTxId = await wavesHelper.WaitTxAndGetId(exTx);

                            Logger.Info($"Execute order tx id:{exTxId}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex);
                }

                await Task.Delay(TimeSpan.FromSeconds(settings.TimeoutSec));
            }
        }
예제 #21
0
        PrivateKeyAccount CreateAccount(int nonce)
        {
            var seed = Utils.ParseHexString(seedHex);

            return(PrivateKeyAccount.CreateFromSeed(seed, ChainId(), nonce));
        }